📄 ledgerservices.java
字号:
/* * Copyright (C) 2006 Open Source Strategies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */package com.opensourcestrategies.financials.ledger;import java.sql.Timestamp;import java.util.ArrayList;import java.util.Date;import java.util.HashMap;import java.util.Iterator;import java.util.LinkedList;import java.util.List;import java.util.Map;import java.util.Set;import java.math.BigDecimal;import org.ofbiz.accounting.util.UtilAccounting;import org.ofbiz.accounting.AccountingException;import org.ofbiz.base.util.Debug;import org.ofbiz.base.util.UtilDateTime;import org.ofbiz.base.util.UtilMisc;import org.ofbiz.base.util.UtilNumber;import org.ofbiz.base.util.UtilValidate;import org.ofbiz.base.util.StringUtil;import org.ofbiz.entity.GenericDelegator;import org.ofbiz.entity.GenericEntityException;import org.ofbiz.entity.GenericValue;import org.ofbiz.entity.condition.EntityCondition;import org.ofbiz.entity.condition.EntityConditionList;import org.ofbiz.entity.condition.EntityExpr;import org.ofbiz.entity.condition.EntityOperator;import org.ofbiz.entity.util.EntityUtil;import org.ofbiz.service.DispatchContext;import org.ofbiz.service.GenericServiceException;import org.ofbiz.service.LocalDispatcher;import org.ofbiz.service.ModelService;import org.ofbiz.service.ServiceUtil;import com.opensourcestrategies.financials.util.UtilCOGS;import com.opensourcestrategies.financials.util.UtilFinancial;/** * LedgerServices - Services for posting transactions to the general ledger * * @author <a href="mailto:sichen@opensourcestrategies.com">Si Chen</a> * @version $Rev: 341 $ * @since 2.2 */public class LedgerServices { public static final String module = LedgerServices.class.getName(); public static final String INVOICE_PRODUCT_ITEM_TYPE = "INV_FPROD_ITEM"; // invoiceTypeId for invoice items which are products public static final String PURCHINV_PRODUCT_ITEM_TYPE = "PINV_FPROD_ITEM"; // invoiceTypeId for invoice items which are products public static final String RETINV_PRODUCT_ITEM_TYPE = "RINV_FPROD_ITEM"; // invoiceTypeId for invoice items which are products // TODO: replace code that uses epsilon with BigDecimal and also set BigDecimal config in some common class/properties file public static final double epsilon = 0.000001; // smallest allowable rounding error in accounting transactions private static BigDecimal ZERO = new BigDecimal("0"); private static int decimals = -1; private static int rounding = -1; static { decimals = UtilNumber.getBigDecimalScale("invoice.decimals"); rounding = UtilNumber.getBigDecimalRoundingMode("invoice.rounding"); // set zero to the proper scale ZERO.setScale(decimals); } public static Map postInvoiceToGl(DispatchContext dctx, Map context) { GenericDelegator delegator = dctx.getDelegator(); LocalDispatcher dispatcher = dctx.getDispatcher(); GenericValue userLogin = (GenericValue) context.get("userLogin"); String invoiceId = (String) context.get("invoiceId"); try { // get the invoice and make sure it has an invoiceTypeId GenericValue invoice = delegator.findByPrimaryKeyCache("Invoice", UtilMisc.toMap("invoiceId", invoiceId)); if (invoice == null) { return ServiceUtil.returnError("No invoice found for invoiceId of " + invoiceId); } else if (invoice.get("invoiceTypeId") == null) { return ServiceUtil.returnError("Invoice " + invoiceId + " has a null invoice type and cannot be processed"); } String invoiceTypeId = (String) invoice.get("invoiceTypeId"); // accounting data String transactionPartyId = null; String transactionPartyRoleTypeId = null; String acctgTransTypeId = null; String organizationPartyId = null; String offsettingGlAccountTypeId = null; String defaultDebitCreditFlag = null; String offsettingDebitCreditFlag = null; String defaultGlAccountTypeId = null; // set accounting data according to invoiceTypeId if ("SALES_INVOICE".equals(invoiceTypeId)) { acctgTransTypeId = "SALES_ACCTG_TRANS"; offsettingGlAccountTypeId = "ACCOUNTS_RECEIVABLE"; organizationPartyId = invoice.getString("partyIdFrom"); transactionPartyId = invoice.getString("partyId"); transactionPartyRoleTypeId = "BILL_TO_CUSTOMER"; defaultDebitCreditFlag = "C"; offsettingDebitCreditFlag = "D"; defaultGlAccountTypeId = "SALES_ACCOUNT"; } else if ("PURCHASE_INVOICE".equals(invoiceTypeId)) { acctgTransTypeId = "OBLIGATION_ACCTG_TRA"; offsettingGlAccountTypeId = "ACCOUNTS_PAYABLE"; organizationPartyId = invoice.getString("partyId"); transactionPartyId = invoice.getString("partyIdFrom"); transactionPartyRoleTypeId = "BILL_FROM_VENDOR"; defaultDebitCreditFlag = "D"; offsettingDebitCreditFlag = "C"; defaultGlAccountTypeId = "UNINVOICED_SHIP_RCPT"; } else if ("CUST_RTN_INVOICE".equals(invoiceTypeId)) { acctgTransTypeId = "OBLIGATION_ACCTG_TRA"; offsettingGlAccountTypeId = "CUSTOMER_CREDIT"; organizationPartyId = invoice.getString("partyId"); transactionPartyId = invoice.getString("partyIdFrom"); transactionPartyRoleTypeId = "BILL_TO_CUSTOMER"; defaultDebitCreditFlag = "D"; offsettingDebitCreditFlag = "C"; defaultGlAccountTypeId = "SALES_RETURN"; } else { return ServiceUtil.returnError("Unknown invoiceTypeId '" + invoiceTypeId + "' for Invoice [" + invoiceId + "]"); } // invoke helper method to process invoice items Map tmpResult = processInvoiceItems( delegator, dispatcher, userLogin, invoice, acctgTransTypeId, offsettingGlAccountTypeId, organizationPartyId, transactionPartyId, transactionPartyRoleTypeId, defaultDebitCreditFlag, defaultGlAccountTypeId ); // return on any service errors if (ServiceUtil.isError(tmpResult)) return tmpResult; // create a list of AcctgTransEntries based on processInvoiceItems int itemSeqId = 1; List acctgTransEntries = new ArrayList(); List acctgTransEntryMaps = (List) tmpResult.get("acctgTransEntries"); for (Iterator iter = acctgTransEntryMaps.iterator(); iter.hasNext(); ) { Map input = (Map) iter.next(); // skip those with amount 0 if (((Double) input.get("amount")).doubleValue() == 0.0) { continue; } // make the next transaction entry input.put("acctgTransEntrySeqId", Integer.toString(itemSeqId)); acctgTransEntries.add(delegator.makeValue("AcctgTransEntry", input)); itemSeqId++; if (Debug.verboseOn()) { Debug.logInfo(acctgTransEntries.get(acctgTransEntries.size()-1).toString(), module); } } // create the offsetting GL transaction and add to list Map input = new HashMap(); input.put("glAccountId", tmpResult.get("offsettingGlAccountId")); input.put("acctgTransEntrySeqId", Integer.toString(itemSeqId)); input.put("organizationPartyId", organizationPartyId); input.put("partyId", transactionPartyId); input.put("roleTypeId", transactionPartyRoleTypeId); input.put("debitCreditFlag", offsettingDebitCreditFlag); input.put("amount", tmpResult.get("postingTotal")); input.put("acctgTransEntryTypeId", "_NA_"); Debug.logInfo(input.toString(), module); GenericValue offsettingAcctgTransEntry = delegator.makeValue("AcctgTransEntry", input); acctgTransEntries.add(offsettingAcctgTransEntry); // now use createAcctgTransAndEntries to create an accounting transaction for the invoice input = new HashMap(); input.put("acctgTransEntries", acctgTransEntries); input.put("invoiceId", invoiceId); input.put("partyId", transactionPartyId); input.put("roleTypeId", transactionPartyRoleTypeId); input.put("glFiscalTypeId", "ACTUAL"); input.put("acctgTransTypeId", acctgTransTypeId); input.put("userLogin", userLogin); tmpResult = dispatcher.runSync("createAcctgTransAndEntries", input); // on success, return the acctgTransId if (((String) tmpResult.get(ModelService.RESPONSE_MESSAGE)).equals(ModelService.RESPOND_SUCCESS)) { Map result = ServiceUtil.returnSuccess(); result.put("acctgTransId", tmpResult.get("acctgTransId")); return(result); } // otherwise we have an error, which we pass up return tmpResult; } catch (GenericEntityException ee) { return ServiceUtil.returnError(ee.getMessage()); } catch (GenericServiceException se) { return ServiceUtil.returnError(se.getMessage()); } } /** * Iterates through each InvoiceItem in an Invoice and creates a map based on * AcctgTransEntry for each invoice item. Also determines the offsettingGlAccountId * and keeps a running total for all the transactions. The general code for processing * all invoice types is here, and special processing by invoice type for each InvoiceItem
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -