📄 ledgerservices.java
字号:
// If method is COGS_AVG_COST, also compute the inventory adjustment amount = (prodAvgCost - unitCost) * quantityOnHandVar BigDecimal inventoryAdjAmount = null; if ((cogsMethodId != null) && (cogsMethodId.equals("COGS_AVG_COST"))) { BigDecimal prodAvgCost = UtilCOGS.getProductAverageCost(productId, ownerPartyId, userLogin, delegator, dispatcher); if (prodAvgCost == null) return ServiceUtil.returnError("Unable to find a product average cost for product ["+productId+"] in organization ["+ownerPartyId+"]"); // TODO: there could be rounding issues here; maybe it's better to do something like this: // (prodAvgCost * quantityOnHandVar) - (unitCost * quantityOnHandVar) and then set the scale. inventoryAdjAmount = prodAvgCost.subtract(unitCost).multiply(quantityOnHandVar).setScale(decimals, rounding); } // Inventory GL account String invGlAcctId = UtilAccounting.getProductOrgGlAccountId(productId, "INVENTORY_ACCOUNT", ownerPartyId, delegator); // Variance Expense GL Account // TODO: At some point, maybe we should add an accountTypeId field to the primary key of the VarianceReasonGlAccount so that // we can set, for each and every variance reason, the account for the primary transaction and // the account for the adjustment? // For now I'll assume that the credit (C) accounts for the primary transaction // and for the adjustment transaction are the same. GenericValue varianceReason = inventoryVariance.getRelatedOne("VarianceReason"); GenericValue varExpGlAcct = EntityUtil.getFirst(varianceReason.getRelatedByAnd("VarianceReasonGlAccount", UtilMisc.toMap("organizationPartyId", ownerPartyId))); if (varExpGlAcct == null) { return ServiceUtil.returnError("Could not find Variance Expense GL Account for variance reason ["+varianceReason.get("description")+"]."); } String varExpGlAcctId = (String) varExpGlAcct.get("glAccountId"); // =========================================================== // Transaction to credit the variance expense GL acct tmpMap = UtilMisc.toMap("glAccountId", varExpGlAcctId, "debitCreditFlag", "C", "amount", new Double(transactionAmount.doubleValue()), "acctgTransEntrySeqId", Integer.toString(0), "organizationPartyId", ownerPartyId, "acctgTransEntryTypeId", "_NA_"); tmpMap.put("productId", productId); GenericValue varExpGlAcctTrans = delegator.makeValue("AcctgTransEntry", tmpMap); // Transaction to debit the inventory GL acct tmpMap = UtilMisc.toMap("glAccountId", invGlAcctId, "debitCreditFlag", "D", "amount", new Double(transactionAmount.doubleValue()), "acctgTransEntrySeqId", Integer.toString(1), "organizationPartyId", ownerPartyId, "acctgTransEntryTypeId", "_NA_"); tmpMap.put("productId", productId); GenericValue invGlAcctTrans = delegator.makeValue("AcctgTransEntry", tmpMap); List transEntries = UtilMisc.toList(varExpGlAcctTrans, invGlAcctTrans); // Adjustment transaction for the difference of unit cost and average cost if ((inventoryAdjAmount != null) && (inventoryAdjAmount.compareTo(ZERO) != 0)) { // Inventory GL account for inventory cost adjustments String invGlAcctAdjId = UtilAccounting.getProductOrgGlAccountId(productId, "INV_ADJ_AVG_COST", ownerPartyId, delegator); // TODO: for now I'll assume that the credit (C) account // for the adjustment transaction is the same one of the // primary transaction. // Transaction to credit the variance expense GL acct tmpMap = UtilMisc.toMap("glAccountId", varExpGlAcctId, "debitCreditFlag", "C", "amount", new Double(inventoryAdjAmount.doubleValue()), "acctgTransEntrySeqId", Integer.toString(0), "organizationPartyId", ownerPartyId, "acctgTransEntryTypeId", "_NA_"); tmpMap.put("productId", productId); GenericValue varExpGlAcctAdjTrans = delegator.makeValue("AcctgTransEntry", tmpMap); transEntries.add(varExpGlAcctAdjTrans); // Transaction to debit the inventory GL acct tmpMap = UtilMisc.toMap("glAccountId", invGlAcctAdjId, "debitCreditFlag", "D", "amount", new Double(inventoryAdjAmount.doubleValue()), "acctgTransEntrySeqId", Integer.toString(1), "organizationPartyId", ownerPartyId, "acctgTransEntryTypeId", "_NA_"); tmpMap.put("productId", productId); GenericValue invGlAcctAdjTrans = delegator.makeValue("AcctgTransEntry", tmpMap); transEntries.add(invGlAcctAdjTrans); } // Perform the transaction tmpMap = UtilMisc.toMap("acctgTransEntries", transEntries, "glFiscalTypeId", "ACTUAL", "acctgTransTypeId", "ITEM_VARIANCE_ACCTG_", "transactionDate", UtilDateTime.nowTimestamp(), "userLogin", userLogin); tmpMap.put("inventoryItemId", inventoryItemId); tmpMap.put("physicalInventoryId", physicalInventoryId); tmpMap = dispatcher.runSync("createAcctgTransAndEntries", tmpMap); if (ServiceUtil.isError(tmpMap)) { return tmpMap; } Map result = ServiceUtil.returnSuccess(); result.put("acctgTransId", tmpMap.get("acctgTransId")); return result; } catch (GenericEntityException ex) { return(ServiceUtil.returnError(ex.getMessage())); } catch (GenericServiceException ex) { return(ServiceUtil.returnError(ex.getMessage())); } } /** * Service to post outbound Shipments to GL. * @author Jacopo Cappellato */ public static Map postShipmentToGl(DispatchContext dctx, Map context) { GenericDelegator delegator = dctx.getDelegator(); LocalDispatcher dispatcher = dctx.getDispatcher(); GenericValue userLogin = (GenericValue) context.get("userLogin"); String shipmentId = (String) context.get("shipmentId"); try { List issuances = delegator.findByAnd("ItemIssuance", UtilMisc.toMap("shipmentId", shipmentId)); Iterator issuancesIt = issuances.iterator(); List transEntries = new ArrayList(); Map input = null; String partyIdTo = null; while (issuancesIt.hasNext()) { GenericValue itemIssuance = (GenericValue)issuancesIt.next(); GenericValue inventoryItem = itemIssuance.getRelatedOne("InventoryItem"); GenericValue orderHeader = itemIssuance.getRelatedOne("OrderHeader"); GenericValue orderRole = EntityUtil.getFirst(orderHeader.getRelatedByAnd("OrderRole", UtilMisc.toMap("roleTypeId", "BILL_TO_CUSTOMER"))); partyIdTo = orderRole.getString("partyId"); String productId = inventoryItem.getString("productId"); BigDecimal quantityIssued = itemIssuance.getBigDecimal("quantity"); // get the inventory item's owner String ownerPartyId = inventoryItem.getString("ownerPartyId"); // get the inventory item unit cost BigDecimal unitCost = inventoryItem.getBigDecimal("unitCost"); // get the currency conversion factor BigDecimal conversionFactor = new BigDecimal(UtilFinancial.determineUomConversionFactor(delegator, dispatcher, ownerPartyId, inventoryItem.getString("currencyUomId"))); // validate the unitCost and compute transaction amount if (unitCost == null) { return ServiceUtil.returnError("Could not determine unitCost of product [" + productId + "] for item issuance [" + itemIssuance.getString("itemIssuanceId") + "] and inventory item [" + inventoryItem + "]"); } // convert the intentory item's unit cost into the owner's currency unitCost = unitCost.multiply(conversionFactor).setScale(decimals, rounding); BigDecimal transactionAmount = unitCost.multiply(quantityIssued).setScale(decimals, rounding); // Inventory GL account String invGlAcctId = UtilAccounting.getProductOrgGlAccountId(productId, "INVENTORY_ACCOUNT", ownerPartyId, delegator); String invGlAcctCogsId = UtilAccounting.getProductOrgGlAccountId(productId, "COGS_ACCOUNT", ownerPartyId, delegator); // Transaction to credit the inventory account input = UtilMisc.toMap("glAccountId", invGlAcctId, "organizationPartyId", ownerPartyId, "partyId", partyIdTo); input.put("productId", productId); input.put("amount", new Double(transactionAmount.doubleValue())); input.put("acctgTransEntryTypeId", "_NA_"); input.put("debitCreditFlag", "C"); input.put("acctgTransEntrySeqId", Integer.toString(0)); input.put("roleTypeId", "BILL_TO_CUSTOMER"); GenericValue creditAcctTrans = delegator.makeValue("AcctgTransEntry", input); transEntries.add(creditAcctTrans); // Transaction to debit the cogs account input = UtilMisc.toMap("glAccountId", invGlAcctCogsId, "organizationPartyId", ownerPartyId, "partyId", partyIdTo); input.put("productId", productId); input.put("amount", new Double(transactionAmount.doubleValue())); input.put("acctgTransEntryTypeId", "_NA_"); input.put("debitCreditFlag", "D"); input.put("acctgTransEntrySeqId", Integer.toString(1)); input.put("roleTypeId", "BILL_TO_CUSTOMER"); GenericValue debitAcctTrans = delegator.makeValue("AcctgTransEntry", input); transEntries.add(debitAcctTrans); // Get owner's party COGS method. If method is COGS_AVG_COST, also compute the inventory adjustment amount = (prodAvgCost - unitCost) * quantityOnHandVar GenericValue acctgPref = delegator.findByPrimaryKeyCache("PartyAcctgPreference", UtilMisc.toMap("partyId", ownerPartyId)); String cogsMethodId = acctgPref.getString("cogsMethodId"); BigDecimal inventoryAdjAmount = null; if ((cogsMethodId != null) && (cogsMethodId.equals("COGS_AVG_COST"))) { BigDecimal prodAvgCost = UtilCOGS.getProductAverageCost(productId, ownerPartyId, userLogin, delegator, dispatcher); if (prodAvgCost == null) return ServiceUtil.returnError("Unable to find a product average cost for product ["+productId+"] in organization ["+ownerPartyId+"]"); // TODO: there could be rounding issues here; maybe it's better to do something like this: // (prodAvgCost * quantityOnHandVar) - (unitCost * quantityOnHandVar) and then set the scale. inventoryAdjAmount = prodAvgCost.subtract(unitCost).multiply(quantityIssued).setScale(decimals, rounding); } // Adjustment accounting transaction if ((inventoryAdjAmount != null) && (inventoryAdjAmount.compareTo(ZERO) != 0)) { // GL accounts for cost adjustments due to Average Cost. Right now we're going to use a separate INVENTORY AVG_COST adjustment, but the COGS adjustment just goes to COGS String invGlAcctAdjId = UtilAccounting.getProductOrgGlAccountId(productId, "INV_ADJ_AVG_COST", ownerPartyId, delegator); String invGlAcctAdjCogsId = UtilAccounting.getProductOrgGlAccountId(productId, "COGS_ADJ_AVG_COST", ownerPartyId, delegator); // Transaction to credit the adj inventory GL acct input = UtilMisc.toMap("glAccountId", invGlAcctAdjId, "debitCreditFlag", "C", "amount", new Double(inventoryAdjAmount.doubleValue()), "acctgTransEntrySeqId", Integer.toString(0), "organizationPartyId", ownerPartyId, "acctgTransEntryTypeId", "_NA_"); input.put("productId", productId); input.put("partyId", partyIdTo); input.put("roleTypeId", "BILL_TO_CUSTOMER"); transEntries.add(delegator.makeValue("AcctgTransEntry", input)); // Transaction to debit the adj cogs GL acct input = UtilMisc.toMap("glAccountId", invGlAcctAdjCogsId, "debitCreditFlag", "D", "amount", new Double(inventoryAdjAmount.doubleValue()), "acctgTransEntrySeqId", Integer.toString(1), "organizationPartyId", ownerPartyId, "acctgTransEntryTypeId", "_NA_"); input.put("productId", productId); input.put("partyId", partyIdTo); input.put("roleTypeId", "BILL_TO_CUSTOMER"); transEntries.add(delegator.makeValue("AcctgTransEntry", input)); } } // Perform the transaction input = UtilMisc.toMap("transactionDate", UtilDateTime.nowTimestamp(), "userLogin", userLogin); input.put("acctgTransEntries", transEntries); input.put("glFiscalTypeId", "ACTUAL"); input.put("acctgTransTypeId", "OBLIGATION_ACCTG_TRA"); input.put("shipmentId", shipmentId); Map servResult = dispatcher.runSync("createAcctgTransAndEntries", input); if (ServiceUtil.isError(servResult)) { return servResult; } Map result = ServiceUtil.returnSuccess(); result.put("acctgTransId", servResult.get("acctgTransId")); } catch (GenericEntityException ex) { return(ServiceUtil.returnError(ex.getMessage())); } catch (GenericServiceException ex) { return(ServiceUtil.returnError(ex.getMessage())); } return ServiceUtil.returnSuccess(); } /** * Service to post a shipment receipt to GL. * @author Leon Torres */ public static Map postShipmentReceiptToGl(DispatchContext dctx, Map context) { GenericDelegator delegator = dctx.getDelegator(); LocalDispatcher dispatcher = dctx.getDispatcher(); GenericValue userLogin = (GenericValue) context.get("userLogin");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -