Java tutorial
/* ****************************************************************************** * The contents of this file are subject to the Compiere License Version 1.1 * ("License"); You may not use this file except in compliance with the License * You may obtain a copy of the License at http://www.compiere.org/license.html * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for * the specific language governing rights and limitations under the License. * The Original Code is Compiere ERP & CRM Business Solution * The Initial Developer of the Original Code is Jorg Janke and ComPiere, Inc. * Portions created by Jorg Janke are Copyright (C) 1999-2001 Jorg Janke, parts * created by ComPiere are Copyright (C) ComPiere, Inc.; All Rights Reserved. * Contributor(s): Openbravo SLU * Contributions are Copyright (C) 2001-2015 Openbravo S.L.U. ****************************************************************************** */ package org.openbravo.erpCommon.ad_forms; import java.io.IOException; import java.math.BigDecimal; import java.math.MathContext; import java.math.RoundingMode; import java.sql.Connection; import java.sql.SQLException; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.Vector; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.hibernate.criterion.Projections; import org.hibernate.criterion.Restrictions; import org.openbravo.advpaymentmngt.APRM_FinaccTransactionV; import org.openbravo.base.exception.OBException; import org.openbravo.base.secureApp.VariablesSecureApp; import org.openbravo.base.session.OBPropertiesProvider; import org.openbravo.client.kernel.RequestContext; import org.openbravo.dal.core.DalUtil; import org.openbravo.dal.core.OBContext; import org.openbravo.dal.service.OBCriteria; import org.openbravo.dal.service.OBDal; import org.openbravo.dal.service.OBDao; import org.openbravo.dal.service.OBQuery; import org.openbravo.data.FieldProvider; import org.openbravo.database.ConnectionProvider; import org.openbravo.erpCommon.utility.DateTimeData; import org.openbravo.erpCommon.utility.FieldProviderFactory; import org.openbravo.erpCommon.utility.OBDateUtils; import org.openbravo.erpCommon.utility.OBError; import org.openbravo.erpCommon.utility.OBMessageUtils; import org.openbravo.erpCommon.utility.SequenceIdData; import org.openbravo.erpCommon.utility.Utility; import org.openbravo.exception.NoConnectionAvailableException; import org.openbravo.model.common.businesspartner.BusinessPartner; import org.openbravo.model.common.businesspartner.CategoryAccounts; import org.openbravo.model.common.businesspartner.CustomerAccounts; import org.openbravo.model.common.businesspartner.VendorAccounts; import org.openbravo.model.common.currency.ConversionRateDoc; import org.openbravo.model.common.currency.Currency; import org.openbravo.model.common.enterprise.AcctSchemaTableDocType; import org.openbravo.model.common.invoice.Invoice; import org.openbravo.model.common.invoice.ReversedInvoice; import org.openbravo.model.financialmgmt.accounting.FIN_FinancialAccountAccounting; import org.openbravo.model.financialmgmt.accounting.coa.AcctSchemaTable; import org.openbravo.model.financialmgmt.gl.GLItem; import org.openbravo.model.financialmgmt.gl.GLItemAccounts; import org.openbravo.model.financialmgmt.payment.FIN_FinaccTransaction; import org.openbravo.model.financialmgmt.payment.FIN_FinancialAccount; import org.openbravo.model.financialmgmt.payment.FIN_Payment; import org.openbravo.model.financialmgmt.payment.FIN_PaymentDetail; import org.openbravo.model.financialmgmt.payment.FIN_PaymentSchedule; import org.openbravo.model.financialmgmt.payment.FIN_PaymentScheduleDetail; import org.openbravo.model.materialmgmt.transaction.MaterialTransaction; public abstract class AcctServer { static Logger log4j = Logger.getLogger(AcctServer.class); protected ConnectionProvider connectionProvider; public String batchSize = "100"; public BigDecimal ZERO = BigDecimal.ZERO; public String groupLines = ""; public String Qty = null; public String tableName = ""; public String strDateColumn = ""; public String AD_Table_ID = ""; public String AD_Client_ID = ""; public String AD_Org_ID = ""; public String Status = ""; public String C_BPartner_ID = ""; public String C_BPartner_Location_ID = ""; public String M_Product_ID = ""; public String AD_OrgTrx_ID = ""; public String C_SalesRegion_ID = ""; public String C_Project_ID = ""; public String C_Campaign_ID = ""; public String C_Activity_ID = ""; public String C_LocFrom_ID = ""; public String C_LocTo_ID = ""; public String User1_ID = ""; public String User2_ID = ""; public String C_Costcenter_ID = ""; public String Name = ""; public String DocumentNo = ""; public String DateAcct = ""; public Date dateAcct = null; public String DateDoc = ""; public String C_Period_ID = ""; public String C_Currency_ID = ""; public String C_DocType_ID = ""; public String C_Charge_ID = ""; public String ChargeAmt = ""; public String C_BankAccount_ID = ""; public String C_CashBook_ID = ""; public String M_Warehouse_ID = ""; public String Posted = ""; public String DocumentType = ""; public String TaxIncluded = ""; public String GL_Category_ID = ""; public String Record_ID = ""; public String IsReversal = ""; public String IsReturn = ""; /** No Currency in Document Indicator */ protected static final String NO_CURRENCY = "-1"; // This is just for the initialization of the accounting public String m_IsOpening = "N"; // To match balances public String m_Record_Id2 = ""; public Fact[] m_fact = null; public AcctSchema[] m_as = null; private FieldProvider objectFieldProvider[]; public String[] Amounts = new String[4]; // Conversion Rate precision. defaulted to 6 as it is stated in Format.xml int conversionRatePrecision = 6; public DocLine[] p_lines = new DocLine[0]; public DocLine_Payment[] m_debt_payments = new DocLine_Payment[0]; /** * Is (Source) Multi-Currency Document - i.e. the document has different currencies (if true, the * document will not be source balanced) */ public boolean MultiCurrency = false; /** Amount Type - Invoice */ public static final int AMTTYPE_Gross = 0; public static final int AMTTYPE_Net = 1; public static final int AMTTYPE_Charge = 2; /** Amount Type - Allocation */ public static final int AMTTYPE_Invoice = 0; public static final int AMTTYPE_Allocation = 1; public static final int AMTTYPE_Discount = 2; public static final int AMTTYPE_WriteOff = 3; /** Document Status */ public static final String STATUS_NotPosted = "N"; /** Document Status */ public static final String STATUS_NotBalanced = "b"; /** Document Status */ public static final String STATUS_NotConvertible = "c"; /** Document Status */ public static final String STATUS_PeriodClosed = "p"; /** Document Status */ public static final String STATUS_InvalidAccount = "i"; /** Document Status */ public static final String STATUS_PostPrepared = "y"; /** Document Status */ public static final String STATUS_Posted = "Y"; /** Document Status */ public static final String STATUS_Error = "E"; /** Document Status */ public static final String STATUS_InvalidCost = "C"; /** Document Status */ public static final String STATUS_NotCalculatedCost = "NC"; /** Document Status */ public static final String STATUS_NoRelatedPO = "NO"; /** Document Status */ public static final String STATUS_DocumentLocked = "L"; /** Document Status */ public static final String STATUS_DocumentDisabled = "D"; /** Document Status */ public static final String STATUS_TableDisabled = "T"; /** Document Status */ public static final String STATUS_BackgroundDisabled = "d"; /** Document Status */ public static final String STATUS_NoAccountingDate = "AD"; /** Table IDs for document level conversion rates */ public static final String TABLEID_Invoice = "318"; public static final String TABLEID_Payment = "D1A97202E832470285C9B1EB026D54E2"; public static final String TABLEID_Transaction = "4D8C3B3C31D1410DA046140C9F024D17"; public static final String TABLEID_Reconciliation = "B1B7075C46934F0A9FD4C4D0F1457B42"; @Deprecated // Use TABLEID_Invoice instead public static final String EXCHANGE_DOCTYPE_Invoice = "318"; @Deprecated // Use TABLEID_Payment instead public static final String EXCHANGE_DOCTYPE_Payment = "D1A97202E832470285C9B1EB026D54E2"; @Deprecated // Use TABLEID_Transaction instead public static final String EXCHANGE_DOCTYPE_Transaction = "4D8C3B3C31D1410DA046140C9F024D17"; OBError messageResult = null; String strMessage = null; /** AR Invoices */ public static final String DOCTYPE_ARInvoice = "ARI"; /** Return Material Sales Invoice */ public static final String DOCTYPE_RMSalesInvoice = "ARI_RM"; /** AR Credit Memo */ public static final String DOCTYPE_ARCredit = "ARC"; /** AR Receipt */ public static final String DOCTYPE_ARReceipt = "ARR"; /** AR ProForma */ public static final String DOCTYPE_ARProForma = "ARF"; /** AP Invoices */ public static final String DOCTYPE_APInvoice = "API"; /** AP Credit Memo */ public static final String DOCTYPE_APCredit = "APC"; /** AP Payment */ public static final String DOCTYPE_APPayment = "APP"; /** CashManagement Bank Statement */ public static final String DOCTYPE_BankStatement = "CMB"; /** CashManagement Cash Journals */ public static final String DOCTYPE_CashJournal = "CMC"; /** CashManagement Allocations */ public static final String DOCTYPE_Allocation = "CMA"; /** Amortization */ public static final String DOCTYPE_Amortization = "AMZ"; /** Material Shipment */ public static final String DOCTYPE_MatShipment = "MMS"; /** Material Receipt */ public static final String DOCTYPE_MatReceipt = "MMR"; /** Material Inventory */ public static final String DOCTYPE_MatInventory = "MMI"; /** Material Movement */ public static final String DOCTYPE_MatMovement = "MMM"; /** Material Production */ public static final String DOCTYPE_MatProduction = "MMP"; /** Material Internal Consumption */ public static final String DOCTYPE_MatInternalConsumption = "MIC"; /** Match Invoice */ public static final String DOCTYPE_MatMatchInv = "MXI"; /** Match PO */ public static final String DOCTYPE_MatMatchPO = "MXP"; /** GL Journal */ public static final String DOCTYPE_GLJournal = "GLJ"; /** Purchase Order */ public static final String DOCTYPE_POrder = "POO"; /** Sales Order */ public static final String DOCTYPE_SOrder = "SOO"; // DPManagement public static final String DOCTYPE_DPManagement = "DPM"; // FinAccTransaction public static final String DOCTYPE_FinAccTransaction = "FAT"; // FinReconciliation public static final String DOCTYPE_Reconciliation = "REC"; // FinBankStatement public static final String DOCTYPE_FinBankStatement = "BST"; // CostAdjustment public static final String DOCTYPE_CostAdjustment = "CAD"; // LandedCost public static final String DOCTYPE_LandedCost = "LDC"; // LandedCostCost public static final String DOCTYPE_LandedCostCost = "LCC"; /*************************************************************************/ /** Account Type - Invoice */ public static final String ACCTTYPE_Charge = "0"; public static final String ACCTTYPE_C_Receivable = "1"; public static final String ACCTTYPE_V_Liability = "2"; public static final String ACCTTYPE_V_Liability_Services = "3"; /** Account Type - Payment */ public static final String ACCTTYPE_UnallocatedCash = "10"; public static final String ACCTTYPE_BankInTransit = "11"; public static final String ACCTTYPE_PaymentSelect = "12"; public static final String ACCTTYPE_WriteOffDefault = "13"; public static final String ACCTTYPE_WriteOffDefault_Revenue = "63"; public static final String ACCTTYPE_BankInTransitDefault = "14"; public static final String ACCTTYPE_ConvertChargeDefaultAmt = "15"; public static final String ACCTTYPE_ConvertGainDefaultAmt = "16"; /** Account Type - Cash */ public static final String ACCTTYPE_CashAsset = "20"; public static final String ACCTTYPE_CashTransfer = "21"; public static final String ACCTTYPE_CashExpense = "22"; public static final String ACCTTYPE_CashReceipt = "23"; public static final String ACCTTYPE_CashDifference = "24"; /** Account Type - Allocation */ public static final String ACCTTYPE_DiscountExp = "30"; public static final String ACCTTYPE_DiscountRev = "31"; public static final String ACCTTYPE_WriteOff = "32"; public static final String ACCTTYPE_WriteOff_Revenue = "64"; /** Account Type - Bank Statement */ public static final String ACCTTYPE_BankAsset = "40"; public static final String ACCTTYPE_InterestRev = "41"; public static final String ACCTTYPE_InterestExp = "42"; public static final String ACCTTYPE_ConvertChargeLossAmt = "43"; public static final String ACCTTYPE_ConvertChargeGainAmt = "44"; /** Inventory Accounts */ public static final String ACCTTYPE_InvDifferences = "50"; public static final String ACCTTYPE_NotInvoicedReceipts = "51"; /** Project Accounts */ public static final String ACCTTYPE_ProjectAsset = "61"; public static final String ACCTTYPE_ProjectWIP = "62"; /** GL Accounts */ public static final String ACCTTYPE_PPVOffset = "60"; // Reference (to find SalesRegion from BPartner) public String BP_C_SalesRegion_ID = ""; // set in FactLine public int errors = 0; int success = 0; // Distinguish background process boolean isBackground = false; /** * Constructor * * @param m_AD_Client_ID * Client ID of these Documents * @param connectionProvider * Provider for db connections. */ public AcctServer(String m_AD_Client_ID, String m_AD_Org_ID, ConnectionProvider connectionProvider) { AD_Client_ID = m_AD_Client_ID; AD_Org_ID = m_AD_Org_ID; this.connectionProvider = connectionProvider; if (log4j.isDebugEnabled()) log4j.debug("AcctServer - LOADING ARRAY: " + m_AD_Client_ID); m_as = AcctSchema.getAcctSchemaArray(connectionProvider, m_AD_Client_ID, m_AD_Org_ID); } // /* * Empty constructor to initialize the class using reflexion, set() method should be called * afterwards. */ public AcctServer() { } public void setBatchSize(String newbatchSize) { batchSize = newbatchSize; } public void run(VariablesSecureApp vars) throws IOException, ServletException { run(vars, null, null); } public void run(VariablesSecureApp vars, String strDateFrom, String strDateTo) throws IOException, ServletException { if (AD_Client_ID.equals("")) AD_Client_ID = vars.getClient(); Connection con = null; try { String strIDs = ""; if (log4j.isDebugEnabled()) { log4j.debug("AcctServer - Run - TableName = " + tableName + strDateFrom + strDateTo); } log4j.debug("AcctServer.run - AD_Client_ID: " + AD_Client_ID); AcctServerData[] data = null; final Set<String> orgSet = OBContext.getOBContext().getOrganizationStructureProvider(AD_Client_ID) .getChildTree(AD_Org_ID, true); String strOrgs = Utility.getInStrSet(orgSet); data = AcctServerData.select(connectionProvider, tableName, strDateColumn, AD_Client_ID, strOrgs, strDateFrom, strDateTo, 0, Integer.valueOf(batchSize).intValue()); if (data != null && data.length > 0) { if (log4j.isDebugEnabled()) { log4j.debug("AcctServer - Run -Select inicial realizada N = " + data.length + " - Key: " + data[0].id); } } for (int i = 0; data != null && i < data.length; i++) { con = connectionProvider.getTransactionConnection(); strIDs += data[i].getField("ID") + ", "; this.setMessageResult(null); AcctServer tempServer = get(AD_Table_ID, AD_Client_ID, AD_Org_ID, connectionProvider); boolean postSuccess = false; postSuccess = tempServer.post(data[i].getField("ID"), false, vars, connectionProvider, con); errors = errors + tempServer.errors; success = success + tempServer.success; if (!postSuccess) { connectionProvider.releaseRollbackConnection(con); return; } else { connectionProvider.releaseCommitConnection(con); OBDal.getInstance().commitAndClose(); } } if (log4j.isDebugEnabled() && data != null) log4j.debug("AcctServer - Run -" + data.length + " IDs [" + strIDs + "]"); // Create Automatic Matching // match (vars, this,con); } catch (NoConnectionAvailableException ex) { throw new ServletException("@CODE=NoConnectionAvailable", ex); } catch (SQLException ex2) { try { connectionProvider.releaseRollbackConnection(con); } catch (SQLException se) { log4j.error("Failed to close connection after an error", se); } throw new ServletException("@CODE=" + Integer.toString(ex2.getErrorCode()) + "@" + ex2.getMessage(), ex2); } catch (Exception ex3) { log4j.error("Exception in AcctServer.run", ex3); try { connectionProvider.releaseRollbackConnection(con); } catch (SQLException se) { log4j.error("Failed to close connection after an error", se); } } } /** * @return the isBackground */ public boolean isBackground() { return isBackground; } /** * @param isBackground * the isBackground to set */ public void setBackground(boolean isBackground) { this.isBackground = isBackground; } /** * Factory - Create Posting document * * @param AD_Table_ID * Table ID of Documents * @param AD_Client_ID * Client ID of Documents * @param connectionProvider * Database connection provider * @return Document */ public static AcctServer get(String AD_Table_ID, String AD_Client_ID, String AD_Org_ID, ConnectionProvider connectionProvider) throws ServletException { AcctServer acct = null; if (log4j.isDebugEnabled()) log4j.debug("get - table: " + AD_Table_ID); if (AD_Table_ID.equals("318") || AD_Table_ID.equals("800060") || AD_Table_ID.equals("800176") || AD_Table_ID.equals("407") || AD_Table_ID.equals("392") || AD_Table_ID.equals("259") || AD_Table_ID.equals("800019") || AD_Table_ID.equals("319") || AD_Table_ID.equals("321") || AD_Table_ID.equals("323") || AD_Table_ID.equals("325") || AD_Table_ID.equals("224") || AD_Table_ID.equals("472") || AD_Table_ID.equals("800168")) { switch (Integer.parseInt(AD_Table_ID)) { case 318: acct = new DocInvoice(AD_Client_ID, AD_Org_ID, connectionProvider); acct.tableName = "C_Invoice"; acct.AD_Table_ID = "318"; acct.strDateColumn = "DateAcct"; acct.reloadAcctSchemaArray(); acct.groupLines = AcctServerData.selectGroupLines(acct.connectionProvider, AD_Client_ID); break; /* * case 390: acct = new DocAllocation (AD_Client_ID); acct.strDateColumn = ""; * acct.AD_Table_ID = "390"; acct.reloadAcctSchemaArray(); acct.break; */ case 800060: acct = new DocAmortization(AD_Client_ID, AD_Org_ID, connectionProvider); acct.tableName = "A_Amortization"; acct.AD_Table_ID = "800060"; acct.strDateColumn = "DateAcct"; acct.reloadAcctSchemaArray(); break; case 800176: if (log4j.isDebugEnabled()) log4j.debug("AcctServer - Get DPM"); acct = new DocDPManagement(AD_Client_ID, AD_Org_ID, connectionProvider); acct.tableName = "C_DP_Management"; acct.AD_Table_ID = "800176"; acct.strDateColumn = "DateAcct"; acct.reloadAcctSchemaArray(); break; case 407: acct = new DocCash(AD_Client_ID, AD_Org_ID, connectionProvider); acct.tableName = "C_Cash"; acct.strDateColumn = "DateAcct"; acct.AD_Table_ID = "407"; acct.reloadAcctSchemaArray(); break; case 392: acct = new DocBank(AD_Client_ID, AD_Org_ID, connectionProvider); acct.tableName = "C_Bankstatement"; acct.strDateColumn = "StatementDate"; acct.AD_Table_ID = "392"; acct.reloadAcctSchemaArray(); break; case 259: acct = new DocOrder(AD_Client_ID, AD_Org_ID, connectionProvider); acct.tableName = "C_Order"; acct.strDateColumn = "DateAcct"; acct.AD_Table_ID = "259"; acct.reloadAcctSchemaArray(); break; case 800019: acct = new DocPayment(AD_Client_ID, AD_Org_ID, connectionProvider); acct.tableName = "C_Settlement"; acct.strDateColumn = "Dateacct"; acct.AD_Table_ID = "800019"; acct.reloadAcctSchemaArray(); break; case 319: acct = new DocInOut(AD_Client_ID, AD_Org_ID, connectionProvider); acct.tableName = "M_InOut"; acct.strDateColumn = "DateAcct"; acct.AD_Table_ID = "319"; acct.reloadAcctSchemaArray(); break; case 321: acct = new DocInventory(AD_Client_ID, AD_Org_ID, connectionProvider); acct.tableName = "M_Inventory"; acct.strDateColumn = "MovementDate"; acct.AD_Table_ID = "321"; acct.reloadAcctSchemaArray(); break; case 323: acct = new DocMovement(AD_Client_ID, AD_Org_ID, connectionProvider); acct.tableName = "M_Movement"; acct.strDateColumn = "MovementDate"; acct.AD_Table_ID = "323"; acct.reloadAcctSchemaArray(); break; case 325: acct = new DocProduction(AD_Client_ID, AD_Org_ID, connectionProvider); acct.tableName = "M_Production"; acct.strDateColumn = "MovementDate"; acct.AD_Table_ID = "325"; acct.reloadAcctSchemaArray(); break; case 224: if (log4j.isDebugEnabled()) log4j.debug("AcctServer - Before OBJECT CREATION"); acct = new DocGLJournal(AD_Client_ID, AD_Org_ID, connectionProvider); acct.tableName = "GL_Journal"; acct.strDateColumn = "DateAcct"; acct.AD_Table_ID = "224"; acct.reloadAcctSchemaArray(); break; case 472: acct = new DocMatchInv(AD_Client_ID, AD_Org_ID, connectionProvider); acct.tableName = "M_MatchInv"; acct.strDateColumn = "DateTrx"; acct.AD_Table_ID = "472"; acct.reloadAcctSchemaArray(); break; case 800168: acct = new DocInternalConsumption(AD_Client_ID, AD_Org_ID, connectionProvider); acct.tableName = "M_Internal_Consumption"; acct.strDateColumn = "MovementDate"; acct.AD_Table_ID = "800168"; acct.reloadAcctSchemaArray(); break; // case 473: acct = new // DocMatchPO (AD_Client_ID); acct.strDateColumn = "MovementDate"; // acct.reloadAcctSchemaArray(); break; case DocProjectIssue.AD_TABLE_ID: acct = new // DocProjectIssue (AD_Client_ID); acct.strDateColumn = "MovementDate"; // acct.reloadAcctSchemaArray(); break; } } else { AcctServerData[] acctinfo = AcctServerData.getTableInfo(connectionProvider, AD_Table_ID); if (acctinfo != null && acctinfo.length != 0) { if (!acctinfo[0].acctclassname.equals("") && !acctinfo[0].acctdatecolumn.equals("")) { try { acct = (AcctServer) Class.forName(acctinfo[0].acctclassname).newInstance(); acct.set(AD_Table_ID, AD_Client_ID, AD_Org_ID, connectionProvider, acctinfo[0].tablename, acctinfo[0].acctdatecolumn); acct.reloadAcctSchemaArray(); } catch (Exception e) { log4j.error("Error while creating new instance for AcctServer - " + e, e); } } } } if (acct == null) log4j.warn("AcctServer - get - Unknown AD_Table_ID=" + AD_Table_ID); else if (log4j.isDebugEnabled()) log4j.debug("AcctServer - get - AcctSchemaArray length=" + (acct.m_as).length); if (log4j.isDebugEnabled()) log4j.debug("AcctServer - get - AD_Table_ID=" + AD_Table_ID); return acct; } // get public void set(String m_AD_Table_ID, String m_AD_Client_ID, String m_AD_Org_ID, ConnectionProvider connectionProvider, String tablename, String acctdatecolumn) { AD_Client_ID = m_AD_Client_ID; AD_Org_ID = m_AD_Org_ID; this.connectionProvider = connectionProvider; tableName = tablename; strDateColumn = acctdatecolumn; AD_Table_ID = m_AD_Table_ID; if (log4j.isDebugEnabled()) log4j.debug("AcctServer - LOADING ARRAY: " + m_AD_Client_ID); m_as = AcctSchema.getAcctSchemaArray(connectionProvider, m_AD_Client_ID, m_AD_Org_ID); } public void reloadAcctSchemaArray() throws ServletException { if (log4j.isDebugEnabled()) log4j.debug("AcctServer - reloadAcctSchemaArray - " + AD_Table_ID); AcctSchema acct = null; ArrayList<Object> new_as = new ArrayList<Object>(); for (int i = 0; i < (this.m_as).length; i++) { acct = m_as[i]; if (AcctSchemaData.selectAcctSchemaTable(connectionProvider, acct.m_C_AcctSchema_ID, AD_Table_ID)) { new_as.add(new AcctSchema(connectionProvider, acct.m_C_AcctSchema_ID)); } } AcctSchema[] retValue = new AcctSchema[new_as.size()]; new_as.toArray(retValue); if (log4j.isDebugEnabled()) log4j.debug("AcctServer - RELOADING ARRAY: " + retValue.length); this.m_as = retValue; } private void reloadAcctSchemaArray(String adOrgId) throws ServletException { if (log4j.isDebugEnabled()) log4j.debug("AcctServer - reloadAcctSchemaArray - " + AD_Table_ID + ", AD_ORG_ID: " + adOrgId); AcctSchema acct = null; ArrayList<Object> new_as = new ArrayList<Object>(); // We reload again all the acct schemas of the client m_as = AcctSchema.getAcctSchemaArray(connectionProvider, AD_Client_ID, AD_Org_ID); // Filter the right acct schemas for the organization for (int i = 0; i < (this.m_as).length; i++) { acct = m_as[i]; if (AcctSchemaData.selectAcctSchemaTable(connectionProvider, acct.m_C_AcctSchema_ID, AD_Table_ID)) { new_as.add(new AcctSchema(connectionProvider, acct.m_C_AcctSchema_ID)); } } AcctSchema[] retValue = new AcctSchema[new_as.size()]; new_as.toArray(retValue); if (log4j.isDebugEnabled()) log4j.debug("AcctServer - RELOADING ARRAY: " + retValue.length); this.m_as = retValue; } /** * This method handles the accounting of the record identified by strClave. Due to the possibility * of developing processes that may run after the standard accounting the commit of the * transactions made in this method cannot be done here. The commit must be handled in the caller * of this method appropriately. Realize that you must handle the commit of the transactions made * through a normal or a DAL connection. */ public boolean post(String strClave, boolean force, VariablesSecureApp vars, ConnectionProvider conn, Connection con) throws ServletException { Record_ID = strClave; if (log4j.isDebugEnabled()) log4j.debug("post " + strClave + " tablename: " + tableName); try { if (AcctServerData.update(conn, tableName, strClave) != 1) { log4j.warn("AcctServer - Post -Cannot lock Document - ignored: " + tableName + "_ID=" + strClave); setStatus(STATUS_DocumentLocked); // Status locked document this.setMessageResult(conn, vars, STATUS_DocumentLocked, "Error"); return false; } else AcctServerData.delete(connectionProvider, AD_Table_ID, Record_ID); if (log4j.isDebugEnabled()) log4j.debug("AcctServer - Post -TableName -" + tableName + "- ad_client_id -" + AD_Client_ID + "- " + tableName + "_id -" + strClave); try { loadObjectFieldProvider(connectionProvider, AD_Client_ID, strClave); } catch (ServletException e) { log4j.warn(e); e.printStackTrace(); } FieldProvider data[] = getObjectFieldProvider(); // If there is any template active for current document in any accounting schema, skip this // step as getDocumentConfirmation can lock template try { if ((disableDocumentConfirmation() || getDocumentConfirmation(conn, Record_ID)) && post(data, force, vars, conn, con)) { success++; } else { errors++; if (messageResult == null) setMessageResult(conn, vars, getStatus(), ""); save(conn, vars.getUser()); } } catch (Exception e) { errors++; Status = AcctServer.STATUS_Error; save(conn, vars.getUser()); log4j.error("An error ocurred posting RecordId: " + strClave + " - tableId: " + AD_Table_ID, e); } } catch (ServletException e) { log4j.error(e); return false; } return true; } private boolean post(FieldProvider[] data, boolean force, VariablesSecureApp vars, ConnectionProvider conn, Connection con) throws ServletException { if (log4j.isDebugEnabled()) log4j.debug("post data" + C_Currency_ID); if (!loadDocument(data, force, conn, con)) { log4j.warn("AcctServer - post - Error loading document"); return false; } // Set Currency precision conversionRatePrecision = getConversionRatePrecision(vars); if (data == null || data.length == 0) return false; // if (log4j.isDebugEnabled()) // log4j.debug("AcctServer - Post - Antes de getAcctSchemaArray - C_CURRENCY_ID = " // + C_Currency_ID); // Create Fact per AcctSchema // if (log4j.isDebugEnabled()) log4j.debug("POSTLOADING ARRAY: " + // AD_Client_ID); if (!String.valueOf(data[0].getField("multiGl")).equals("N")) { // m_as = AcctSchema.getAcctSchemaArray(conn, AD_Client_ID, AD_Org_ID); reloadAcctSchemaArray(AD_Org_ID); } // if (log4j.isDebugEnabled()) // log4j.debug("AcctServer - Post - Antes de new Fact - C_CURRENCY_ID = " // + C_Currency_ID); m_fact = new Fact[m_as.length]; // AcctSchema Table check boolean isTableActive = false; try { OBContext.setAdminMode(true); for (AcctSchema as : m_as) { AcctSchemaTable table = null; OBCriteria<AcctSchemaTable> criteria = OBDao.getFilteredCriteria(AcctSchemaTable.class, Restrictions.eq("accountingSchema.id", as.getC_AcctSchema_ID()), Restrictions.eq("table.id", AD_Table_ID)); criteria.setFilterOnReadableClients(false); criteria.setFilterOnReadableOrganization(false); table = (AcctSchemaTable) criteria.uniqueResult(); if (table != null) { isTableActive = true; break; } } } finally { OBContext.restorePreviousMode(); } if (!isTableActive) { setMessageResult(conn, vars, STATUS_TableDisabled, "Warning"); return false; } // for all Accounting Schema boolean OK = true; if (log4j.isDebugEnabled()) log4j.debug("AcctServer - Post -Beforde the loop - C_CURRENCY_ID = " + C_Currency_ID); for (int i = 0; OK && i < m_as.length; i++) { setStatus(STATUS_NotPosted); if (isBackground && !isBackGroundEnabled(conn, m_as[i], AD_Table_ID)) { setStatus(STATUS_BackgroundDisabled); break; } if (log4j.isDebugEnabled()) log4j.debug("AcctServer - Post - Before the postLogic - C_CURRENCY_ID = " + C_Currency_ID); Status = postLogic(i, conn, con, vars, m_as[i]); if (log4j.isDebugEnabled()) log4j.debug("AcctServer - Post - After postLogic"); if (!Status.equals(STATUS_Posted)) return false; } if (log4j.isDebugEnabled()) log4j.debug("AcctServer - Post - Before the postCommit - C_CURRENCY_ID = " + C_Currency_ID); for (int i = 0; i < m_fact.length; i++) if (m_fact[i] != null && (m_fact[i].getLines() == null || m_fact[i].getLines().length == 0)) return false; // commitFact Status = postCommit(Status, conn, vars, con); // dispose facts for (int i = 0; i < m_fact.length; i++) if (m_fact[i] != null) m_fact[i].dispose(); p_lines = null; return Status.equals(STATUS_Posted); } // post boolean isBackGroundEnabled(ConnectionProvider conn, AcctSchema acctSchema, String adTableId) throws ServletException { return AcctServerData.selectBackgroundEnabled(conn, acctSchema.m_C_AcctSchema_ID, adTableId); } /** * Post Commit. Save Facts & Document * * @param status * status * @return Posting Status */ private final String postCommit(String status, ConnectionProvider conn, VariablesSecureApp vars, Connection con) throws ServletException { log4j.debug("AcctServer - postCommit Sta=" + status + " DT=" + DocumentType + " ID=" + Record_ID); Status = status; try { // *** Transaction Start *** // Commit Facts if (Status.equals(AcctServer.STATUS_Posted)) { if (m_fact != null && m_fact.length != 0) { log4j.debug("AcctServer - postCommit - m_fact.length = " + m_fact.length); for (int i = 0; i < m_fact.length; i++) { if (m_fact[i] != null && m_fact[i].save(con, conn, vars)) ; else { // conn.releaseRollbackConnection(con); unlock(conn); Status = AcctServer.STATUS_Error; } } } } // Commit Doc if (!save(conn, vars.getUser())) { // contains unlock // conn.releaseRollbackConnection(con); unlock(conn); // Status = AcctServer.STATUS_Error; } // conn.releaseCommitConnection(con); // *** Transaction End *** } catch (Exception e) { log4j.warn("AcctServer - postCommit" + e); Status = AcctServer.STATUS_Error; // conn.releaseRollbackConnection(con); unlock(conn); } return Status; } // postCommit /** * Save to Disk - set posted flag * * @param conn * connection * @param strUser * AD_User_ID * @return true if saved */ private final boolean save(ConnectionProvider conn, String strUser) { int no = 0; try { no = AcctServerData.updateSave(conn, tableName, Status, strUser, Record_ID); } catch (ServletException e) { log4j.warn(e); e.printStackTrace(); } return no == 1; } // save /** * Unlock Document */ private void unlock(ConnectionProvider conn) { try { AcctServerData.updateUnlock(conn, tableName, Record_ID); } catch (ServletException e) { log4j.warn("AcctServer - Document locked: -" + e); } } // unlock @Deprecated // Deprecated in 2.50 because of a missing connection needed public boolean loadDocument(FieldProvider[] data, boolean force, ConnectionProvider conn) { try { Connection con = conn.getConnection(); return loadDocument(data, force, conn, con); } catch (NoConnectionAvailableException e) { log4j.warn(e); e.printStackTrace(); return false; } } public boolean loadDocument(FieldProvider[] data, boolean force, ConnectionProvider conn, Connection con) { if (log4j.isDebugEnabled()) log4j.debug("loadDocument " + data.length); setStatus(STATUS_NotPosted); Name = ""; AD_Client_ID = data[0].getField("AD_Client_ID"); AD_Org_ID = data[0].getField("AD_Org_ID"); C_BPartner_ID = data[0].getField("C_BPartner_ID"); M_Product_ID = data[0].getField("M_Product_ID"); AD_OrgTrx_ID = data[0].getField("AD_OrgTrx_ID"); C_SalesRegion_ID = data[0].getField("C_SalesRegion_ID"); C_Project_ID = data[0].getField("C_Project_ID"); C_Campaign_ID = data[0].getField("C_Campaign_ID"); C_Activity_ID = data[0].getField("C_Activity_ID"); C_LocFrom_ID = data[0].getField("C_LocFrom_ID"); C_LocTo_ID = data[0].getField("C_LocTo_ID"); User1_ID = data[0].getField("User1_ID"); User2_ID = data[0].getField("User2_ID"); C_Costcenter_ID = data[0].getField("C_Costcenter_ID"); Name = data[0].getField("Name"); DocumentNo = data[0].getField("DocumentNo"); DateAcct = data[0].getField("DateAcct"); DateDoc = data[0].getField("DateDoc"); C_Period_ID = data[0].getField("C_Period_ID"); C_Currency_ID = data[0].getField("C_Currency_ID"); C_DocType_ID = data[0].getField("C_DocType_ID"); C_Charge_ID = data[0].getField("C_Charge_ID"); ChargeAmt = data[0].getField("ChargeAmt"); C_BankAccount_ID = data[0].getField("C_BankAccount_ID"); if (log4j.isDebugEnabled()) log4j.debug("AcctServer - loadDocument - C_BankAccount_ID : " + C_BankAccount_ID); Posted = data[0].getField("Posted"); if (!loadDocumentDetails(data, conn)) loadDocumentType(); // if (log4j.isDebugEnabled()) // log4j.debug("AcctServer - loadDocument - DocumentDetails Loaded"); if ((DateAcct == null || DateAcct.equals("")) && (DateDoc != null && !DateDoc.equals(""))) DateAcct = DateDoc; else if ((DateDoc == null || DateDoc.equals("")) && (DateAcct != null && !DateAcct.equals(""))) DateDoc = DateAcct; // DocumentNo (or Name) if (DocumentNo == null || DocumentNo.length() == 0) DocumentNo = Name; // if (DocumentNo == null || DocumentNo.length() == // 0)(DateDoc.equals("") && !DateAcct.equals("")) // DocumentNo = ""; // Check Mandatory Info // if (log4j.isDebugEnabled()) // log4j.debug("AcctServer - loadDocument - C_Currency_ID : " + // C_Currency_ID); String error = ""; if (AD_Table_ID == null || AD_Table_ID.equals("")) error += " AD_Table_ID"; if (Record_ID == null || Record_ID.equals("")) error += " Record_ID"; if (AD_Client_ID == null || AD_Client_ID.equals("")) error += " AD_Client_ID"; if (AD_Org_ID == null || AD_Org_ID.equals("")) error += " AD_Org_ID"; if (C_Currency_ID == null || C_Currency_ID.equals("")) error += " C_Currency_ID"; if (DateAcct == null || DateAcct.equals("")) error += " DateAcct"; if (DateDoc == null || DateDoc.equals("")) error += " DateDoc"; if (error.length() > 0) { log4j.warn("AcctServer - loadDocument - " + DocumentNo + " - Mandatory info missing: " + error); return false; } try { dateAcct = OBDateUtils.getDate(DateAcct); } catch (ParseException e1) { // Do nothing } // Delete existing Accounting if (force) { if (Posted.equals("Y") && !isPeriodOpen()) { // already posted - // don't delete if // period closed log4j.warn("AcctServer - loadDocument - " + DocumentNo + " - Period Closed for already posted document"); return false; } // delete it try { AcctServerData.delete(connectionProvider, AD_Table_ID, Record_ID); } catch (ServletException e) { log4j.warn(e); e.printStackTrace(); } // if (log4j.isDebugEnabled()) log4j.debug("post - deleted=" + no); } else if (Posted.equals("Y")) { log4j.warn("AcctServer - loadDocument - " + DocumentNo + " - Document already posted"); return false; } // if (log4j.isDebugEnabled()) // log4j.debug("AcctServer - loadDocument -finished"); return true; } // loadDocument public void loadDocumentType() { loadDocumentType(false); } public void loadDocumentType(boolean supressWarnings) { // if (log4j.isDebugEnabled()) // log4j.debug("AcctServer - loadDocumentType - DocumentType: " + // DocumentType + " - C_DocType_ID : " + C_DocType_ID); try { if (/* DocumentType.equals("") && */C_DocType_ID != null && C_DocType_ID != "") { AcctServerData[] data = AcctServerData.selectDocType(connectionProvider, C_DocType_ID); DocumentType = data[0].docbasetype; GL_Category_ID = data[0].glCategoryId; IsReversal = data[0].isreversal; IsReturn = data[0].isreturn; } // We have a document Type, but no GL info - search for DocType if (GL_Category_ID != null && GL_Category_ID.equals("")) { AcctServerData[] data = AcctServerData.selectGLCategory(connectionProvider, AD_Client_ID, DocumentType); if (data != null && data.length != 0) { GL_Category_ID = data[0].glCategoryId; IsReversal = data[0].isreversal; IsReturn = data[0].isreturn; } } if (!supressWarnings && DocumentType != null && DocumentType.equals("")) log4j.warn("AcctServer - loadDocumentType - No DocType for GL Info"); if (GL_Category_ID != null && GL_Category_ID.equals("")) { AcctServerData[] data = AcctServerData.selectDefaultGLCategory(connectionProvider, AD_Client_ID); GL_Category_ID = data[0].glCategoryId; } } catch (ServletException e) { log4j.warn(e); e.printStackTrace(); } if (GL_Category_ID != null && GL_Category_ID.equals("")) log4j.warn("AcctServer - loadDocumentType - No GL Info"); // if (log4j.isDebugEnabled()) // log4j.debug("AcctServer - loadDocumentType -" + tableName + "_ID : " // + Record_ID + " - C_DocType_ID: " + C_DocType_ID + // " - DocumentType: " + DocumentType); } /** * @deprecated During cleanup for 3.0 the entire table ad_node was removed from core, so this * insertNote method doesn't serve have any purpose anymore. Keep as deprecated noop * in case any module may call it. */ @Deprecated public boolean insertNote(String AD_Client_ID, String AD_Org_ID, String AD_User_ID, String AD_Table_ID, String Record_ID, String AD_MessageValue, String Text, String Reference, VariablesSecureApp vars, ConnectionProvider conn, Connection con) { return false; } /** * Posting logic for Accounting Schema index * * @param index * Accounting Schema index * @return posting status/error code */ private final String postLogic(int index, ConnectionProvider conn, Connection con, VariablesSecureApp vars, AcctSchema as) throws ServletException { // rejectUnbalanced if (!m_as[index].isSuspenseBalancing() && !isBalanced()) return STATUS_NotBalanced; // rejectUnconvertible if (!isConvertible(m_as[index], conn)) return STATUS_NotConvertible; // if (log4j.isDebugEnabled()) // log4j.debug("AcctServer - Before isPeriodOpen"); // rejectPeriodClosed if (!isPeriodOpen()) return STATUS_PeriodClosed; // if (log4j.isDebugEnabled()) // log4j.debug("AcctServer - After isPeriodOpen"); // createFacts try { m_fact[index] = createFact(m_as[index], conn, con, vars); } catch (OBException e) { log4j.warn("Accounting process failed. RecordID: " + Record_ID + " - TableId: " + AD_Table_ID, e); String strMessageError = e.getMessage(); if (strMessageError.indexOf("") != -1) { setMessageResult(OBMessageUtils.translateError(strMessageError)); if ("@NotConvertible@".equals(strMessageError)) { return STATUS_NotConvertible; } else if (StringUtils.equals(strMessageError, "@PeriodNotAvailable@")) { return STATUS_PeriodClosed; } } return STATUS_Error; } catch (Exception e) { log4j.warn("Accounting process failed. RecordID: " + Record_ID + " - TableId: " + AD_Table_ID, e); return STATUS_Error; } if (!Status.equals(STATUS_NotPosted)) return Status; if (m_fact[index] == null) return STATUS_Error; Status = STATUS_PostPrepared; // Distinguish multi-currency Documents MultiCurrency = m_fact[index].isMulticurrencyDocument(); // if (log4j.isDebugEnabled()) // log4j.debug("AcctServer - Before balanceSource"); // balanceSource if (!MultiCurrency && !m_fact[index].isSourceBalanced()) m_fact[index].balanceSource(conn); // if (log4j.isDebugEnabled()) // log4j.debug("AcctServer - After balanceSource"); // if (log4j.isDebugEnabled()) // log4j.debug("AcctServer - Before isSegmentBalanced"); // balanceSegments if (!MultiCurrency && !m_fact[index].isSegmentBalanced(conn)) m_fact[index].balanceSegments(conn); // if (log4j.isDebugEnabled()) // log4j.debug("AcctServer - After isSegmentBalanced"); // balanceAccounting if (!m_fact[index].isAcctBalanced()) m_fact[index].balanceAccounting(conn); // Here processes defined to be executed at posting time, when existing, will be executed AcctServerData[] data = AcctServerData.selectAcctProcess(conn, as.m_C_AcctSchema_ID); for (int i = 0; data != null && i < data.length; i++) { String strClassname = data[i].classname; if (!strClassname.equals("")) { try { AcctProcessTemplate newTemplate = (AcctProcessTemplate) Class.forName(strClassname) .newInstance(); if (!newTemplate.execute(this, as, conn, con, vars)) { OBDal.getInstance().rollbackAndClose(); return getStatus(); } } catch (Exception e) { log4j.error("Error while creating new instance for AcctProcessTemplate - " + e); return AcctServer.STATUS_Error; } } } if (messageResult != null) return getStatus(); return STATUS_Posted; } // postLogic /** * Is the Source Document Balanced * * @return true if (source) balanced */ public boolean isBalanced() { // Multi-Currency documents are source balanced by definition if (MultiCurrency) return true; // boolean retValue = (getBalance().compareTo(ZERO) == 0); if (retValue) { if (log4j.isDebugEnabled()) log4j.debug("AcctServer - isBalanced - " + DocumentNo); } else log4j.warn("AcctServer - is not Balanced - " + DocumentNo); return retValue; } // isBalanced /** * Is Document convertible to currency and Conversion Type * * @param acctSchema * accounting schema * @return true, if convertible to accounting currency */ public boolean isConvertible(AcctSchema acctSchema, ConnectionProvider conn) throws ServletException { // No Currency in document if (NO_CURRENCY.equals(C_Currency_ID)) { // if (log4j.isDebugEnabled()) // log4j.debug("AcctServer - isConvertible (none) - " + DocumentNo); return true; } // Get All Currencies Vector<Object> set = new Vector<Object>(); set.addElement(C_Currency_ID); for (int i = 0; p_lines != null && i < p_lines.length; i++) { String currency = p_lines[i].m_C_Currency_ID; if (currency != null && !currency.equals("")) set.addElement(currency); } // just one and the same if (set.size() == 1 && acctSchema.m_C_Currency_ID.equals(C_Currency_ID)) { // if (log4j.isDebugEnabled()) log4j.debug // ("AcctServer - isConvertible (same) Cur=" + C_Currency_ID + " - " // + DocumentNo); return true; } boolean convertible = true; for (int i = 0; i < set.size() && convertible == true; i++) { // if (log4j.isDebugEnabled()) log4j.debug // ("AcctServer - get currency"); String currency = (String) set.elementAt(i); if (currency == null) currency = ""; // if (log4j.isDebugEnabled()) log4j.debug // ("AcctServer - currency = " + currency); if (!currency.equals(acctSchema.m_C_Currency_ID)) { // if (log4j.isDebugEnabled()) log4j.debug // ("AcctServer - get converted amount (init)"); String amt = ""; OBQuery<ConversionRateDoc> conversionQuery = null; int conversionCount = 0; if (AD_Table_ID.equals(TABLEID_Invoice)) { conversionQuery = OBDal.getInstance().createQuery(ConversionRateDoc.class, "invoice = '" + Record_ID + "' and currency='" + currency + "' and toCurrency='" + acctSchema.m_C_Currency_ID + "'"); } else if (AD_Table_ID.equals(TABLEID_Payment)) { conversionQuery = OBDal.getInstance().createQuery(ConversionRateDoc.class, "payment = '" + Record_ID + "' and currency='" + currency + "' and toCurrency='" + acctSchema.m_C_Currency_ID + "'"); } else if (AD_Table_ID.equals(TABLEID_Transaction)) { conversionQuery = OBDal.getInstance().createQuery(ConversionRateDoc.class, "financialAccountTransaction = '" + Record_ID + "' and currency='" + currency + "' and toCurrency='" + acctSchema.m_C_Currency_ID + "'"); } if (conversionQuery != null) { conversionCount = conversionQuery.count(); } if (conversionCount > 0) { List<ConversionRateDoc> conversionRate = conversionQuery.list(); OBCriteria<Currency> currencyCrit = OBDal.getInstance().createCriteria(Currency.class); currencyCrit.add(Restrictions.eq(Currency.PROPERTY_ID, acctSchema.m_C_Currency_ID)); currencyCrit.setProjection(Projections.max(Currency.PROPERTY_STANDARDPRECISION)); Long precision = 0L; if (currencyCrit.count() > 0) { List<Currency> toCurrency = currencyCrit.list(); precision = toCurrency.get(0).getStandardPrecision(); } BigDecimal convertedAmount = new BigDecimal("1").multiply(conversionRate.get(0).getRate()); amt = convertedAmount.setScale(precision.intValue(), RoundingMode.HALF_UP).toString(); } if (("").equals(amt) || amt == null) amt = getConvertedAmt("1", currency, acctSchema.m_C_Currency_ID, DateAcct, acctSchema.m_CurrencyRateType, AD_Client_ID, AD_Org_ID, conn); // if (log4j.isDebugEnabled()) log4j.debug // ("get converted amount (end)"); if (amt == null || ("").equals(amt)) { convertible = false; log4j.warn("AcctServer - isConvertible NOT from " + currency + " - " + DocumentNo); } else if (log4j.isDebugEnabled()) log4j.debug("AcctServer - isConvertible from " + currency); } } // if (log4j.isDebugEnabled()) log4j.debug // ("AcctServer - isConvertible=" + convertible + ", AcctSchemaCur=" + // acctSchema.m_C_Currency_ID + " - " + DocumentNo); return convertible; } // isConvertible /** * Get the Amount (loaded in loadDocumentDetails) * * @param AmtType * see AMTTYPE_* * @return Amount */ public String getAmount(int AmtType) { if (AmtType < 0 || Amounts == null || AmtType >= Amounts.length) return null; return (Amounts[AmtType].equals("")) ? "0" : Amounts[AmtType]; } // getAmount /** * Get Amount with index 0 * * @return Amount (primary document amount) */ public String getAmount() { return Amounts[0]; } // getAmount /** * Convert an amount * * @param CurFrom_ID * The C_Currency_ID FROM * @param CurTo_ID * The C_Currency_ID TO * @param ConvDate * The Conversion date - if null - use current date * @param RateType * The Conversion rate type - if null/empty - use Spot * @param Amt * The amount to be converted * @return converted amount */ public static String getConvertedAmt(String Amt, String CurFrom_ID, String CurTo_ID, String ConvDate, String RateType, ConnectionProvider conn) { if (log4j.isDebugEnabled()) log4j.debug("AcctServer - getConvertedAmount no client nor org"); return getConvertedAmt(Amt, CurFrom_ID, CurTo_ID, ConvDate, RateType, "", "", conn); } public static String getConvertedAmt(String Amt, String CurFrom_ID, String CurTo_ID, String ConvDate, String RateType, String client, String org, ConnectionProvider conn) { if (log4j.isDebugEnabled()) log4j.debug("AcctServer - getConvertedAmount - starting method - Amt : " + Amt + " - CurFrom_ID : " + CurFrom_ID + " - CurTo_ID : " + CurTo_ID + "- ConvDate: " + ConvDate + " - RateType:" + RateType + " - client:" + client + "- org:" + org); if (Amt.equals("")) throw new IllegalArgumentException("AcctServer - getConvertedAmt - required parameter missing - Amt"); if (CurFrom_ID.equals(CurTo_ID) || Amt.equals("0")) return Amt; AcctServerData[] data = null; try { if (ConvDate != null && ConvDate.equals("")) ConvDate = DateTimeData.today(conn); // ConvDate IN DATE if (RateType == null || RateType.equals("")) RateType = "S"; data = AcctServerData.currencyConvert(conn, Amt, CurFrom_ID, CurTo_ID, ConvDate, RateType, client, org); } catch (ServletException e) { log4j.warn(e); e.printStackTrace(); } if (data == null || data.length == 0) { /* * log4j.error("No conversion ratio"); throw new * ServletException("No conversion ratio defined!"); */ return ""; } else { if (log4j.isDebugEnabled()) log4j.debug("getConvertedAmount - converted:" + data[0].converted); return data[0].converted; } } // getConvertedAmt public static BigDecimal getConvertionRate(String CurFrom_ID, String CurTo_ID, String ConvDate, String RateType, String client, String org, ConnectionProvider conn) { if (CurFrom_ID.equals(CurTo_ID)) return BigDecimal.ONE; AcctServerData[] data = null; try { if (ConvDate != null && ConvDate.equals("")) ConvDate = DateTimeData.today(conn); // ConvDate IN DATE if (RateType == null || RateType.equals("")) RateType = "S"; data = AcctServerData.currencyConvertionRate(conn, CurFrom_ID, CurTo_ID, ConvDate, RateType, client, org); } catch (ServletException e) { log4j.warn(e); e.printStackTrace(); } if (data == null || data.length == 0) { log4j.error("No conversion ratio"); return BigDecimal.ZERO; } else { if (log4j.isDebugEnabled()) log4j.debug("getConvertionRate - rate:" + data[0].converted); return new BigDecimal(data[0].converted); } } // getConvertedAmt /** * Is Period Open * * @return true if period is open */ public boolean isPeriodOpen() { // if (log4j.isDebugEnabled()) // log4j.debug(" ***************************** AD_Client_ID - " + // AD_Client_ID + " -- DateAcct - " + DateAcct + " -- DocumentType - " + // DocumentType); setC_Period_ID(); boolean open = (!C_Period_ID.equals("")); if (open) { if (log4j.isDebugEnabled()) log4j.debug("AcctServer - isPeriodOpen - " + DocumentNo); } else { log4j.warn("AcctServer - isPeriodOpen NO - " + DocumentNo); } return open; } // isPeriodOpen /** * Calculate Period ID. Set to -1 if no period open, 0 if no period control */ public void setC_Period_ID() { if (C_Period_ID != null) return; if (log4j.isDebugEnabled()) log4j.debug("AcctServer - setC_Period_ID - AD_Client_ID - " + AD_Client_ID + "--DateAcct - " + DateAcct + "--DocumentType -" + DocumentType); AcctServerData[] data = null; try { if (log4j.isDebugEnabled()) log4j.debug("setC_Period_ID - inside try - AD_Client_ID - " + AD_Client_ID + " -- DateAcct - " + DateAcct + " -- DocumentType - " + DocumentType); data = AcctServerData.periodOpen(connectionProvider, AD_Client_ID, DocumentType, AD_Org_ID, DateAcct); C_Period_ID = data[0].period; if (log4j.isDebugEnabled()) log4j.debug("AcctServer - setC_Period_ID - " + AD_Client_ID + "/" + DateAcct + "/" + DocumentType + " => " + C_Period_ID); } catch (ServletException e) { log4j.warn(e); e.printStackTrace(); } } // setC_Period_ID /** * Matching * * <pre> * Derive Invoice-Receipt Match from PO-Invoice and PO-Receipt * Purchase Order (20) * - Invoice1 (10) * - Invoice2 (10) * - Receipt1 (5) * - Receipt2 (15) * (a) Creates Directs * - Invoice1 - Receipt1 (5) * - Invoice2 - Receipt2 (10) * (b) Creates Indirects * - Invoice1 - Receipt2 (5) * (Not imlemented) * * * </pre> * * @return number of records created */ public int match(VariablesSecureApp vars, ConnectionProvider conn, Connection con) { // if (log4j.isDebugEnabled()) // log4j.debug("AcctServer - Match--Starting"); int counter = 0; // (a) Direct Matches AcctServerData[] data = null; try { data = AcctServerData.selectMatch(conn, AD_Client_ID); for (int i = 0; i < data.length; i++) { BigDecimal qty1 = new BigDecimal(data[i].qty1); BigDecimal qty2 = new BigDecimal(data[i].qty2); BigDecimal Qty = qty1.min(qty2); if (Qty.toString().equals("0")) continue; // if (log4j.isDebugEnabled()) // log4j.debug("AcctServer - Match--dateTrx1 :->" + data[i].datetrx1 // + "Match--dateTrx2: ->" + data[i].datetrx2); String dateTrx1 = data[i].datetrx1; String dateTrx2 = data[i].datetrx2; String compare = ""; try { compare = DateTimeData.compare(conn, dateTrx1, dateTrx2); } catch (ServletException e) { log4j.warn(e); e.printStackTrace(); } String DateTrx = dateTrx1; if (compare.equals("-1")) DateTrx = dateTrx2; // String strQty = Qty.toString(); String strDateTrx = DateTrx; String AD_Client_ID = data[i].adClientId; String AD_Org_ID = data[i].adOrgId; String C_InvoiceLine_ID = data[i].cInvoicelineId; String M_InOutLine_ID = data[i].mInoutlineId; String M_Product_ID = data[i].mProductId; // if (createMatchInv(AD_Client_ID, AD_Org_ID, M_InOutLine_ID, C_InvoiceLine_ID, M_Product_ID, strDateTrx, strQty, vars, conn, con) == 1) counter++; } } catch (ServletException e) { log4j.warn(e); e.printStackTrace(); } // if (log4j.isDebugEnabled()) // log4j.debug("AcctServer - Matcher.match - Client_ID=" + AD_Client_ID // + ", Records created=" + counter); return counter; } // match /** * Create MatchInv record * * @param AD_Client_ID * Client * @param AD_Org_ID * Org * @param M_InOutLine_ID * Receipt * @param C_InvoiceLine_ID * Invoice * @param M_Product_ID * Product * @param DateTrx * Date * @param Qty * Qty * @return true if record created */ private int createMatchInv(String AD_Client_ID, String AD_Org_ID, String M_InOutLine_ID, String C_InvoiceLine_ID, String M_Product_ID, String DateTrx, String Qty, VariablesSecureApp vars, ConnectionProvider conn, Connection con) { // if (log4j.isDebugEnabled()) // log4j.debug("AcctServer - createMatchInv - InvLine=" + // C_InvoiceLine_ID + ",Rec=" + M_InOutLine_ID + ", Qty=" + Qty + ", " + // DateTrx); int no = 0; try { String M_MatchInv_ID = SequenceIdData.getUUID(); // no = AcctServerData.insertMatchInv(con, conn, M_MatchInv_ID, AD_Client_ID, AD_Org_ID, M_InOutLine_ID, C_InvoiceLine_ID, M_Product_ID, DateTrx, Qty); } catch (ServletException e) { log4j.warn(e); e.printStackTrace(); } return no; } // createMatchInv /** * Get the account for Accounting Schema * * @param AcctType * see ACCTTYPE_* * @param as * accounting schema * @return Account */ public final Account getAccount(String AcctType, AcctSchema as, ConnectionProvider conn) { BigDecimal AMT = null; AcctServerData[] data = null; // if (log4j.isDebugEnabled()) // log4j.debug("*******************************getAccount 1: AcctType:-->" // + AcctType); try { /** Account Type - Invoice */ if (AcctType.equals(ACCTTYPE_Charge)) { // see getChargeAccount in // DocLine // if (log4j.isDebugEnabled()) // log4j.debug("AcctServer - *******************amount(AMT);-->" // + getAmount(AMTTYPE_Charge)); AMT = new BigDecimal(getAmount(AMTTYPE_Charge)); // if (log4j.isDebugEnabled()) // log4j.debug("AcctServer - *******************AMT;-->" + AMT); int cmp = AMT.compareTo(BigDecimal.ZERO); // if (log4j.isDebugEnabled()) // log4j.debug("AcctServer - ******************* CMP: " + cmp); if (cmp == 0) return null; else if (cmp < 0) data = AcctServerData.selectExpenseAcct(conn, C_Charge_ID, as.getC_AcctSchema_ID()); else data = AcctServerData.selectRevenueAcct(conn, C_Charge_ID, as.getC_AcctSchema_ID()); // if (log4j.isDebugEnabled()) // log4j.debug("AcctServer - *******************************getAccount 2"); } else if (AcctType.equals(ACCTTYPE_V_Liability)) { data = AcctServerData.selectLiabilityAcct(conn, C_BPartner_ID, as.getC_AcctSchema_ID()); } else if (AcctType.equals(ACCTTYPE_V_Liability_Services)) { data = AcctServerData.selectLiabilityServicesAcct(conn, C_BPartner_ID, as.getC_AcctSchema_ID()); } else if (AcctType.equals(ACCTTYPE_C_Receivable)) { data = AcctServerData.selectReceivableAcct(conn, C_BPartner_ID, as.getC_AcctSchema_ID()); } else if (AcctType.equals(ACCTTYPE_UnallocatedCash)) { /** Account Type - Payment */ data = AcctServerData.selectUnallocatedCashAcct(conn, C_BankAccount_ID, as.getC_AcctSchema_ID()); } else if (AcctType.equals(ACCTTYPE_BankInTransit)) { data = AcctServerData.selectInTransitAcct(conn, C_BankAccount_ID, as.getC_AcctSchema_ID()); } else if (AcctType.equals(ACCTTYPE_BankInTransitDefault)) { data = AcctServerData.selectInTransitDefaultAcct(conn, as.getC_AcctSchema_ID()); } else if (AcctType.equals(ACCTTYPE_ConvertChargeDefaultAmt)) { data = AcctServerData.selectConvertChargeDefaultAmtAcct(conn, as.getC_AcctSchema_ID()); } else if (AcctType.equals(ACCTTYPE_ConvertGainDefaultAmt)) { data = AcctServerData.selectConvertGainDefaultAmtAcct(conn, as.getC_AcctSchema_ID()); } else if (AcctType.equals(ACCTTYPE_PaymentSelect)) { data = AcctServerData.selectPaymentSelectAcct(conn, C_BankAccount_ID, as.getC_AcctSchema_ID()); } else if (AcctType.equals(ACCTTYPE_WriteOffDefault)) { data = AcctServerData.selectWriteOffDefault(conn, as.getC_AcctSchema_ID()); } else if (AcctType.equals(ACCTTYPE_WriteOffDefault_Revenue)) { data = AcctServerData.selectWriteOffDefaultRevenue(conn, as.getC_AcctSchema_ID()); } else if (AcctType.equals(ACCTTYPE_DiscountExp)) { /** Account Type - Allocation */ data = AcctServerData.selectDiscountExpAcct(conn, C_BPartner_ID, as.getC_AcctSchema_ID()); } else if (AcctType.equals(ACCTTYPE_DiscountRev)) { data = AcctServerData.selectDiscountRevAcct(conn, C_BPartner_ID, as.getC_AcctSchema_ID()); } else if (AcctType.equals(ACCTTYPE_WriteOff)) { data = AcctServerData.selectWriteOffAcct(conn, C_BPartner_ID, as.getC_AcctSchema_ID()); } else if (AcctType.equals(ACCTTYPE_WriteOff_Revenue)) { data = AcctServerData.selectWriteOffAcctRevenue(conn, C_BPartner_ID, as.getC_AcctSchema_ID()); } else if (AcctType.equals(ACCTTYPE_ConvertChargeLossAmt)) { /** Account Type - Bank Statement */ data = AcctServerData.selectConvertChargeLossAmt(conn, C_BankAccount_ID, as.getC_AcctSchema_ID()); } else if (AcctType.equals(ACCTTYPE_ConvertChargeGainAmt)) { data = AcctServerData.selectConvertChargeGainAmt(conn, C_BankAccount_ID, as.getC_AcctSchema_ID()); } else if (AcctType.equals(ACCTTYPE_BankAsset)) { data = AcctServerData.selectAssetAcct(conn, C_BankAccount_ID, as.getC_AcctSchema_ID()); } else if (AcctType.equals(ACCTTYPE_InterestRev)) { data = AcctServerData.selectInterestRevAcct(conn, C_BankAccount_ID, as.getC_AcctSchema_ID()); } else if (AcctType.equals(ACCTTYPE_InterestExp)) { data = AcctServerData.selectInterestExpAcct(conn, C_BankAccount_ID, as.getC_AcctSchema_ID()); } else if (AcctType.equals(ACCTTYPE_CashAsset)) { /** Account Type - Cash */ data = AcctServerData.selectCBAssetAcct(conn, C_CashBook_ID, as.getC_AcctSchema_ID()); } else if (AcctType.equals(ACCTTYPE_CashTransfer)) { data = AcctServerData.selectCashTransferAcct(conn, C_CashBook_ID, as.getC_AcctSchema_ID()); } else if (AcctType.equals(ACCTTYPE_CashExpense)) { data = AcctServerData.selectCBExpenseAcct(conn, C_CashBook_ID, as.getC_AcctSchema_ID()); } else if (AcctType.equals(ACCTTYPE_CashReceipt)) { data = AcctServerData.selectCBReceiptAcct(conn, C_CashBook_ID, as.getC_AcctSchema_ID()); } else if (AcctType.equals(ACCTTYPE_CashDifference)) { data = AcctServerData.selectCBDifferencesAcct(conn, C_CashBook_ID, as.getC_AcctSchema_ID()); } else if (AcctType.equals(ACCTTYPE_InvDifferences)) { /** Inventory Accounts */ data = AcctServerData.selectWDifferencesAcct(conn, M_Warehouse_ID, as.getC_AcctSchema_ID()); } else if (AcctType.equals(ACCTTYPE_NotInvoicedReceipts)) { if (log4j.isDebugEnabled()) log4j.debug("AcctServer - getAccount - ACCTYPE_NotInvoicedReceipts - C_BPartner_ID - " + C_BPartner_ID); data = AcctServerData.selectNotInvoicedReceiptsAcct(conn, C_BPartner_ID, as.getC_AcctSchema_ID()); } else if (AcctType.equals(ACCTTYPE_ProjectAsset)) { /** Project Accounts */ data = AcctServerData.selectPJAssetAcct(conn, C_Project_ID, as.getC_AcctSchema_ID()); } else if (AcctType.equals(ACCTTYPE_ProjectWIP)) { data = AcctServerData.selectPJWIPAcct(conn, C_Project_ID, as.getC_AcctSchema_ID()); } else if (AcctType.equals(ACCTTYPE_PPVOffset)) { /** GL Accounts */ data = AcctServerData.selectPPVOffsetAcct(conn, as.getC_AcctSchema_ID()); } else { log4j.warn("AcctServer - getAccount - Not found AcctType=" + AcctType); return null; } // if (log4j.isDebugEnabled()) // log4j.debug("AcctServer - *******************************getAccount 3"); } catch (ServletException e) { log4j.warn(e); e.printStackTrace(); } // Get Acct String Account_ID = ""; if (data != null && data.length != 0) { Account_ID = data[0].accountId; } else return null; // No account if (Account_ID.equals("")) { log4j.warn("AcctServer - getAccount - NO account Type=" + AcctType + ", Record=" + Record_ID); return null; } // if (log4j.isDebugEnabled()) // log4j.debug("AcctServer - *******************************getAccount 4"); // Return Account Account acct = null; try { acct = Account.getAccount(conn, Account_ID); } catch (ServletException e) { log4j.warn(e); e.printStackTrace(); } return acct; } // getAccount /** * Get the account for Accounting Schema * * @param cBPartnerId * business partner id * @param as * accounting schema * @return Account */ public final Account getAccountBPartner(String cBPartnerId, AcctSchema as, boolean isReceipt, boolean isPrepayment, ConnectionProvider conn) throws ServletException { return getAccountBPartner(cBPartnerId, as, isReceipt, isPrepayment, false, conn); } /** * Get the account for Accounting Schema * * @param cBPartnerId * business partner id * @param as * accounting schema * @return Account */ public final Account getAccountBPartner(String cBPartnerId, AcctSchema as, boolean isReceipt, boolean isPrepayment, boolean isDoubtfuldebt, ConnectionProvider conn) throws ServletException { String strValidCombination = ""; OBContext.setAdminMode(); try { if (isReceipt) { final StringBuilder whereClause = new StringBuilder(); if (isDoubtfuldebt) { BusinessPartner bp = OBDal.getInstance().get(BusinessPartner.class, cBPartnerId); whereClause.append(" as cuscata "); whereClause.append(" where cuscata.businessPartnerCategory.id = :bpCategoryID"); whereClause.append(" and cuscata.accountingSchema.id = :acctSchemaID"); final OBQuery<CategoryAccounts> obqParameters = OBDal.getInstance() .createQuery(CategoryAccounts.class, whereClause.toString()); obqParameters.setFilterOnReadableClients(false); obqParameters.setFilterOnReadableOrganization(false); obqParameters.setNamedParameter("bpCategoryID", bp.getBusinessPartnerCategory().getId()); obqParameters.setNamedParameter("acctSchemaID", as.m_C_AcctSchema_ID); final List<CategoryAccounts> customerAccounts = obqParameters.list(); if (customerAccounts != null && customerAccounts.size() > 0 && customerAccounts.get(0).getDoubtfulDebtAccount() != null) { strValidCombination = customerAccounts.get(0).getDoubtfulDebtAccount().getId(); } if (strValidCombination.equals("")) { Map<String, String> parameters = new HashMap<String, String>(); parameters.put("Account", "@DoubtfulDebt@"); parameters.put("Entity", bp.getBusinessPartnerCategory().getIdentifier()); parameters.put("AccountingSchema", OBDal.getInstance() .get(org.openbravo.model.financialmgmt.accounting.coa.AcctSchema.class, as.getC_AcctSchema_ID()) .getIdentifier()); setMessageResult(conn, STATUS_InvalidAccount, "error", parameters); throw new IllegalStateException(); } return new Account(conn, strValidCombination); } whereClause.append(" as cusa "); whereClause.append(" where cusa.businessPartner.id = '" + cBPartnerId + "'"); whereClause.append(" and cusa.accountingSchema.id = '" + as.m_C_AcctSchema_ID + "'"); whereClause.append(" and (cusa.status is null or cusa.status = 'DE')"); final OBQuery<CustomerAccounts> obqParameters = OBDal.getInstance() .createQuery(CustomerAccounts.class, whereClause.toString()); obqParameters.setFilterOnReadableClients(false); obqParameters.setFilterOnReadableOrganization(false); final List<CustomerAccounts> customerAccounts = obqParameters.list(); if (customerAccounts != null && customerAccounts.size() > 0 && customerAccounts.get(0).getCustomerReceivablesNo() != null && !isPrepayment) { strValidCombination = customerAccounts.get(0).getCustomerReceivablesNo().getId(); } if (customerAccounts != null && customerAccounts.size() > 0 && customerAccounts.get(0).getCustomerPrepayment() != null && isPrepayment) { strValidCombination = customerAccounts.get(0).getCustomerPrepayment().getId(); } } else { final StringBuilder whereClause = new StringBuilder(); whereClause.append(" as vena "); whereClause.append(" where vena.businessPartner.id = '" + cBPartnerId + "'"); whereClause.append(" and vena.accountingSchema.id = '" + as.m_C_AcctSchema_ID + "'"); whereClause.append(" and (vena.status is null or vena.status = 'DE')"); final OBQuery<VendorAccounts> obqParameters = OBDal.getInstance().createQuery(VendorAccounts.class, whereClause.toString()); obqParameters.setFilterOnReadableClients(false); obqParameters.setFilterOnReadableOrganization(false); final List<VendorAccounts> vendorAccounts = obqParameters.list(); if (vendorAccounts != null && vendorAccounts.size() > 0 && vendorAccounts.get(0).getVendorLiability() != null && !isPrepayment) { strValidCombination = vendorAccounts.get(0).getVendorLiability().getId(); } if (vendorAccounts != null && vendorAccounts.size() > 0 && vendorAccounts.get(0).getVendorPrepayment() != null && isPrepayment) { strValidCombination = vendorAccounts.get(0).getVendorPrepayment().getId(); } } if (strValidCombination.equals("")) { Map<String, String> parameters = new HashMap<String, String>(); parameters.put("Account", isReceipt ? (isPrepayment ? "@CustomerPrepayment@" : "@CustomerReceivables@") : (isPrepayment ? "@VendorPrepayment@" : "@VendorLiability@")); BusinessPartner bp = OBDal.getInstance().get(BusinessPartner.class, cBPartnerId); if (bp != null) { parameters.put("Entity", bp.getIdentifier()); } parameters.put("AccountingSchema", OBDal.getInstance().get(org.openbravo.model.financialmgmt.accounting.coa.AcctSchema.class, as.getC_AcctSchema_ID()).getIdentifier()); setMessageResult(conn, STATUS_InvalidAccount, "error", parameters); throw new IllegalStateException(); } } finally { OBContext.restorePreviousMode(); } return new Account(conn, strValidCombination); } // getAccount /** * It gets Account to be used to provision for the selected Business Partner * * @param BPartnerId * : ID of the Business Partner * @param isExpense * : Provision Expense Account. If not it applies to Provision Applied account * @param as * : Accounting Schema * @param conn * : Connection Provider * @return Account * @throws ServletException */ public final Account getAccountBPartnerBadDebt(String BPartnerId, boolean isExpense, AcctSchema as, ConnectionProvider conn) throws ServletException { String strValidCombination = ""; final StringBuilder whereClause = new StringBuilder(); BusinessPartner bp = OBDal.getInstance().get(BusinessPartner.class, BPartnerId); whereClause.append(" as cuscata "); whereClause.append(" where cuscata.businessPartnerCategory.id = :bpCategoryID"); whereClause.append(" and cuscata.accountingSchema.id = :acctSchemaID"); final OBQuery<CategoryAccounts> obqParameters = OBDal.getInstance().createQuery(CategoryAccounts.class, whereClause.toString()); obqParameters.setFilterOnReadableClients(false); obqParameters.setFilterOnReadableOrganization(false); obqParameters.setNamedParameter("bpCategoryID", bp.getBusinessPartnerCategory().getId()); obqParameters.setNamedParameter("acctSchemaID", as.m_C_AcctSchema_ID); final List<CategoryAccounts> customerAccounts = obqParameters.list(); if (customerAccounts != null && customerAccounts.size() > 0 && customerAccounts.get(0).getBadDebtExpenseAccount() != null && isExpense) { strValidCombination = customerAccounts.get(0).getBadDebtExpenseAccount().getId(); } else if (customerAccounts != null && customerAccounts.size() > 0 && customerAccounts.get(0).getBadDebtRevenueAccount() != null && !isExpense) { strValidCombination = customerAccounts.get(0).getBadDebtRevenueAccount().getId(); } if (strValidCombination.equals("")) { Map<String, String> parameters = new HashMap<String, String>(); if (isExpense) { parameters.put("Account", "@BadDebtExpenseAccount@"); } else { parameters.put("Account", "@BadDebtRevenueAccount@"); } parameters.put("Entity", bp.getBusinessPartnerCategory().getIdentifier()); parameters.put("AccountingSchema", OBDal.getInstance() .get(org.openbravo.model.financialmgmt.accounting.coa.AcctSchema.class, as.getC_AcctSchema_ID()) .getIdentifier()); setMessageResult(conn, STATUS_InvalidAccount, "error", parameters); throw new IllegalStateException(); } return new Account(conn, strValidCombination); } // getAccountBPartnerBadDebt /** * It gets Account to be used to provision for the selected Business Partner * * @param BPartnerId * : ID of the Business Partner * @param as * : Accounting Schema * @param conn * : Connection Provider * @return Account * @throws ServletException */ public final Account getAccountBPartnerAllowanceForDoubtfulDebt(String BPartnerId, AcctSchema as, ConnectionProvider conn) throws ServletException { String strValidCombination = ""; final StringBuilder whereClause = new StringBuilder(); BusinessPartner bp = OBDal.getInstance().get(BusinessPartner.class, BPartnerId); whereClause.append(" as cuscata "); whereClause.append(" where cuscata.businessPartnerCategory.id = :bpCategoryID"); whereClause.append(" and cuscata.accountingSchema.id = :acctSchemaID"); final OBQuery<CategoryAccounts> obqParameters = OBDal.getInstance().createQuery(CategoryAccounts.class, whereClause.toString()); obqParameters.setFilterOnReadableClients(false); obqParameters.setFilterOnReadableOrganization(false); obqParameters.setNamedParameter("bpCategoryID", bp.getBusinessPartnerCategory().getId()); obqParameters.setNamedParameter("acctSchemaID", as.m_C_AcctSchema_ID); final List<CategoryAccounts> customerAccounts = obqParameters.list(); if (customerAccounts != null && customerAccounts.size() > 0 && customerAccounts.get(0).getAllowanceForDoubtfulDebtAccount() != null) { strValidCombination = customerAccounts.get(0).getAllowanceForDoubtfulDebtAccount().getId(); } if (strValidCombination.equals("")) { Map<String, String> parameters = new HashMap<String, String>(); parameters.put("Account", "@AllowanceForDoubtfulDebtAccount@"); parameters.put("Entity", bp.getBusinessPartnerCategory().getIdentifier()); parameters.put("AccountingSchema", OBDal.getInstance() .get(org.openbravo.model.financialmgmt.accounting.coa.AcctSchema.class, as.getC_AcctSchema_ID()) .getIdentifier()); setMessageResult(conn, STATUS_InvalidAccount, "error", parameters); throw new IllegalStateException(); } return new Account(conn, strValidCombination); } /** * Get the account for GL Item */ public Account getAccountGLItem(GLItem glItem, AcctSchema as, boolean bIsReceipt, ConnectionProvider conn) throws ServletException { OBContext.setAdminMode(); Account account = null; try { OBCriteria<GLItemAccounts> accounts = OBDal.getInstance().createCriteria(GLItemAccounts.class); accounts.add(Restrictions.eq(GLItemAccounts.PROPERTY_GLITEM, glItem)); accounts.add(Restrictions.eq(GLItemAccounts.PROPERTY_ACCOUNTINGSCHEMA, OBDal.getInstance() .get(org.openbravo.model.financialmgmt.accounting.coa.AcctSchema.class, as.m_C_AcctSchema_ID))); accounts.add(Restrictions.eq(GLItemAccounts.PROPERTY_ACTIVE, true)); accounts.setFilterOnReadableClients(false); accounts.setFilterOnReadableOrganization(false); List<GLItemAccounts> accountList = accounts.list(); if (accountList == null || accountList.size() == 0) return null; if (bIsReceipt) account = new Account(conn, accountList.get(0).getGlitemCreditAcct().getId()); else account = new Account(conn, accountList.get(0).getGlitemDebitAcct().getId()); } finally { OBContext.restorePreviousMode(); if (account == null) { Map<String, String> parameters = new HashMap<String, String>(); parameters.put("Account", bIsReceipt ? "@GlitemCreditAccount@" : "@GlitemDebitAccount@"); if (glItem != null) { parameters.put("Entity", glItem.getIdentifier()); } parameters.put("AccountingSchema", OBDal.getInstance().get(org.openbravo.model.financialmgmt.accounting.coa.AcctSchema.class, as.getC_AcctSchema_ID()).getIdentifier()); setMessageResult(conn, STATUS_InvalidAccount, "error", parameters); throw new IllegalStateException(); } } return account; } public Account getAccountFee(AcctSchema as, FIN_FinancialAccount finAccount, ConnectionProvider conn) throws ServletException { Account account = null; OBContext.setAdminMode(); try { OBCriteria<FIN_FinancialAccountAccounting> accounts = OBDal.getInstance() .createCriteria(FIN_FinancialAccountAccounting.class); accounts.add(Restrictions.eq(FIN_FinancialAccountAccounting.PROPERTY_ACCOUNT, finAccount)); accounts.add(Restrictions.eq(FIN_FinancialAccountAccounting.PROPERTY_ACCOUNTINGSCHEMA, OBDal.getInstance().get(org.openbravo.model.financialmgmt.accounting.coa.AcctSchema.class, as.m_C_AcctSchema_ID))); accounts.add(Restrictions.eq(FIN_FinancialAccountAccounting.PROPERTY_ACTIVE, true)); accounts.setFilterOnReadableClients(false); accounts.setFilterOnReadableOrganization(false); List<FIN_FinancialAccountAccounting> accountList = accounts.list(); if (accountList == null || accountList.size() == 0) return account; account = new Account(conn, accountList.get(0).getFINBankfeeAcct().getId()); } finally { OBContext.restorePreviousMode(); if (account == null) { Map<String, String> parameters = new HashMap<String, String>(); parameters.put("Account", "@BankfeeAccount@"); if (finAccount != null) { parameters.put("Entity", finAccount.getIdentifier()); } parameters.put("AccountingSchema", OBDal.getInstance().get(org.openbravo.model.financialmgmt.accounting.coa.AcctSchema.class, as.getC_AcctSchema_ID()).getIdentifier()); setMessageResult(conn, STATUS_InvalidAccount, "error", parameters); throw new IllegalStateException(); } } return account; } /** * Get the account for Financial Account (Uses: INT - In Transit DEP - Deposit CLE - Clearing WIT * - Withdraw) */ public Account getAccount(ConnectionProvider conn, String use, FIN_FinancialAccountAccounting financialAccountAccounting, boolean bIsReceipt) throws ServletException { OBContext.setAdminMode(); Account account = null; String strvalidCombination = ""; try { if ("INT".equals(use)) strvalidCombination = bIsReceipt ? financialAccountAccounting.getInTransitPaymentAccountIN().getId() : financialAccountAccounting.getFINOutIntransitAcct().getId(); else if ("DEP".equals(use)) strvalidCombination = financialAccountAccounting.getDepositAccount().getId(); else if ("CLE".equals(use)) strvalidCombination = bIsReceipt ? financialAccountAccounting.getClearedPaymentAccount().getId() : financialAccountAccounting.getClearedPaymentAccountOUT().getId(); else if ("WIT".equals(use)) strvalidCombination = financialAccountAccounting.getWithdrawalAccount().getId(); else return account; account = new Account(conn, strvalidCombination); } finally { OBContext.restorePreviousMode(); if (account == null) { Map<String, String> parameters = new HashMap<String, String>(); String strAccount = bIsReceipt ? ("INT".equals(use) ? "@InTransitPaymentAccountIN@" : ("DEP".equals(use) ? "@DepositAccount@" : "@ClearedPaymentAccount@")) : ("INT".equals(use) ? "@InTransitPaymentAccountOUT@" : ("CLE".equals(use) ? "@ClearedPaymentAccountOUT@" : "@WithdrawalAccount@")); parameters.put("Account", strAccount); if (financialAccountAccounting.getAccount() != null) { parameters.put("Entity", financialAccountAccounting.getAccount().getIdentifier()); } parameters.put("AccountingSchema", financialAccountAccounting.getAccountingSchema().getIdentifier()); setMessageResult(conn, STATUS_InvalidAccount, "error", parameters); throw new IllegalStateException(); } } return account; } public FieldProvider[] getObjectFieldProvider() { return objectFieldProvider; } public void setObjectFieldProvider(FieldProvider[] fieldProvider) { objectFieldProvider = fieldProvider; } public abstract void loadObjectFieldProvider(ConnectionProvider conn, String AD_Client_ID, String Id) throws ServletException; public abstract boolean loadDocumentDetails(FieldProvider[] data, ConnectionProvider conn); /** * Get Source Currency Balance - subtracts line (and tax) amounts from total - no rounding * * @return positive amount, if total header is bigger than lines */ public abstract BigDecimal getBalance(); /** * Create Facts (the accounting logic) * * @param as * accounting schema * @return Fact */ public abstract Fact createFact(AcctSchema as, ConnectionProvider conn, Connection con, VariablesSecureApp vars) throws ServletException; public abstract boolean getDocumentConfirmation(ConnectionProvider conn, String strRecordId); public String getInfo(VariablesSecureApp vars) { return (Utility.messageBD(connectionProvider, "Created", vars.getLanguage()) + "=" + success // + ", " + Utility . messageBD ( this , "Errors" , vars . getLanguage ( ) ) + "=" + errors ); } // end of getInfo() method /** * @param language * @return a String representing the result of created */ public String getInfo(String language) { return (Utility.messageBD(connectionProvider, "Created", language) + "=" + success); } public boolean checkDocuments() throws ServletException { return checkDocuments(null, null); } public boolean checkDocuments(String dateFrom, String dateTo) throws ServletException { if (m_as.length == 0) return false; AcctServerData[] docTypes = AcctServerData.selectDocTypes(connectionProvider, AD_Table_ID, AD_Client_ID); // if (log4j.isDebugEnabled()) // log4j.debug("AcctServer - AcctSchema length-" + (this.m_as).length); final Set<String> orgSet = OBContext.getOBContext().getOrganizationStructureProvider(AD_Client_ID) .getChildTree(AD_Org_ID, true); String strorgs = Utility.getInStrSet(orgSet); for (int i = 0; i < docTypes.length; i++) { long init = System.currentTimeMillis(); AcctServerData data = AcctServerData.selectDocumentsDates(connectionProvider, strDateColumn, tableName, AD_Client_ID, strorgs, docTypes[i].name, dateFrom, dateTo); log4j.debug("AcctServerData.selectDocumentsDates for: " + docTypes[i].name + " took: " + (System.currentTimeMillis() - init)); if (data != null) { if (data.id != null && !data.id.equals("")) { return true; } } } return false; } // end of checkDocuments() method @Deprecated /* * Use checkDocuments method instead */ public boolean filterDatesCheckDocuments(String dateFrom, String dateTo) throws ServletException { return checkDocuments(dateFrom, dateTo); } // end of filterDatesCheckDocuments() method public void setMessageResult(OBError error) { messageResult = error; } /* * Sets OBError message for the given status */ public void setMessageResult(ConnectionProvider conn, VariablesSecureApp vars, String strStatus, String strMessageType) { setMessageResult(conn, strStatus, strMessageType, null); } /* * Sets OBError message for the given status */ public void setMessageResult(ConnectionProvider conn, String _strStatus, String strMessageType, Map<String, String> _parameters) { HttpServletRequest request = RequestContext.get().getRequest(); VariablesSecureApp vars; if (request != null) { // getting context info from session vars = new VariablesSecureApp(RequestContext.get().getRequest()); } else { // there is no session, getting context info from OBContext OBContext ctx = OBContext.getOBContext(); vars = new VariablesSecureApp((String) DalUtil.getId(ctx.getUser()), (String) DalUtil.getId(ctx.getCurrentClient()), (String) DalUtil.getId(ctx.getCurrentOrganization()), (String) DalUtil.getId(ctx.getRole()), ctx.getLanguage().getLanguage()); } setMessageResult(conn, vars, _strStatus, strMessageType, _parameters); } /* * Sets OBError message for the given status */ public void setMessageResult(ConnectionProvider conn, VariablesSecureApp vars, String _strStatus, String strMessageType, Map<String, String> _parameters) { String strStatus = StringUtils.isEmpty(_strStatus) ? getStatus() : _strStatus; setStatus(strStatus); String strTitle = ""; Map<String, String> parameters = _parameters != null ? _parameters : new HashMap<String, String>(); if (messageResult == null) messageResult = new OBError(); if (strMessageType == null || strMessageType.equals("")) messageResult.setType("Error"); else messageResult.setType(strMessageType); if (strStatus.equals(STATUS_Error)) strTitle = "@ProcessRunError@"; else if (strStatus.equals(STATUS_DocumentLocked)) { strTitle = "@OtherPostingProcessActive@"; messageResult.setType("Warning"); } else if (strStatus.equals(STATUS_NotCalculatedCost)) { if (parameters.isEmpty()) { strTitle = "@NotCalculatedCost@"; } else { strTitle = "@NotCalculatedCostWithTransaction@"; } } else if (strStatus.equals(STATUS_InvalidCost)) { if (parameters.isEmpty()) { strTitle = "@InvalidCost@"; } else { strTitle = "@InvalidCostWhichProduct@"; // Transalate account name from messages parameters.put("Account", Utility.parseTranslation(conn, vars, vars.getLanguage(), parameters.get("Account"))); } } else if (strStatus.equals(STATUS_NoRelatedPO)) { if (parameters.isEmpty()) { strTitle = "@GoodsReceiptTransactionWithNoPO@"; } else { strTitle = "@GoodsReceiptTransactionWithNoPOWichProduct@"; } } else if (strStatus.equals(STATUS_DocumentDisabled)) { strTitle = "@DocumentDisabled@"; messageResult.setType("Warning"); } else if (strStatus.equals(STATUS_BackgroundDisabled)) { strTitle = "@BackgroundDisabled@"; messageResult.setType("Warning"); } else if (strStatus.equals(STATUS_InvalidAccount)) { if (parameters.isEmpty()) { strTitle = "@InvalidAccount@"; } else { strTitle = "@InvalidWhichAccount@"; // Transalate account name from messages parameters.put("Account", Utility.parseTranslation(conn, vars, vars.getLanguage(), parameters.get("Account"))); } } else if (strStatus.equals(STATUS_PeriodClosed)) { strTitle = "@PeriodNotAvailable@"; } else if (strStatus.equals(STATUS_NotConvertible)) { strTitle = "@NotConvertible@"; } else if (strStatus.equals(STATUS_NotBalanced)) { strTitle = "@NotBalanced@"; } else if (strStatus.equals(STATUS_NotPosted)) { strTitle = "@NotPosted@"; } else if (strStatus.equals(STATUS_PostPrepared)) { strTitle = "@PostPrepared@"; } else if (strStatus.equals(STATUS_Posted)) { strTitle = "@Posted@"; } else if (strStatus.equals(STATUS_TableDisabled)) { strTitle = "@TableDisabled@"; parameters.put("Table", tableName); messageResult.setType("Warning"); } else if (strStatus.equals(STATUS_NoAccountingDate)) { strTitle = "@NoAccountingDate@"; } messageResult.setMessage(Utility.parseTranslation(conn, vars, parameters, vars.getLanguage(), Utility.parseTranslation(conn, vars, vars.getLanguage(), strTitle))); if (strMessage != null) { messageResult.setMessage(Utility.parseTranslation(conn, vars, parameters, vars.getLanguage(), Utility.parseTranslation(conn, vars, vars.getLanguage(), strMessage))); } } public Map<String, String> getInvalidAccountParameters(String strAccount, String strEntity, String strAccountingSchema) { Map<String, String> parameters = new HashMap<String, String>(); parameters.put("Account", strAccount); parameters.put("Entity", strEntity); parameters.put("AccountingSchema", strAccountingSchema); return parameters; } public Map<String, String> getInvalidCostParameters(String strProduct, String strDate) { Map<String, String> parameters = new HashMap<String, String>(); parameters.put("Product", strProduct); parameters.put("Date", strDate); return parameters; } public Map<String, String> getNotCalculatedCostParameters(MaterialTransaction trx) { Map<String, String> parameters = new HashMap<String, String>(); parameters.put("trx", trx.getIdentifier()); parameters.put("product", trx.getProduct().getIdentifier()); return parameters; } public OBError getMessageResult() { return messageResult; } public String getServletInfo() { return "Servlet for the accounting"; } // end of getServletInfo() method public String getStatus() { return Status; } public void setStatus(String strStatus) { Status = strStatus; } public ConnectionProvider getConnectionProvider() { return connectionProvider; } public ConversionRateDoc getConversionRateDoc(String table_ID, String record_ID, String curFrom_ID, String curTo_ID) { OBCriteria<ConversionRateDoc> docRateCriteria = OBDal.getInstance().createCriteria(ConversionRateDoc.class); docRateCriteria.setFilterOnReadableClients(false); docRateCriteria.setFilterOnReadableOrganization(false); docRateCriteria.add(Restrictions.eq(ConversionRateDoc.PROPERTY_TOCURRENCY, OBDal.getInstance().get(Currency.class, curTo_ID))); docRateCriteria.add(Restrictions.eq(ConversionRateDoc.PROPERTY_CURRENCY, OBDal.getInstance().get(Currency.class, curFrom_ID))); if (record_ID != null) { if (table_ID.equals(TABLEID_Invoice)) { docRateCriteria.add(Restrictions.eq(ConversionRateDoc.PROPERTY_INVOICE, OBDal.getInstance() .get(Invoice.class, OBDal.getInstance().get(Invoice.class, record_ID).getId()))); } else if (table_ID.equals(TABLEID_Payment)) { docRateCriteria.add(Restrictions.eq(ConversionRateDoc.PROPERTY_PAYMENT, OBDal.getInstance() .get(FIN_Payment.class, OBDal.getInstance().get(FIN_Payment.class, record_ID).getId()))); } else if (table_ID.equals(TABLEID_Transaction)) { docRateCriteria.add(Restrictions.eq(ConversionRateDoc.PROPERTY_FINANCIALACCOUNTTRANSACTION, OBDal.getInstance().get(FIN_FinaccTransaction.class, OBDal.getInstance().get(FIN_FinaccTransaction.class, record_ID).getId()))); } else { return null; } } else { return null; } List<ConversionRateDoc> conversionRates = docRateCriteria.list(); if (!conversionRates.isEmpty()) { return conversionRates.get(0); } return null; } // public BigDecimal convertAmount(BigDecimal _amount, boolean isReceipt, String dateAcct, // String conversionDate, String currencyIDFrom, String currencyIDTo, DocLine line, // AcctSchema as, Fact fact, String Fact_Acct_Group_ID, String seqNo, ConnectionProvider conn) // throws ServletException { // BigDecimal amount = _amount; // if (log4j.isDebugEnabled()) // log4j.debug("Amount:" + amount + " curr from:" + currencyIDFrom + " Curr to:" + currencyIDTo // + " convDate:" + conversionDate + " DateAcct:" + dateAcct); // if (amount == null || amount.compareTo(BigDecimal.ZERO) == 0) { // return amount; // } // if (currencyIDFrom.equals(currencyIDTo)) { // return amount; // } // MultiCurrency = true; // BigDecimal amt = new BigDecimal(getConvertedAmt(amount.toString(), currencyIDFrom, // currencyIDTo, conversionDate, "", AD_Client_ID, AD_Org_ID, conn)); // BigDecimal amtTo = new BigDecimal(getConvertedAmt(amount.toString(), currencyIDFrom, // currencyIDTo, dateAcct, "", AD_Client_ID, AD_Org_ID, conn)); // BigDecimal amtDiff = (amtTo).subtract(amt); // if ((isReceipt && amtDiff.compareTo(BigDecimal.ZERO) == 1) // || (!isReceipt && amtDiff.compareTo(BigDecimal.ZERO) == -1)) { // fact.createLine(line, getAccount(AcctServer.ACCTTYPE_ConvertGainDefaultAmt, as, conn), // currencyIDTo, "", amtDiff.abs().toString(), Fact_Acct_Group_ID, seqNo, DocumentType, conn); // } else { // fact.createLine(line, getAccount(AcctServer.ACCTTYPE_ConvertChargeDefaultAmt, as, conn), // currencyIDTo, amtDiff.abs().toString(), "", Fact_Acct_Group_ID, seqNo, DocumentType, conn); // } // return amt; // } public BigDecimal convertAmount(BigDecimal _amount, boolean isReceipt, String dateAcct, String table_ID, String record_ID, String currencyIDFrom, String currencyIDTo, DocLine line, AcctSchema as, Fact fact, String Fact_Acct_Group_ID, String seqNo, ConnectionProvider conn) throws ServletException { return convertAmount(_amount, isReceipt, dateAcct, table_ID, record_ID, currencyIDFrom, currencyIDTo, line, as, fact, Fact_Acct_Group_ID, seqNo, conn, true); } /* * Returns an amount without applying currency precision for rounding purposes */ public BigDecimal convertAmount(BigDecimal _amount, boolean isReceipt, String dateAcct, String table_ID, String record_ID, String currencyIDFrom, String currencyIDTo, DocLine line, AcctSchema as, Fact fact, String Fact_Acct_Group_ID, String seqNo, ConnectionProvider conn, boolean bookDifferences) throws ServletException { BigDecimal amtDiff = BigDecimal.ZERO; if (_amount == null || _amount.compareTo(BigDecimal.ZERO) == 0) { return _amount; } String conversionDate = dateAcct; String strDateFormat = OBPropertiesProvider.getInstance().getOpenbravoProperties() .getProperty("dateFormat.java"); final SimpleDateFormat dateFormat = new SimpleDateFormat(strDateFormat); ConversionRateDoc conversionRateDoc = getConversionRateDoc(table_ID, record_ID, currencyIDFrom, currencyIDTo); BigDecimal amtFrom = BigDecimal.ZERO; BigDecimal amtFromSourcecurrency = BigDecimal.ZERO; BigDecimal amtTo = BigDecimal.ZERO; if (table_ID.equals(TABLEID_Invoice)) { Invoice invoice = OBDal.getInstance().get(Invoice.class, record_ID); conversionDate = dateFormat.format(invoice.getAccountingDate()); } else if (table_ID.equals(TABLEID_Payment)) { FIN_Payment payment = OBDal.getInstance().get(FIN_Payment.class, record_ID); conversionDate = dateFormat.format(payment.getPaymentDate()); } else if (table_ID.equals(TABLEID_Transaction)) { FIN_FinaccTransaction transaction = OBDal.getInstance().get(FIN_FinaccTransaction.class, record_ID); conversionDate = dateFormat.format(transaction.getDateAcct()); } if (conversionRateDoc != null && record_ID != null) { amtFrom = applyRate(_amount, conversionRateDoc, true); } else { // I try to find a reversal rate for the doc, if exists i apply it reversal as well conversionRateDoc = getConversionRateDoc(table_ID, record_ID, currencyIDTo, currencyIDFrom); if (conversionRateDoc != null) { amtFrom = applyRate(_amount, conversionRateDoc, false); } else { String convertedAmt = getConvertedAmt(_amount.toString(), currencyIDFrom, currencyIDTo, conversionDate, "", AD_Client_ID, AD_Org_ID, conn); if (convertedAmt != null && !"".equals(convertedAmt)) { amtFrom = new BigDecimal(convertedAmt); } else { throw new OBException("@NotConvertible@"); } } } ConversionRateDoc conversionRateCurrentDoc = getConversionRateDoc(AD_Table_ID, Record_ID, currencyIDFrom, currencyIDTo); if (AD_Table_ID.equals(TABLEID_Invoice)) { Invoice invoice = OBDal.getInstance().get(Invoice.class, Record_ID); conversionDate = dateFormat.format(invoice.getAccountingDate()); } else if (AD_Table_ID.equals(TABLEID_Payment)) { FIN_Payment payment = OBDal.getInstance().get(FIN_Payment.class, Record_ID); conversionDate = dateFormat.format(payment.getPaymentDate()); } else if (AD_Table_ID.equals(TABLEID_Transaction) || AD_Table_ID.equals(TABLEID_Reconciliation)) { String transactionID = Record_ID; // When TableID= Reconciliation info is loaded from transaction if (AD_Table_ID.equals(AcctServer.TABLEID_Reconciliation) && line instanceof DocLine_FINReconciliation) { transactionID = ((DocLine_FINReconciliation) line).getFinFinAccTransactionId(); } FIN_FinaccTransaction transaction = OBDal.getInstance().get(FIN_FinaccTransaction.class, transactionID); conversionDate = dateFormat.format(transaction.getDateAcct()); conversionRateCurrentDoc = getConversionRateDoc(TABLEID_Transaction, transaction.getId(), currencyIDFrom, currencyIDTo); } else { conversionDate = dateAcct; } if (conversionRateCurrentDoc != null) { amtTo = applyRate(_amount, conversionRateCurrentDoc, true); amtFromSourcecurrency = applyRate(amtFrom, conversionRateCurrentDoc, false); } else { // I try to find a reversal rate for the doc, if exists i apply it reversal as well if (AD_Table_ID.equals(AcctServer.TABLEID_Reconciliation) && line instanceof DocLine_FINReconciliation) { String transactionID = ((DocLine_FINReconciliation) line).getFinFinAccTransactionId(); conversionRateCurrentDoc = getConversionRateDoc(TABLEID_Transaction, transactionID, currencyIDTo, currencyIDFrom); } else { conversionRateCurrentDoc = getConversionRateDoc(AD_Table_ID, Record_ID, currencyIDTo, currencyIDFrom); } if (conversionRateCurrentDoc != null) { amtTo = applyRate(_amount, conversionRateCurrentDoc, false); amtFromSourcecurrency = applyRate(amtFrom, conversionRateCurrentDoc, true); } else { String convertedAmt = getConvertedAmt(_amount.toString(), currencyIDFrom, currencyIDTo, conversionDate, "", AD_Client_ID, AD_Org_ID, conn); if (convertedAmt != null && !"".equals(convertedAmt)) { amtTo = new BigDecimal(convertedAmt); } else { throw new OBException("@NotConvertible@"); } if (amtTo.compareTo(BigDecimal.ZERO) != 0) amtFromSourcecurrency = amtFrom.multiply(_amount).divide(amtTo, conversionRatePrecision, BigDecimal.ROUND_HALF_EVEN); else amtFromSourcecurrency = amtFrom; } } amtDiff = (amtTo).subtract(amtFrom); // Add differences related to Different rates for accounting among currencies // _amount * ((TrxRate * // AccountingRateCurrencyFromCurrencyTo)-AccountingRateCurrencyDocCurrencyTo) amtDiff = amtDiff.add(calculateMultipleRatesDifferences(_amount, currencyIDFrom, currencyIDTo, line, conn)); Currency currencyTo = OBDal.getInstance().get(Currency.class, currencyIDTo); amtDiff = amtDiff.setScale(currencyTo.getStandardPrecision().intValue(), BigDecimal.ROUND_HALF_EVEN); if (bookDifferences) { if ((!isReceipt && amtDiff.compareTo(BigDecimal.ZERO) == 1) || (isReceipt && amtDiff.compareTo(BigDecimal.ZERO) == -1)) { fact.createLine(line, getAccount(AcctServer.ACCTTYPE_ConvertGainDefaultAmt, as, conn), currencyIDTo, "", amtDiff.abs().toString(), Fact_Acct_Group_ID, seqNo, DocumentType, conn); } else if (amtDiff.compareTo(BigDecimal.ZERO) != 0) { fact.createLine(line, getAccount(AcctServer.ACCTTYPE_ConvertChargeDefaultAmt, as, conn), currencyIDTo, amtDiff.abs().toString(), "", Fact_Acct_Group_ID, seqNo, DocumentType, conn); } else { return amtFromSourcecurrency; } } if (log4j.isDebugEnabled()) log4j.debug("Amt from: " + amtFrom + "[" + currencyIDFrom + "]" + " Amt to: " + amtTo + "[" + currencyIDTo + "] - amtFromSourcecurrency: " + amtFromSourcecurrency); // return value in original currency return amtFromSourcecurrency; } @Deprecated public static String getConvertedAmt(String Amt, String CurFrom_ID, String CurTo_ID, String ConvDate, String RateType, String client, String org, String recordId, String docType, ConnectionProvider conn) { boolean useSystemConversionRate = true; if (log4j.isDebugEnabled()) log4j.debug("AcctServer - getConvertedAmount - starting method - Amt : " + Amt + " - CurFrom_ID : " + CurFrom_ID + " - CurTo_ID : " + CurTo_ID + "- ConvDate: " + ConvDate + " - RateType:" + RateType + " - client:" + client + "- org:" + org); if (Amt.equals("")) throw new IllegalArgumentException("AcctServer - getConvertedAmt - required parameter missing - Amt"); if ((CurFrom_ID.equals(CurTo_ID) && !docType.equals(EXCHANGE_DOCTYPE_Transaction)) || Amt.equals("0")) return Amt; AcctServerData[] data = null; OBContext.setAdminMode(); try { if (ConvDate != null && ConvDate.equals("")) ConvDate = DateTimeData.today(conn); // ConvDate IN DATE if (RateType == null || RateType.equals("")) RateType = "S"; data = AcctServerData.currencyConvert(conn, Amt, CurFrom_ID, CurTo_ID, ConvDate, RateType, client, org); // Search if exists any conversion rate at document level OBCriteria<ConversionRateDoc> docRateCriteria = OBDal.getInstance() .createCriteria(ConversionRateDoc.class); if (docType.equals(EXCHANGE_DOCTYPE_Invoice) && recordId != null) { docRateCriteria.add(Restrictions.eq(ConversionRateDoc.PROPERTY_TOCURRENCY, OBDal.getInstance().get(Currency.class, CurTo_ID))); docRateCriteria.add(Restrictions.eq(ConversionRateDoc.PROPERTY_CURRENCY, OBDal.getInstance().get(Currency.class, CurFrom_ID))); // get reversed invoice id if exist. OBCriteria<ReversedInvoice> reversedCriteria = OBDal.getInstance() .createCriteria(ReversedInvoice.class); reversedCriteria.add(Restrictions.eq(ReversedInvoice.PROPERTY_INVOICE, OBDal.getInstance().get(Invoice.class, recordId))); if (!reversedCriteria.list().isEmpty()) { String strDateFormat; strDateFormat = OBPropertiesProvider.getInstance().getOpenbravoProperties() .getProperty("dateFormat.java"); final SimpleDateFormat dateFormat = new SimpleDateFormat(strDateFormat); ConvDate = dateFormat .format(reversedCriteria.list().get(0).getReversedInvoice().getAccountingDate()); data = AcctServerData.currencyConvert(conn, Amt, CurFrom_ID, CurTo_ID, ConvDate, RateType, client, org); docRateCriteria.add(Restrictions.eq(ConversionRateDoc.PROPERTY_INVOICE, OBDal.getInstance() .get(Invoice.class, reversedCriteria.list().get(0).getReversedInvoice().getId()))); } else { docRateCriteria.add(Restrictions.eq(ConversionRateDoc.PROPERTY_INVOICE, OBDal.getInstance().get(Invoice.class, recordId))); } useSystemConversionRate = false; } else if (docType.equals(EXCHANGE_DOCTYPE_Payment)) { docRateCriteria.add(Restrictions.eq(ConversionRateDoc.PROPERTY_TOCURRENCY, OBDal.getInstance().get(Currency.class, CurTo_ID))); docRateCriteria.add(Restrictions.eq(ConversionRateDoc.PROPERTY_CURRENCY, OBDal.getInstance().get(Currency.class, CurFrom_ID))); docRateCriteria.add(Restrictions.eq(ConversionRateDoc.PROPERTY_PAYMENT, OBDal.getInstance().get(FIN_Payment.class, recordId))); useSystemConversionRate = false; } else if (docType.equals(EXCHANGE_DOCTYPE_Transaction)) { APRM_FinaccTransactionV a = OBDal.getInstance().get(APRM_FinaccTransactionV.class, recordId); if (a.getForeignCurrency() != null) { // && !a.getForeignCurrency().getId().equals(CurTo_ID) String strDateFormat; strDateFormat = OBPropertiesProvider.getInstance().getOpenbravoProperties() .getProperty("dateFormat.java"); final SimpleDateFormat dateFormat = new SimpleDateFormat(strDateFormat); Amt = a.getForeignAmount().toString(); data = AcctServerData.currencyConvert(conn, Amt, a.getForeignCurrency().getId(), CurTo_ID, ConvDate, RateType, client, org); docRateCriteria.add(Restrictions.eq(ConversionRateDoc.PROPERTY_TOCURRENCY, OBDal.getInstance().get(Currency.class, CurTo_ID))); docRateCriteria.add(Restrictions.eq(ConversionRateDoc.PROPERTY_CURRENCY, OBDal.getInstance().get(Currency.class, a.getForeignCurrency().getId()))); } else { docRateCriteria.add(Restrictions.eq(ConversionRateDoc.PROPERTY_TOCURRENCY, OBDal.getInstance().get(Currency.class, CurTo_ID))); docRateCriteria.add(Restrictions.eq(ConversionRateDoc.PROPERTY_CURRENCY, OBDal.getInstance().get(Currency.class, CurFrom_ID))); } docRateCriteria.add(Restrictions.eq(ConversionRateDoc.PROPERTY_FINANCIALACCOUNTTRANSACTION, OBDal.getInstance().get(APRM_FinaccTransactionV.class, recordId))); useSystemConversionRate = false; } if (docType.equals(EXCHANGE_DOCTYPE_Invoice) || docType.equals(EXCHANGE_DOCTYPE_Payment) || docType.equals(EXCHANGE_DOCTYPE_Transaction)) { List<ConversionRateDoc> conversionRates = docRateCriteria.list(); if (!conversionRates.isEmpty() && !useSystemConversionRate) { BigDecimal Amount = new BigDecimal(Amt); BigDecimal AmountConverted = Amount.multiply(conversionRates.get(0).getRate()).setScale(2, BigDecimal.ROUND_HALF_UP); return AmountConverted.toString(); } } } catch (ServletException e) { log4j.warn(e); e.printStackTrace(); } finally { OBContext.restorePreviousMode(); } if (data == null || data.length == 0) { /* * log4j.error("No conversion ratio"); throw new * ServletException("No conversion ratio defined!"); */ return ""; } else { if (log4j.isDebugEnabled()) log4j.debug("getConvertedAmount - converted:" + data[0].converted); return data[0].converted; } } // getConvertedAmt private BigDecimal calculateMultipleRatesDifferences(BigDecimal _amount, String currencyIDFrom, String currencyIDTo, DocLine line, ConnectionProvider conn) { // _amount * ((TrxRate * // AccountingRateCurrencyFromCurrencyTo)-AccountingRateCurrencyDocCurrencyTo) String conversionDate = DateAcct; String strDateFormat = OBPropertiesProvider.getInstance().getOpenbravoProperties() .getProperty("dateFormat.java"); final SimpleDateFormat dateFormat = new SimpleDateFormat(strDateFormat); // Calculate accountingRateCurrencyFromCurrencyTo BigDecimal accountingRateCurrencyFromCurrencyTo = BigDecimal.ONE; if (!currencyIDFrom.equals(currencyIDTo)) { ConversionRateDoc conversionRateCurrentDoc = getConversionRateDoc(AD_Table_ID, Record_ID, currencyIDFrom, currencyIDTo); if (AD_Table_ID.equals(AcctServer.TABLEID_Reconciliation) && line instanceof DocLine_FINReconciliation) { String transactionID = ((DocLine_FINReconciliation) line).getFinFinAccTransactionId(); FIN_FinaccTransaction transaction = OBDal.getInstance().get(FIN_FinaccTransaction.class, transactionID); conversionDate = dateFormat.format(transaction.getDateAcct()); conversionRateCurrentDoc = getConversionRateDoc(TABLEID_Transaction, transaction.getId(), currencyIDFrom, currencyIDTo); } if (conversionRateCurrentDoc != null) { accountingRateCurrencyFromCurrencyTo = conversionRateCurrentDoc.getRate(); } else { // I try to find a reversal rate for the doc, if exists i apply it reversal as well if (AD_Table_ID.equals(AcctServer.TABLEID_Reconciliation) && line instanceof DocLine_FINReconciliation) { String transactionID = ((DocLine_FINReconciliation) line).getFinFinAccTransactionId(); FIN_FinaccTransaction transaction = OBDal.getInstance().get(FIN_FinaccTransaction.class, transactionID); conversionRateCurrentDoc = getConversionRateDoc(TABLEID_Transaction, transaction.getId(), currencyIDTo, currencyIDFrom); } else { conversionRateCurrentDoc = getConversionRateDoc(AD_Table_ID, Record_ID, currencyIDTo, currencyIDFrom); } if (conversionRateCurrentDoc != null) { accountingRateCurrencyFromCurrencyTo = BigDecimal.ONE.divide(conversionRateCurrentDoc.getRate(), MathContext.DECIMAL64); } else { accountingRateCurrencyFromCurrencyTo = getConvertionRate(currencyIDFrom, currencyIDTo, conversionDate, "", AD_Client_ID, AD_Org_ID, conn); } } } // Calculate accountingRateCurrencyFromCurrencyTo BigDecimal accountingRateCurrencyDocCurrencyTo = BigDecimal.ONE; if (!C_Currency_ID.equals(currencyIDTo)) { ConversionRateDoc conversionRateCurrentDoc = getConversionRateDoc(AD_Table_ID, Record_ID, C_Currency_ID, currencyIDTo); if (AD_Table_ID.equals(AcctServer.TABLEID_Reconciliation) && line instanceof DocLine_FINReconciliation) { String transactionID = ((DocLine_FINReconciliation) line).getFinFinAccTransactionId(); FIN_FinaccTransaction transaction = OBDal.getInstance().get(FIN_FinaccTransaction.class, transactionID); conversionDate = dateFormat.format(transaction.getTransactionDate()); conversionRateCurrentDoc = getConversionRateDoc(TABLEID_Transaction, transaction.getId(), C_Currency_ID, currencyIDTo); } if (conversionRateCurrentDoc != null) { accountingRateCurrencyDocCurrencyTo = conversionRateCurrentDoc.getRate(); } else { // I try to find a reversal rate for the doc, if exists i apply it reversal as well if (AD_Table_ID.equals(AcctServer.TABLEID_Reconciliation) && line instanceof DocLine_FINReconciliation) { String transactionID = ((DocLine_FINReconciliation) line).getFinFinAccTransactionId(); FIN_FinaccTransaction transaction = OBDal.getInstance().get(FIN_FinaccTransaction.class, transactionID); conversionRateCurrentDoc = getConversionRateDoc(TABLEID_Transaction, transaction.getId(), currencyIDTo, C_Currency_ID); } else { conversionRateCurrentDoc = getConversionRateDoc(AD_Table_ID, Record_ID, currencyIDTo, C_Currency_ID); } if (conversionRateCurrentDoc != null) { accountingRateCurrencyDocCurrencyTo = BigDecimal.ONE.divide(conversionRateCurrentDoc.getRate(), MathContext.DECIMAL64); } else { accountingRateCurrencyDocCurrencyTo = getConvertionRate(C_Currency_ID, currencyIDTo, conversionDate, "", AD_Client_ID, AD_Org_ID, conn); } } } // Calculate transaction rate BigDecimal trxRate = BigDecimal.ONE; if (!C_Currency_ID.equals(currencyIDFrom)) { if (AD_Table_ID.equals(TABLEID_Payment)) { FIN_Payment payment = OBDal.getInstance().get(FIN_Payment.class, Record_ID); trxRate = payment.getFinancialTransactionConvertRate(); } else if (AD_Table_ID.equals(TABLEID_Transaction) || AD_Table_ID.equals(TABLEID_Reconciliation)) { String transactionID = Record_ID; // When TableID = Reconciliation info is loaded from transaction if (AD_Table_ID.equals(AcctServer.TABLEID_Reconciliation) && line instanceof DocLine_FINReconciliation) { transactionID = ((DocLine_FINReconciliation) line).getFinFinAccTransactionId(); } FIN_FinaccTransaction transaction = OBDal.getInstance().get(FIN_FinaccTransaction.class, transactionID); trxRate = transaction.getForeignConversionRate(); } } Currency currencyFrom = OBDal.getInstance().get(Currency.class, currencyIDTo); return _amount .multiply(trxRate.multiply(accountingRateCurrencyDocCurrencyTo) .subtract(accountingRateCurrencyFromCurrencyTo)) .setScale(currencyFrom.getStandardPrecision().intValue(), BigDecimal.ROUND_HALF_EVEN); } /* * Returns an amount without applying currency precision for rounding purposes */ public static BigDecimal applyRate(BigDecimal _amount, ConversionRateDoc conversionRateDoc, boolean multiply) { BigDecimal amount = _amount; if (multiply) { return amount.multiply(conversionRateDoc.getRate()); } else { return amount.divide(conversionRateDoc.getRate(), 6, BigDecimal.ROUND_HALF_EVEN); } } public static int getConversionRatePrecision(VariablesSecureApp vars) { try { String formatOutput = vars.getSessionValue("#FormatOutput|generalQtyEdition", "#0.######"); String decimalSeparator = "."; if (formatOutput.contains(decimalSeparator)) { formatOutput = formatOutput.substring(formatOutput.indexOf(decimalSeparator), formatOutput.length()); return formatOutput.length() - decimalSeparator.length(); } else { return 0; } } catch (Exception e) { log4j.error(e); return 6; // by default precision of 6 decimals as is defaulted in Format.xml } } /** * If there is any template active for current document in any accounting schema, it returns true * to skip this step as getDocumentConfirmation can lock template */ boolean disableDocumentConfirmation() { C_DocType_ID = objectFieldProvider[0].getField("cDoctypeId"); if ("".equals(DocumentType)) { loadDocumentType(true); } OBContext.setAdminMode(); try { for (int i = 0; i < m_as.length; i++) { StringBuffer whereClause = new StringBuffer(); whereClause.append(" as astdt "); whereClause.append( " where astdt.acctschemaTable.accountingSchema.id = '" + m_as[i].m_C_AcctSchema_ID + "'"); whereClause.append(" and astdt.acctschemaTable.table.id = '" + AD_Table_ID + "'"); if (!"".equals(DocumentType)) { whereClause.append(" and astdt.documentCategory = '" + DocumentType + "'"); } final OBQuery<AcctSchemaTableDocType> obqParameters = OBDal.getInstance() .createQuery(AcctSchemaTableDocType.class, whereClause.toString()); final List<AcctSchemaTableDocType> acctSchemaTableDocTypes = obqParameters.list(); if (acctSchemaTableDocTypes != null && acctSchemaTableDocTypes.size() > 0 && acctSchemaTableDocTypes.get(0).getCreatefactTemplate() != null) { return true; } final StringBuilder whereClause2 = new StringBuilder(); whereClause2.append(" as ast "); whereClause2.append(" where ast.accountingSchema.id = '" + m_as[i].m_C_AcctSchema_ID + "'"); whereClause2.append(" and ast.table.id = '" + AD_Table_ID + "'"); final OBQuery<AcctSchemaTable> obqParameters2 = OBDal.getInstance() .createQuery(AcctSchemaTable.class, whereClause2.toString()); final List<AcctSchemaTable> acctSchemaTables = obqParameters2.list(); if (acctSchemaTables != null && acctSchemaTables.size() > 0 && acctSchemaTables.get(0).getCreatefactTemplate() != null) { return true; } } } finally { OBContext.restorePreviousMode(); } return false; } /** * Returns the amount of a Payment Detail. In case the related Payment Schedule Detail was * generated for compensate the difference between an Order and a related Invoice, it merges it's * amount with the next Payment Schedule Detail. Issue 19567: * https://issues.openbravo.com/view.php?id=19567 * * @param paymentDetails * List of payment Details * @param ps * Previous Payment Schedule * @param psi * Invoice Payment Schedule of actual Payment Detail * @param pso * Order Payment Schedule of actual Payment Detail * @param currentPaymentDetailIndex * Index */ @Deprecated public BigDecimal getPaymentDetailAmount(List<FIN_PaymentDetail> paymentDetails, FIN_PaymentSchedule ps, FIN_PaymentSchedule psi, FIN_PaymentSchedule pso, int currentPaymentDetailIndex) { if (psi == null && pso == null) { return paymentDetails.get(currentPaymentDetailIndex).getAmount(); } // If the actual Payment Detail belongs to the same Invoice Payment Schedule as the previous // record, or it has no Order related. if ((psi != null && psi.equals(ps)) || pso == null) { FIN_PaymentScheduleDetail psdNext = (currentPaymentDetailIndex == paymentDetails.size() - 1) ? null : paymentDetails.get(currentPaymentDetailIndex + 1).getFINPaymentScheduleDetailList().get(0); FIN_PaymentScheduleDetail psdPrevious = (currentPaymentDetailIndex == 0) ? null : paymentDetails.get(currentPaymentDetailIndex - 1).getFINPaymentScheduleDetailList().get(0); // If it has no Order related, and the next record belongs to the same Invoice Payment // Schedule and the next record has an Order related. if (pso == null && psdNext != null && psdNext.getInvoicePaymentSchedule() == psi && psdNext.getOrderPaymentSchedule() != null) { return null; // If the previous record belongs to the same Invoice Payment Schedule and the previous // record has no Order related. } else if (psdPrevious != null && psdPrevious.getInvoicePaymentSchedule() == psi && psdPrevious.getOrderPaymentSchedule() == null) { return paymentDetails.get(currentPaymentDetailIndex).getAmount() .add(paymentDetails.get(currentPaymentDetailIndex - 1).getAmount()); } else { return paymentDetails.get(currentPaymentDetailIndex).getAmount(); } } else { return paymentDetails.get(currentPaymentDetailIndex).getAmount(); } } /** * Returns the writeoff and the amount of a Payment Detail. In case the related Payment Schedule * Detail was generated for compensate the difference between an Order and a related Invoice, it * merges it's amount with the next Payment Schedule Detail. Issue 19567: * https://issues.openbravo.com/view.php?id=19567 * * @param paymentDetails * List of payment Details * @param ps * Previous Payment Schedule * @param psi * Invoice Payment Schedule of actual Payment Detail * @param pso * Order Payment Schedule of actual Payment Detail * @param currentPaymentDetailIndex * Index */ public HashMap<String, BigDecimal> getPaymentDetailWriteOffAndAmount(List<FIN_PaymentDetail> paymentDetails, FIN_PaymentSchedule ps, FIN_PaymentSchedule psi, FIN_PaymentSchedule pso, int currentPaymentDetailIndex) { return getPaymentDetailWriteOffAndAmount(paymentDetails, ps, psi, pso, currentPaymentDetailIndex, null); } /** * Returns the writeoff and the amount of a Payment Detail. In case the related Payment Schedule * Detail was generated for compensate the difference between an Order and a related Invoice, it * merges it's amount with the next Payment Schedule Detail. Issue 19567: * https://issues.openbravo.com/view.php?id=19567 <br /> * It does exactly the same as the * {@link #getPaymentDetailWriteOffAndAmount(List, FIN_PaymentSchedule, FIN_PaymentSchedule, FIN_PaymentSchedule, int)} * method, but it also stores a new field "MergedPaymentDetailId" inside the fieldProvider with * the merged payment detail id (if any). * * @param paymentDetails * List of payment Details * @param ps * Previous Payment Schedule * @param psi * Invoice Payment Schedule of actual Payment Detail * @param pso * Order Payment Schedule of actual Payment Detail * @param currentPaymentDetailIndex * Index * @param fieldProvider * contains the FieldProvider with the Payment Detail currently being processed. Used to * store the "MergedPaymentDetailId" (if any) as a new field of the fieldProvider */ public HashMap<String, BigDecimal> getPaymentDetailWriteOffAndAmount(List<FIN_PaymentDetail> paymentDetails, FIN_PaymentSchedule ps, FIN_PaymentSchedule psi, FIN_PaymentSchedule pso, int currentPaymentDetailIndex, final FieldProvider fieldProvider) { HashMap<String, BigDecimal> amountAndWriteOff = new HashMap<String, BigDecimal>(); // Default return values amountAndWriteOff.put("amount", paymentDetails.get(currentPaymentDetailIndex).getAmount()); amountAndWriteOff.put("writeoff", paymentDetails.get(currentPaymentDetailIndex).getWriteoffAmount()); // If the Payment Detail has either an Invoice or an Order associated to it if (psi != null || pso != null) { // If the Payment Detail has no Order associated to it, or it has an Invoice associated and is // the same one as the previous Payment Detail if ((psi != null && psi.equals(ps)) || pso == null) { FIN_PaymentScheduleDetail psdNext = (currentPaymentDetailIndex == paymentDetails.size() - 1) ? null : paymentDetails.get(currentPaymentDetailIndex + 1).getFINPaymentScheduleDetailList() .get(0); FIN_PaymentScheduleDetail psdPrevious = (currentPaymentDetailIndex == 0) ? null : paymentDetails.get(currentPaymentDetailIndex - 1).getFINPaymentScheduleDetailList() .get(0); // If the Payment Detail has no Order associated, and the next Payment Detail belongs to the // same Invoice and it has an Order related, then return null if (pso == null && psdNext != null && psdNext.getInvoicePaymentSchedule() == psi && psdNext.getOrderPaymentSchedule() != null) { amountAndWriteOff.put("amount", null); amountAndWriteOff.put("writeoff", null); // If there is a previous Payment Detail that belongs to the same Invoice and has no Order // related to it, return the sum of amounts. } else if (psdPrevious != null && psdPrevious.getInvoicePaymentSchedule() == psi && psdPrevious.getOrderPaymentSchedule() == null) { amountAndWriteOff.put("amount", paymentDetails.get(currentPaymentDetailIndex).getAmount() .add(paymentDetails.get(currentPaymentDetailIndex - 1).getAmount())); amountAndWriteOff.put("writeoff", paymentDetails.get(currentPaymentDetailIndex).getWriteoffAmount() .add(paymentDetails.get(currentPaymentDetailIndex - 1).getWriteoffAmount())); if (fieldProvider != null) { FieldProviderFactory.setField(fieldProvider, "MergedPaymentDetailId", paymentDetails.get(currentPaymentDetailIndex - 1).getId()); } } } } return amountAndWriteOff; } }