Java tutorial
/* * Copyright 2003 - 2016 The eFaps Team * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.efaps.esjp.accounting.transaction; import java.io.File; import java.math.BigDecimal; import java.math.RoundingMode; import java.text.DecimalFormat; import java.text.ParseException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang3.BooleanUtils; import org.efaps.admin.datamodel.Status; import org.efaps.admin.datamodel.Type; import org.efaps.admin.datamodel.attributetype.DecimalType; import org.efaps.admin.dbproperty.DBProperties; import org.efaps.admin.event.Parameter; import org.efaps.admin.event.Parameter.ParameterValues; import org.efaps.admin.event.Return; import org.efaps.admin.event.Return.ReturnValues; import org.efaps.admin.program.esjp.EFapsApplication; import org.efaps.admin.program.esjp.EFapsUUID; import org.efaps.ci.CIType; import org.efaps.db.CachedPrintQuery; import org.efaps.db.Context; import org.efaps.db.Insert; import org.efaps.db.Instance; import org.efaps.db.InstanceQuery; import org.efaps.db.MultiPrintQuery; import org.efaps.db.PrintQuery; import org.efaps.db.QueryBuilder; import org.efaps.db.SelectBuilder; import org.efaps.esjp.accounting.Period; import org.efaps.esjp.accounting.PurchaseRecord; import org.efaps.esjp.accounting.SubPeriod_Base; import org.efaps.esjp.accounting.TransactionDocument; import org.efaps.esjp.accounting.transaction.TransInfo_Base.PositionInfo; import org.efaps.esjp.accounting.transaction.evaluation.DocumentEvaluation; import org.efaps.esjp.accounting.transaction.evaluation.DocumentInfo; import org.efaps.esjp.accounting.util.Accounting; import org.efaps.esjp.accounting.util.Accounting.ArchiveConfig; import org.efaps.esjp.accounting.util.Accounting.TransPosType; import org.efaps.esjp.accounting.util.AccountingSettings; import org.efaps.esjp.ci.CIAccounting; import org.efaps.esjp.ci.CIContacts; import org.efaps.esjp.ci.CIERP; import org.efaps.esjp.ci.CIFormAccounting; import org.efaps.esjp.ci.CISales; import org.efaps.esjp.common.parameter.ParameterUtil; import org.efaps.esjp.common.util.InterfaceUtils; import org.efaps.esjp.db.InstanceUtils; import org.efaps.esjp.erp.Currency; import org.efaps.esjp.erp.CurrencyInst; import org.efaps.esjp.erp.NumberFormatter; import org.efaps.esjp.erp.RateInfo; import org.efaps.util.DateTimeUtil; import org.efaps.util.EFapsException; import org.joda.time.DateTime; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * TODO comment! * * @author The eFaps Team */ @EFapsUUID("7b2870fe-4566-4688-b015-263c910c34e2") @EFapsApplication("eFapsApp-Accounting") public abstract class Create_Base extends Transaction { /** * Logger for this class. */ private static final Logger LOG = LoggerFactory.getLogger(Create_Base.class); /** * Method called to create a transaction including its positions. * * @param _parameter Parameter as passed from the eFaps API * @return new Return * @throws EFapsException on error */ public Return create(final Parameter _parameter) throws EFapsException { final Return ret = new Return(); final Instance transInst = createFromUI(_parameter); connect2SubJournal(_parameter, transInst, null); final CreatedDoc transDoc = new TransactionDocument().createDoc4Transaction(_parameter, transInst); connectDocs2Transaction(_parameter, transInst, transDoc.getInstance()); final Parameter parameter = ParameterUtil.clone(_parameter, Parameter.ParameterValues.INSTANCE, transInst); final File file = getTransactionReport(parameter, true); if (file != null) { ret.put(ReturnValues.VALUES, file); ret.put(ReturnValues.TRUE, true); } return ret; } /** * Method is used to create a transaction for a given account. e.g. the user * selects an account and than only selects the amount and the target * accounts. * * @param _parameter Parameter as passed from the eFaps API * @return new Return * @throws EFapsException on error */ public Return create4Account(final Parameter _parameter) throws EFapsException { final Map<?, ?> properties = (Map<?, ?>) _parameter.get(ParameterValues.PROPERTIES); properties.get("TypePostfix"); final Instance periodInst = new Period().evaluateCurrentPeriod(_parameter); final Insert insert = new Insert(CIAccounting.Transaction); insert.add(CIAccounting.Transaction.Name, _parameter.getParameterValue("name")); insert.add(CIAccounting.Transaction.Description, _parameter.getParameterValue("description")); insert.add(CIAccounting.Transaction.Date, _parameter.getParameterValue("date")); insert.add(CIAccounting.Transaction.PeriodLink, periodInst.getId()); insert.add(CIAccounting.Transaction.Status, Status.find(CIAccounting.TransactionStatus.Open)); insert.add(CIAccounting.Transaction.Identifier, Transaction.IDENTTEMP); insert.execute(); // final Instance instance = insert.getInstance(); // final int pos = insertPositions(_parameter, instance, postfix, new String[] { _parameter.getCallInstance() // .getOid() }, 0); // insertPositions(_parameter, instance, "Debit".equals(postfix) ? "Credit" : "Debit", null, pos); // new org.efaps.esjp.common.uiform.Create().insertClassification(_parameter, instance); return new Return(); } /** * Create4 others pay. * * @param _parameter Parameter as passed by the eFaps API * @return the return * @throws EFapsException on error */ public Return create4OthersPay(final Parameter _parameter) throws EFapsException { return create4External(_parameter); } /** * Create4 others pay massiv. * * @param _parameter Parameter as passed by the eFaps API * @return the return * @throws EFapsException on error */ public Return create4OthersPayMassiv(final Parameter _parameter) throws EFapsException { return create4ExternalMassive(_parameter); } /** * Create4 others collect. * * @param _parameter Parameter as passed by the eFaps API * @return the return * @throws EFapsException on error */ public Return create4OthersCollect(final Parameter _parameter) throws EFapsException { return create4Doc(_parameter); } /** * Create4 others collect massive. * * @param _parameter Parameter as passed by the eFaps API * @return the return * @throws EFapsException on error */ public Return create4OthersCollectMassive(final Parameter _parameter) throws EFapsException { return create4DocMassive(_parameter); } /** * Create4 payroll. * * @param _parameter Parameter as passed by the eFaps API * @return the return * @throws EFapsException on error */ public Return create4Payroll(final Parameter _parameter) throws EFapsException { return create4Doc(_parameter); } /** * Create4 payroll massive. * * @param _parameter Parameter as passed by the eFaps API * @return the return * @throws EFapsException on error */ public Return create4PayrollMassive(final Parameter _parameter) throws EFapsException { return create4DocMassive(_parameter); } /** * Called from event for creation of a transaction with a document. * * @param _parameter Parameter as passed from the eFaps API * @return new Return * @throws EFapsException on error */ public Return create4Doc(final Parameter _parameter) throws EFapsException { final Return ret = new Return(); final Instance transInst = createFromUI(_parameter); connect2SubJournal(_parameter, transInst, null); final List<Instance> docInsts = getDocInstsFromUI(_parameter); connectDocs2Transaction(_parameter, transInst, docInsts.toArray(new Instance[docInsts.size()])); markDocs4ArchiveConfig(_parameter, docInsts.toArray(new Instance[docInsts.size()])); add2Create4Doc(_parameter); final Parameter parameter = ParameterUtil.clone(_parameter, Parameter.ParameterValues.INSTANCE, transInst); final File file = getTransactionReport(parameter, true); if (file != null) { ret.put(ReturnValues.VALUES, file); ret.put(ReturnValues.TRUE, true); } return ret; } /** * @param _parameter Parameter as passed from the eFaps API * @return new empty Return * @throws EFapsException on error */ public Return create4DocMassive(final Parameter _parameter) throws EFapsException { final List<DocumentInfo> docInfos = new DocumentEvaluation().evalDocuments(_parameter); final DateTime date = new DateTime( _parameter.getParameterValue(CIFormAccounting.Accounting_MassiveRegister4DocumentForm.date.name)); final boolean useDate = Boolean.parseBoolean(_parameter .getParameterValue(CIFormAccounting.Accounting_MassiveRegister4DocumentForm.useDate.name)); final boolean oneTransPerDoc = Boolean.parseBoolean(_parameter.getParameterValue("oneTransPerDoc")); if (!oneTransPerDoc) { final DocumentInfo docInfo = DocumentInfo.getCombined(docInfos, getSummarizeConfig(_parameter), getSummarizeCriteria(_parameter)); docInfo.setDate(date); if (docInfo.isValid(_parameter)) { final TransInfo transinfo = TransInfo.get4DocInfo(_parameter, docInfo, false); if (useDate) { transinfo.setDate(date); } transinfo.create(_parameter); final List<Instance> docInsts = getDocInstsFromDocInfoList(_parameter, docInfos); connectDocs2Transaction(_parameter, transinfo.getInstance(), docInsts.toArray(new Instance[docInsts.size()])); markDocs4ArchiveConfig(_parameter, docInsts.toArray(new Instance[docInsts.size()])); connect2SubJournal(_parameter, transinfo.getInstance(), null); } } else { for (final DocumentInfo docInfo : docInfos) { if (docInfo.isValid(_parameter)) { final TransInfo transinfo = TransInfo.get4DocInfo(_parameter, docInfo, true); if (useDate) { transinfo.setDate(date); } transinfo.create(_parameter); connectDocs2Transaction(_parameter, transinfo.getInstance(), docInfo.getInstance()); markDocs4ArchiveConfig(_parameter, docInfo.getInstance()); connect2SubJournal(_parameter, transinfo.getInstance(), docInfo.getInstance()); } } } return new Return(); } /** * Called from event for creation of a transaction with a external document. * * @param _parameter Parameter as passed from the eFaps API * @return new Return * @throws EFapsException on error */ public Return create4External(final Parameter _parameter) throws EFapsException { final Return ret = new Return(); final Instance transInst = createFromUI(_parameter); final List<Instance> docInsts = getDocInstsFromUI(_parameter); connect2SubJournal(_parameter, transInst, null); connectDocs2Transaction(_parameter, transInst, docInsts.toArray(new Instance[docInsts.size()])); connectDocs2PurchaseRecord(_parameter, docInsts.toArray(new Instance[docInsts.size()])); markDocs4ArchiveConfig(_parameter, docInsts.toArray(new Instance[docInsts.size()])); final Parameter parameter = ParameterUtil.clone(_parameter, Parameter.ParameterValues.INSTANCE, transInst); final File file = getTransactionReport(parameter, true); if (file != null) { ret.put(ReturnValues.VALUES, file); ret.put(ReturnValues.TRUE, true); } return ret; } /** * Create4 external massive. * * @param _parameter Parameter as passed by the eFaps API * @return the return * @throws EFapsException on error */ public Return create4ExternalMassive(final Parameter _parameter) throws EFapsException { final List<DocumentInfo> docInfos = new DocumentEvaluation().evalDocuments(_parameter); final DateTime date = new DateTime(_parameter.getParameterValue("date")); final boolean useDate = Boolean.parseBoolean(_parameter.getParameterValue("useDate")); final boolean oneTransPerDoc = Boolean.parseBoolean(_parameter.getParameterValue("oneTransPerDoc")); if (!oneTransPerDoc) { final DocumentInfo docInfo = DocumentInfo.getCombined(docInfos, getSummarizeConfig(_parameter), getSummarizeCriteria(_parameter)); docInfo.setDate(date); if (docInfo.isValid(_parameter)) { final TransInfo transinfo = TransInfo.get4DocInfo(_parameter, docInfo, false); if (useDate) { transinfo.setDate(date); } transinfo.create(_parameter); final List<Instance> docInsts = getDocInstsFromDocInfoList(_parameter, docInfos); connectDocs2Transaction(_parameter, transinfo.getInstance(), docInsts.toArray(new Instance[docInsts.size()])); connectDocs2PurchaseRecord(_parameter, docInsts.toArray(new Instance[docInsts.size()])); markDocs4ArchiveConfig(_parameter, docInsts.toArray(new Instance[docInsts.size()])); connect2SubJournal(_parameter, transinfo.getInstance(), null); } } else { for (final DocumentInfo docInfo : docInfos) { if (docInfo.isValid(_parameter)) { final TransInfo transinfo = TransInfo.get4DocInfo(_parameter, docInfo, true); if (useDate) { transinfo.setDate(date); } transinfo.create(_parameter); connectDocs2Transaction(_parameter, transinfo.getInstance(), docInfo.getInstance()); connectDocs2PurchaseRecord(_parameter, docInfo.getInstance()); markDocs4ArchiveConfig(_parameter, docInfo.getInstance()); connect2SubJournal(_parameter, transinfo.getInstance(), docInfo.getInstance()); } } } return new Return(); } /** * @param _parameter as passed from the eFaps API * @return new empty Return * @throws EFapsException on error. */ public Return create4Exchange(final Parameter _parameter) throws EFapsException { final Return ret = new Return(); final Instance transInst = createFromUI(_parameter); connect2SubJournal(_parameter, transInst, null); final List<Instance> docInsts = getDocInstsFromUI(_parameter); connectDocs2Transaction(_parameter, transInst, docInsts.toArray(new Instance[docInsts.size()])); if (BooleanUtils.toBoolean(_parameter.getParameterValue("connectSwapInstance"))) { final List<Instance> swapDocuments = getInstances(_parameter, "swapDocument"); connectDocs2Transaction(_parameter, transInst, swapDocuments.toArray(new Instance[swapDocuments.size()])); docInsts.addAll(swapDocuments); } markDocs4ArchiveConfig(_parameter, docInsts.toArray(new Instance[docInsts.size()])); add2Create4Doc(_parameter); final Parameter parameter = ParameterUtil.clone(_parameter, Parameter.ParameterValues.INSTANCE, transInst); final File file = getTransactionReport(parameter, true); if (file != null) { ret.put(ReturnValues.VALUES, file); ret.put(ReturnValues.TRUE, true); } return ret; } /** * @param _parameter as passed from the eFaps API * @return new empty Return * @throws EFapsException on error. */ public Return create4IncomingExchange(final Parameter _parameter) throws EFapsException { return create4Exchange(_parameter); } /** * @param _parameter as passed from the eFaps API * @return new empty Return * @throws EFapsException on error. */ public Return create4FundsToBeSettled(final Parameter _parameter) throws EFapsException { return create4Doc(_parameter); } /** * @param _parameter as passed from the eFaps API * @return new empty Return * @throws EFapsException on error. */ public Return create4FundsToBeSettledMassive(final Parameter _parameter) throws EFapsException { return create4DocMassive(_parameter); } /** * @param _parameter as passed from the eFaps API * @return new empty Return * @throws EFapsException on error. */ public Return create4PettyCashReceipt(final Parameter _parameter) throws EFapsException { return create4External(_parameter); } /** * @param _parameter as passed from the eFaps API * @return new empty Return * @throws EFapsException on error. */ public Return create4PettyCashMassive(final Parameter _parameter) throws EFapsException { return create4ExternalMassive(_parameter); } /** * @param _parameter as passed from the eFaps API * @return new empty Return * @throws EFapsException on error. */ public Return create4RetPer(final Parameter _parameter) throws EFapsException { return create4Doc(_parameter); } /** * @param _parameter as passed from the eFaps API * @return new empty Return * @throws EFapsException on error. */ public Return create4RetPerMassive(final Parameter _parameter) throws EFapsException { return create4DocMassive(_parameter); } /** * @param _parameter as passed from the eFaps API * @return new empty Return * @throws EFapsException on error. */ public Return create4Swap(final Parameter _parameter) throws EFapsException { return create4Doc(_parameter); } /** * Create a Transaction for a PaymentDocument. * Connects the PaymentDocument and the related Document with the transaction. * * @param _parameter Parameter as passed by the eFaps API * @return new empty Return * @throws EFapsException on error */ public Return create4Payment(final Parameter _parameter) throws EFapsException { final Return ret = new Return(); final Instance transInst = createFromUI(_parameter); final List<Instance> docInsts = getDocInstsFromUI(_parameter); markDocs4ArchiveConfig(_parameter, docInsts.toArray(new Instance[docInsts.size()])); for (final Instance docInst : docInsts) { connect2SubJournal(_parameter, transInst, docInst); } // evaluate for the documents the payment belongs to final List<DocumentInfo> docInfos = new DocumentEvaluation().evalDocuments(_parameter); for (final DocumentInfo docInfo : docInfos) { CollectionUtils.addAll(docInsts, docInfo.getDocInsts(false)); } connectDocs2Transaction(_parameter, transInst, docInsts.toArray(new Instance[docInsts.size()])); final Parameter parameter = ParameterUtil.clone(_parameter, Parameter.ParameterValues.INSTANCE, transInst); final File file = getTransactionReport(parameter, true); if (file != null) { ret.put(ReturnValues.VALUES, file); ret.put(ReturnValues.TRUE, true); } return ret; } /** * @param _parameter Parameter as passed by the eFaps API * @return new empty Return * @throws EFapsException on error */ public Return create4PaymentMassive(final Parameter _parameter) throws EFapsException { final DateTime date = new DateTime(_parameter .getParameterValue(CIFormAccounting.Accounting_TransactionCreate4PaymentMassiveForm.date.name)); final boolean usedate = Boolean.parseBoolean(_parameter .getParameterValue(CIFormAccounting.Accounting_TransactionCreate4PaymentMassiveForm.useDate.name)); final List<DocumentInfo> docInfos = new DocumentEvaluation().evalDocuments(_parameter); for (final DocumentInfo docInfo : docInfos) { if (docInfo.isValid(_parameter)) { final TransInfo transinfo = TransInfo.get4DocInfo(_parameter, docInfo, true); if (usedate) { transinfo.setDate(date); } transinfo.create(_parameter); connectDocs2Transaction(_parameter, transinfo.getInstance(), docInfo.getDocInsts(true)); markDocs4ArchiveConfig(_parameter, docInfo.getInstance()); connect2SubJournal(_parameter, transinfo.getInstance(), docInfo.getInstance()); } } return new Return(); } /** * @param _parameter as passed from the eFaps API * @return new empty Return * @throws EFapsException on error. */ public Return create4Securities(final Parameter _parameter) throws EFapsException { return create4Doc(_parameter); } /** * @param _parameter as passed from the eFaps API * @return new empty Return * @throws EFapsException on error. */ public Return create4Undeductible(final Parameter _parameter) throws EFapsException { return create4External(_parameter); } /** * Create the transaction for a group of docs without user interaction. * @param _parameter Parameter as passed from the eFaps API * @return new Return * @throws EFapsException on error */ public Return create4StockDocMassive(final Parameter _parameter) throws EFapsException { String[] oids = new String[0]; final Object obj = _parameter.get(ParameterValues.OTHERS); if (obj instanceof String[]) { oids = (String[]) obj; } else if (Context.getThreadContext().containsSessionAttribute("storeOIDS") && Context.getThreadContext().getSessionAttribute("storeOIDS") != null) { oids = (String[]) Context.getThreadContext().getSessionAttribute("storeOIDS"); Context.getThreadContext().setSessionAttribute("storeOIDS", null); } final DateTime date = _parameter.getParameterValue("date") != null ? new DateTime(_parameter.getParameterValue("date")) : new DateTime().withTime(0, 0, 0, 0); for (final String oid : oids) { final Instance docInst = Instance.get(oid); final String description = "TODO"; final PrintQuery print = new PrintQuery(oid); print.addAttribute(CIERP.DocumentAbstract.Name); print.execute(); final String name = print.<String>getAttribute(CIERP.DocumentAbstract.Name); final DocumentInfo doc = new DocumentInfo(docInst); new FieldValue().getCostInformation(_parameter, date, doc); if (doc.getInstance() != null) { doc.setInvert(doc.getInstance().getType().isKindOf(CISales.ReturnSlip.getType())); } if (doc.isCostValidated() && doc.getDifference(_parameter).compareTo(BigDecimal.ZERO) == 0 && doc.getAmount(null).compareTo(BigDecimal.ZERO) != 0 && doc.getCreditSum(_parameter).compareTo(doc.getAmount(null)) == 0 && validateDoc(_parameter, doc, oids)) { final Insert insert = new Insert(CIAccounting.Transaction); insert.add(CIAccounting.Transaction.Name, name); insert.add(CIAccounting.Transaction.Description, description); insert.add(CIAccounting.Transaction.Date, date); insert.add(CIAccounting.Transaction.PeriodLink, _parameter.getInstance().getId()); insert.add(CIAccounting.Transaction.Status, Status.find(CIAccounting.TransactionStatus.Open)); insert.add(CIAccounting.Transaction.Identifier, Transaction.IDENTTEMP); insert.execute(); final Instance transInst = insert.getInstance(); for (final AccountInfo account : doc.getCreditAccounts()) { insertPosition4Massiv(_parameter, doc, transInst, CIAccounting.TransactionPositionCredit, account); } for (final AccountInfo account : doc.getDebitAccounts()) { insertPosition4Massiv(_parameter, doc, transInst, CIAccounting.TransactionPositionDebit, account); } connectDocs2Transaction(_parameter, transInst, docInst); } } return new Return(); } /** * @param _parameter Parameter as passe by the eFaps api * @param _transInst instance of the transaction * @param _docInstances docuemtn instances * @throws EFapsException on error */ public void connectDocs2Transaction(final Parameter _parameter, final Instance _transInst, final Instance... _docInstances) throws EFapsException { for (final Instance docInst : _docInstances) { if (InstanceUtils.isKindOf(docInst, CIERP.DocumentAbstract)) { final Insert insert; if (docInst.getType().isKindOf(CIERP.PaymentDocumentAbstract.getType())) { insert = new Insert(CIAccounting.Transaction2PaymentDocument); } else { insert = new Insert(CIAccounting.Transaction2SalesDocument); } insert.add(CIAccounting.Transaction2ERPDocument.FromLink, _transInst); insert.add(CIAccounting.Transaction2ERPDocument.ToLinkAbstract, docInst); insert.execute(); } } } /** * Get the list of documents. * * @param _parameter Parameter as passed from the eFaps API * @return List of document instances * @throws EFapsException on error */ protected List<Instance> getDocInstsFromUI(final Parameter _parameter) throws EFapsException { final String[] docOids = _parameter.getParameterValues("document"); final List<Instance> ret = new ArrayList<>(); if (docOids != null) { for (final String docOid : docOids) { final Instance docInst = Instance.get(docOid); if (docInst.isValid()) { ret.add(docInst); } } } return ret; } /** * Get the list of documents. * * @param _parameter Parameter as passed from the eFaps API * @param _docInfos the doc infos * @return List of document instances * @throws EFapsException on error */ protected List<Instance> getDocInstsFromDocInfoList(final Parameter _parameter, final List<DocumentInfo> _docInfos) throws EFapsException { final List<Instance> ret = new ArrayList<>(); for (final DocumentInfo docInfo : _docInfos) { ret.add(docInfo.getInstance()); } return ret; } /** * Create the base transaction. * * @param _parameter Parameter as passed from the eFaps API * @return Instance of the Transaction * @throws EFapsException on error */ protected Instance createFromUI(final Parameter _parameter) throws EFapsException { final Instance periodInst = Period.evalCurrent(_parameter); final TransInfo transInfo = new TransInfo(); transInfo.setType(CIAccounting.Transaction.getType()).setName(_parameter.getParameterValue("name")) .setDescription(_parameter.getParameterValue("description")) .setDate(DateTimeUtil.translateFromUI(_parameter.getParameterValue("date"))) .setStatus(Status.find(CIAccounting.TransactionStatus.Open)).setIdentifier(Transaction.IDENTTEMP) .setPeriodInst(periodInst); createTransactionDoc4Contact(_parameter); analysePositionsFromUI(_parameter, transInfo, "Debit", null, true); analysePositionsFromUI(_parameter, transInfo, "Credit", null, true); transInfo.create(_parameter); return transInfo.getInstance(); } /** * Creates the transaction doc for contact. * * @param _parameter Parameter as passed by the eFaps API * @throws EFapsException on error */ protected void createTransactionDoc4Contact(final Parameter _parameter) throws EFapsException { final Map<String, String> map = new HashMap<>(); createTransactionDoc4Contact(_parameter, map, "Debit"); createTransactionDoc4Contact(_parameter, map, "Credit"); final String[] docOids = _parameter.getParameterValues("document"); if (ArrayUtils.isNotEmpty(docOids)) { for (int i = 0; i < docOids.length; i++) { final Instance inst = Instance.get(docOids[i]); if (InstanceUtils.isKindOf(inst, CIContacts.ContactAbstract) && map.containsKey(docOids[i])) { docOids[i] = map.get(docOids[i]); } } } } /** * Creates the transaction doc for contact. * * @param _parameter Parameter as passed by the eFaps API * @param _map the map * @param _suffix the suffix * @throws EFapsException on error */ protected void createTransactionDoc4Contact(final Parameter _parameter, final Map<String, String> _map, final String _suffix) throws EFapsException { final String[] docLinkOids = _parameter.getParameterValues("docLink_" + _suffix); if (ArrayUtils.isNotEmpty(docLinkOids)) { for (int i = 0; i < docLinkOids.length; i++) { final Instance inst = Instance.get(docLinkOids[i]); if (InstanceUtils.isKindOf(inst, CIContacts.ContactAbstract)) { if (!_map.containsKey(inst.getOid())) { final Instance docinst = new TransactionDocument().createDoc4Contact(_parameter, inst); _map.put(inst.getOid(), docinst.getOid()); } docLinkOids[i] = _map.get(inst.getOid()); } } } } /** * Connect the document to the Purchaserecord. * * @param _parameter Parameter as passed by the eFaps API * @param _docInsts the doc insts * @throws EFapsException on error */ protected void connectDocs2PurchaseRecord(final Parameter _parameter, final Instance... _docInsts) throws EFapsException { new PurchaseRecord().connectDocuments(_parameter, _docInsts); } /** * Set the status to booked if marked in the Form. Set Status to Open if in status Digitized. * @param _parameter Parameter as passed by the eFasp API * @param _instances instance of the document * @throws EFapsException on error */ protected void markDocs4ArchiveConfig(final Parameter _parameter, final Instance... _instances) throws EFapsException { final String archiveConfigStr = _parameter.getParameterValue("archiveConfig"); if (StringUtils.isNotEmpty(archiveConfigStr)) { final ArchiveConfig config = ArchiveConfig.values()[Integer.valueOf(archiveConfigStr)]; switch (config) { case ENTERED: case ARCHIVED: final Instance periodInst = new Period().evaluateCurrentPeriod(_parameter, null); for (final Instance docInst : _instances) { if (InstanceUtils.isKindOf(docInst, CIERP.DocumentAbstract)) { final Insert insert = new Insert(CIAccounting.Period2ERPDocument); insert.add(CIAccounting.Period2ERPDocument.FromLink, periodInst); insert.add(CIAccounting.Period2ERPDocument.ToLink, docInst); insert.add(CIAccounting.Period2ERPDocument.Archived, ArchiveConfig.ARCHIVED.equals(config)); insert.execute(); } } break; default: break; } } } /** * Method to execute additional events. * * @param _parameter as passed from eFaps API. * @throws EFapsException on error. */ protected void add2Create4Doc(final Parameter _parameter) throws EFapsException { } /** * Connect2 sub journal. * * @param _parameter Parameter as passed from the eFaps API * @param _transactionInstance instance of the Transaction * @param _docInstance the doc instance * @throws EFapsException on error */ protected void connect2SubJournal(final Parameter _parameter, final Instance _transactionInstance, final Instance _docInstance) throws EFapsException { Instance repInst = Instance.get(_parameter.getParameterValue("subJournal")); if (!repInst.isValid() && _docInstance != null && _docInstance.isValid() && _docInstance.getType().isKindOf(CIERP.PaymentDocumentAbstract.getType())) { final Instance periodInst = new Period().evaluateCurrentPeriod(_parameter, _transactionInstance); final Properties props = Accounting.getSysConfig().getObjectAttributeValueAsProperties(periodInst); String journalname = "NONE"; if (_docInstance.getType().isKindOf(CISales.PaymentDocumentOutAbstract.getType())) { journalname = props.getProperty(AccountingSettings.PERIOD_SUBJOURNAL4PAYOUT, "NONE"); } else if (_docInstance.getType().isKindOf(CISales.PaymentDocumentAbstract.getType())) { journalname = props.getProperty(AccountingSettings.PERIOD_SUBJOURNAL4PAYIN, "NONE"); } final QueryBuilder queryBldr = new QueryBuilder(CIAccounting.ReportSubJournal); queryBldr.addWhereAttrEqValue(CIAccounting.ReportSubJournal.PeriodLink, periodInst); queryBldr.addWhereAttrEqValue(CIAccounting.ReportSubJournal.Name, journalname); final InstanceQuery query = queryBldr.getQuery(); query.execute(); if (query.next()) { repInst = query.getCurrentValue(); } } if (repInst.isValid()) { final Insert insert = new Insert(CIAccounting.ReportSubJournal2Transaction); insert.add(CIAccounting.ReportSubJournal2Transaction.FromLink, repInst.getId()); insert.add(CIAccounting.ReportSubJournal2Transaction.ToLink, _transactionInstance.getId()); insert.execute(); } } /** * Analyse positions from ui. * * @param _parameter Parameter as passed by the eFaps API * @param _transInfo the trans info * @param _postFix the post fix * @param _accountOids the account oids * @param _executeRels the execute rels * @throws EFapsException on error */ public void analysePositionsFromUI(final Parameter _parameter, final TransInfo _transInfo, final String _postFix, final String[] _accountOids, final boolean _executeRels) throws EFapsException { @SuppressWarnings("unchecked") final Map<String, String> oidMap = (Map<String, String>) _parameter.get(ParameterValues.OIDMAP4UI); final String[] rowKeys = InterfaceUtils.getRowKeys(_parameter, "amount_" + _postFix, "amount_Debit", "amount_Credit"); final String[] accountOids = _accountOids == null ? _parameter.getParameterValues("accountLink_" + _postFix) : _accountOids; final String[] amounts = _parameter.getParameterValues("amount_" + _postFix); final String[] types = _parameter.getParameterValues("type_" + _postFix); final String[] rateCurIds = _parameter.getParameterValues("rateCurrencyLink_" + _postFix); final String[] acc2accOids = _parameter.getParameterValues("acc2acc_" + _postFix); final String[] labelLinkOids = _parameter.getParameterValues("labelLink_" + _postFix); final String[] docLinkOids = _parameter.getParameterValues("docLink_" + _postFix); final String[] remarks = _parameter.getParameterValues("remark_" + _postFix); final DecimalFormat formater = NumberFormatter.get().getFormatter(); try { Instance inst = _parameter.getCallInstance(); if (!inst.getType().isKindOf(CIAccounting.Period.getType())) { inst = new Period().evaluateCurrentPeriod(_parameter); } final Instance curInstance = new Period().getCurrency(inst).getInstance(); if (amounts != null) { for (int i = 0; i < amounts.length; i++) { final Instance rateCurrInst = CurrencyInst.get(Long.parseLong(rateCurIds[i])).getInstance(); final Instance accInst = Instance.get(accountOids[i]); final Object[] rateObj = getRateObject(_parameter, "_" + _postFix, i); final RateInfo rateInfo = getRateInfo4UI(_parameter, "_" + _postFix, i); final Type type = Type.get(Long.parseLong(types[i])); final boolean isDebitTrans = type.getUUID().equals(CIAccounting.TransactionPositionDebit.uuid); final BigDecimal rateAmount = ((BigDecimal) formater.parse(amounts[i])).setScale(2, RoundingMode.HALF_UP); final BigDecimal amount = Currency .convertToCurrency(_parameter, rateAmount, rateInfo, null, curInstance) .setScale(2, RoundingMode.HALF_UP); final PositionInfo pos = new PositionInfo(); _transInfo.addPosition(pos); pos.setType(type).setAccInst(accInst).setCurrInst(curInstance).setRateCurrInst(rateCurrInst) .setRate(rateObj).setRateAmount(isDebitTrans ? rateAmount.negate() : rateAmount) .setAmount(isDebitTrans ? amount.negate() : amount).setOrder(i) .setRemark(remarks == null ? null : remarks[i]) .setInstance(Instance.get(oidMap.get(rowKeys[i]))); if (labelLinkOids != null) { final Instance labelInst = Instance.get(labelLinkOids[i]); if (labelInst.isValid()) { pos.setLabelInst(labelInst) .setLabelRelType(_postFix.equalsIgnoreCase("Debit") ? CIAccounting.TransactionPositionDebit2LabelProject.getType() : CIAccounting.TransactionPositionCredit2LabelProject.getType()); } } if (docLinkOids != null) { final Instance docInst = Instance.get(docLinkOids[i]); if (docInst.isValid()) { final DocumentInfo docInfoTmp = new DocumentInfo(docInst); if (docInfoTmp.isSumsDoc()) { pos.setDocInst(docInst) .setDocRelType(_postFix.equalsIgnoreCase("Debit") ? CIAccounting.TransactionPositionDebit2SalesDocument.getType() : CIAccounting.TransactionPositionCredit2SalesDocument.getType()); } else { pos.setDocInst(docInst) .setDocRelType(_postFix.equalsIgnoreCase("Debit") ? CIAccounting.TransactionPositionDebit2PaymentDocument.getType() : CIAccounting.TransactionPositionCredit2PaymentDocument.getType()); } } } if (_executeRels) { final QueryBuilder queryBldr = new QueryBuilder(CIAccounting.Account2AccountAbstract); queryBldr.addWhereAttrEqValue(CIAccounting.Account2AccountAbstract.FromAccountLink, accInst); final MultiPrintQuery multi = queryBldr.getPrint(); final SelectBuilder selAcc = SelectBuilder.get() .linkto(CIAccounting.Account2AccountAbstract.ToAccountLink).instance(); multi.addSelect(selAcc); multi.addAttribute(CIAccounting.Account2AccountAbstract.Numerator, CIAccounting.Account2AccountAbstract.Denominator, CIAccounting.Account2AccountAbstract.Config); multi.execute(); int y = 1; final int group = _transInfo.getNextGroup(); while (multi.next()) { final Instance instance = multi.getCurrentInstance(); final PositionInfo connPos = new PositionInfo(); connPos.setPosType(TransPosType.CONNECTION); final Collection<Accounting.Account2AccountConfig> configs = multi .getAttribute(CIAccounting.Account2AccountAbstract.Config); final boolean deactivatable = configs != null && configs.contains(Accounting.Account2AccountConfig.DEACTIVATABLE); final boolean confCheck = isDebitTrans && configs != null && configs.contains(Accounting.Account2AccountConfig.APPLY4DEBIT) || !isDebitTrans && configs != null && configs.contains(Accounting.Account2AccountConfig.APPLY4CREDIT); // if cannot be deactivated or selected in the UserInterface if (confCheck && (!deactivatable || acc2accOids != null && deactivatable && Arrays.asList(acc2accOids).contains(instance.getOid()))) { final BigDecimal numerator = new BigDecimal(multi .<Integer>getAttribute(CIAccounting.Account2AccountAbstract.Numerator)); final BigDecimal denominator = new BigDecimal(multi .<Integer>getAttribute(CIAccounting.Account2AccountAbstract.Denominator)); BigDecimal amount2 = amount.multiply(numerator).divide(denominator, BigDecimal.ROUND_HALF_UP); BigDecimal rateAmount2 = rateAmount.multiply(numerator).divide(denominator, BigDecimal.ROUND_HALF_UP); if (instance.getType().isCIType(CIAccounting.Account2AccountCosting)) { connPos.setType(type); } else if (instance.getType() .isCIType(CIAccounting.Account2AccountCostingInverse)) { if (type.getUUID().equals(CIAccounting.TransactionPositionDebit.uuid)) { connPos.setType(CIAccounting.TransactionPositionCredit.getType()); } else { connPos.setType(CIAccounting.TransactionPositionDebit.getType()); } amount2 = amount2.negate(); } else if (instance.getType().isCIType(CIAccounting.Account2AccountCredit)) { if (isDebitTrans) { connPos.setType(CIAccounting.TransactionPositionCredit.getType()); } else { connPos.setType(CIAccounting.TransactionPositionDebit.getType()); amount2 = amount2.negate(); rateAmount2 = rateAmount2.negate(); } } else if (instance.getType().isCIType(CIAccounting.Account2AccountDebit)) { if (isDebitTrans) { connPos.setType(CIAccounting.TransactionPositionDebit.getType()); amount2 = amount2.negate(); rateAmount2 = rateAmount2.negate(); } else { connPos.setType(CIAccounting.TransactionPositionCredit.getType()); } } if (connPos.getType() == null) { Create_Base.LOG.error("Missing definition"); } else { connPos.setOrder(i).setConnOrder(y).setGroupId(group) .setAccInst(multi.<Instance>getSelect(selAcc)).setCurrInst(curInstance) .setRateCurrInst(rateCurrInst).setRate(rateObj).setAmount(amount2) .setRateAmount(rateAmount2); _transInfo.addPosition(connPos); } y++; } } } } } } catch (final ParseException e) { throw new EFapsException(Transaction_Base.class, "insertPositions", e); } } /** * Create a position. The type is given with the properties of the calling * command. * * @param _parameter Parameter as passed from the eFaps API * @return new Return * @throws EFapsException on error */ public Return createPosition(final Parameter _parameter) throws EFapsException { final Instance parent = _parameter.getCallInstance(); final String amountStr = _parameter.getParameterValue("rateAmount"); final String account = _parameter.getParameterValue("accountLink"); final String rateCurrencyLink = _parameter.getParameterValue("rateCurrencyLink"); final Map<?, ?> properties = (Map<?, ?>) _parameter.get(ParameterValues.PROPERTIES); final String typeName = (String) properties.get("Type"); final Instance curInstance; if (parent.getType().isKindOf(CIAccounting.TransactionAbstract.getType())) { final PrintQuery print = new PrintQuery(parent); final SelectBuilder sel = new SelectBuilder().linkto(CIAccounting.TransactionAbstract.PeriodLink).oid(); print.addSelect(sel); print.execute(); final Instance periodInst = Instance.get(print.<String>getSelect(sel)); curInstance = new Period().getCurrency(periodInst).getInstance(); } else { curInstance = new Period().getCurrency(_parameter.getCallInstance()).getInstance(); } BigDecimal amount = DecimalType.parseLocalized(amountStr); final Type type = Type.get(typeName); if (!type.getUUID().equals(CIAccounting.TransactionPositionCredit.uuid)) { amount = amount.negate(); } final Object[] rateObj = new Transaction().getRateObject(_parameter, "", 0); final BigDecimal rate = ((BigDecimal) rateObj[0]).divide((BigDecimal) rateObj[1], 12, BigDecimal.ROUND_HALF_UP); final Insert insert = new Insert(type); insert.add(CIAccounting.TransactionPositionAbstract.TransactionLink, parent.getId()); insert.add(CIAccounting.TransactionPositionAbstract.AccountLink, Instance.get(account).getId()); insert.add(CIAccounting.TransactionPositionAbstract.CurrencyLink, curInstance.getId()); insert.add(CIAccounting.TransactionPositionAbstract.RateCurrencyLink, rateCurrencyLink); insert.add(CIAccounting.TransactionPositionAbstract.Rate, rateObj); insert.add(CIAccounting.TransactionPositionAbstract.Amount, amount.divide(rate, 12, BigDecimal.ROUND_HALF_UP)); insert.add(CIAccounting.TransactionPositionAbstract.RateAmount, amount); insert.execute(); return new Return(); } /** * Used form a from to create the transaction for opening a balance. * * @param _parameter Paramter as passed from the eFaps API * @return new Return * @throws EFapsException on error */ public Return createTransactionOpeningBalance(final Parameter _parameter) throws EFapsException { final String debitAccOId = _parameter.getParameterValue("accountLink_Debit"); final String[] amounts = _parameter.getParameterValues("amount"); final String[] accounts = _parameter.getParameterValues("accountLink_Credit"); final Instance periodInst = _parameter.getInstance(); final Insert insert = new Insert(CIAccounting.TransactionOpeningBalance); insert.add(CIAccounting.TransactionOpeningBalance.Name, 0); insert.add(CIAccounting.TransactionOpeningBalance.Description, DBProperties.getProperty("org.efaps.esjp.accounting.Transaction.openingBalance.description")); insert.add(CIAccounting.TransactionOpeningBalance.Date, _parameter.getParameterValue("date")); insert.add(CIAccounting.TransactionOpeningBalance.PeriodLink, periodInst.getId()); insert.add(CIAccounting.TransactionOpeningBalance.Status, ((Long) Status.find(CIAccounting.TransactionStatus.uuid, "Open").getId()).toString()); insert.execute(); BigDecimal debitAmount = BigDecimal.ZERO; final CurrencyInst curr = new Period().getCurrency(periodInst); final DecimalFormat formater = NumberFormatter.get().getFormatter(null, 2); for (int i = 0; i < amounts.length; i++) { final Instance accInst = Instance.get(accounts[i]); final PrintQuery print = new PrintQuery(accInst); print.addAttribute(CIAccounting.AccountAbstract.SumReport); print.execute(); final BigDecimal sumreport = print.<BigDecimal>getAttribute(CIAccounting.AccountAbstract.SumReport); try { BigDecimal amount = (BigDecimal) formater.parse(amounts[i]); amount = amount.subtract(sumreport == null ? BigDecimal.ZERO : sumreport); final CIType type = amount.compareTo(BigDecimal.ZERO) > 0 ? CIAccounting.TransactionPositionCredit : CIAccounting.TransactionPositionDebit; final Insert posInsert = new Insert(type); posInsert.add(CIAccounting.TransactionPositionAbstract.AccountLink, accInst.getId()); posInsert.add(CIAccounting.TransactionPositionAbstract.Amount, amount); posInsert.add(CIAccounting.TransactionPositionAbstract.CurrencyLink, curr.getInstance().getId()); posInsert.add(CIAccounting.TransactionPositionAbstract.Rate, new Object[] { 1, 1 }); posInsert.add(CIAccounting.TransactionPositionAbstract.RateAmount, amount); posInsert.add(CIAccounting.TransactionPositionAbstract.RateCurrencyLink, curr.getInstance().getId()); posInsert.add(CIAccounting.TransactionPositionAbstract.TransactionLink, insert.getInstance().getId()); posInsert.execute(); debitAmount = debitAmount.add(amount); } catch (final ParseException e) { throw new EFapsException(Create_Base.class, "createTransactionOpeningBalance", e); } } final Instance accInst = Instance.get(debitAccOId); final CIType type = debitAmount.compareTo(BigDecimal.ZERO) < 0 ? CIAccounting.TransactionPositionCredit : CIAccounting.TransactionPositionDebit; final Insert posInsert = new Insert(type); posInsert.add(CIAccounting.TransactionPositionAbstract.AccountLink, accInst.getId()); posInsert.add(CIAccounting.TransactionPositionAbstract.Amount, debitAmount.negate()); posInsert.add(CIAccounting.TransactionPositionAbstract.CurrencyLink, curr.getInstance().getId()); posInsert.add(CIAccounting.TransactionPositionAbstract.Rate, new Object[] { 1, 1 }); posInsert.add(CIAccounting.TransactionPositionAbstract.RateAmount, debitAmount.negate()); posInsert.add(CIAccounting.TransactionPositionAbstract.RateCurrencyLink, curr.getInstance().getId()); posInsert.add(CIAccounting.TransactionPositionAbstract.TransactionLink, insert.getInstance().getId()); posInsert.execute(); return new Return(); } /** * To be overwritten from implementation. * @param _parameter Paramter as passed from the eFaps API * @param _doc Document to be validates * @param _oids Array of OIDs the ,method iterates * @return true if validation succeded else false * @throws EFapsException on error */ protected boolean validateDoc(final Parameter _parameter, final DocumentInfo _doc, final String[] _oids) throws EFapsException { return true; } /** * @param _parameter Parameter as passed from the eFaps API * @param _key key the account is wanted for * @return target acccount * @throws EFapsException on error */ protected AccountInfo getRoundingAccount(final Parameter _parameter, final String _key) throws EFapsException { final Instance periodInst = new Period().evaluateCurrentPeriod(_parameter); AccountInfo ret = null; final Properties props = Accounting.getSysConfig().getObjectAttributeValueAsProperties(periodInst); final String name = props.getProperty(_key); final QueryBuilder queryBldr = new QueryBuilder(CIAccounting.AccountAbstract); queryBldr.addWhereAttrEqValue(CIAccounting.AccountAbstract.Name, name); queryBldr.addWhereAttrEqValue(CIAccounting.AccountAbstract.PeriodAbstractLink, periodInst); final MultiPrintQuery multi = queryBldr.getPrint(); multi.executeWithoutAccessCheck(); while (multi.next()) { ret = new AccountInfo(multi.getCurrentInstance()); } if (ret == null) { Create_Base.LOG.warn("Cannot find Account for: '{}'", _key); } return ret; } /** * @param _parameter Parameter as passed from the eFaps API * @param _doc Document to add the info * @param _instPeriod period * @param _description description * @throws EFapsException on error */ protected void createTrans4DocMassive(final Parameter _parameter, final DocumentInfo _doc, final Instance _instPeriod, final String _description) throws EFapsException { _parameter.get(ParameterValues.PROPERTIES); final Insert insert = new Insert(CIAccounting.Transaction); insert.add(CIAccounting.Transaction.Description, _description); insert.add(CIAccounting.Transaction.Date, _doc.getDate()); insert.add(CIAccounting.Transaction.PeriodLink, _instPeriod); insert.add(CIAccounting.Transaction.Status, Status.find(CIAccounting.TransactionStatus.Open)); insert.execute(); final Instance transInst = insert.getInstance(); connectDocs2Transaction(_parameter, transInst, _doc.getInstance()); for (final AccountInfo account : _doc.getCreditAccounts()) { insertPosition4Massiv(_parameter, _doc, transInst, CIAccounting.TransactionPositionCredit, account); } for (final AccountInfo account : _doc.getDebitAccounts()) { insertPosition4Massiv(_parameter, _doc, transInst, CIAccounting.TransactionPositionDebit, account); } } /** * @param _parameter Parameter as passed from the eFaps API * @param _doc Document * @param _transInst Transaction Instance * @param _type CITYpe * @param _account TargetAccount * @return Instance of the new position * @throws EFapsException on error */ protected Instance insertPosition4Massiv(final Parameter _parameter, final DocumentInfo _doc, final Instance _transInst, final CIType _type, final AccountInfo _account) throws EFapsException { final boolean isDebitTrans = _type.equals(CIAccounting.TransactionPositionDebit); final Instance accInst = _account.getInstance(); Instance periodInst = _parameter.getCallInstance(); if (_parameter.getCallInstance().getType().isKindOf(CIAccounting.SubPeriod.getType())) { final PrintQuery print = new CachedPrintQuery(_parameter.getCallInstance(), SubPeriod_Base.CACHEKEY); final SelectBuilder selPeriodInst = SelectBuilder.get().linkto(CIAccounting.SubPeriod.PeriodLink) .instance(); print.addSelect(selPeriodInst); print.execute(); periodInst = print.<Instance>getSelect(selPeriodInst); } final Instance curInstance = new Period().getCurrency(periodInst).getInstance(); final Insert insert = new Insert(_type); insert.add(CIAccounting.TransactionPositionAbstract.TransactionLink, _transInst.getId()); insert.add(CIAccounting.TransactionPositionAbstract.AccountLink, accInst.getId()); insert.add(CIAccounting.TransactionPositionAbstract.CurrencyLink, curInstance); insert.add(CIAccounting.TransactionPositionAbstract.RateCurrencyLink, _account.getRateInfo().getCurrencyInstance()); insert.add(CIAccounting.TransactionPositionAbstract.Rate, new Object[] { _doc.getRateInfo().getRate(), _account.getRateInfo().getRate() }); final BigDecimal rateAmount = _account.getAmount(); insert.add(CIAccounting.TransactionPositionAbstract.RateAmount, isDebitTrans ? rateAmount.negate() : rateAmount); final BigDecimal amount = _account.getAmountRate(_parameter).setScale(2, BigDecimal.ROUND_HALF_UP); insert.add(CIAccounting.TransactionPositionAbstract.Amount, isDebitTrans ? amount.negate() : amount); insert.execute(); final QueryBuilder queryBldr = new QueryBuilder(CIAccounting.Account2AccountAbstract); queryBldr.addWhereAttrEqValue(CIAccounting.Account2AccountAbstract.FromAccountLink, accInst.getId()); final MultiPrintQuery multi = queryBldr.getPrint(); multi.addAttribute(CIAccounting.Account2AccountAbstract.Numerator, CIAccounting.Account2AccountAbstract.Denominator, CIAccounting.Account2AccountAbstract.ToAccountLink, CIAccounting.Account2AccountAbstract.Config); multi.execute(); while (multi.next()) { final Instance instance = multi.getCurrentInstance(); boolean add = false; Insert insert3 = null; BigDecimal amount2 = amount.multiply( new BigDecimal(multi.<Integer>getAttribute(CIAccounting.Account2AccountAbstract.Numerator)) .divide(new BigDecimal( multi.<Integer>getAttribute(CIAccounting.Account2AccountAbstract.Denominator)), BigDecimal.ROUND_HALF_UP)); BigDecimal rateAmount2 = rateAmount.multiply( new BigDecimal(multi.<Integer>getAttribute(CIAccounting.Account2AccountAbstract.Numerator)) .divide(new BigDecimal( multi.<Integer>getAttribute(CIAccounting.Account2AccountAbstract.Denominator)), BigDecimal.ROUND_HALF_UP)); if (instance.getType().getUUID().equals(CIAccounting.Account2AccountCosting.uuid)) { add = true; insert3 = new Insert(_type); } else if (instance.getType().getUUID().equals(CIAccounting.Account2AccountCostingInverse.uuid)) { if (_type.equals(CIAccounting.TransactionPositionDebit)) { insert3 = new Insert(CIAccounting.TransactionPositionCredit); } else { insert3 = new Insert(CIAccounting.TransactionPositionDebit); } amount2 = amount2.negate(); rateAmount2 = rateAmount2.negate(); add = true; } else if (instance.getType().getUUID().equals(CIAccounting.Account2AccountCredit.uuid)) { if (isDebitTrans) { insert3 = new Insert(CIAccounting.TransactionPositionCredit); } else { insert3 = new Insert(CIAccounting.TransactionPositionDebit); amount2 = amount2.negate(); rateAmount2 = rateAmount2.negate(); } add = true; } else if (instance.getType().getUUID().equals(CIAccounting.Account2AccountDebit.uuid)) { if (isDebitTrans) { insert3 = new Insert(CIAccounting.TransactionPositionDebit); amount2 = amount2.negate(); rateAmount2 = rateAmount2.negate(); } else { insert3 = new Insert(CIAccounting.TransactionPositionCredit); } add = true; } final Collection<Accounting.Account2AccountConfig> configs = multi .getAttribute(CIAccounting.Account2AccountAbstract.Config); add = add && (isDebitTrans && configs != null && configs.contains(Accounting.Account2AccountConfig.APPLY4DEBIT) || !isDebitTrans && configs != null && configs.contains(Accounting.Account2AccountConfig.APPLY4CREDIT)); if (add) { insert3.add(CIAccounting.TransactionPositionAbstract.TransactionLink, _transInst.getId()); insert3.add(CIAccounting.TransactionPositionAbstract.AccountLink, multi.<Long>getAttribute(CIAccounting.Account2AccountAbstract.ToAccountLink)); insert3.add(CIAccounting.TransactionPositionAbstract.CurrencyLink, curInstance); insert3.add(CIAccounting.TransactionPositionAbstract.RateCurrencyLink, _account.getRateInfo().getCurrencyInstance()); insert3.add(CIAccounting.TransactionPositionAbstract.Rate, new Object[] { _doc.getRateInfo().getRate(), _account.getRateInfo().getRate() }); insert3.add(CIAccounting.TransactionPositionAbstract.Amount, amount2); insert3.add(CIAccounting.TransactionPositionAbstract.RateAmount, rateAmount2); insert3.execute(); } } return insert.getInstance(); } }