📄 ledgerservices.java
字号:
acctgTransEntry.put("roleTypeId", transactionPartyRoleTypeId); } // update loop variables acctgTransEntries.add(acctgTransEntry); postingTotal = postingTotal.add(postingAmount); // this preserves the postingAmount scale (addition => scale = max(scale1, scale2)) // next, if an invoice item is a product, then we will need to post COGS and INVENTORY as well. // Must check invoiceItemTypeId or you'd end up posting to COGS for adjustment entries, sales tax, etc. if (!(invoiceItem.getString("invoiceItemTypeId").equals("INV_FPROD_ITEM") && (invoiceItem.getString("productId") != null))) { return UtilMisc.toMap("postingTotal", postingTotal); } return UtilMisc.toMap("postingTotal", postingTotal); } /** * If an invoice item is not a product, or if it has no specific GL account defined, * check if there is a GL account defined generally for this invoice item type and * this accounting organization (party). If there is still no organization-specific * GL account for this invoice item type, then use InvoiceItemType's default GL account. * However, if an overrideGlAccountId is present in the invoiceItem, return that instead. */ private static String getDefaultGlAccount(GenericValue invoiceItem, String organizationPartyId) throws GenericEntityException { if (invoiceItem.getString("overrideGlAccountId") != null) return invoiceItem.getString("overrideGlAccountId"); GenericValue invoiceItemType = invoiceItem.getRelatedOne("InvoiceItemType"); List orgInvoiceItemTypeGlAccounts = invoiceItemType.getRelatedByAnd("InvoiceItemTypeGlAccount", UtilMisc.toMap("organizationPartyId", organizationPartyId)); if ((orgInvoiceItemTypeGlAccounts != null) && (orgInvoiceItemTypeGlAccounts.size() == 1)) { return ((GenericValue) orgInvoiceItemTypeGlAccounts.get(0)).getString("glAccountId"); } else { return invoiceItemType.getString("defaultGlAccountId"); } } /* ====================================================================== */ /* ===== END POST INVOICE TO GL ===== */ /* ====================================================================== */ /** * Service to post a payment other than tax payments to the General Ledger. * @param paymentId * @return * @author Leon Torres */ public static Map postPaymentToGl(DispatchContext dctx, Map context) { GenericDelegator delegator = dctx.getDelegator(); LocalDispatcher dispatcher = dctx.getDispatcher(); GenericValue userLogin = (GenericValue) context.get("userLogin"); String paymentId = (String) context.get("paymentId"); try { GenericValue payment = delegator.findByPrimaryKey("Payment", UtilMisc.toMap("paymentId", paymentId)); // figure out the parties involved and the payment gl account Map results = dispatcher.runSync("getPaymentAccountAndParties", UtilMisc.toMap("paymentId", paymentId)); if (results.get(ModelService.RESPONSE_MESSAGE).equals(ModelService.RESPOND_ERROR)) { return results; } String organizationPartyId = (String) results.get("organizationPartyId"); String transactionPartyId = (String) results.get("transactionPartyId"); String paymentGlAccountId = (String) results.get("glAccountId"); // determine the amount of the payment involved double conversionFactor = UtilFinancial.determineUomConversionFactor(delegator, dispatcher, organizationPartyId, payment.getString("currencyUomId")); if (payment.getDouble("amount") == null) { return ServiceUtil.returnError("Cannot post Payment to GL: Payment with paymentId " + paymentId + " has no amount."); } double transactionAmount = conversionFactor * payment.getDouble("amount").doubleValue(); // These Maps hold glAccountId (String) -> amount (Double) pairs are designed to track how much of the payment goes to each gl account. Right now // they are only used for tax-related payments where a tax authority can have different GL accounts in different Geos, but they // also allow much more flexibility in mapping out payments. Map paymentGlAccountAmounts = UtilMisc.toMap(paymentGlAccountId, new Double(transactionAmount)); Map offsettingGlAccountAmounts = new HashMap(); if (UtilAccounting.isTaxPayment(payment)) { // Build a Map of gl account Id and amount based on the Geo specified in PaymentApplication and the combination of partyId // and geo which specify a gl account in TaxAuthorityGlAccount List paymentApplications = payment.getRelated("PaymentApplication"); for (Iterator pAi = paymentApplications.iterator(); pAi.hasNext(); ) { GenericValue appl = (GenericValue) pAi.next(); if (appl.getString("taxAuthGeoId") != null) { GenericValue taxAuthGlAccount = delegator.findByPrimaryKeyCache("TaxAuthorityGlAccount", UtilMisc.toMap("organizationPartyId", organizationPartyId, "taxAuthPartyId", transactionPartyId, "taxAuthGeoId", appl.getString("taxAuthGeoId"))); offsettingGlAccountAmounts.put(taxAuthGlAccount.getString("glAccountId"), new Double(appl.getDouble("amountApplied").doubleValue() * conversionFactor)); } } } else { String offsettingGlAccountId = getOffsettingPaymentGlAccount(dispatcher, payment, organizationPartyId, userLogin); offsettingGlAccountAmounts.put(offsettingGlAccountId, new Double(transactionAmount)); } // determine which to credit and debit Map creditGlAccountAmounts = null; Map debitGlAccountAmounts = null; if (UtilAccounting.isDisbursement(payment)) { creditGlAccountAmounts = paymentGlAccountAmounts; debitGlAccountAmounts = offsettingGlAccountAmounts; } else if (UtilAccounting.isReceipt(payment)) { creditGlAccountAmounts = offsettingGlAccountAmounts; debitGlAccountAmounts = paymentGlAccountAmounts; } else { return ServiceUtil.returnError("Cannot Post Payment to GL: Payment with paymentId " + paymentId + " has unsupported paymentTypeId " + payment.getString("paymentTypeId") + " (Must be or have a parent type of DISBURSEMENT or RECEIPT.)"); } if ((creditGlAccountAmounts == null) || (creditGlAccountAmounts.keySet().size() == 0)) { return ServiceUtil.returnError("No credit GL accounts found for payment posting"); } if (debitGlAccountAmounts == null) { return ServiceUtil.returnError("No debit GL accounts found for payment posting"); } List acctgTransEntries = makePaymentEntries(creditGlAccountAmounts, debitGlAccountAmounts, organizationPartyId, transactionPartyId, delegator); // Post transaction Map tmpMap = UtilMisc.toMap("acctgTransEntries", acctgTransEntries, "glFiscalTypeId", "ACTUAL", "acctgTransTypeId", "PAYMENT_ACCTG_TRANS", "transactionDate", UtilDateTime.nowTimestamp(), "userLogin", userLogin); tmpMap.put("paymentId", paymentId); tmpMap.put("partyId", transactionPartyId); tmpMap = dispatcher.runSync("createAcctgTransAndEntries", tmpMap); if (((String) tmpMap.get(ModelService.RESPONSE_MESSAGE)).equals(ModelService.RESPOND_SUCCESS)) { results = ServiceUtil.returnSuccess(); results.put("acctgTransId", tmpMap.get("acctgTransId")); return(results); } else { return tmpMap; } } catch (GenericEntityException ex) { return(ServiceUtil.returnError(ex.getMessage())); } catch (GenericServiceException ex) { return(ServiceUtil.returnError(ex.getMessage())); } } /** * Get the offsetting account for a payment. * @param dispatcher * @param payment * @param organizationPartyId * @param userLogin * @return The offsetting glAccountId of a payment or null if one cannot be found * @throws GenericServiceException if no GlAccount was configured for the organization */ public static String getOffsettingPaymentGlAccount(LocalDispatcher dispatcher, GenericValue payment, String organizationPartyId, GenericValue userLogin) throws GenericServiceException, GenericEntityException { // Find the type of the offsetting GL Account (ACCOUNTS_RECEIVABLE, INVENTORY, etc.) in GlAccountTypeDefault based on glAccoutTypeId of the PaymentType List tmpList = payment.getRelatedOne("PaymentType").getRelatedByAnd("PaymentGlAccountTypeMap", UtilMisc.toMap("organizationPartyId", organizationPartyId)); if (tmpList.size() == 0) { throw new AccountingException("Offsetting GL account for payment type " + payment.getString("paymentTypeId") + " of organization " + organizationPartyId + " has not been configured."); } String offsettingGlAccountTypeId = ((GenericValue) tmpList.get(0)).getString("glAccountTypeId"); // get the GL account from the type return UtilAccounting.getDefaultAccountId(offsettingGlAccountTypeId, organizationPartyId, userLogin.getDelegator()); } /** * A little helper method to postPaymentToGl. Maybe one day it'll get a promotion and help the other services too? * @param creditGlAccountAmounts * @param debitGlAccountAmounts * @param organizationPartyId * @param transactionPartyId * @throws GenericEntityException */ private static List makePaymentEntries(Map creditGlAccountAmounts, Map debitGlAccountAmounts, String organizationPartyId, String transactionPartyId, GenericDelegator delegator) throws GenericEntityException { List acctgTransEntries = new LinkedList(); int itemSeq = 1; for (Iterator ai = creditGlAccountAmounts.keySet().iterator(); ai.hasNext(); ) { String creditGlAccountId = (String) ai.next(); Map tmpMap = UtilMisc.toMap("glAccountId", creditGlAccountId, "debitCreditFlag", "C", "amount", creditGlAccountAmounts.get(creditGlAccountId), "acctgTransEntrySeqId", Integer.toString(itemSeq), "organizationPartyId", organizationPartyId, "acctgTransEntryTypeId", "_NA_"); tmpMap.put("partyId", transactionPartyId); GenericValue creditAcctTransEntry = delegator.makeValue("AcctgTransEntry", tmpMap); acctgTransEntries.add(creditAcctTransEntry); itemSeq++; } for (Iterator ai = debitGlAccountAmounts.keySet().iterator(); ai.hasNext(); ) { String debitGlAccountId = (String) ai.next(); Map tmpMap = UtilMisc.toMap("glAccountId", debitGlAccountId, "debitCreditFlag", "D", "amount", debitGlAccountAmounts.get(debitGlAccountId), "acctgTransEntrySeqId", Integer.toString(itemSeq), "organizationPartyId", organizationPartyId, "acctgTransEntryTypeId", "_NA_"); tmpMap.put("partyId", transactionPartyId); GenericValue debitAcctTransEntry = delegator.makeValue("AcctgTransEntry", tmpMap); acctgTransEntries.add(debitAcctTransEntry); itemSeq++; } return acctgTransEntries; } /** * Service to determine accounting parties and GL account of a payment * @param paymentId * @return * @author Leon Torres */ public static Map getPaymentAccountAndParties(DispatchContext dctx, Map context) { GenericDelegator delegator = dctx.getDelegator(); LocalDispatcher dispatcher = dctx.getDispatcher(); GenericValue userLogin = (GenericValue) context.get("userLogin"); String paymentId = (String) context.get("paymentId"); // return values Map result = ServiceUtil.returnSuccess(); String organizationPartyId = null; String transactionPartyId = null; String glAccountId = null; try { GenericValue payment = delegator.findByPrimaryKey("Payment", UtilMisc.toMap("paymentId", paymentId)); if (payment == null) { return ServiceUtil.returnError("Payment " + paymentId + " doesn't exist!");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -