List of usage examples for java.math BigDecimal signum
public int signum()
From source file:org.openvpms.archetype.rules.finance.account.CustomerBalanceSummaryQuery.java
/** * Returns the next set in the iteration. * * @return the next set or {@code null} if overdue balances are being queried and the current balance is not overdue *//*from w w w . ja v a 2 s.com*/ private ObjectSet doNext() { IMObjectReference current = null; Map<IMObjectReference, ObjectSet> sets = new LinkedHashMap<IMObjectReference, ObjectSet>(); // the sets for the current customer, keyed on act. This is necessary // to filter duplicate rows, should a customer erroneously have > 1 // account type configured if (last != null) { sets.put(getAct(last), last); current = getEntity(last); last = null; } while (iterator.hasNext()) { ObjectSet set = iterator.next(); IMObjectReference party = getEntity(set); if (party != null) { if (current == null || current.equals(party)) { current = party; sets.put(getAct(set), set); } else { last = set; break; } } } if (sets.isEmpty()) { throw new NoSuchElementException(); } String name = null; BigDecimal balance = BigDecimal.ZERO; BigDecimal overdueBalance = BigDecimal.ZERO; BigDecimal creditBalance = BigDecimal.ZERO; BigDecimal unbilled = BigDecimal.ZERO; Date overdueDate = null; Date overdueFrom = null; Date overdueTo = null; String code; Lookup lookup = null; for (ObjectSet set : sets.values()) { name = (String) set.get("e.name"); Date startTime = (Date) set.get("a.startTime"); if (startTime instanceof Timestamp) { startTime = new Date(startTime.getTime()); } String status = (String) set.get("a.status"); BigDecimal amount = (BigDecimal) set.get("a.amount"); BigDecimal allocated = (BigDecimal) set.get("a.allocatedAmount"); boolean credit = (Boolean) set.get("a.credit"); if (POSTED.equals(status)) { BigDecimal unallocated = balanceCalc.getAllocatable(amount, allocated); balance = calculator.addAmount(balance, unallocated, credit); code = (String) set.get("c.code"); if (code != null && lookup == null) { lookup = getLookup(code); } if (overdueDate == null) { if (lookup == null) { overdueDate = date; } else { overdueDate = rules.getOverdueDate(lookup, date); } overdueFrom = overdueDate; if (from > 0) { overdueFrom = DateRules.getDate(overdueFrom, -from, DateUnits.DAYS); } if (to > 0) { overdueTo = DateRules.getDate(overdueDate, -to, DateUnits.DAYS); } } if (!credit && startTime.compareTo(overdueFrom) < 0 && (overdueTo == null || (overdueTo != null && startTime.compareTo(overdueTo) > 0))) { overdueBalance = calculator.addAmount(overdueBalance, unallocated, credit); } if (credit) { creditBalance = calculator.addAmount(creditBalance, unallocated, credit); } } else { IMObjectReference act = getAct(set); if (TypeHelper.isA(act, INVOICE, COUNTER, CREDIT)) { unbilled = calculator.addAmount(unbilled, amount, credit); } } } if (overdueBalance.signum() < 0) { overdueBalance = BigDecimal.ZERO; } ObjectSet result = null; boolean exclude = true; if (overdue && overdueBalance.compareTo(BigDecimal.ZERO) != 0) { exclude = false; } if (nonOverdue && overdueBalance.compareTo(BigDecimal.ZERO) == 0) { exclude = false; } if (excludeCredit && creditBalance.compareTo(BigDecimal.ZERO) != 0) { exclude = true; } if (!exclude) { result = new BalanceObjectSet(current); result.set(CUSTOMER_REFERENCE, current); result.set(CUSTOMER_NAME, name); result.set(BALANCE, balance); result.set(OVERDUE_BALANCE, overdueBalance); result.set(CREDIT_BALANCE, creditBalance); result.set(UNBILLED_AMOUNT, unbilled); } return result; }
From source file:org.ofbiz.accounting.invoice.InvoiceServices.java
private static BigDecimal calcHeaderAdj(Delegator delegator, GenericValue adj, String invoiceTypeId, String invoiceId, String invoiceItemSeqId, BigDecimal divisor, BigDecimal multiplier, BigDecimal baseAmount, int decimals, int rounding, GenericValue userLogin, LocalDispatcher dispatcher, Locale locale) {//from w w w. j av a2 s.c o m BigDecimal adjAmount = ZERO; if (adj.get("amount") != null) { // pro-rate the amount BigDecimal amount = ZERO; // make sure the divisor is not 0 to avoid NaN problems; just leave the amount as 0 and skip it in essense if (divisor.signum() != 0) { // multiply first then divide to avoid rounding errors amount = baseAmount.multiply(multiplier).divide(divisor, decimals, rounding); } if (amount.signum() != 0) { Map<String, Object> createInvoiceItemContext = FastMap.newInstance(); createInvoiceItemContext.put("invoiceId", invoiceId); createInvoiceItemContext.put("invoiceItemSeqId", invoiceItemSeqId); createInvoiceItemContext.put("invoiceItemTypeId", getInvoiceItemType(delegator, adj.getString("orderAdjustmentTypeId"), null, invoiceTypeId, "INVOICE_ADJ")); createInvoiceItemContext.put("description", adj.get("description")); createInvoiceItemContext.put("quantity", BigDecimal.ONE); createInvoiceItemContext.put("amount", amount); createInvoiceItemContext.put("overrideGlAccountId", adj.get("overrideGlAccountId")); //createInvoiceItemContext.put("productId", orderItem.get("productId")); //createInvoiceItemContext.put("productFeatureId", orderItem.get("productFeatureId")); //createInvoiceItemContext.put("uomId", ""); //createInvoiceItemContext.put("taxableFlag", product.get("taxable")); createInvoiceItemContext.put("taxAuthPartyId", adj.get("taxAuthPartyId")); createInvoiceItemContext.put("taxAuthGeoId", adj.get("taxAuthGeoId")); createInvoiceItemContext.put("taxAuthorityRateSeqId", adj.get("taxAuthorityRateSeqId")); createInvoiceItemContext.put("userLogin", userLogin); Map<String, Object> createInvoiceItemResult = null; try { createInvoiceItemResult = dispatcher.runSync("createInvoiceItem", createInvoiceItemContext); } catch (GenericServiceException e) { Debug.logError(e, "Service/other problem creating InvoiceItem from order header adjustment", module); return adjAmount; } if (ServiceUtil.isError(createInvoiceItemResult)) { return adjAmount; } // Create the OrderAdjustmentBilling record Map<String, Object> createOrderAdjustmentBillingContext = FastMap.newInstance(); createOrderAdjustmentBillingContext.put("orderAdjustmentId", adj.getString("orderAdjustmentId")); createOrderAdjustmentBillingContext.put("invoiceId", invoiceId); createOrderAdjustmentBillingContext.put("invoiceItemSeqId", invoiceItemSeqId); createOrderAdjustmentBillingContext.put("amount", amount); createOrderAdjustmentBillingContext.put("userLogin", userLogin); try { dispatcher.runSync("createOrderAdjustmentBilling", createOrderAdjustmentBillingContext); } catch (GenericServiceException e) { return adjAmount; } } amount = amount.setScale(decimals, rounding); adjAmount = amount; } else if (adj.get("sourcePercentage") != null) { // pro-rate the amount BigDecimal percent = adj.getBigDecimal("sourcePercentage"); percent = percent.divide(new BigDecimal(100), 100, rounding); BigDecimal amount = ZERO; // make sure the divisor is not 0 to avoid NaN problems; just leave the amount as 0 and skip it in essense if (divisor.signum() != 0) { // multiply first then divide to avoid rounding errors amount = percent.multiply(divisor); } if (amount.signum() != 0) { Map<String, Object> createInvoiceItemContext = FastMap.newInstance(); createInvoiceItemContext.put("invoiceId", invoiceId); createInvoiceItemContext.put("invoiceItemSeqId", invoiceItemSeqId); createInvoiceItemContext.put("invoiceItemTypeId", getInvoiceItemType(delegator, adj.getString("orderAdjustmentTypeId"), null, invoiceTypeId, "INVOICE_ADJ")); createInvoiceItemContext.put("description", adj.get("description")); createInvoiceItemContext.put("quantity", BigDecimal.ONE); createInvoiceItemContext.put("amount", amount); createInvoiceItemContext.put("overrideGlAccountId", adj.get("overrideGlAccountId")); //createInvoiceItemContext.put("productId", orderItem.get("productId")); //createInvoiceItemContext.put("productFeatureId", orderItem.get("productFeatureId")); //createInvoiceItemContext.put("uomId", ""); //createInvoiceItemContext.put("taxableFlag", product.get("taxable")); createInvoiceItemContext.put("taxAuthPartyId", adj.get("taxAuthPartyId")); createInvoiceItemContext.put("taxAuthGeoId", adj.get("taxAuthGeoId")); createInvoiceItemContext.put("taxAuthorityRateSeqId", adj.get("taxAuthorityRateSeqId")); createInvoiceItemContext.put("userLogin", userLogin); Map<String, Object> createInvoiceItemResult = null; try { createInvoiceItemResult = dispatcher.runSync("createInvoiceItem", createInvoiceItemContext); } catch (GenericServiceException e) { Debug.logError(e, "Service/other problem creating InvoiceItem from order header adjustment", module); return adjAmount; } if (ServiceUtil.isError(createInvoiceItemResult)) { return adjAmount; } // Create the OrderAdjustmentBilling record Map<String, Object> createOrderAdjustmentBillingContext = FastMap.newInstance(); createOrderAdjustmentBillingContext.put("orderAdjustmentId", adj.getString("orderAdjustmentId")); createOrderAdjustmentBillingContext.put("invoiceId", invoiceId); createOrderAdjustmentBillingContext.put("invoiceItemSeqId", invoiceItemSeqId); createOrderAdjustmentBillingContext.put("amount", amount); createOrderAdjustmentBillingContext.put("userLogin", userLogin); try { dispatcher.runSync("createOrderAdjustmentBilling", createOrderAdjustmentBillingContext); } catch (GenericServiceException e) { return adjAmount; } } amount = amount.setScale(decimals, rounding); adjAmount = amount; } Debug.logInfo("adjAmount: " + adjAmount + ", divisor: " + divisor + ", multiplier: " + multiplier + ", invoiceTypeId: " + invoiceTypeId + ", invoiceId: " + invoiceId + ", itemSeqId: " + invoiceItemSeqId + ", decimals: " + decimals + ", rounding: " + rounding + ", adj: " + adj, module); return adjAmount; }
From source file:org.apache.ofbiz.accounting.invoice.InvoiceServices.java
private static BigDecimal calcHeaderAdj(Delegator delegator, GenericValue adj, String invoiceTypeId, String invoiceId, String invoiceItemSeqId, BigDecimal divisor, BigDecimal multiplier, BigDecimal baseAmount, int decimals, int rounding, GenericValue userLogin, LocalDispatcher dispatcher, Locale locale) {//from www. ja va2 s .co m BigDecimal adjAmount = ZERO; if (adj.get("amount") != null) { // pro-rate the amount BigDecimal amount = ZERO; if ("DONATION_ADJUSTMENT".equals(adj.getString("orderAdjustmentTypeId"))) { amount = baseAmount; } else if (divisor.signum() != 0) { // make sure the divisor is not 0 to avoid NaN problems; just leave the amount as 0 and skip it in essense // multiply first then divide to avoid rounding errors amount = baseAmount.multiply(multiplier).divide(divisor, decimals, rounding); } if (amount.signum() != 0) { Map<String, Object> createInvoiceItemContext = new HashMap<String, Object>(); createInvoiceItemContext.put("invoiceId", invoiceId); createInvoiceItemContext.put("invoiceItemSeqId", invoiceItemSeqId); createInvoiceItemContext.put("invoiceItemTypeId", getInvoiceItemType(delegator, adj.getString("orderAdjustmentTypeId"), null, invoiceTypeId, "INVOICE_ADJ")); createInvoiceItemContext.put("description", adj.get("description")); createInvoiceItemContext.put("quantity", BigDecimal.ONE); createInvoiceItemContext.put("amount", amount); createInvoiceItemContext.put("overrideGlAccountId", adj.get("overrideGlAccountId")); createInvoiceItemContext.put("taxAuthPartyId", adj.get("taxAuthPartyId")); createInvoiceItemContext.put("taxAuthGeoId", adj.get("taxAuthGeoId")); createInvoiceItemContext.put("taxAuthorityRateSeqId", adj.get("taxAuthorityRateSeqId")); createInvoiceItemContext.put("userLogin", userLogin); Map<String, Object> createInvoiceItemResult = null; try { createInvoiceItemResult = dispatcher.runSync("createInvoiceItem", createInvoiceItemContext); } catch (GenericServiceException e) { Debug.logError(e, "Service/other problem creating InvoiceItem from order header adjustment", module); return adjAmount; } if (ServiceUtil.isError(createInvoiceItemResult)) { return adjAmount; } // Create the OrderAdjustmentBilling record Map<String, Object> createOrderAdjustmentBillingContext = new HashMap<String, Object>(); createOrderAdjustmentBillingContext.put("orderAdjustmentId", adj.getString("orderAdjustmentId")); createOrderAdjustmentBillingContext.put("invoiceId", invoiceId); createOrderAdjustmentBillingContext.put("invoiceItemSeqId", invoiceItemSeqId); createOrderAdjustmentBillingContext.put("amount", amount); createOrderAdjustmentBillingContext.put("userLogin", userLogin); try { dispatcher.runSync("createOrderAdjustmentBilling", createOrderAdjustmentBillingContext); } catch (GenericServiceException e) { return adjAmount; } } amount = amount.setScale(decimals, rounding); adjAmount = amount; } else if (adj.get("sourcePercentage") != null) { // pro-rate the amount BigDecimal percent = adj.getBigDecimal("sourcePercentage"); percent = percent.divide(new BigDecimal(100), 100, rounding); BigDecimal amount = ZERO; // make sure the divisor is not 0 to avoid NaN problems; just leave the amount as 0 and skip it in essense if (divisor.signum() != 0) { // multiply first then divide to avoid rounding errors amount = percent.multiply(divisor); } if (amount.signum() != 0) { Map<String, Object> createInvoiceItemContext = new HashMap<String, Object>(); createInvoiceItemContext.put("invoiceId", invoiceId); createInvoiceItemContext.put("invoiceItemSeqId", invoiceItemSeqId); createInvoiceItemContext.put("invoiceItemTypeId", getInvoiceItemType(delegator, adj.getString("orderAdjustmentTypeId"), null, invoiceTypeId, "INVOICE_ADJ")); createInvoiceItemContext.put("description", adj.get("description")); createInvoiceItemContext.put("quantity", BigDecimal.ONE); createInvoiceItemContext.put("amount", amount); createInvoiceItemContext.put("overrideGlAccountId", adj.get("overrideGlAccountId")); createInvoiceItemContext.put("taxAuthPartyId", adj.get("taxAuthPartyId")); createInvoiceItemContext.put("taxAuthGeoId", adj.get("taxAuthGeoId")); createInvoiceItemContext.put("taxAuthorityRateSeqId", adj.get("taxAuthorityRateSeqId")); createInvoiceItemContext.put("userLogin", userLogin); Map<String, Object> createInvoiceItemResult = null; try { createInvoiceItemResult = dispatcher.runSync("createInvoiceItem", createInvoiceItemContext); } catch (GenericServiceException e) { Debug.logError(e, "Service/other problem creating InvoiceItem from order header adjustment", module); return adjAmount; } if (ServiceUtil.isError(createInvoiceItemResult)) { return adjAmount; } // Create the OrderAdjustmentBilling record Map<String, Object> createOrderAdjustmentBillingContext = new HashMap<String, Object>(); createOrderAdjustmentBillingContext.put("orderAdjustmentId", adj.getString("orderAdjustmentId")); createOrderAdjustmentBillingContext.put("invoiceId", invoiceId); createOrderAdjustmentBillingContext.put("invoiceItemSeqId", invoiceItemSeqId); createOrderAdjustmentBillingContext.put("amount", amount); createOrderAdjustmentBillingContext.put("userLogin", userLogin); try { dispatcher.runSync("createOrderAdjustmentBilling", createOrderAdjustmentBillingContext); } catch (GenericServiceException e) { return adjAmount; } } amount = amount.setScale(decimals, rounding); adjAmount = amount; } Debug.logInfo("adjAmount: " + adjAmount + ", divisor: " + divisor + ", multiplier: " + multiplier + ", invoiceTypeId: " + invoiceTypeId + ", invoiceId: " + invoiceId + ", itemSeqId: " + invoiceItemSeqId + ", decimals: " + decimals + ", rounding: " + rounding + ", adj: " + adj, module); return adjAmount; }
From source file:org.efaps.esjp.accounting.transaction.Recalculate_Base.java
/** * @param _parameter Parameter as passed by the eFasp API * @return new Return/*from ww w .ja v a2 s.com*/ * @throws EFapsException on error */ public Return createGainLoss4SimpleAccount(final Parameter _parameter) throws EFapsException { final PrintQuery printPer = new PrintQuery(_parameter.getInstance()); final SelectBuilder selCurrInst = SelectBuilder.get().linkto(CIAccounting.Period.CurrencyLink).instance(); printPer.addSelect(selCurrInst); printPer.addAttribute(CIAccounting.Period.FromDate, CIAccounting.Period.CurrencyLink); printPer.execute(); final DateTime dateFrom = printPer.<DateTime>getAttribute(CIAccounting.Period.FromDate); final Instance currencyInst = printPer.<Instance>getSelect(selCurrInst); final String[] relOIDs = (String[]) Context.getThreadContext() .getSessionAttribute(CIFormAccounting.Accounting_GainLoss4SimpleAccountForm.config2period.name); final DateTime dateTo = new DateTime(_parameter .getParameterValue(CIFormAccounting.Accounting_GainLoss4SimpleAccountForm.transactionDate.name)); final DateTime dateEx = new DateTime(_parameter .getParameterValue(CIFormAccounting.Accounting_GainLoss4SimpleAccountForm.exchangeDate.name)); Insert insert = null; BigDecimal totalSum = BigDecimal.ZERO; for (final String oid : relOIDs) { Instance tarCurInst = null; final Instance relInst = Instance.get(oid); final PrintQuery print = new PrintQuery(relInst); final SelectBuilder selAccount = new SelectBuilder() .linkto(CIAccounting.AccountConfigSimple2Period.FromLink).oid(); print.addSelect(selAccount); print.addAttribute(CIAccounting.AccountConfigSimple2Period.IsSale); if (print.execute()) { final Instance instAcc = Instance.get(print.<String>getSelect(selAccount)); final boolean isSale = print.<Boolean>getAttribute(CIAccounting.AccountConfigSimple2Period.IsSale); final QueryBuilder attrQuerBldr = new QueryBuilder(CIAccounting.Transaction); attrQuerBldr.addWhereAttrEqValue(CIAccounting.Transaction.PeriodLink, _parameter.getInstance()); attrQuerBldr.addWhereAttrGreaterValue(CIAccounting.Transaction.Date, dateFrom.minusMinutes(1)); attrQuerBldr.addWhereAttrLessValue(CIAccounting.Transaction.Date, dateTo.plusDays(1)); final AttributeQuery attrQuery = attrQuerBldr.getAttributeQuery(CIAccounting.Transaction.ID); final QueryBuilder queryBldr = new QueryBuilder(CIAccounting.TransactionPositionAbstract); queryBldr.addWhereAttrEqValue(CIAccounting.TransactionPositionAbstract.AccountLink, instAcc); queryBldr.addWhereAttrInQuery(CIAccounting.TransactionPositionAbstract.TransactionLink, attrQuery); final MultiPrintQuery multi = queryBldr.getPrint(); final SelectBuilder selTRInst = SelectBuilder.get() .linkto(CIAccounting.TransactionPositionAbstract.RateCurrencyLink).instance(); multi.addSelect(selTRInst); multi.addAttribute(CIAccounting.TransactionPositionAbstract.Amount, CIAccounting.TransactionPositionAbstract.RateAmount); BigDecimal gainlossSum = BigDecimal.ZERO; multi.execute(); while (multi.next()) { final BigDecimal oldRateAmount = multi .<BigDecimal>getAttribute(CIAccounting.TransactionPositionAbstract.RateAmount); final BigDecimal oldAmount = multi .<BigDecimal>getAttribute(CIAccounting.TransactionPositionAbstract.Amount); final Instance targetCurrInst = multi.<Instance>getSelect(selTRInst); final BigDecimal rate = evaluateRate(_parameter, dateEx, currencyInst, targetCurrInst, isSale); final BigDecimal newAmount = oldRateAmount.divide(rate, BigDecimal.ROUND_HALF_UP); BigDecimal gainloss = BigDecimal.ZERO; if (!currencyInst.equals(targetCurrInst)) { gainloss = newAmount.subtract(oldAmount); tarCurInst = targetCurrInst; } else { gainloss = newAmount; } gainlossSum = gainlossSum.add(gainloss); } totalSum = totalSum.add(gainlossSum); final Map<String, String[]> map = validateInfo(_parameter, gainlossSum); final String[] accs = map.get("accs"); final String[] check = map.get("check"); if (checkAccounts(accs, 0, check).length() > 0) { if (gainlossSum.compareTo(BigDecimal.ZERO) != 0) { final String[] accOids = map.get("accountOids"); if (insert == null) { final String descr = DBProperties.getFormatedDBProperty( Recalculate.class.getName() + ".gainLoss4SimpleAccountTransDesc", dateTo.toDate()); insert = new Insert(CIAccounting.Transaction); insert.add(CIAccounting.Transaction.Description, descr); insert.add(CIAccounting.Transaction.Date, dateTo); insert.add(CIAccounting.Transaction.PeriodLink, _parameter.getInstance()); insert.add(CIAccounting.Transaction.Status, Status.find(CIAccounting.TransactionStatus.Open)); insert.execute(); } Insert insertPos = new Insert(CIAccounting.TransactionPositionDebit); insertPos.add(CIAccounting.TransactionPositionDebit.TransactionLink, insert.getInstance()); if (gainlossSum.signum() > 0) { insertPos.add(CIAccounting.TransactionPositionDebit.AccountLink, Instance.get(accOids[0])); } else { insertPos.add(CIAccounting.TransactionPositionDebit.AccountLink, instAcc); } insertPos.add(CIAccounting.TransactionPositionDebit.Amount, gainlossSum.abs().negate()); insertPos.add(CIAccounting.TransactionPositionDebit.RateAmount, BigDecimal.ZERO); insertPos.add(CIAccounting.TransactionPositionDebit.CurrencyLink, currencyInst); insertPos.add(CIAccounting.TransactionPositionDebit.RateCurrencyLink, tarCurInst); insertPos.add(CIAccounting.TransactionPositionDebit.Rate, new Object[] { BigDecimal.ONE, BigDecimal.ONE }); insertPos.execute(); insertPos = new Insert(CIAccounting.TransactionPositionCredit); insertPos.add(CIAccounting.TransactionPositionCredit.TransactionLink, insert.getInstance()); if (gainlossSum.signum() > 0) { insertPos.add(CIAccounting.TransactionPositionCredit.AccountLink, instAcc); } else { insertPos.add(CIAccounting.TransactionPositionCredit.AccountLink, Instance.get(accOids[0])); } insertPos.add(CIAccounting.TransactionPositionCredit.Amount, gainlossSum.abs()); insertPos.add(CIAccounting.TransactionPositionCredit.RateAmount, BigDecimal.ZERO); insertPos.add(CIAccounting.TransactionPositionCredit.CurrencyLink, currencyInst); insertPos.add(CIAccounting.TransactionPositionCredit.RateCurrencyLink, tarCurInst); insertPos.add(CIAccounting.TransactionPositionCredit.Rate, new Object[] { BigDecimal.ONE, BigDecimal.ONE }); insertPos.execute(); } } } } if (insert != null) { final Instance instance = insert.getInstance(); // create classifications final Classification classification1 = (Classification) CIAccounting.TransactionClass.getType(); final Insert relInsert1 = new Insert(classification1.getClassifyRelationType()); relInsert1.add(classification1.getRelLinkAttributeName(), instance); relInsert1.add(classification1.getRelTypeAttributeName(), classification1.getId()); relInsert1.execute(); final Insert classInsert1 = new Insert(classification1); classInsert1.add(classification1.getLinkAttributeName(), instance); classInsert1.execute(); final Classification classification = (Classification) CIAccounting.TransactionClassGainLoss.getType(); final Insert relInsert = new Insert(classification.getClassifyRelationType()); relInsert.add(classification.getRelLinkAttributeName(), instance); relInsert.add(classification.getRelTypeAttributeName(), classification.getId()); relInsert.execute(); final Insert classInsert = new Insert(classification); classInsert.add(classification.getLinkAttributeName(), instance); classInsert.add(CIAccounting.TransactionClassGainLoss.Amount, totalSum); classInsert.add(CIAccounting.TransactionClassGainLoss.RateAmount, totalSum); classInsert.add(CIAccounting.TransactionClassGainLoss.CurrencyLink, currencyInst); classInsert.add(CIAccounting.TransactionClassGainLoss.RateCurrencyLink, currencyInst); classInsert.add(CIAccounting.TransactionClassGainLoss.Rate, new Object[] { BigDecimal.ONE, BigDecimal.ONE }); classInsert.execute(); } // clean up Context.getThreadContext() .removeSessionAttribute(CIFormAccounting.Accounting_GainLoss4SimpleAccountForm.config2period.name); return new Return(); }
From source file:org.ofbiz.accounting.invoice.InvoiceServices.java
public static Map<String, Object> createInvoiceForOrder(DispatchContext dctx, Map<String, Object> context) { Delegator delegator = dctx.getDelegator(); LocalDispatcher dispatcher = dctx.getDispatcher(); GenericValue userLogin = (GenericValue) context.get("userLogin"); Locale locale = (Locale) context.get("locale"); if (DECIMALS == -1 || ROUNDING == -1) { return ServiceUtil.returnError( UtilProperties.getMessage(resource, "AccountingAritmeticPropertiesNotConfigured", locale)); }/*from w w w . ja va 2 s .c om*/ String orderId = (String) context.get("orderId"); List<GenericValue> billItems = UtilGenerics.checkList(context.get("billItems")); String invoiceId = (String) context.get("invoiceId"); if (UtilValidate.isEmpty(billItems)) { Debug.logVerbose("No order items to invoice; not creating invoice; returning success", module); return ServiceUtil .returnSuccess(UtilProperties.getMessage(resource, "AccountingNoOrderItemsToInvoice", locale)); } try { GenericValue orderHeader = EntityQuery.use(delegator).from("OrderHeader").where("orderId", orderId) .queryOne(); if (orderHeader == null) { return ServiceUtil .returnError(UtilProperties.getMessage(resource, "AccountingNoOrderHeader", locale)); } // figure out the invoice type String invoiceType = null; String orderType = orderHeader.getString("orderTypeId"); if (orderType.equals("SALES_ORDER")) { invoiceType = "SALES_INVOICE"; } else if (orderType.equals("PURCHASE_ORDER")) { invoiceType = "PURCHASE_INVOICE"; } // Set the precision depending on the type of invoice int invoiceTypeDecimals = UtilNumber.getBigDecimalScale("invoice." + invoiceType + ".decimals"); if (invoiceTypeDecimals == -1) invoiceTypeDecimals = DECIMALS; // Make an order read helper from the order OrderReadHelper orh = new OrderReadHelper(orderHeader); // get the product store GenericValue productStore = orh.getProductStore(); // get the shipping adjustment mode (Y = Pro-Rate; N = First-Invoice) String prorateShipping = productStore != null ? productStore.getString("prorateShipping") : "Y"; if (prorateShipping == null) { prorateShipping = "Y"; } // get the billing parties String billToCustomerPartyId = orh.getBillToParty().getString("partyId"); String billFromVendorPartyId = orh.getBillFromParty().getString("partyId"); // get some price totals BigDecimal shippableAmount = orh.getShippableTotal(null); BigDecimal orderSubTotal = orh.getOrderItemsSubTotal(); // these variables are for pro-rating order amounts across invoices, so they should not be rounded off for maximum accuracy BigDecimal invoiceShipProRateAmount = ZERO; BigDecimal invoiceSubTotal = ZERO; BigDecimal invoiceQuantity = ZERO; GenericValue billingAccount = orderHeader.getRelatedOne("BillingAccount", false); String billingAccountId = billingAccount != null ? billingAccount.getString("billingAccountId") : null; Timestamp invoiceDate = (Timestamp) context.get("eventDate"); if (UtilValidate.isEmpty(invoiceDate)) { // TODO: ideally this should be the same time as when a shipment is sent and be passed in as a parameter invoiceDate = UtilDateTime.nowTimestamp(); } // TODO: perhaps consider billing account net days term as well? Long orderTermNetDays = orh.getOrderTermNetDays(); Timestamp dueDate = null; if (orderTermNetDays != null) { dueDate = UtilDateTime.getDayEnd(invoiceDate, orderTermNetDays); } // create the invoice record if (UtilValidate.isEmpty(invoiceId)) { Map<String, Object> createInvoiceContext = FastMap.newInstance(); createInvoiceContext.put("partyId", billToCustomerPartyId); createInvoiceContext.put("partyIdFrom", billFromVendorPartyId); createInvoiceContext.put("billingAccountId", billingAccountId); createInvoiceContext.put("invoiceDate", invoiceDate); createInvoiceContext.put("dueDate", dueDate); createInvoiceContext.put("invoiceTypeId", invoiceType); // start with INVOICE_IN_PROCESS, in the INVOICE_READY we can't change the invoice (or shouldn't be able to...) createInvoiceContext.put("statusId", "INVOICE_IN_PROCESS"); createInvoiceContext.put("currencyUomId", orderHeader.getString("currencyUom")); createInvoiceContext.put("userLogin", userLogin); // store the invoice first Map<String, Object> createInvoiceResult = dispatcher.runSync("createInvoice", createInvoiceContext); if (ServiceUtil.isError(createInvoiceResult)) { return ServiceUtil.returnError( UtilProperties.getMessage(resource, "AccountingErrorCreatingInvoiceFromOrder", locale), null, null, createInvoiceResult); } // call service, not direct entity op: delegator.create(invoice); invoiceId = (String) createInvoiceResult.get("invoiceId"); } // order roles to invoice roles List<GenericValue> orderRoles = orderHeader.getRelated("OrderRole", null, null, false); Map<String, Object> createInvoiceRoleContext = FastMap.newInstance(); createInvoiceRoleContext.put("invoiceId", invoiceId); createInvoiceRoleContext.put("userLogin", userLogin); for (GenericValue orderRole : orderRoles) { createInvoiceRoleContext.put("partyId", orderRole.getString("partyId")); createInvoiceRoleContext.put("roleTypeId", orderRole.getString("roleTypeId")); Map<String, Object> createInvoiceRoleResult = dispatcher.runSync("createInvoiceRole", createInvoiceRoleContext); if (ServiceUtil.isError(createInvoiceRoleResult)) { return ServiceUtil.returnError( UtilProperties.getMessage(resource, "AccountingErrorCreatingInvoiceFromOrder", locale), null, null, createInvoiceRoleResult); } } // order terms to invoice terms. // TODO: it might be nice to filter OrderTerms to only copy over financial terms. List<GenericValue> orderTerms = orh.getOrderTerms(); createInvoiceTerms(delegator, dispatcher, invoiceId, orderTerms, userLogin, locale); // billing accounts // List billingAccountTerms = null; // for billing accounts we will use related information if (billingAccount != null) { /* * jacopoc: billing account terms were already copied as order terms * when the order was created. // get the billing account terms billingAccountTerms = billingAccount.getRelated("BillingAccountTerm", null, null, false); // set the invoice terms as defined for the billing account createInvoiceTerms(delegator, dispatcher, invoiceId, billingAccountTerms, userLogin, locale); */ // set the invoice bill_to_customer from the billing account List<GenericValue> billToRoles = billingAccount.getRelated("BillingAccountRole", UtilMisc.toMap("roleTypeId", "BILL_TO_CUSTOMER"), null, false); for (GenericValue billToRole : billToRoles) { if (!(billToRole.getString("partyId").equals(billToCustomerPartyId))) { createInvoiceRoleContext = UtilMisc.toMap("invoiceId", invoiceId, "partyId", billToRole.get("partyId"), "roleTypeId", "BILL_TO_CUSTOMER", "userLogin", userLogin); Map<String, Object> createInvoiceRoleResult = dispatcher.runSync("createInvoiceRole", createInvoiceRoleContext); if (ServiceUtil.isError(createInvoiceRoleResult)) { return ServiceUtil.returnError( UtilProperties.getMessage(resource, "AccountingErrorCreatingInvoiceRoleFromOrder", locale), null, null, createInvoiceRoleResult); } } } // set the bill-to contact mech as the contact mech of the billing account if (UtilValidate.isNotEmpty(billingAccount.getString("contactMechId"))) { Map<String, Object> createBillToContactMechContext = UtilMisc.toMap("invoiceId", invoiceId, "contactMechId", billingAccount.getString("contactMechId"), "contactMechPurposeTypeId", "BILLING_LOCATION", "userLogin", userLogin); Map<String, Object> createBillToContactMechResult = dispatcher .runSync("createInvoiceContactMech", createBillToContactMechContext); if (ServiceUtil.isError(createBillToContactMechResult)) { return ServiceUtil.returnError( UtilProperties.getMessage(resource, "AccountingErrorCreatingInvoiceContactMechFromOrder", locale), null, null, createBillToContactMechResult); } } } else { List<GenericValue> billingLocations = orh.getBillingLocations(); if (UtilValidate.isNotEmpty(billingLocations)) { for (GenericValue ocm : billingLocations) { Map<String, Object> createBillToContactMechContext = UtilMisc.toMap("invoiceId", invoiceId, "contactMechId", ocm.getString("contactMechId"), "contactMechPurposeTypeId", "BILLING_LOCATION", "userLogin", userLogin); Map<String, Object> createBillToContactMechResult = dispatcher .runSync("createInvoiceContactMech", createBillToContactMechContext); if (ServiceUtil.isError(createBillToContactMechResult)) { return ServiceUtil.returnError( UtilProperties.getMessage(resource, "AccountingErrorCreatingInvoiceContactMechFromOrder", locale), null, null, createBillToContactMechResult); } } } else { Debug.logWarning("No billing locations found for order [" + orderId + "] and none were created for Invoice [" + invoiceId + "]", module); } } // get a list of the payment method types //DEJ20050705 doesn't appear to be used: List paymentPreferences = orderHeader.getRelated("OrderPaymentPreference", null, null, false); // create the bill-from (or pay-to) contact mech as the primary PAYMENT_LOCATION of the party from the store GenericValue payToAddress = null; if (invoiceType.equals("PURCHASE_INVOICE")) { // for purchase orders, the pay to address is the BILLING_LOCATION of the vendor GenericValue billFromVendor = orh.getPartyFromRole("BILL_FROM_VENDOR"); if (billFromVendor != null) { List<GenericValue> billingContactMechs = billFromVendor.getRelatedOne("Party", false) .getRelated("PartyContactMechPurpose", UtilMisc.toMap("contactMechPurposeTypeId", "BILLING_LOCATION"), null, false); if (UtilValidate.isNotEmpty(billingContactMechs)) { payToAddress = EntityUtil.getFirst(billingContactMechs); } } } else { // for sales orders, it is the payment address on file for the store payToAddress = PaymentWorker.getPaymentAddress(delegator, productStore.getString("payToPartyId")); } if (payToAddress != null) { Map<String, Object> createPayToContactMechContext = UtilMisc.toMap("invoiceId", invoiceId, "contactMechId", payToAddress.getString("contactMechId"), "contactMechPurposeTypeId", "PAYMENT_LOCATION", "userLogin", userLogin); Map<String, Object> createPayToContactMechResult = dispatcher.runSync("createInvoiceContactMech", createPayToContactMechContext); if (ServiceUtil.isError(createPayToContactMechResult)) { return ServiceUtil.returnError( UtilProperties.getMessage(resource, "AccountingErrorCreatingInvoiceContactMechFromOrder", locale), null, null, createPayToContactMechResult); } } // sequence for items - all OrderItems or InventoryReservations + all Adjustments int invoiceItemSeqNum = 1; String invoiceItemSeqId = UtilFormatOut.formatPaddedNumber(invoiceItemSeqNum, INVOICE_ITEM_SEQUENCE_ID_DIGITS); // create the item records for (GenericValue currentValue : billItems) { GenericValue itemIssuance = null; GenericValue orderItem = null; GenericValue shipmentReceipt = null; if ("ItemIssuance".equals(currentValue.getEntityName())) { itemIssuance = currentValue; } else if ("OrderItem".equals(currentValue.getEntityName())) { orderItem = currentValue; } else if ("ShipmentReceipt".equals(currentValue.getEntityName())) { shipmentReceipt = currentValue; } else { Debug.logError("Unexpected entity " + currentValue + " of type " + currentValue.getEntityName(), module); } if (orderItem == null && itemIssuance != null) { orderItem = itemIssuance.getRelatedOne("OrderItem", false); } else if ((orderItem == null) && (shipmentReceipt != null)) { orderItem = shipmentReceipt.getRelatedOne("OrderItem", false); } else if ((orderItem == null) && (itemIssuance == null) && (shipmentReceipt == null)) { Debug.logError( "Cannot create invoice when orderItem, itemIssuance, and shipmentReceipt are all null", module); return ServiceUtil.returnError(UtilProperties.getMessage(resource, "AccountingIllegalValuesPassedToCreateInvoiceService", locale)); } GenericValue product = null; if (orderItem.get("productId") != null) { product = orderItem.getRelatedOne("Product", false); } // get some quantities BigDecimal billingQuantity = null; if (itemIssuance != null) { billingQuantity = itemIssuance.getBigDecimal("quantity"); BigDecimal cancelQty = itemIssuance.getBigDecimal("cancelQuantity"); if (cancelQty == null) { cancelQty = ZERO; } billingQuantity = billingQuantity.subtract(cancelQty).setScale(DECIMALS, ROUNDING); } else if (shipmentReceipt != null) { billingQuantity = shipmentReceipt.getBigDecimal("quantityAccepted"); } else { BigDecimal orderedQuantity = OrderReadHelper.getOrderItemQuantity(orderItem); BigDecimal invoicedQuantity = OrderReadHelper.getOrderItemInvoicedQuantity(orderItem); billingQuantity = orderedQuantity.subtract(invoicedQuantity); if (billingQuantity.compareTo(ZERO) < 0) { billingQuantity = ZERO; } } if (billingQuantity == null) billingQuantity = ZERO; // check if shipping applies to this item. Shipping is calculated for sales invoices, not purchase invoices. boolean shippingApplies = false; if ((product != null) && (ProductWorker.shippingApplies(product)) && (invoiceType.equals("SALES_INVOICE"))) { shippingApplies = true; } BigDecimal billingAmount = orderItem.getBigDecimal("unitPrice").setScale(invoiceTypeDecimals, ROUNDING); Map<String, Object> createInvoiceItemContext = FastMap.newInstance(); createInvoiceItemContext.put("invoiceId", invoiceId); createInvoiceItemContext.put("invoiceItemSeqId", invoiceItemSeqId); createInvoiceItemContext.put("invoiceItemTypeId", getInvoiceItemType(delegator, (orderItem.getString("orderItemTypeId")), (product == null ? null : product.getString("productTypeId")), invoiceType, "INV_FPROD_ITEM")); createInvoiceItemContext.put("description", orderItem.get("itemDescription")); createInvoiceItemContext.put("quantity", billingQuantity); createInvoiceItemContext.put("amount", billingAmount); createInvoiceItemContext.put("productId", orderItem.get("productId")); createInvoiceItemContext.put("productFeatureId", orderItem.get("productFeatureId")); createInvoiceItemContext.put("overrideGlAccountId", orderItem.get("overrideGlAccountId")); //createInvoiceItemContext.put("uomId", ""); createInvoiceItemContext.put("userLogin", userLogin); String itemIssuanceId = null; if (itemIssuance != null && itemIssuance.get("inventoryItemId") != null) { itemIssuanceId = itemIssuance.getString("itemIssuanceId"); createInvoiceItemContext.put("inventoryItemId", itemIssuance.get("inventoryItemId")); } // similarly, tax only for purchase invoices if ((product != null) && (invoiceType.equals("SALES_INVOICE"))) { createInvoiceItemContext.put("taxableFlag", product.get("taxable")); } Map<String, Object> createInvoiceItemResult = dispatcher.runSync("createInvoiceItem", createInvoiceItemContext); if (ServiceUtil.isError(createInvoiceItemResult)) { return ServiceUtil .returnError( UtilProperties.getMessage(resource, "AccountingErrorCreatingInvoiceItemFromOrder", locale), null, null, createInvoiceItemResult); } // this item total BigDecimal thisAmount = billingAmount.multiply(billingQuantity).setScale(invoiceTypeDecimals, ROUNDING); // add to the ship amount only if it applies to this item if (shippingApplies) { invoiceShipProRateAmount = invoiceShipProRateAmount.add(thisAmount) .setScale(invoiceTypeDecimals, ROUNDING); } // increment the invoice subtotal invoiceSubTotal = invoiceSubTotal.add(thisAmount).setScale(100, ROUNDING); // increment the invoice quantity invoiceQuantity = invoiceQuantity.add(billingQuantity).setScale(invoiceTypeDecimals, ROUNDING); // create the OrderItemBilling record Map<String, Object> createOrderItemBillingContext = FastMap.newInstance(); createOrderItemBillingContext.put("invoiceId", invoiceId); createOrderItemBillingContext.put("invoiceItemSeqId", invoiceItemSeqId); createOrderItemBillingContext.put("orderId", orderItem.get("orderId")); createOrderItemBillingContext.put("orderItemSeqId", orderItem.get("orderItemSeqId")); createOrderItemBillingContext.put("itemIssuanceId", itemIssuanceId); createOrderItemBillingContext.put("quantity", billingQuantity); createOrderItemBillingContext.put("amount", billingAmount); createOrderItemBillingContext.put("userLogin", userLogin); if ((shipmentReceipt != null) && (shipmentReceipt.getString("receiptId") != null)) { createOrderItemBillingContext.put("shipmentReceiptId", shipmentReceipt.getString("receiptId")); } Map<String, Object> createOrderItemBillingResult = dispatcher.runSync("createOrderItemBilling", createOrderItemBillingContext); if (ServiceUtil.isError(createOrderItemBillingResult)) { return ServiceUtil .returnError( UtilProperties.getMessage(resource, "AccountingErrorCreatingOrderItemBillingFromOrder", locale), null, null, createOrderItemBillingResult); } if ("ItemIssuance".equals(currentValue.getEntityName())) { List<GenericValue> shipmentItemBillings = EntityQuery.use(delegator).from("ShipmentItemBilling") .where("shipmentId", currentValue.get("shipmentId"), "shipmentItemSeqId", currentValue.get("shipmentItemSeqId")) .queryList(); if (UtilValidate.isEmpty(shipmentItemBillings)) { // create the ShipmentItemBilling record GenericValue shipmentItemBilling = delegator.makeValue("ShipmentItemBilling", UtilMisc.toMap("invoiceId", invoiceId, "invoiceItemSeqId", invoiceItemSeqId)); shipmentItemBilling.put("shipmentId", currentValue.get("shipmentId")); shipmentItemBilling.put("shipmentItemSeqId", currentValue.get("shipmentItemSeqId")); shipmentItemBilling.create(); } } String parentInvoiceItemSeqId = invoiceItemSeqId; // increment the counter invoiceItemSeqNum++; invoiceItemSeqId = UtilFormatOut.formatPaddedNumber(invoiceItemSeqNum, INVOICE_ITEM_SEQUENCE_ID_DIGITS); // Get the original order item from the DB, in case the quantity has been overridden GenericValue originalOrderItem = EntityQuery.use(delegator).from("OrderItem") .where("orderId", orderId, "orderItemSeqId", orderItem.get("orderItemSeqId")).queryOne(); // create the item adjustment as line items List<GenericValue> itemAdjustments = OrderReadHelper.getOrderItemAdjustmentList(orderItem, orh.getAdjustments()); for (GenericValue adj : itemAdjustments) { // Check against OrderAdjustmentBilling to see how much of this adjustment has already been invoiced BigDecimal adjAlreadyInvoicedAmount = null; try { Map<String, Object> checkResult = dispatcher.runSync("calculateInvoicedAdjustmentTotal", UtilMisc.toMap("orderAdjustment", adj)); adjAlreadyInvoicedAmount = (BigDecimal) checkResult.get("invoicedTotal"); } catch (GenericServiceException e) { Debug.logError(e, "Accounting trouble calling calculateInvoicedAdjustmentTotal service", module); return ServiceUtil.returnError(UtilProperties.getMessage(resource, "AccountingTroubleCallingCalculateInvoicedAdjustmentTotalService", locale)); } // If the absolute invoiced amount >= the abs of the adjustment amount, the full amount has already been invoiced, // so skip this adjustment if (adj.get("amount") == null) { // JLR 17/4/7 : fix a bug coming from POS in case of use of a discount (on item(s) or sale, item(s) here) and a cash amount higher than total (hence issuing change) continue; } if (adjAlreadyInvoicedAmount.abs().compareTo( adj.getBigDecimal("amount").setScale(invoiceTypeDecimals, ROUNDING).abs()) > 0) { continue; } BigDecimal originalOrderItemQuantity = OrderReadHelper.getOrderItemQuantity(originalOrderItem); BigDecimal amount = ZERO; if (originalOrderItemQuantity.signum() != 0) { if (adj.get("amount") != null) { // pro-rate the amount // set decimals = 100 means we don't round this intermediate value, which is very important amount = adj.getBigDecimal("amount").divide(originalOrderItemQuantity, 100, ROUNDING); amount = amount.multiply(billingQuantity); // Tax needs to be rounded differently from other order adjustments if (adj.getString("orderAdjustmentTypeId").equals("SALES_TAX")) { amount = amount.setScale(TAX_DECIMALS, TAX_ROUNDING); } else { amount = amount.setScale(invoiceTypeDecimals, ROUNDING); } } else if (adj.get("sourcePercentage") != null) { // pro-rate the amount // set decimals = 100 means we don't round this intermediate value, which is very important BigDecimal percent = adj.getBigDecimal("sourcePercentage"); percent = percent.divide(new BigDecimal(100), 100, ROUNDING); amount = billingAmount.multiply(percent); amount = amount.divide(originalOrderItemQuantity, 100, ROUNDING); amount = amount.multiply(billingQuantity); amount = amount.setScale(invoiceTypeDecimals, ROUNDING); } } if (amount.signum() != 0) { Map<String, Object> createInvoiceItemAdjContext = FastMap.newInstance(); createInvoiceItemAdjContext.put("invoiceId", invoiceId); createInvoiceItemAdjContext.put("invoiceItemSeqId", invoiceItemSeqId); createInvoiceItemAdjContext.put("invoiceItemTypeId", getInvoiceItemType(delegator, adj.getString("orderAdjustmentTypeId"), null, invoiceType, "INVOICE_ITM_ADJ")); createInvoiceItemAdjContext.put("quantity", BigDecimal.ONE); createInvoiceItemAdjContext.put("amount", amount); createInvoiceItemAdjContext.put("productId", orderItem.get("productId")); createInvoiceItemAdjContext.put("productFeatureId", orderItem.get("productFeatureId")); createInvoiceItemAdjContext.put("overrideGlAccountId", adj.get("overrideGlAccountId")); createInvoiceItemAdjContext.put("parentInvoiceId", invoiceId); createInvoiceItemAdjContext.put("parentInvoiceItemSeqId", parentInvoiceItemSeqId); //createInvoiceItemAdjContext.put("uomId", ""); createInvoiceItemAdjContext.put("userLogin", userLogin); createInvoiceItemAdjContext.put("taxAuthPartyId", adj.get("taxAuthPartyId")); createInvoiceItemAdjContext.put("taxAuthGeoId", adj.get("taxAuthGeoId")); createInvoiceItemAdjContext.put("taxAuthorityRateSeqId", adj.get("taxAuthorityRateSeqId")); // some adjustments fill out the comments field instead String description = (UtilValidate.isEmpty(adj.getString("description")) ? adj.getString("comments") : adj.getString("description")); createInvoiceItemAdjContext.put("description", description); // invoice items for sales tax are not taxable themselves // TODO: This is not an ideal solution. Instead, we need to use OrderAdjustment.includeInTax when it is implemented if (!(adj.getString("orderAdjustmentTypeId").equals("SALES_TAX"))) { createInvoiceItemAdjContext.put("taxableFlag", product.get("taxable")); } // If the OrderAdjustment is associated to a ProductPromo, // and the field ProductPromo.overrideOrgPartyId is set, // copy the value to InvoiceItem.overrideOrgPartyId: this // represent an organization override for the payToPartyId if (UtilValidate.isNotEmpty(adj.getString("productPromoId"))) { try { GenericValue productPromo = adj.getRelatedOne("ProductPromo", false); if (UtilValidate.isNotEmpty(productPromo.getString("overrideOrgPartyId"))) { createInvoiceItemAdjContext.put("overrideOrgPartyId", productPromo.getString("overrideOrgPartyId")); } } catch (GenericEntityException e) { Debug.logError(e, "Error looking up ProductPromo with id [" + adj.getString("productPromoId") + "]", module); } } Map<String, Object> createInvoiceItemAdjResult = dispatcher.runSync("createInvoiceItem", createInvoiceItemAdjContext); if (ServiceUtil.isError(createInvoiceItemAdjResult)) { return ServiceUtil.returnError( UtilProperties.getMessage(resource, "AccountingErrorCreatingInvoiceItemFromOrder", locale), null, null, createInvoiceItemAdjResult); } // Create the OrderAdjustmentBilling record Map<String, Object> createOrderAdjustmentBillingContext = FastMap.newInstance(); createOrderAdjustmentBillingContext.put("orderAdjustmentId", adj.getString("orderAdjustmentId")); createOrderAdjustmentBillingContext.put("invoiceId", invoiceId); createOrderAdjustmentBillingContext.put("invoiceItemSeqId", invoiceItemSeqId); createOrderAdjustmentBillingContext.put("amount", amount); createOrderAdjustmentBillingContext.put("userLogin", userLogin); Map<String, Object> createOrderAdjustmentBillingResult = dispatcher .runSync("createOrderAdjustmentBilling", createOrderAdjustmentBillingContext); if (ServiceUtil.isError(createOrderAdjustmentBillingResult)) { return ServiceUtil.returnError( UtilProperties.getMessage(resource, "AccountingErrorCreatingOrderAdjustmentBillingFromOrder", locale), null, null, createOrderAdjustmentBillingContext); } // this adjustment amount BigDecimal thisAdjAmount = amount; // adjustments only apply to totals when they are not tax or shipping adjustments if (!"SALES_TAX".equals(adj.getString("orderAdjustmentTypeId")) && !"SHIPPING_ADJUSTMENT".equals(adj.getString("orderAdjustmentTypeId"))) { // increment the invoice subtotal invoiceSubTotal = invoiceSubTotal.add(thisAdjAmount).setScale(100, ROUNDING); // add to the ship amount only if it applies to this item if (shippingApplies) { invoiceShipProRateAmount = invoiceShipProRateAmount.add(thisAdjAmount) .setScale(invoiceTypeDecimals, ROUNDING); } } // increment the counter invoiceItemSeqNum++; invoiceItemSeqId = UtilFormatOut.formatPaddedNumber(invoiceItemSeqNum, INVOICE_ITEM_SEQUENCE_ID_DIGITS); } } } // create header adjustments as line items -- always to tax/shipping last Map<GenericValue, BigDecimal> shipAdjustments = FastMap.newInstance(); Map<GenericValue, BigDecimal> taxAdjustments = FastMap.newInstance(); List<GenericValue> headerAdjustments = orh.getOrderHeaderAdjustments(); for (GenericValue adj : headerAdjustments) { // Check against OrderAdjustmentBilling to see how much of this adjustment has already been invoiced BigDecimal adjAlreadyInvoicedAmount = null; try { Map<String, Object> checkResult = dispatcher.runSync("calculateInvoicedAdjustmentTotal", UtilMisc.toMap("orderAdjustment", adj)); adjAlreadyInvoicedAmount = ((BigDecimal) checkResult.get("invoicedTotal")) .setScale(invoiceTypeDecimals, ROUNDING); } catch (GenericServiceException e) { Debug.logError(e, "Accounting trouble calling calculateInvoicedAdjustmentTotal service", module); return ServiceUtil.returnError(UtilProperties.getMessage(resource, "AccountingTroubleCallingCalculateInvoicedAdjustmentTotalService", locale)); } // If the absolute invoiced amount >= the abs of the adjustment amount, the full amount has already been invoiced, // so skip this adjustment if (null == adj.get("amount")) { // JLR 17/4/7 : fix a bug coming from POS in case of use of a discount (on item(s) or sale, sale here) and a cash amount higher than total (hence issuing change) continue; } if (adjAlreadyInvoicedAmount.abs() .compareTo(adj.getBigDecimal("amount").setScale(invoiceTypeDecimals, ROUNDING).abs()) > 0) { continue; } if ("SHIPPING_CHARGES".equals(adj.getString("orderAdjustmentTypeId"))) { shipAdjustments.put(adj, adjAlreadyInvoicedAmount); } else if ("SALES_TAX".equals(adj.getString("orderAdjustmentTypeId"))) { taxAdjustments.put(adj, adjAlreadyInvoicedAmount); } else { // these will effect the shipping pro-rate (unless commented) // other adjustment type calcHeaderAdj(delegator, adj, invoiceType, invoiceId, invoiceItemSeqId, orderSubTotal, invoiceSubTotal, adj.getBigDecimal("amount").setScale(invoiceTypeDecimals, ROUNDING), invoiceTypeDecimals, ROUNDING, userLogin, dispatcher, locale); // invoiceShipProRateAmount += adjAmount; // do adjustments compound or are they based off subtotal? Here we will (unless commented) // invoiceSubTotal += adjAmount; // increment the counter invoiceItemSeqNum++; invoiceItemSeqId = UtilFormatOut.formatPaddedNumber(invoiceItemSeqNum, INVOICE_ITEM_SEQUENCE_ID_DIGITS); } } // next do the shipping adjustments. Note that we do not want to add these to the invoiceSubTotal or orderSubTotal for pro-rating tax later, as that would cause // numerator/denominator problems when the shipping is not pro-rated but rather charged all on the first invoice for (GenericValue adj : shipAdjustments.keySet()) { BigDecimal adjAlreadyInvoicedAmount = shipAdjustments.get(adj); if ("N".equalsIgnoreCase(prorateShipping)) { // Set the divisor and multiplier to 1 to avoid prorating BigDecimal divisor = BigDecimal.ONE; BigDecimal multiplier = BigDecimal.ONE; // The base amount in this case is the adjustment amount minus the total already invoiced for that adjustment, since // it won't be prorated BigDecimal baseAmount = adj.getBigDecimal("amount").setScale(invoiceTypeDecimals, ROUNDING) .subtract(adjAlreadyInvoicedAmount); calcHeaderAdj(delegator, adj, invoiceType, invoiceId, invoiceItemSeqId, divisor, multiplier, baseAmount, invoiceTypeDecimals, ROUNDING, userLogin, dispatcher, locale); } else { // Pro-rate the shipping amount based on shippable information BigDecimal divisor = shippableAmount; BigDecimal multiplier = invoiceShipProRateAmount; // The base amount in this case is the adjustment amount, since we want to prorate based on the full amount BigDecimal baseAmount = adj.getBigDecimal("amount").setScale(invoiceTypeDecimals, ROUNDING); calcHeaderAdj(delegator, adj, invoiceType, invoiceId, invoiceItemSeqId, divisor, multiplier, baseAmount, invoiceTypeDecimals, ROUNDING, userLogin, dispatcher, locale); } // Increment the counter invoiceItemSeqNum++; invoiceItemSeqId = UtilFormatOut.formatPaddedNumber(invoiceItemSeqNum, INVOICE_ITEM_SEQUENCE_ID_DIGITS); } // last do the tax adjustments String prorateTaxes = productStore != null ? productStore.getString("prorateTaxes") : "Y"; if (prorateTaxes == null) { prorateTaxes = "Y"; } for (Map.Entry<GenericValue, BigDecimal> entry : taxAdjustments.entrySet()) { GenericValue adj = entry.getKey(); BigDecimal adjAlreadyInvoicedAmount = entry.getValue(); BigDecimal adjAmount = null; if ("N".equalsIgnoreCase(prorateTaxes)) { // Set the divisor and multiplier to 1 to avoid prorating BigDecimal divisor = BigDecimal.ONE; BigDecimal multiplier = BigDecimal.ONE; // The base amount in this case is the adjustment amount minus the total already invoiced for that adjustment, since // it won't be prorated BigDecimal baseAmount = adj.getBigDecimal("amount").setScale(TAX_DECIMALS, TAX_ROUNDING) .subtract(adjAlreadyInvoicedAmount); adjAmount = calcHeaderAdj(delegator, adj, invoiceType, invoiceId, invoiceItemSeqId, divisor, multiplier, baseAmount, TAX_DECIMALS, TAX_ROUNDING, userLogin, dispatcher, locale); } else { // Pro-rate the tax amount based on shippable information BigDecimal divisor = orderSubTotal; BigDecimal multiplier = invoiceSubTotal; // The base amount in this case is the adjustment amount, since we want to prorate based on the full amount BigDecimal baseAmount = adj.getBigDecimal("amount"); adjAmount = calcHeaderAdj(delegator, adj, invoiceType, invoiceId, invoiceItemSeqId, divisor, multiplier, baseAmount, TAX_DECIMALS, TAX_ROUNDING, userLogin, dispatcher, locale); } invoiceSubTotal = invoiceSubTotal.add(adjAmount).setScale(invoiceTypeDecimals, ROUNDING); // Increment the counter invoiceItemSeqNum++; invoiceItemSeqId = UtilFormatOut.formatPaddedNumber(invoiceItemSeqNum, INVOICE_ITEM_SEQUENCE_ID_DIGITS); } // check for previous order payments List<GenericValue> orderPaymentPrefs = EntityQuery.use(delegator).from("OrderPaymentPreference").where( EntityCondition.makeCondition("orderId", EntityOperator.EQUALS, orderId), EntityCondition.makeCondition("statusId", EntityOperator.NOT_EQUAL, "PAYMENT_CANCELLED")) .queryList(); List<GenericValue> currentPayments = FastList.newInstance(); for (GenericValue paymentPref : orderPaymentPrefs) { List<GenericValue> payments = paymentPref.getRelated("Payment", null, null, false); currentPayments.addAll(payments); } // apply these payments to the invoice if they have any remaining amount to apply for (GenericValue payment : currentPayments) { if ("PMNT_VOID".equals(payment.getString("statusId")) || "PMNT_CANCELLED".equals(payment.getString("statusId"))) { continue; } BigDecimal notApplied = PaymentWorker.getPaymentNotApplied(payment); if (notApplied.signum() > 0) { Map<String, Object> appl = FastMap.newInstance(); appl.put("paymentId", payment.get("paymentId")); appl.put("invoiceId", invoiceId); appl.put("billingAccountId", billingAccountId); appl.put("amountApplied", notApplied); appl.put("userLogin", userLogin); Map<String, Object> createPayApplResult = dispatcher.runSync("createPaymentApplication", appl); if (ServiceUtil.isError(createPayApplResult)) { return ServiceUtil .returnError( UtilProperties.getMessage(resource, "AccountingErrorCreatingInvoiceFromOrder", locale), null, null, createPayApplResult); } } } // Should all be in place now. Depending on the ProductStore.autoApproveInvoice setting, set status to INVOICE_READY (unless it's a purchase invoice, which we set to INVOICE_IN_PROCESS) String autoApproveInvoice = productStore != null ? productStore.getString("autoApproveInvoice") : "Y"; if (!"N".equals(autoApproveInvoice)) { String nextStatusId = "PURCHASE_INVOICE".equals(invoiceType) ? "INVOICE_IN_PROCESS" : "INVOICE_READY"; Map<String, Object> setInvoiceStatusResult = dispatcher.runSync("setInvoiceStatus", UtilMisc.<String, Object>toMap("invoiceId", invoiceId, "statusId", nextStatusId, "userLogin", userLogin)); if (ServiceUtil.isError(setInvoiceStatusResult)) { return ServiceUtil.returnError( UtilProperties.getMessage(resource, "AccountingErrorCreatingInvoiceFromOrder", locale), null, null, setInvoiceStatusResult); } } Map<String, Object> resp = ServiceUtil.returnSuccess(); resp.put("invoiceId", invoiceId); resp.put("invoiceTypeId", invoiceType); return resp; } catch (GenericEntityException e) { Debug.logError(e, "Entity/data problem creating invoice from order items: " + e.toString(), module); return ServiceUtil.returnError( UtilProperties.getMessage(resource, "AccountingEntityDataProblemCreatingInvoiceFromOrderItems", UtilMisc.toMap("reason", e.toString()), locale)); } catch (GenericServiceException e) { Debug.logError(e, "Service/other problem creating invoice from order items: " + e.toString(), module); return ServiceUtil.returnError(UtilProperties.getMessage(resource, "AccountingServiceOtherProblemCreatingInvoiceFromOrderItems", UtilMisc.toMap("reason", e.toString()), locale)); } }
From source file:org.apache.ofbiz.accounting.invoice.InvoiceServices.java
public static Map<String, Object> createInvoiceForOrder(DispatchContext dctx, Map<String, Object> context) { Delegator delegator = dctx.getDelegator(); LocalDispatcher dispatcher = dctx.getDispatcher(); GenericValue userLogin = (GenericValue) context.get("userLogin"); Locale locale = (Locale) context.get("locale"); if (DECIMALS == -1 || ROUNDING == -1) { return ServiceUtil.returnError( UtilProperties.getMessage(resource, "AccountingAritmeticPropertiesNotConfigured", locale)); }//from www. ja v a2 s . c o m String orderId = (String) context.get("orderId"); List<GenericValue> billItems = UtilGenerics.checkList(context.get("billItems")); String invoiceId = (String) context.get("invoiceId"); if (UtilValidate.isEmpty(billItems)) { Debug.logVerbose("No order items to invoice; not creating invoice; returning success", module); return ServiceUtil .returnSuccess(UtilProperties.getMessage(resource, "AccountingNoOrderItemsToInvoice", locale)); } try { GenericValue orderHeader = EntityQuery.use(delegator).from("OrderHeader").where("orderId", orderId) .queryOne(); if (orderHeader == null) { return ServiceUtil .returnError(UtilProperties.getMessage(resource, "AccountingNoOrderHeader", locale)); } // figure out the invoice type String invoiceType = null; String orderType = orderHeader.getString("orderTypeId"); if (orderType.equals("SALES_ORDER")) { invoiceType = "SALES_INVOICE"; } else if (orderType.equals("PURCHASE_ORDER")) { invoiceType = "PURCHASE_INVOICE"; } // Set the precision depending on the type of invoice int invoiceTypeDecimals = UtilNumber.getBigDecimalScale("invoice." + invoiceType + ".decimals"); if (invoiceTypeDecimals == -1) invoiceTypeDecimals = DECIMALS; // Make an order read helper from the order OrderReadHelper orh = new OrderReadHelper(orderHeader); // get the product store GenericValue productStore = orh.getProductStore(); // get the shipping adjustment mode (Y = Pro-Rate; N = First-Invoice) String prorateShipping = productStore != null ? productStore.getString("prorateShipping") : "Y"; if (prorateShipping == null) { prorateShipping = "Y"; } // get the billing parties String billToCustomerPartyId = orh.getBillToParty().getString("partyId"); String billFromVendorPartyId = orh.getBillFromParty().getString("partyId"); // get some price totals BigDecimal shippableAmount = orh.getShippableTotal(null); BigDecimal shippableQuantity = orh.getShippableQuantity(null); BigDecimal orderSubTotal = orh.getOrderItemsSubTotal(); BigDecimal orderQuantity = orh.getTotalOrderItemsQuantity(); // these variables are for pro-rating order amounts across invoices, so they should not be rounded off for maximum accuracy BigDecimal invoiceShipProRateAmount = ZERO; BigDecimal invoiceShippableQuantity = ZERO; BigDecimal invoiceSubTotal = ZERO; BigDecimal invoiceQuantity = ZERO; GenericValue billingAccount = orderHeader.getRelatedOne("BillingAccount", false); String billingAccountId = billingAccount != null ? billingAccount.getString("billingAccountId") : null; Timestamp invoiceDate = (Timestamp) context.get("eventDate"); if (UtilValidate.isEmpty(invoiceDate)) { // TODO: ideally this should be the same time as when a shipment is sent and be passed in as a parameter invoiceDate = UtilDateTime.nowTimestamp(); } // TODO: perhaps consider billing account net days term as well? Long orderTermNetDays = orh.getOrderTermNetDays(); Timestamp dueDate = null; if (orderTermNetDays != null) { dueDate = UtilDateTime.getDayEnd(invoiceDate, orderTermNetDays); } // create the invoice record if (UtilValidate.isEmpty(invoiceId)) { Map<String, Object> createInvoiceContext = new HashMap<String, Object>(); createInvoiceContext.put("partyId", billToCustomerPartyId); createInvoiceContext.put("partyIdFrom", billFromVendorPartyId); createInvoiceContext.put("billingAccountId", billingAccountId); createInvoiceContext.put("invoiceDate", invoiceDate); createInvoiceContext.put("dueDate", dueDate); createInvoiceContext.put("invoiceTypeId", invoiceType); // start with INVOICE_IN_PROCESS, in the INVOICE_READY we can't change the invoice (or shouldn't be able to...) createInvoiceContext.put("statusId", "INVOICE_IN_PROCESS"); createInvoiceContext.put("currencyUomId", orderHeader.getString("currencyUom")); createInvoiceContext.put("userLogin", userLogin); // store the invoice first Map<String, Object> createInvoiceResult = dispatcher.runSync("createInvoice", createInvoiceContext); if (ServiceUtil.isError(createInvoiceResult)) { return ServiceUtil.returnError( UtilProperties.getMessage(resource, "AccountingErrorCreatingInvoiceFromOrder", locale), null, null, createInvoiceResult); } // call service, not direct entity op: delegator.create(invoice); invoiceId = (String) createInvoiceResult.get("invoiceId"); } // order roles to invoice roles List<GenericValue> orderRoles = orderHeader.getRelated("OrderRole", null, null, false); Map<String, Object> createInvoiceRoleContext = new HashMap<String, Object>(); createInvoiceRoleContext.put("invoiceId", invoiceId); createInvoiceRoleContext.put("userLogin", userLogin); for (GenericValue orderRole : orderRoles) { createInvoiceRoleContext.put("partyId", orderRole.getString("partyId")); createInvoiceRoleContext.put("roleTypeId", orderRole.getString("roleTypeId")); Map<String, Object> createInvoiceRoleResult = dispatcher.runSync("createInvoiceRole", createInvoiceRoleContext); if (ServiceUtil.isError(createInvoiceRoleResult)) { return ServiceUtil.returnError( UtilProperties.getMessage(resource, "AccountingErrorCreatingInvoiceFromOrder", locale), null, null, createInvoiceRoleResult); } } // order terms to invoice terms. // TODO: it might be nice to filter OrderTerms to only copy over financial terms. List<GenericValue> orderTerms = orh.getOrderTerms(); createInvoiceTerms(delegator, dispatcher, invoiceId, orderTerms, userLogin, locale); // billing accounts // List billingAccountTerms = null; // for billing accounts we will use related information if (billingAccount != null) { /* * jacopoc: billing account terms were already copied as order terms * when the order was created. // get the billing account terms billingAccountTerms = billingAccount.getRelated("BillingAccountTerm", null, null, false); // set the invoice terms as defined for the billing account createInvoiceTerms(delegator, dispatcher, invoiceId, billingAccountTerms, userLogin, locale); */ // set the invoice bill_to_customer from the billing account List<GenericValue> billToRoles = billingAccount.getRelated("BillingAccountRole", UtilMisc.toMap("roleTypeId", "BILL_TO_CUSTOMER"), null, false); for (GenericValue billToRole : billToRoles) { if (!(billToRole.getString("partyId").equals(billToCustomerPartyId))) { createInvoiceRoleContext = UtilMisc.toMap("invoiceId", invoiceId, "partyId", billToRole.get("partyId"), "roleTypeId", "BILL_TO_CUSTOMER", "userLogin", userLogin); Map<String, Object> createInvoiceRoleResult = dispatcher.runSync("createInvoiceRole", createInvoiceRoleContext); if (ServiceUtil.isError(createInvoiceRoleResult)) { return ServiceUtil.returnError( UtilProperties.getMessage(resource, "AccountingErrorCreatingInvoiceRoleFromOrder", locale), null, null, createInvoiceRoleResult); } } } // set the bill-to contact mech as the contact mech of the billing account if (UtilValidate.isNotEmpty(billingAccount.getString("contactMechId"))) { Map<String, Object> createBillToContactMechContext = UtilMisc.toMap("invoiceId", invoiceId, "contactMechId", billingAccount.getString("contactMechId"), "contactMechPurposeTypeId", "BILLING_LOCATION", "userLogin", userLogin); Map<String, Object> createBillToContactMechResult = dispatcher .runSync("createInvoiceContactMech", createBillToContactMechContext); if (ServiceUtil.isError(createBillToContactMechResult)) { return ServiceUtil.returnError( UtilProperties.getMessage(resource, "AccountingErrorCreatingInvoiceContactMechFromOrder", locale), null, null, createBillToContactMechResult); } } } else { List<GenericValue> billingLocations = orh.getBillingLocations(); if (UtilValidate.isNotEmpty(billingLocations)) { for (GenericValue ocm : billingLocations) { Map<String, Object> createBillToContactMechContext = UtilMisc.toMap("invoiceId", invoiceId, "contactMechId", ocm.getString("contactMechId"), "contactMechPurposeTypeId", "BILLING_LOCATION", "userLogin", userLogin); Map<String, Object> createBillToContactMechResult = dispatcher .runSync("createInvoiceContactMech", createBillToContactMechContext); if (ServiceUtil.isError(createBillToContactMechResult)) { return ServiceUtil.returnError( UtilProperties.getMessage(resource, "AccountingErrorCreatingInvoiceContactMechFromOrder", locale), null, null, createBillToContactMechResult); } } } else { Debug.logWarning("No billing locations found for order [" + orderId + "] and none were created for Invoice [" + invoiceId + "]", module); } } // get a list of the payment method types //DEJ20050705 doesn't appear to be used: List paymentPreferences = orderHeader.getRelated("OrderPaymentPreference", null, null, false); // create the bill-from (or pay-to) contact mech as the primary PAYMENT_LOCATION of the party from the store GenericValue payToAddress = null; if (invoiceType.equals("PURCHASE_INVOICE")) { // for purchase orders, the pay to address is the BILLING_LOCATION of the vendor GenericValue billFromVendor = orh.getPartyFromRole("BILL_FROM_VENDOR"); if (billFromVendor != null) { List<GenericValue> billingContactMechs = billFromVendor.getRelatedOne("Party", false) .getRelated("PartyContactMechPurpose", UtilMisc.toMap("contactMechPurposeTypeId", "BILLING_LOCATION"), null, false); if (UtilValidate.isNotEmpty(billingContactMechs)) { payToAddress = EntityUtil.getFirst(billingContactMechs); } } } else { // for sales orders, it is the payment address on file for the store payToAddress = PaymentWorker.getPaymentAddress(delegator, productStore.getString("payToPartyId")); } if (payToAddress != null) { Map<String, Object> createPayToContactMechContext = UtilMisc.toMap("invoiceId", invoiceId, "contactMechId", payToAddress.getString("contactMechId"), "contactMechPurposeTypeId", "PAYMENT_LOCATION", "userLogin", userLogin); Map<String, Object> createPayToContactMechResult = dispatcher.runSync("createInvoiceContactMech", createPayToContactMechContext); if (ServiceUtil.isError(createPayToContactMechResult)) { return ServiceUtil.returnError( UtilProperties.getMessage(resource, "AccountingErrorCreatingInvoiceContactMechFromOrder", locale), null, null, createPayToContactMechResult); } } // sequence for items - all OrderItems or InventoryReservations + all Adjustments int invoiceItemSeqNum = 1; String invoiceItemSeqId = UtilFormatOut.formatPaddedNumber(invoiceItemSeqNum, INVOICE_ITEM_SEQUENCE_ID_DIGITS); // create the item records for (GenericValue currentValue : billItems) { GenericValue itemIssuance = null; GenericValue orderItem = null; GenericValue shipmentReceipt = null; if ("ItemIssuance".equals(currentValue.getEntityName())) { itemIssuance = currentValue; } else if ("OrderItem".equals(currentValue.getEntityName())) { orderItem = currentValue; } else if ("ShipmentReceipt".equals(currentValue.getEntityName())) { shipmentReceipt = currentValue; } else { Debug.logError("Unexpected entity " + currentValue + " of type " + currentValue.getEntityName(), module); } if (orderItem == null && itemIssuance != null) { orderItem = itemIssuance.getRelatedOne("OrderItem", false); } else if ((orderItem == null) && (shipmentReceipt != null)) { orderItem = shipmentReceipt.getRelatedOne("OrderItem", false); } else if ((orderItem == null) && (itemIssuance == null) && (shipmentReceipt == null)) { Debug.logError( "Cannot create invoice when orderItem, itemIssuance, and shipmentReceipt are all null", module); return ServiceUtil.returnError(UtilProperties.getMessage(resource, "AccountingIllegalValuesPassedToCreateInvoiceService", locale)); } GenericValue product = null; if (orderItem.get("productId") != null) { product = orderItem.getRelatedOne("Product", false); } // get some quantities BigDecimal billingQuantity = null; if (itemIssuance != null) { billingQuantity = itemIssuance.getBigDecimal("quantity"); BigDecimal cancelQty = itemIssuance.getBigDecimal("cancelQuantity"); if (cancelQty == null) { cancelQty = ZERO; } billingQuantity = billingQuantity.subtract(cancelQty).setScale(DECIMALS, ROUNDING); } else if (shipmentReceipt != null) { billingQuantity = shipmentReceipt.getBigDecimal("quantityAccepted"); } else { BigDecimal orderedQuantity = OrderReadHelper.getOrderItemQuantity(orderItem); BigDecimal invoicedQuantity = OrderReadHelper.getOrderItemInvoicedQuantity(orderItem); billingQuantity = orderedQuantity.subtract(invoicedQuantity); if (billingQuantity.compareTo(ZERO) < 0) { billingQuantity = ZERO; } } if (billingQuantity == null) billingQuantity = ZERO; // check if shipping applies to this item. Shipping is calculated for sales invoices, not purchase invoices. boolean shippingApplies = false; if ((product != null) && (ProductWorker.shippingApplies(product)) && (invoiceType.equals("SALES_INVOICE"))) { shippingApplies = true; } BigDecimal billingAmount = BigDecimal.ZERO; GenericValue OrderAdjustment = EntityUtil.getFirst(orderItem.getRelated("OrderAdjustment", UtilMisc.toMap("orderAdjustmentTypeId", "VAT_TAX"), null, false)); /* Apply formula to get actual product price to set amount in invoice item Formula is: productPrice = (productPriceWithTax.multiply(100)) / (orderAdj sourcePercentage + 100)) product price = (43*100) / (20+100) = 35.83 (Here product price is 43 with VAT) */ if (UtilValidate.isNotEmpty(OrderAdjustment) && (OrderAdjustment.getBigDecimal("amount").signum() == 0) && UtilValidate.isNotEmpty(OrderAdjustment.getBigDecimal("amountAlreadyIncluded")) && OrderAdjustment.getBigDecimal("amountAlreadyIncluded").signum() != 0) { BigDecimal sourcePercentageTotal = OrderAdjustment.getBigDecimal("sourcePercentage") .add(new BigDecimal(100)); billingAmount = orderItem.getBigDecimal("unitPrice") .divide(sourcePercentageTotal, 100, ROUNDING).multiply(new BigDecimal(100)) .setScale(invoiceTypeDecimals, ROUNDING); } else { billingAmount = orderItem.getBigDecimal("unitPrice").setScale(invoiceTypeDecimals, ROUNDING); } Map<String, Object> createInvoiceItemContext = new HashMap<String, Object>(); createInvoiceItemContext.put("invoiceId", invoiceId); createInvoiceItemContext.put("invoiceItemSeqId", invoiceItemSeqId); createInvoiceItemContext.put("invoiceItemTypeId", getInvoiceItemType(delegator, (orderItem.getString("orderItemTypeId")), (product == null ? null : product.getString("productTypeId")), invoiceType, "INV_FPROD_ITEM")); createInvoiceItemContext.put("description", orderItem.get("itemDescription")); createInvoiceItemContext.put("quantity", billingQuantity); createInvoiceItemContext.put("amount", billingAmount); createInvoiceItemContext.put("productId", orderItem.get("productId")); createInvoiceItemContext.put("productFeatureId", orderItem.get("productFeatureId")); createInvoiceItemContext.put("overrideGlAccountId", orderItem.get("overrideGlAccountId")); createInvoiceItemContext.put("userLogin", userLogin); String itemIssuanceId = null; if (itemIssuance != null && itemIssuance.get("inventoryItemId") != null) { itemIssuanceId = itemIssuance.getString("itemIssuanceId"); createInvoiceItemContext.put("inventoryItemId", itemIssuance.get("inventoryItemId")); } // similarly, tax only for purchase invoices if ((product != null) && (invoiceType.equals("SALES_INVOICE"))) { createInvoiceItemContext.put("taxableFlag", product.get("taxable")); } Map<String, Object> createInvoiceItemResult = dispatcher.runSync("createInvoiceItem", createInvoiceItemContext); if (ServiceUtil.isError(createInvoiceItemResult)) { return ServiceUtil .returnError( UtilProperties.getMessage(resource, "AccountingErrorCreatingInvoiceItemFromOrder", locale), null, null, createInvoiceItemResult); } // this item total BigDecimal thisAmount = billingAmount.multiply(billingQuantity).setScale(invoiceTypeDecimals, ROUNDING); // add to the ship amount only if it applies to this item if (shippingApplies) { invoiceShipProRateAmount = invoiceShipProRateAmount.add(thisAmount) .setScale(invoiceTypeDecimals, ROUNDING); invoiceShippableQuantity = invoiceQuantity.add(billingQuantity).setScale(invoiceTypeDecimals, ROUNDING); } // increment the invoice subtotal invoiceSubTotal = invoiceSubTotal.add(thisAmount).setScale(100, ROUNDING); // increment the invoice quantity invoiceQuantity = invoiceQuantity.add(billingQuantity).setScale(invoiceTypeDecimals, ROUNDING); // create the OrderItemBilling record Map<String, Object> createOrderItemBillingContext = new HashMap<String, Object>(); createOrderItemBillingContext.put("invoiceId", invoiceId); createOrderItemBillingContext.put("invoiceItemSeqId", invoiceItemSeqId); createOrderItemBillingContext.put("orderId", orderItem.get("orderId")); createOrderItemBillingContext.put("orderItemSeqId", orderItem.get("orderItemSeqId")); createOrderItemBillingContext.put("itemIssuanceId", itemIssuanceId); createOrderItemBillingContext.put("quantity", billingQuantity); createOrderItemBillingContext.put("amount", billingAmount); createOrderItemBillingContext.put("userLogin", userLogin); if ((shipmentReceipt != null) && (shipmentReceipt.getString("receiptId") != null)) { createOrderItemBillingContext.put("shipmentReceiptId", shipmentReceipt.getString("receiptId")); } Map<String, Object> createOrderItemBillingResult = dispatcher.runSync("createOrderItemBilling", createOrderItemBillingContext); if (ServiceUtil.isError(createOrderItemBillingResult)) { return ServiceUtil .returnError( UtilProperties.getMessage(resource, "AccountingErrorCreatingOrderItemBillingFromOrder", locale), null, null, createOrderItemBillingResult); } if ("ItemIssuance".equals(currentValue.getEntityName())) { /* Find ShipmentItemBilling based on shipmentId, shipmentItemSeqId, invoiceId, invoiceItemSeqId as because if any order item has multiple quantity and reserved by multiple inventories then there will be multiple invoice items. In that case ShipmentItemBilling was creating only for one invoice item. Fixed under OFBIZ-6806. */ List<GenericValue> shipmentItemBillings = EntityQuery.use(delegator).from("ShipmentItemBilling") .where("shipmentId", currentValue.get("shipmentId"), "shipmentItemSeqId", currentValue.get("shipmentItemSeqId"), "invoiceId", invoiceId, "invoiceItemSeqId", invoiceItemSeqId) .queryList(); if (UtilValidate.isEmpty(shipmentItemBillings)) { // create the ShipmentItemBilling record GenericValue shipmentItemBilling = delegator.makeValue("ShipmentItemBilling", UtilMisc.toMap("invoiceId", invoiceId, "invoiceItemSeqId", invoiceItemSeqId)); shipmentItemBilling.put("shipmentId", currentValue.get("shipmentId")); shipmentItemBilling.put("shipmentItemSeqId", currentValue.get("shipmentItemSeqId")); shipmentItemBilling.create(); } } String parentInvoiceItemSeqId = invoiceItemSeqId; // increment the counter invoiceItemSeqNum++; invoiceItemSeqId = UtilFormatOut.formatPaddedNumber(invoiceItemSeqNum, INVOICE_ITEM_SEQUENCE_ID_DIGITS); // Get the original order item from the DB, in case the quantity has been overridden GenericValue originalOrderItem = EntityQuery.use(delegator).from("OrderItem") .where("orderId", orderId, "orderItemSeqId", orderItem.get("orderItemSeqId")).queryOne(); // create the item adjustment as line items List<GenericValue> itemAdjustments = OrderReadHelper.getOrderItemAdjustmentList(orderItem, orh.getAdjustments()); for (GenericValue adj : itemAdjustments) { // Check against OrderAdjustmentBilling to see how much of this adjustment has already been invoiced BigDecimal adjAlreadyInvoicedAmount = null; try { Map<String, Object> checkResult = dispatcher.runSync("calculateInvoicedAdjustmentTotal", UtilMisc.toMap("orderAdjustment", adj)); adjAlreadyInvoicedAmount = (BigDecimal) checkResult.get("invoicedTotal"); } catch (GenericServiceException e) { Debug.logError(e, "Accounting trouble calling calculateInvoicedAdjustmentTotal service", module); return ServiceUtil.returnError(UtilProperties.getMessage(resource, "AccountingTroubleCallingCalculateInvoicedAdjustmentTotalService", locale)); } // if (adj.get("amount") == null) { TODO check usage with webPos. Was: fix a bug coming from POS in case of use of a discount (on item(s) or sale, item(s) here) and a cash amount higher than total (hence issuing change) // continue; // } // Set adjustment amount as amountAlreadyIncluded to continue invoice item creation process Boolean isTaxIncludedInPrice = adj.getString("orderAdjustmentTypeId").equals("VAT_TAX") && UtilValidate.isNotEmpty(adj.getBigDecimal("amountAlreadyIncluded")) && adj.getBigDecimal("amountAlreadyIncluded").signum() != 0; if ((adj.getBigDecimal("amount").signum() == 0) && isTaxIncludedInPrice) { adj.set("amount", adj.getBigDecimal("amountAlreadyIncluded")); } // If the absolute invoiced amount >= the abs of the adjustment amount, the full amount has already been invoiced, so skip this adjustment if (adjAlreadyInvoicedAmount.abs().compareTo( adj.getBigDecimal("amount").setScale(invoiceTypeDecimals, ROUNDING).abs()) > 0) { continue; } BigDecimal originalOrderItemQuantity = OrderReadHelper.getOrderItemQuantity(originalOrderItem); BigDecimal amount = ZERO; if (originalOrderItemQuantity.signum() != 0) { if (adj.get("amount") != null) { if ("PROMOTION_ADJUSTMENT".equals(adj.getString("orderAdjustmentTypeId")) && adj.get("productPromoId") != null) { /* Find negative amountAlreadyIncluded in OrderAdjustment to subtract it from discounted amount. As we stored negative sales tax amount in order adjustment for discounted item. */ List<EntityExpr> exprs = UtilMisc.toList( EntityCondition.makeCondition("orderId", EntityOperator.EQUALS, orderItem.getString("orderId")), EntityCondition.makeCondition("orderItemSeqId", EntityOperator.EQUALS, orderItem.getString("orderItemSeqId")), EntityCondition.makeCondition("orderAdjustmentTypeId", EntityOperator.EQUALS, "VAT_TAX"), EntityCondition.makeCondition("amountAlreadyIncluded", EntityOperator.LESS_THAN, BigDecimal.ZERO)); EntityCondition andCondition = EntityCondition.makeCondition(exprs, EntityOperator.AND); GenericValue orderAdjustment = EntityUtil.getFirst(delegator .findList("OrderAdjustment", andCondition, null, null, null, false)); if (UtilValidate.isNotEmpty(orderAdjustment)) { amount = adj.getBigDecimal("amount") .subtract(orderAdjustment.getBigDecimal("amountAlreadyIncluded")) .setScale(100, ROUNDING); } else { amount = adj.getBigDecimal("amount"); } } else { // pro-rate the amount // set decimals = 100 means we don't round this intermediate value, which is very important if (isTaxIncludedInPrice) { BigDecimal priceWithTax = originalOrderItem.getBigDecimal("unitPrice"); // Get tax included in item price amount = priceWithTax.subtract(billingAmount); amount = amount.multiply(billingQuantity); // get adjustment amount /* Get tax amount of other invoice and calculate remaining amount need to store in invoice item(Handle case of of partial shipment and promotional item) to adjust tax amount in invoice item. */ BigDecimal otherInvoiceTaxAmount = BigDecimal.ZERO; GenericValue orderAdjBilling = EntityUtil.getFirst(delegator.findByAnd( "OrderAdjustmentBilling", UtilMisc.toMap("orderAdjustmentId", adj.getString("orderAdjustmentId")), null, false)); if (UtilValidate.isNotEmpty(orderAdjBilling)) { List<GenericValue> invoiceItems = delegator.findByAnd("InvoiceItem", UtilMisc.toMap("invoiceId", orderAdjBilling.getString("invoiceId"), "invoiceItemTypeId", "ITM_SALES_TAX", "productId", originalOrderItem.getString("productId")), null, isTaxIncludedInPrice); for (GenericValue invoiceItem : invoiceItems) { otherInvoiceTaxAmount = otherInvoiceTaxAmount .add(invoiceItem.getBigDecimal("amount")); } if (otherInvoiceTaxAmount.compareTo(BigDecimal.ZERO) > 0) { BigDecimal remainingAmount = adj.getBigDecimal("amountAlreadyIncluded") .subtract(otherInvoiceTaxAmount); amount = amount.min(remainingAmount); } } amount = amount.min(adj.getBigDecimal("amountAlreadyIncluded")).setScale(100, ROUNDING); } else { amount = adj.getBigDecimal("amount").divide(originalOrderItemQuantity, 100, ROUNDING); amount = amount.multiply(billingQuantity); } } // Tax needs to be rounded differently from other order adjustments if (adj.getString("orderAdjustmentTypeId").equals("SALES_TAX")) { amount = amount.setScale(TAX_DECIMALS, TAX_ROUNDING); } else { amount = amount.setScale(invoiceTypeDecimals, ROUNDING); } } else if (adj.get("sourcePercentage") != null) { // pro-rate the amount // set decimals = 100 means we don't round this intermediate value, which is very important BigDecimal percent = adj.getBigDecimal("sourcePercentage"); percent = percent.divide(new BigDecimal(100), 100, ROUNDING); amount = billingAmount.multiply(percent); amount = amount.divide(originalOrderItemQuantity, 100, ROUNDING); amount = amount.multiply(billingQuantity); amount = amount.setScale(invoiceTypeDecimals, ROUNDING); } } if (amount.signum() != 0) { Map<String, Object> createInvoiceItemAdjContext = new HashMap<String, Object>(); createInvoiceItemAdjContext.put("invoiceId", invoiceId); createInvoiceItemAdjContext.put("invoiceItemSeqId", invoiceItemSeqId); createInvoiceItemAdjContext.put("invoiceItemTypeId", getInvoiceItemType(delegator, adj.getString("orderAdjustmentTypeId"), null, invoiceType, "INVOICE_ITM_ADJ")); createInvoiceItemAdjContext.put("quantity", BigDecimal.ONE); createInvoiceItemAdjContext.put("amount", amount); createInvoiceItemAdjContext.put("productId", orderItem.get("productId")); createInvoiceItemAdjContext.put("productFeatureId", orderItem.get("productFeatureId")); createInvoiceItemAdjContext.put("overrideGlAccountId", adj.get("overrideGlAccountId")); createInvoiceItemAdjContext.put("parentInvoiceId", invoiceId); createInvoiceItemAdjContext.put("parentInvoiceItemSeqId", parentInvoiceItemSeqId); createInvoiceItemAdjContext.put("userLogin", userLogin); createInvoiceItemAdjContext.put("taxAuthPartyId", adj.get("taxAuthPartyId")); createInvoiceItemAdjContext.put("taxAuthGeoId", adj.get("taxAuthGeoId")); createInvoiceItemAdjContext.put("taxAuthorityRateSeqId", adj.get("taxAuthorityRateSeqId")); // some adjustments fill out the comments field instead String description = (UtilValidate.isEmpty(adj.getString("description")) ? adj.getString("comments") : adj.getString("description")); createInvoiceItemAdjContext.put("description", description); // invoice items for sales tax are not taxable themselves // TODO: This is not an ideal solution. Instead, we need to use OrderAdjustment.includeInTax when it is implemented if (!(adj.getString("orderAdjustmentTypeId").equals("SALES_TAX"))) { createInvoiceItemAdjContext.put("taxableFlag", product.get("taxable")); } // If the OrderAdjustment is associated to a ProductPromo, // and the field ProductPromo.overrideOrgPartyId is set, // copy the value to InvoiceItem.overrideOrgPartyId: this // represent an organization override for the payToPartyId if (UtilValidate.isNotEmpty(adj.getString("productPromoId"))) { try { GenericValue productPromo = adj.getRelatedOne("ProductPromo", false); if (UtilValidate.isNotEmpty(productPromo.getString("overrideOrgPartyId"))) { createInvoiceItemAdjContext.put("overrideOrgPartyId", productPromo.getString("overrideOrgPartyId")); } } catch (GenericEntityException e) { Debug.logError(e, "Error looking up ProductPromo with id [" + adj.getString("productPromoId") + "]", module); } } Map<String, Object> createInvoiceItemAdjResult = dispatcher.runSync("createInvoiceItem", createInvoiceItemAdjContext); if (ServiceUtil.isError(createInvoiceItemAdjResult)) { return ServiceUtil.returnError( UtilProperties.getMessage(resource, "AccountingErrorCreatingInvoiceItemFromOrder", locale), null, null, createInvoiceItemAdjResult); } // Create the OrderAdjustmentBilling record Map<String, Object> createOrderAdjustmentBillingContext = new HashMap<String, Object>(); createOrderAdjustmentBillingContext.put("orderAdjustmentId", adj.getString("orderAdjustmentId")); createOrderAdjustmentBillingContext.put("invoiceId", invoiceId); createOrderAdjustmentBillingContext.put("invoiceItemSeqId", invoiceItemSeqId); createOrderAdjustmentBillingContext.put("amount", amount); createOrderAdjustmentBillingContext.put("userLogin", userLogin); Map<String, Object> createOrderAdjustmentBillingResult = dispatcher .runSync("createOrderAdjustmentBilling", createOrderAdjustmentBillingContext); if (ServiceUtil.isError(createOrderAdjustmentBillingResult)) { return ServiceUtil.returnError( UtilProperties.getMessage(resource, "AccountingErrorCreatingOrderAdjustmentBillingFromOrder", locale), null, null, createOrderAdjustmentBillingContext); } // this adjustment amount BigDecimal thisAdjAmount = amount; // adjustments only apply to totals when they are not tax or shipping adjustments if (!"SALES_TAX".equals(adj.getString("orderAdjustmentTypeId")) && !"SHIPPING_ADJUSTMENT".equals(adj.getString("orderAdjustmentTypeId"))) { // increment the invoice subtotal invoiceSubTotal = invoiceSubTotal.add(thisAdjAmount).setScale(100, ROUNDING); // add to the ship amount only if it applies to this item if (shippingApplies) { invoiceShipProRateAmount = invoiceShipProRateAmount.add(thisAdjAmount) .setScale(invoiceTypeDecimals, ROUNDING); } } // increment the counter invoiceItemSeqNum++; invoiceItemSeqId = UtilFormatOut.formatPaddedNumber(invoiceItemSeqNum, INVOICE_ITEM_SEQUENCE_ID_DIGITS); } } } // create header adjustments as line items -- always to tax/shipping last Map<GenericValue, BigDecimal> shipAdjustments = new HashMap<GenericValue, BigDecimal>(); Map<GenericValue, BigDecimal> taxAdjustments = new HashMap<GenericValue, BigDecimal>(); List<GenericValue> headerAdjustments = orh.getOrderHeaderAdjustments(); for (GenericValue adj : headerAdjustments) { // Check against OrderAdjustmentBilling to see how much of this adjustment has already been invoiced BigDecimal adjAlreadyInvoicedAmount = null; try { Map<String, Object> checkResult = dispatcher.runSync("calculateInvoicedAdjustmentTotal", UtilMisc.toMap("orderAdjustment", adj)); adjAlreadyInvoicedAmount = ((BigDecimal) checkResult.get("invoicedTotal")) .setScale(invoiceTypeDecimals, ROUNDING); } catch (GenericServiceException e) { Debug.logError(e, "Accounting trouble calling calculateInvoicedAdjustmentTotal service", module); return ServiceUtil.returnError(UtilProperties.getMessage(resource, "AccountingTroubleCallingCalculateInvoicedAdjustmentTotalService", locale)); } // if (null == adj.get("amount")) { TODO check usage with webPos. Was: fix a bug coming from POS in case of use of a discount (on item(s) or sale, sale here) and a cash amount higher than total (hence issuing change) // continue; // } // If the absolute invoiced amount >= the abs of the adjustment amount, the full amount has already been invoiced, so skip this adjustment if (adjAlreadyInvoicedAmount.abs().compareTo( adj.getBigDecimal("amount").setScale(invoiceTypeDecimals, ROUNDING).abs()) >= 0) { continue; } if ("SHIPPING_CHARGES".equals(adj.getString("orderAdjustmentTypeId"))) { shipAdjustments.put(adj, adjAlreadyInvoicedAmount); } else if ("SALES_TAX".equals(adj.getString("orderAdjustmentTypeId"))) { taxAdjustments.put(adj, adjAlreadyInvoicedAmount); } else { // these will effect the shipping pro-rate (unless commented) // other adjustment type BigDecimal divisor = orderSubTotal; BigDecimal multiplier = invoiceSubTotal; if (BigDecimal.ZERO.compareTo(multiplier) == 0 && BigDecimal.ZERO.compareTo(divisor) == 0) { // if multiplier and divisor are equal to zero then use the quantities instead of the amounts // this is useful when the order has free items and misc charges divisor = orderQuantity; multiplier = invoiceQuantity; } calcHeaderAdj(delegator, adj, invoiceType, invoiceId, invoiceItemSeqId, divisor, multiplier, adj.getBigDecimal("amount").setScale(invoiceTypeDecimals, ROUNDING), invoiceTypeDecimals, ROUNDING, userLogin, dispatcher, locale); // invoiceShipProRateAmount += adjAmount; // do adjustments compound or are they based off subtotal? Here we will (unless commented) // invoiceSubTotal += adjAmount; // increment the counter invoiceItemSeqNum++; invoiceItemSeqId = UtilFormatOut.formatPaddedNumber(invoiceItemSeqNum, INVOICE_ITEM_SEQUENCE_ID_DIGITS); } } // next do the shipping adjustments. Note that we do not want to add these to the invoiceSubTotal or orderSubTotal for pro-rating tax later, as that would cause // numerator/denominator problems when the shipping is not pro-rated but rather charged all on the first invoice for (GenericValue adj : shipAdjustments.keySet()) { BigDecimal adjAlreadyInvoicedAmount = shipAdjustments.get(adj); if ("N".equalsIgnoreCase(prorateShipping)) { // Set the divisor and multiplier to 1 to avoid prorating BigDecimal divisor = BigDecimal.ONE; BigDecimal multiplier = BigDecimal.ONE; // The base amount in this case is the adjustment amount minus the total already invoiced for that adjustment, since // it won't be prorated BigDecimal baseAmount = adj.getBigDecimal("amount").setScale(invoiceTypeDecimals, ROUNDING) .subtract(adjAlreadyInvoicedAmount); calcHeaderAdj(delegator, adj, invoiceType, invoiceId, invoiceItemSeqId, divisor, multiplier, baseAmount, invoiceTypeDecimals, ROUNDING, userLogin, dispatcher, locale); } else { // Pro-rate the shipping amount based on shippable information BigDecimal divisor = shippableAmount; BigDecimal multiplier = invoiceShipProRateAmount; if (BigDecimal.ZERO.compareTo(multiplier) == 0 && BigDecimal.ZERO.compareTo(divisor) == 0) { // if multiplier and divisor are equal to zero then use the quantities instead of the amounts // this is useful when the order has free items and shipping charges divisor = shippableQuantity; multiplier = invoiceShippableQuantity; } // The base amount in this case is the adjustment amount, since we want to prorate based on the full amount BigDecimal baseAmount = adj.getBigDecimal("amount").setScale(invoiceTypeDecimals, ROUNDING); calcHeaderAdj(delegator, adj, invoiceType, invoiceId, invoiceItemSeqId, divisor, multiplier, baseAmount, invoiceTypeDecimals, ROUNDING, userLogin, dispatcher, locale); } // Increment the counter invoiceItemSeqNum++; invoiceItemSeqId = UtilFormatOut.formatPaddedNumber(invoiceItemSeqNum, INVOICE_ITEM_SEQUENCE_ID_DIGITS); } // last do the tax adjustments String prorateTaxes = productStore != null ? productStore.getString("prorateTaxes") : "Y"; if (prorateTaxes == null) { prorateTaxes = "Y"; } for (Map.Entry<GenericValue, BigDecimal> entry : taxAdjustments.entrySet()) { GenericValue adj = entry.getKey(); BigDecimal adjAlreadyInvoicedAmount = entry.getValue(); BigDecimal adjAmount = null; if ("N".equalsIgnoreCase(prorateTaxes)) { // Set the divisor and multiplier to 1 to avoid prorating BigDecimal divisor = BigDecimal.ONE; BigDecimal multiplier = BigDecimal.ONE; // The base amount in this case is the adjustment amount minus the total already invoiced for that adjustment, since // it won't be prorated BigDecimal baseAmount = adj.getBigDecimal("amount").setScale(TAX_DECIMALS, TAX_ROUNDING) .subtract(adjAlreadyInvoicedAmount); adjAmount = calcHeaderAdj(delegator, adj, invoiceType, invoiceId, invoiceItemSeqId, divisor, multiplier, baseAmount, TAX_DECIMALS, TAX_ROUNDING, userLogin, dispatcher, locale); } else { // Pro-rate the tax amount based on shippable information BigDecimal divisor = orderSubTotal; BigDecimal multiplier = invoiceSubTotal; // The base amount in this case is the adjustment amount, since we want to prorate based on the full amount BigDecimal baseAmount = adj.getBigDecimal("amount"); adjAmount = calcHeaderAdj(delegator, adj, invoiceType, invoiceId, invoiceItemSeqId, divisor, multiplier, baseAmount, TAX_DECIMALS, TAX_ROUNDING, userLogin, dispatcher, locale); } invoiceSubTotal = invoiceSubTotal.add(adjAmount).setScale(invoiceTypeDecimals, ROUNDING); // Increment the counter invoiceItemSeqNum++; invoiceItemSeqId = UtilFormatOut.formatPaddedNumber(invoiceItemSeqNum, INVOICE_ITEM_SEQUENCE_ID_DIGITS); } // check for previous order payments List<GenericValue> orderPaymentPrefs = EntityQuery.use(delegator).from("OrderPaymentPreference").where( EntityCondition.makeCondition("orderId", EntityOperator.EQUALS, orderId), EntityCondition.makeCondition("statusId", EntityOperator.NOT_EQUAL, "PAYMENT_CANCELLED")) .queryList(); List<GenericValue> currentPayments = new LinkedList<GenericValue>(); for (GenericValue paymentPref : orderPaymentPrefs) { List<GenericValue> payments = paymentPref.getRelated("Payment", null, null, false); currentPayments.addAll(payments); } // apply these payments to the invoice if they have any remaining amount to apply for (GenericValue payment : currentPayments) { if ("PMNT_VOID".equals(payment.getString("statusId")) || "PMNT_CANCELLED".equals(payment.getString("statusId"))) { continue; } BigDecimal notApplied = PaymentWorker.getPaymentNotApplied(payment); if (notApplied.signum() > 0) { Map<String, Object> appl = new HashMap<String, Object>(); appl.put("paymentId", payment.get("paymentId")); appl.put("invoiceId", invoiceId); appl.put("billingAccountId", billingAccountId); appl.put("amountApplied", notApplied); appl.put("userLogin", userLogin); Map<String, Object> createPayApplResult = dispatcher.runSync("createPaymentApplication", appl); if (ServiceUtil.isError(createPayApplResult)) { return ServiceUtil .returnError( UtilProperties.getMessage(resource, "AccountingErrorCreatingInvoiceFromOrder", locale), null, null, createPayApplResult); } } } // Should all be in place now. Depending on the ProductStore.autoApproveInvoice setting, set status to INVOICE_READY (unless it's a purchase invoice, which we set to INVOICE_IN_PROCESS) String autoApproveInvoice = productStore != null ? productStore.getString("autoApproveInvoice") : "Y"; if (!"N".equals(autoApproveInvoice)) { String nextStatusId = "PURCHASE_INVOICE".equals(invoiceType) ? "INVOICE_IN_PROCESS" : "INVOICE_READY"; Map<String, Object> setInvoiceStatusResult = dispatcher.runSync("setInvoiceStatus", UtilMisc.<String, Object>toMap("invoiceId", invoiceId, "statusId", nextStatusId, "userLogin", userLogin)); if (ServiceUtil.isError(setInvoiceStatusResult)) { return ServiceUtil.returnError( UtilProperties.getMessage(resource, "AccountingErrorCreatingInvoiceFromOrder", locale), null, null, setInvoiceStatusResult); } } Map<String, Object> resp = ServiceUtil.returnSuccess(); resp.put("invoiceId", invoiceId); resp.put("invoiceTypeId", invoiceType); return resp; } catch (GenericEntityException e) { Debug.logError(e, "Entity/data problem creating invoice from order items: " + e.toString(), module); return ServiceUtil.returnError( UtilProperties.getMessage(resource, "AccountingEntityDataProblemCreatingInvoiceFromOrderItems", UtilMisc.toMap("reason", e.toString()), locale)); } catch (GenericServiceException e) { Debug.logError(e, "Service/other problem creating invoice from order items: " + e.toString(), module); return ServiceUtil.returnError(UtilProperties.getMessage(resource, "AccountingServiceOtherProblemCreatingInvoiceFromOrderItems", UtilMisc.toMap("reason", e.toString()), locale)); } }
From source file:com.lp.server.lieferschein.ejbfac.LieferscheinFacBean.java
protected void uebernimmAuftragsposition(boolean bEsGibtNochPositiveOffene, LieferscheinDto lieferscheinDto, AuftragpositionDto auftragpositionDto, List<Artikelset> artikelsets, TheClientDto theClientDto) throws RemoteException { if (AuftragServiceFac.AUFTRAGPOSITIONSTATUS_ERLEDIGT .equals(auftragpositionDto.getAuftragpositionstatusCNr())) return;/* www . ja va 2s.com*/ if (auftragpositionDto.getNMenge() == null) { LieferscheinpositionDto lieferscheinpositionDto = auftragpositionDto.cloneAsLieferscheinpositionDto(); lieferscheinpositionDto.setLieferscheinIId(lieferscheinDto.getIId()); lieferscheinpositionDto.setISort(null); getLieferscheinpositionFac().createLieferscheinposition(lieferscheinpositionDto, false, theClientDto); return; } // IMS 2129 // wenn es noch positive offene gibt, dann duerfen die // negativen noch nicht geliefert werden if (auftragpositionDto.getNMenge().signum() < 0 && bEsGibtNochPositiveOffene) { return; } // dieses Flag legt fest, ob eine Lieferscheinposition // fuer die aktuelle // Auftragposition angleget oder aktualisiert werden // soll boolean bLieferscheinpositionErzeugen = false; // die Menge, mit der eine neue Lieferscheinposition // angelegt oder eine // bestehende Lieferscheinposition aktualisiert werden // soll BigDecimal nMengeFuerLieferscheinposition = null; // die Serien- oder Chargennummer, die bei der Abbuchung // verwendet werden soll String cSerienchargennummer = null; if (auftragpositionDto.getPositionsartCNr().equals(AuftragServiceFac.AUFTRAGPOSITIONART_HANDEINGABE)) { // PJ17906 if (auftragpositionDto.getNMenge() != null && auftragpositionDto.getNMenge().doubleValue() == 0) { auftragpositionDto.setAuftragpositionstatusCNr(AuftragServiceFac.AUFTRAGPOSITIONSTATUS_ERLEDIGT); getAuftragpositionFac().updateOffeneMengeAuftragposition(auftragpositionDto.getIId(), theClientDto); return; } bLieferscheinpositionErzeugen = true; nMengeFuerLieferscheinposition = auftragpositionDto.getNOffeneMenge(); } else if (auftragpositionDto.getPositionsartCNr().equals(AuftragServiceFac.AUFTRAGPOSITIONART_IDENT)) { // PJ17906 if (auftragpositionDto.getNMenge() != null && auftragpositionDto.getNMenge().doubleValue() == 0) { auftragpositionDto.setAuftragpositionstatusCNr(AuftragServiceFac.AUFTRAGPOSITIONSTATUS_ERLEDIGT); getAuftragpositionFac().updateOffeneMengeAuftragposition(auftragpositionDto.getIId(), theClientDto); return; } ArtikelDto artikelDto = getArtikelFac().artikelFindByPrimaryKey(auftragpositionDto.getArtikelIId(), theClientDto); // nicht lagerbewirtschaftete Artikel werden mit der // vollen offenen Menge uebernommen sofern es nicht ein // Artikelset-Kopfartikel ist if (!artikelDto.isLagerbewirtschaftet()) { bLieferscheinpositionErzeugen = true; if (isArtikelSetHead(artikelDto.getIId(), theClientDto)) { BigDecimal verfuegbareMenge = getAvailableAmountArtikelset(auftragpositionDto.getIId(), artikelsets); nMengeFuerLieferscheinposition = auftragpositionDto.getNOffeneMenge().min(verfuegbareMenge); } else { nMengeFuerLieferscheinposition = auftragpositionDto.getNOffeneMenge(); } } else { if (artikelDto.isSeriennrtragend()) { // seriennummerbehaftete Artikel werden nur // uebernommen wenn sie in einem Artikelset vorhanden sind if (auftragpositionDto.getPositioniIdArtikelset() != null) { Artikelset artikelset = getAppropriateArtikelset( auftragpositionDto.getPositioniIdArtikelset(), artikelsets); if (null != artikelset) { BigDecimal sollsatzgroesse = auftragpositionDto.getNMenge() .divide(artikelset.getHead().getNMenge()); nMengeFuerLieferscheinposition = sollsatzgroesse .multiply(artikelset.getAvailableAmount()); bLieferscheinpositionErzeugen = true; } // BigDecimal verfuegbareMenge = // getAvailableAmountArtikelset(auftragpositionDto. // getPositioniIdArtikelset(), // artikelsets) ; // bLieferscheinpositionErzeugen = true ; // if(verfuegbareMenge != null) { // nMengeFuerLieferscheinposition = // auftragpositionDto.getNOffeneMenge() ; // } } } else if (artikelDto.isChargennrtragend()) { // chargennummernbehaftete Artikel koennen // nur uebernommen werden, wenn // es nur eine Charge gibt und mit der // Menge, die in dieser Charge // vorhanden ist SeriennrChargennrAufLagerDto[] alleChargennummern = getLagerFac().getAllSerienChargennrAufLager( artikelDto.getIId(), lieferscheinDto.getLagerIId(), theClientDto, true, false); if (alleChargennummern != null && alleChargennummern.length == 1) { BigDecimal nLagerstd = alleChargennummern[0].getNMenge(); cSerienchargennummer = alleChargennummern[0].getCSeriennrChargennr(); if (nLagerstd.signum() > 0) { bLieferscheinpositionErzeugen = true; nMengeFuerLieferscheinposition = auftragpositionDto.getNOffeneMenge().min(nLagerstd); } } } else { // bei lagerbewirtschafteten Artikeln muss // die Menge auf Lager // beruecksichtigt werden BigDecimal nMengeAufLager = getLagerFac().getMengeAufLager(artikelDto.getIId(), lieferscheinDto.getLagerIId(), null, theClientDto); if (nMengeAufLager.signum() > 0) { bLieferscheinpositionErzeugen = true; if (auftragpositionDto.getPositioniIdArtikelset() != null) { Artikelset artikelset = getAppropriateArtikelset( auftragpositionDto.getPositioniIdArtikelset(), artikelsets); if (null != artikelset) { BigDecimal sollsatzGroesse = auftragpositionDto.getNMenge() .divide(artikelset.getHead().getNMenge()); nMengeFuerLieferscheinposition = auftragpositionDto.getNOffeneMenge() .min(artikelset.getAvailableAmount()).multiply(sollsatzGroesse) .min(nMengeAufLager); } else { nMengeFuerLieferscheinposition = BigDecimal.ONE; } } else { nMengeFuerLieferscheinposition = auftragpositionDto.getNOffeneMenge() .min(nMengeAufLager); } } } } // TODO: Vorerst mal eine Zwischensummenposition auf "OFFEN" // belassen. ghp, 07.09.2012 // } else // if(auftragpositionDto.getAuftragpositionartCNr().equals(AuftragServiceFac.AUFTRAGPOSITIONART_INTELLIGENTE_ZWISCHENSUMME)) // { // auftragpositionDto.setAuftragpositionstatusCNr(AuftragServiceFac.AUFTRAGPOSITIONSTATUS_ERLEDIGT) // ; // getAuftragpositionFac().updateAuftragpositionOhneWeitereAktion(auftragpositionDto, // theClientDto) ; } if (bLieferscheinpositionErzeugen && nMengeFuerLieferscheinposition != null) { LieferscheinpositionDto lieferscheinpositionBisherDto = getLieferscheinpositionByLieferscheinAuftragposition( lieferscheinDto.getIId(), auftragpositionDto.getIId()); if (lieferscheinpositionBisherDto == null) { LieferscheinpositionDto lieferscheinpositionDto = auftragpositionDto .cloneAsLieferscheinpositionDto(); if (auftragpositionDto.getPositioniIdArtikelset() != null) { LieferscheinpositionDto[] lPositionDtos = null; Query query = em.createNamedQuery("LieferscheinpositionfindByAuftragposition"); query.setParameter(1, auftragpositionDto.getPositioniIdArtikelset()); Collection<?> cl = query.getResultList(); lPositionDtos = assembleLieferscheinpositionDtos(cl); for (int j = 0; j < lPositionDtos.length; j++) { if (lPositionDtos[j].getLieferscheinIId().equals(lieferscheinDto.getIId())) { lieferscheinpositionDto.setPositioniIdArtikelset(lPositionDtos[j].getIId()); break; } } getBelegVerkaufFac().setupPositionWithIdentities(lieferscheinpositionDto, getAvailableSnrsArtikelset(auftragpositionDto.getPositioniIdArtikelset(), artikelsets), theClientDto); cSerienchargennummer = null; } lieferscheinpositionDto.setLieferscheinIId(lieferscheinDto.getIId()); // TODO: Problematisch bei seriennummern-artikeln (artikelset?) lieferscheinpositionDto.setNMenge(nMengeFuerLieferscheinposition); if (null != cSerienchargennummer) { lieferscheinpositionDto.setSeriennrChargennrMitMenge( SeriennrChargennrMitMengeDto.erstelleDtoAusEinerChargennummer(cSerienchargennummer, nMengeFuerLieferscheinposition)); } lieferscheinpositionDto.setISort(null); getLieferscheinpositionFac().createLieferscheinposition(lieferscheinpositionDto, false, theClientDto); } else { lieferscheinpositionBisherDto.setNMenge(nMengeFuerLieferscheinposition); if (auftragpositionDto.getPositionsartCNr().equals(AuftragServiceFac.AUFTRAGPOSITIONART_IDENT)) { ArtikelDto artikelDto = getArtikelFac() .artikelFindByPrimaryKey(auftragpositionDto.getArtikelIId(), theClientDto); if (artikelDto.isChargennrtragend() || artikelDto.isSeriennrtragend()) { lieferscheinpositionBisherDto.setSeriennrChargennrMitMenge( SeriennrChargennrMitMengeDto.erstelleDtoAusEinerChargennummer(cSerienchargennummer, nMengeFuerLieferscheinposition)); } else { lieferscheinpositionBisherDto.setSeriennrChargennrMitMenge(null); } } getLieferscheinpositionFac().updateLieferscheinpositionSichtAuftrag(lieferscheinpositionBisherDto, theClientDto); } } }
From source file:com.turborep.turbotracker.banking.service.BankingServiceImpl.java
public void payingVendorBillDiscount1(Integer MoAccountID, Integer checkNumber, Integer yearID, Integer periodID, String username, Date transactionDate, Integer userID) throws BankingException, VendorException { Integer[] rxMasterID = null;/*from www.j a v a 2 s. co m*/ Session aSession1 = null; StringBuffer totalAmountQuery = null; String vendorPayBeanQuery = null; String rxMasterList = null; try { aSession1 = itsSessionFactory.openSession(); rxMasterList = "SELECT BillPayUniqueIDs.rxMasterID FROM (SELECT rxMasterID FROM (SELECT veBill.rxMasterID FROM veBill LEFT JOIN veBillPay ON veBill.veBillID = veBillPay.veBillID WHERE veBillPay.moAccountId = " + MoAccountID + " And veBillPay.userID = " + userID + " And veBillPay.ApplyingAmount<>0) AS BillPayIDs GROUP BY rxMasterID) AS BillPayUniqueIDs " + "INNER JOIN rxMaster ON BillPayUniqueIDs.rxMasterID = rxMaster.rxMasterID ORDER BY Name"; Query aQuery1 = aSession1.createSQLQuery(rxMasterList); itsLogger.info(aQuery1.toString()); List<?> rxMasterLists = aQuery1.list(); rxMasterID = new Integer[aQuery1.list().size()]; for (int i = 0; i < rxMasterLists.size(); i++) { rxMasterID[i] = (Integer) rxMasterLists.get(i); } itsLogger.info("Checking======>>>" + rxMasterID.length); for (int i = 0; i < rxMasterID.length; i++) { totalAmountQuery = new StringBuffer( "SELECT SUM(P.ApplyingAmount) AS CheckAmount FROM veBillPay AS P INNER JOIN veBill AS B ON P.veBillID = B.veBillID Where P.moAccountId=" + MoAccountID + " And P.userID = " + userID + " And (B.rxMasterID =") .append(rxMasterID[i]).append(")"); Query aQuery2 = aSession1.createSQLQuery(totalAmountQuery.toString()); List<?> totalList = aQuery2.list(); for (int j = 0; j < totalList.size(); j++) { if ((BigDecimal) totalList.get(j) != null) { BigDecimal amt = (BigDecimal) totalList.get(j); if (amt.signum() < 0) { rxMasterID = (Integer[]) ArrayUtils.remove(rxMasterID, i); } } } } itsLogger.info("Checking======>>>" + rxMasterID.length); int chkno = 0; chkno = checkNumber; for (int i = 0; i < rxMasterID.length; i++) { BigDecimal TotalAmt = new BigDecimal(0); BigDecimal ApplyingAmt = new BigDecimal(0); BigDecimal DiscountAmt = new BigDecimal(0); Motransaction aMotransaction = new Motransaction(); aMotransaction.setMoAccountId(MoAccountID); SysAccountLinkage aSysAccountLinkage = gltransactionService.getsysAccountLinkageDetail(); //Get Discount ID Coaccount CoAccountIdDiscountdetails = gltransactionService .getCoaccountDetailsBasedoncoAccountid(aSysAccountLinkage.getCoAccountIddiscountsTaken()); //Get coAccount Details Coaccount coaccount = gltransactionService.getcoAccountDetails(aMotransaction); Coaccount CoAccountIdapdetails = null; CoAccountIdapdetails = gltransactionService .getCoaccountDetailsBasedoncoAccountid(aSysAccountLinkage.getCoAccountIdap()); Rxmaster liRxmasters = gltransactionService.getTransactionDescriptionfromrxMasterID(rxMasterID[i]); Cofiscalperiod aCofiscalperiod = accountingCyclesService.getCurrentPeriod(periodID); Cofiscalyear aCofiscalyear = accountingCyclesService.getCurrentYear(yearID); Coledgersource aColedgersource = gltransactionService.getColedgersourceDetail("WC"); GlTransaction glTransaction = new GlTransaction(); // period glTransaction.setCoFiscalPeriodId(aCofiscalperiod.getCoFiscalPeriodId()); glTransaction.setPeriod(aCofiscalperiod.getPeriod()); glTransaction.setpStartDate(aCofiscalperiod.getStartDate()); glTransaction.setpEndDate(aCofiscalperiod.getEndDate()); // year glTransaction.setCoFiscalYearId(aCofiscalyear.getCoFiscalYearId()); if (aCofiscalyear.getFiscalYear() != null) glTransaction.setFyear(aCofiscalyear.getFiscalYear()); glTransaction.setyStartDate(aCofiscalyear.getStartDate()); glTransaction.setyEndDate(aCofiscalyear.getEndDate()); // journal glTransaction.setJournalId(aColedgersource.getJournalID()); glTransaction.setJournalDesc(aColedgersource.getDescription()); glTransaction.setEntrydate(new Date()); glTransaction.setEnteredBy(username); glTransaction.setTransactionDate(transactionDate); // Ponumber and trDesc glTransaction.setPoNumber("" + chkno); if (liRxmasters.getName() != null) glTransaction.setTransactionDesc(liRxmasters.getName()); ArrayList<VendorPayBean> payBean = new ArrayList<VendorPayBean>(); List<VendorPayBean> payBeanList = new ArrayList<VendorPayBean>(); vendorPayBeanQuery = "SELECT veBillPay.veBillPayID, veBillPay.veBillID, veBillPay.ApplyingAmount, veBillPay.DiscountAmount " + "FROM veBill LEFT JOIN veBillPay ON veBill.veBillID = veBillPay.veBillID " + "WHERE veBillPay.ApplyingAmount<>0 AND veBillPay.moAccountId=" + MoAccountID + " And veBillPay.userID = " + userID + " AND veBill.rxMasterID= " + rxMasterID[i] + " ORDER BY veBill.InvoiceNumber, veBill.BillDate;"; Query aQuery4 = aSession1.createSQLQuery(vendorPayBeanQuery); payBeanList = aQuery4.list(); Iterator<?> aIterator = payBeanList.iterator(); while (aIterator.hasNext()) { Object[] aObj = (Object[]) aIterator.next(); VendorPayBean aPayBean = new VendorPayBean(); aPayBean.setVebillpayId((Integer) aObj[0]); aPayBean.setVebillID((Integer) aObj[1]); aPayBean.setApplyingAmount((BigDecimal) aObj[2]); aPayBean.setDiscountAmount((BigDecimal) aObj[3]); payBean.add(aPayBean); } for (int j = 0; j < payBean.size(); j++) { /*Get Account Payable and Discount IDs*/ TotalAmt = payBean.get(j).getApplyingAmount().add(payBean.get(j).getDiscountAmount()) .add(TotalAmt); ApplyingAmt = payBean.get(j).getApplyingAmount().add(ApplyingAmt); DiscountAmt = payBean.get(j).getDiscountAmount().add(DiscountAmt); } int gltranID = 0; int gltranID1 = 0; int gltranID2 = 0; //insert GlTransacion Table using Banking Details gltranID = insertBankDettoglTranfromwritechecks(glTransaction, coaccount, aColedgersource, ApplyingAmt); /*for(int j=0;j<payBean.size();j++){*/ if (gltranID != 0) //glLinkageInsert(aColedgersource,gltranID,payBean.get(j).getVebillID ()); glLinkageInsert(aColedgersource, gltranID, chkno, MoAccountID); /* }*/ //insert GlTransacion Table using Account Payable Details gltranID1 = insertaccApDettoglTranfromwritechecks(glTransaction, CoAccountIdapdetails, aColedgersource, TotalAmt); /* for(int j=0;j<payBean.size();j++){*/ if (gltranID1 != 0) glLinkageInsert(aColedgersource, gltranID1, chkno, MoAccountID); /* }*/ //insert GlTransacion Table using Discount Details gltranID2 = insertDiscDettoglTranfromwritechecks(glTransaction, CoAccountIdDiscountdetails, aColedgersource, DiscountAmt); /*for(int j=0;j<payBean.size();j++){*/ if (gltranID2 != 0) glLinkageInsert(aColedgersource, gltranID2, chkno, MoAccountID); /*}*/ if (payBeanList.size() > 25) // checkno increment { int incCheckno = payBeanList.size() / 25; if (payBeanList.size() % 25 > 0) incCheckno += 1; chkno = chkno + incCheckno; } else { chkno++; } } } catch (Exception e) { itsLogger.error(e.getMessage(), e); BankingException aBankingException = new BankingException(e.getMessage(), e); throw aBankingException; } finally { aSession1.flush(); aSession1.close(); totalAmountQuery = null; vendorPayBeanQuery = null; rxMasterList = null; } }
From source file:org.efaps.esjp.accounting.transaction.Recalculate_Base.java
/** * Creates the gain loss4 document account. * * @param _parameter Parameter as passed by the eFaps API * @return the return//from ww w. j a va2 s .com * @throws EFapsException on error */ public Return createGainLoss4DocumentAccount(final Parameter _parameter) throws EFapsException { final Set<String> setAccounts = getAccounts4DocumentConfig(_parameter); final String[] oidsDoc = (String[]) Context.getThreadContext().getSessionAttribute( CIFormAccounting.Accounting_GainLoss4DocumentAccountForm.selectedDocuments.name); final DateTime dateTo = new DateTime(_parameter .getParameterValue(CIFormAccounting.Accounting_GainLoss4DocumentAccountForm.transactionDate.name)); for (final String oid : oidsDoc) { final Instance instDoc = Instance.get(oid); final QueryBuilder attrQuerBldr = new QueryBuilder(CIAccounting.Transaction2SalesDocument); attrQuerBldr.addWhereAttrEqValue(CIAccounting.Transaction2SalesDocument.ToLink, instDoc); final AttributeQuery attrQuery = attrQuerBldr .getAttributeQuery(CIAccounting.Transaction2SalesDocument.FromLink); // filter classification Document final QueryBuilder attrQueryBldr2 = new QueryBuilder(CIAccounting.Transaction); attrQueryBldr2.addWhereAttrEqValue(CIAccounting.Transaction.PeriodLink, _parameter.getInstance().getId()); attrQueryBldr2.addWhereAttrInQuery(CIAccounting.Transaction.ID, attrQuery); final AttributeQuery attrQuery2 = attrQuerBldr.getAttributeQuery(CIAccounting.Transaction.ID); final QueryBuilder queryBldr = new QueryBuilder(CIAccounting.TransactionPositionAbstract); queryBldr.addWhereAttrInQuery(CIAccounting.TransactionPositionAbstract.TransactionLink, attrQuery2); final MultiPrintQuery multi = queryBldr.getPrint(); multi.addAttribute(CIAccounting.TransactionPositionAbstract.Amount, CIAccounting.TransactionPositionAbstract.RateAmount, CIAccounting.TransactionPositionAbstract.CurrencyLink, CIAccounting.TransactionPositionAbstract.RateCurrencyLink); final SelectBuilder selAcc = new SelectBuilder() .linkto(CIAccounting.TransactionPositionAbstract.AccountLink).oid(); multi.addSelect(selAcc); multi.execute(); final Map<String, AccountInfo> map = new HashMap<>(); while (multi.next()) { final Instance accountInst = Instance.get(multi.<String>getSelect(selAcc)); if (setAccounts.contains(accountInst.getOid())) { final BigDecimal oldRateAmount = multi .<BigDecimal>getAttribute(CIAccounting.TransactionPositionAbstract.RateAmount); final BigDecimal oldAmount = multi .<BigDecimal>getAttribute(CIAccounting.TransactionPositionAbstract.Amount); final Instance targetCurrInst = Instance.get(CIERP.Currency.getType(), multi.<Long>getAttribute(CIAccounting.TransactionPositionAbstract.RateCurrencyLink)); final Instance currentInst = Instance.get(CIERP.Currency.getType(), multi.<Long>getAttribute(CIAccounting.TransactionPositionAbstract.CurrencyLink)); final PriceUtil priceUtil = new PriceUtil(); final BigDecimal[] rates = priceUtil.getRates(_parameter, targetCurrInst, currentInst); final BigDecimal rate = rates[2]; final BigDecimal newAmount = oldRateAmount.divide(rate, BigDecimal.ROUND_HALF_UP); BigDecimal gainloss = BigDecimal.ZERO; if (!currentInst.equals(targetCurrInst)) { gainloss = newAmount.subtract(oldAmount); } else { gainloss = newAmount; } if (map.containsKey(accountInst.getOid())) { final AccountInfo tarAcc = map.get(accountInst.getOid()); tarAcc.addAmount(gainloss); } else { final AccountInfo tarAcc = new AccountInfo(accountInst, gainloss); tarAcc.setAmountRate(gainloss); tarAcc.setCurrInstance(currentInst); map.put(accountInst.getOid(), tarAcc); } } } if (!map.isEmpty()) { Insert insert = null; CurrencyInst curr = null; BigDecimal gainlossSum = BigDecimal.ZERO; for (final Entry<String, AccountInfo> entry : map.entrySet()) { final AccountInfo tarAcc = entry.getValue(); final Instance instAcc = Instance.get(entry.getKey()); final BigDecimal gainloss = tarAcc.getAmount(); gainlossSum = gainlossSum.add(gainloss); final Instance currInstance = tarAcc.getCurrInstance(); curr = new CurrencyInst(currInstance); final Map<String, String[]> mapVal = validateInfo(_parameter, gainloss); final String[] accs = mapVal.get("accs"); final String[] check = mapVal.get("check"); if (checkAccounts(accs, 0, check).length() > 0) { if (gainloss.compareTo(BigDecimal.ZERO) != 0) { final String[] accOids = mapVal.get("accountOids"); if (insert == null) { final DateTimeFormatter formater = DateTimeFormat.mediumDate(); final String dateStr = dateTo .withChronology(Context.getThreadContext().getChronology()) .toString(formater.withLocale(Context.getThreadContext().getLocale())); final StringBuilder description = new StringBuilder(); description .append(DBProperties .getProperty("Accounting_DocumentAccountForm.TxnRecalculate.Label")) .append(" ").append(dateStr); insert = new Insert(CIAccounting.Transaction); insert.add(CIAccounting.Transaction.Description, description.toString()); insert.add(CIAccounting.Transaction.Date, dateTo); insert.add(CIAccounting.Transaction.PeriodLink, _parameter.getInstance().getId()); insert.add(CIAccounting.Transaction.Status, Status.find(CIAccounting.TransactionStatus.uuid, "Open").getId()); insert.execute(); } Insert insertPos = new Insert(CIAccounting.TransactionPositionCredit); insertPos.add(CIAccounting.TransactionPositionCredit.TransactionLink, insert.getId()); if (gainloss.signum() < 0) { insertPos.add(CIAccounting.TransactionPositionCredit.AccountLink, instAcc.getId()); } else { insertPos.add(CIAccounting.TransactionPositionCredit.AccountLink, Instance.get(accOids[0]).getId()); } insertPos.add(CIAccounting.TransactionPositionCredit.Amount, gainloss.abs()); insertPos.add(CIAccounting.TransactionPositionCredit.RateAmount, gainloss.abs()); insertPos.add(CIAccounting.TransactionPositionCredit.CurrencyLink, currInstance.getId()); insertPos.add(CIAccounting.TransactionPositionCredit.RateCurrencyLink, currInstance.getId()); insertPos.add(CIAccounting.TransactionPositionCredit.Rate, new Object[] { BigDecimal.ONE, BigDecimal.ONE }); insertPos.execute(); insertPos = new Insert(CIAccounting.TransactionPositionDebit); insertPos.add(CIAccounting.TransactionPositionDebit.TransactionLink, insert.getId()); if (gainloss.signum() < 0) { insertPos.add(CIAccounting.TransactionPositionDebit.AccountLink, Instance.get(accOids[0]).getId()); } else { insertPos.add(CIAccounting.TransactionPositionDebit.AccountLink, instAcc.getId()); } insertPos.add(CIAccounting.TransactionPositionDebit.Amount, gainloss.abs().negate()); insertPos.add(CIAccounting.TransactionPositionDebit.RateAmount, gainloss.abs().negate()); insertPos.add(CIAccounting.TransactionPositionDebit.CurrencyLink, currInstance.getId()); insertPos.add(CIAccounting.TransactionPositionDebit.RateCurrencyLink, currInstance.getId()); insertPos.add(CIAccounting.TransactionPositionDebit.Rate, new Object[] { BigDecimal.ONE, BigDecimal.ONE }); insertPos.execute(); } } } if (insert != null) { final Instance instance = insert.getInstance(); // create classifications final Classification classification1 = (Classification) CIAccounting.TransactionClass.getType(); final Insert relInsert1 = new Insert(classification1.getClassifyRelationType()); relInsert1.add(classification1.getRelLinkAttributeName(), instance.getId()); relInsert1.add(classification1.getRelTypeAttributeName(), classification1.getId()); relInsert1.execute(); final Insert classInsert1 = new Insert(classification1); classInsert1.add(classification1.getLinkAttributeName(), instance.getId()); classInsert1.execute(); final Classification classification = (Classification) CIAccounting.TransactionClassGainLoss .getType(); final Insert relInsert = new Insert(classification.getClassifyRelationType()); relInsert.add(classification.getRelLinkAttributeName(), instance.getId()); relInsert.add(classification.getRelTypeAttributeName(), classification.getId()); relInsert.execute(); final Insert classInsert = new Insert(classification); classInsert.add(classification.getLinkAttributeName(), instance.getId()); classInsert.add(CIAccounting.TransactionClassGainLoss.Amount, gainlossSum); classInsert.add(CIAccounting.TransactionClassGainLoss.RateAmount, gainlossSum); classInsert.add(CIAccounting.TransactionClassGainLoss.CurrencyLink, curr.getInstance().getId()); classInsert.add(CIAccounting.TransactionClassGainLoss.RateCurrencyLink, curr.getInstance().getId()); classInsert.add(CIAccounting.TransactionClassGainLoss.Rate, new Object[] { BigDecimal.ONE, BigDecimal.ONE }); classInsert.execute(); new Create().connectDocs2Transaction(_parameter, instance, instDoc); } } } return new Return(); }
From source file:com.turborep.turbotracker.banking.service.BankingServiceImpl.java
@SuppressWarnings("unchecked") @Override/*from w w w . ja v a 2 s .c o m*/ public PrintCheckBean printCheck(Motransaction theMotransaction, Integer checkNumber, Integer yearID, Integer periodID, String userName, Integer userID) throws BankingException { PrintCheckBean aPrintBean = new PrintCheckBean(); Session aSession = itsSessionFactory.openSession(); Transaction aTransaction = null; String deletetemCheck = null, billArrayQuery = null, rxAddressIDQuery = null, vendorPayBeanQuery = null; StringBuffer totalAmountQuery = null; Molinkage aMolinkage = new Molinkage(); Integer moLinkageId = null; Integer moTransactionId = null; Integer moLinkageDetailID = null; Integer[] rxMasterID = null; ArrayList<Integer> rxMasterID1 = new ArrayList<Integer>(); ArrayList<BigDecimal> creditAmtUsed = new ArrayList<BigDecimal>(); BigDecimal[] totalAmount = new BigDecimal[0]; BigDecimal[] totalAmount1 = null; BigDecimal balAmount = new BigDecimal(0); BigDecimal balcalculationAmount = new BigDecimal(0); MoAccount aMoaccount = new MoAccount(); checkDate = theMotransaction.getTransactionDate(); int i = 0; int j = 0; try { aTransaction = aSession.beginTransaction(); aTransaction.begin(); deletetemCheck = "DELETE FROM moVendorCheckTemp"; aSession.createSQLQuery(deletetemCheck).executeUpdate(); billArrayQuery = "select veBillID from veBillPay where moAccountId=" + theMotransaction.getMoAccountId() + " and userID =" + userID; Query aQuery = aSession.createSQLQuery(billArrayQuery); List<?> billIds = aQuery.list(); billId = new Integer[aQuery.list().size()]; for (i = 0; i < billIds.size(); i++) billId[i] = (Integer) billIds.get(i); String rxMasterList = "SELECT BillPayUniqueIDs.rxMasterID FROM (SELECT rxMasterID FROM (SELECT veBill.rxMasterID FROM veBill LEFT JOIN veBillPay ON veBill.veBillID = veBillPay.veBillID WHERE veBillPay.ApplyingAmount<>0 and veBillPay.moAccountId=" + theMotransaction.getMoAccountId() + " and veBillPay.userID = " + userID + ") AS BillPayIDs GROUP BY rxMasterID) AS BillPayUniqueIDs " + "INNER JOIN rxMaster ON BillPayUniqueIDs.rxMasterID = rxMaster.rxMasterID ORDER BY Name;"; Query aQuery1 = aSession.createSQLQuery(rxMasterList); itsLogger.info(aQuery1.toString()); List<?> rxMasterLists = aQuery1.list(); rxMasterID = new Integer[aQuery1.list().size()]; for (i = 0; i < rxMasterLists.size(); i++) { rxMasterID[i] = (Integer) rxMasterLists.get(i); } int counting = 0; totalAmount1 = new BigDecimal[rxMasterID.length]; for (i = 0; i < rxMasterID.length; i++) { totalAmountQuery = new StringBuffer( "SELECT SUM(P.ApplyingAmount) AS CheckAmount FROM veBillPay AS P INNER JOIN veBill AS B ON P.veBillID = B.veBillID Where P.moAccountId=" + theMotransaction.getMoAccountId() + " and P.userID = " + userID + " and (B.rxMasterID =").append(rxMasterID[i]).append(")"); Query aQuery2 = aSession.createSQLQuery(totalAmountQuery.toString()); List<?> totalList = aQuery2.list(); for (j = 0; j < totalList.size(); j++) { if ((BigDecimal) totalList.get(j) != null) { BigDecimal amt = (BigDecimal) totalList.get(j); if (amt.signum() < 0) { rxMasterID1.add(rxMasterID[i]); creditAmtUsed.add((BigDecimal) totalList.get(j)); } else { totalAmount1[counting] = (BigDecimal) totalList.get(j); counting++; } } } } for (int t = 0; t < rxMasterID1.size(); t++) { rxMasterID = (Integer[]) ArrayUtils.removeElement(rxMasterID, rxMasterID1.get(t)); itsLogger.info("rxMasterID::" + rxMasterID1.get(t)); } if (rxMasterID.length > 0) { //Get rxAddress Information from normal payment rxAddressID = new Integer[rxMasterID.length]; for (i = 0; i < rxMasterID.length; i++) { rxAddressIDQuery = "SELECT rxAddressID FROM rxAddress WHERE rxMasterID= " + rxMasterID[i] + " and IsRemitTo = 1"; Query aQuery3 = aSession.createSQLQuery(rxAddressIDQuery); List<?> rxAddressList = aQuery3.list(); if (rxAddressList.size() > 0) { rxAddressID[i] = (Integer) rxAddressList.get(0); } else { rxAddressIDQuery = "SELECT rxAddressID FROM rxAddress WHERE rxMasterID= " + rxMasterID[i] + " limit 1"; aQuery3 = aSession.createSQLQuery(rxAddressIDQuery); rxAddressList = aQuery3.list(); rxAddressID[i] = (Integer) rxAddressList.get(0); } } } else { //Get rxAddress Information from credit payment rxAddressID = new Integer[rxMasterID1.size()]; for (i = 0; i < rxMasterID1.size(); i++) { rxAddressIDQuery = "SELECT rxAddressID FROM rxAddress WHERE rxMasterID= " + rxMasterID1.get(i) + " limit 1"; Query aQuery3 = aSession.createSQLQuery(rxAddressIDQuery); itsLogger.info("Query2 " + aQuery3.toString()); List<?> rxAddressList = aQuery3.list(); for (j = 0; j < rxAddressList.size(); j++) { if ((Integer) rxAddressList.get(j) != null) rxAddressID[i] = (Integer) rxAddressList.get(j); } } } aMolinkage.setDummyVal(true); moLinkageId = (Integer) aSession.save(aMolinkage); int chkno = 0; chkno = checkNumber; if (counting != 0) // Normal Payment { totalAmount = new BigDecimal[counting]; for (int t = 0; t < counting; t++) { totalAmount[t] = totalAmount1[t]; } for (i = 0; i < rxMasterID.length; i++) { List<VendorPayBean> payBeanlist = new ArrayList<VendorPayBean>(); vendorPayBeanQuery = "SELECT veBillPay.veBillPayID, veBillPay.veBillID, veBillPay.ApplyingAmount, veBillPay.DiscountAmount," + "veBill.BillDate,veBill.InvoiceNumber,veBill.BillAmount,veBill.AppliedAmount,vePO.PONumber FROM veBill " + "LEFT JOIN veBillPay ON veBill.veBillID = veBillPay.veBillID LEFT JOIN vePO ON veBill.vePOID = vePO.vePOID " + "WHERE veBillPay.ApplyingAmount<>0 AND veBillPay.moAccountId=" + theMotransaction.getMoAccountId() + " AND veBillPay.userID = " + userID + " AND veBill.rxMasterID= " + rxMasterID[i] + " ORDER BY veBill.InvoiceNumber, veBill.BillDate"; Query aQuery4 = aSession.createSQLQuery(vendorPayBeanQuery); payBeanlist = aQuery4.list(); if (payBeanlist.size() <= 25) // pick invoice count less than 25 for particular vendor { balAmount = new BigDecimal(0); ArrayList<VendorPayBean> payBean = new ArrayList<VendorPayBean>(); balAmount = balAmount.add(totalAmount[i].negate()); Motransaction aMotransaction = new Motransaction(); aMotransaction.setRxMasterId(rxMasterID[i]); aMotransaction.setRxAddressId(rxAddressID[i]); aMotransaction.setCheckType(theMotransaction.getCheckType()); aMotransaction.setTransactionDate(theMotransaction.getTransactionDate()); aMotransaction.setMoAccountId(theMotransaction.getMoAccountId()); aMotransaction.setPrinted(theMotransaction.getPrinted()); aMotransaction.setAmount(totalAmount[i].negate()); balcalculationAmount = balcalculationAmount.add(balAmount); // for each Amount aMotransaction.setBalance(theMotransaction.getBalance().add(balcalculationAmount)); aMotransaction.setCoAccountId(theMotransaction.getCoAccountId()); aMotransaction.setReference("" + chkno); aMotransaction.setUniquechkRef("" + chkno); aMotransaction.setMoTransactionTypeId(theMotransaction.getMoTransactionTypeId()); aMotransaction.setDescription("Vendor Write Checks"); aMotransaction.setVoid_((byte) 0); aMotransaction.setReconciled((byte) 0); aMotransaction.setDirectDeposit((byte) 0); aMotransaction.setTempRec((byte) 0); aMotransaction.setPageflagVoid(false); moTransactionId = (Integer) aSession.save(aMotransaction); Iterator<?> aIterator = aQuery4.list().iterator(); while (aIterator.hasNext()) { Object[] aObj = (Object[]) aIterator.next(); VendorPayBean aPayBean = new VendorPayBean(); aPayBean.setVebillpayId((Integer) aObj[0]); aPayBean.setVebillID((Integer) aObj[1]); aPayBean.setApplyingAmount((BigDecimal) aObj[2]); aPayBean.setDiscountAmount((BigDecimal) aObj[3]); payBean.add(aPayBean); WritecheckDetails wcObj = new WritecheckDetails(); wcObj.setWcDetailsID(1); wcObj.setMoAccountID(theMotransaction.getMoAccountId()); wcObj.setMoTransactionId(moTransactionId); wcObj.setMoTransactionDate(theMotransaction.getTransactionDate()); wcObj.setMoTransAmount(totalAmount[i].negate()); wcObj.setMoLinkappliedAmount((BigDecimal) aObj[2]); wcObj.setMoLinkdiscount((BigDecimal) aObj[3]); wcObj.setCheckno("" + chkno); wcObj.setUserID(userID); wcObj.setRxMasterID(rxMasterID[i]); wcObj.setRxAddressID(rxAddressID[i]); wcObj.setVeBillID((Integer) aObj[1]); wcObj.setVeBillDate((Date) aObj[4]); wcObj.setInvoiceNumber((String) aObj[5]); wcObj.setVeBillAmount((BigDecimal) aObj[6]); wcObj.setVeBillAppliedAmt((BigDecimal) aObj[7]); wcObj.setPoNumber((String) aObj[8]); wcObj.setVoidStatus(0); wcObj.setVeBillBalance(((BigDecimal) aObj[6] != null ? (BigDecimal) aObj[6] : BigDecimal.ZERO).subtract( ((BigDecimal) aObj[2] != null ? (BigDecimal) aObj[2] : BigDecimal.ZERO) .add((BigDecimal) aObj[3] != null ? (BigDecimal) aObj[3] : BigDecimal.ZERO))); aSession.save(wcObj); } /*String billtoRxmasterQuery = "SELECT vb.veBillID FROM veBillPay as vp INNER JOIN veBill as vb on vp.veBillID = vb.veBillID WHERE vb.rxMasterID ="+rxMasterID[i]+";"; List<?> billList = aSession.createSQLQuery(billtoRxmasterQuery).list();*/ for (j = 0; j < payBean.size(); j++) { Molinkagedetail aMolinkagedetail = new Molinkagedetail(); aMolinkagedetail.setVeBillId(payBean.get(j).getVebillID()); aMolinkagedetail.setAmount(payBean.get(j).getApplyingAmount()); aMolinkagedetail.setMoLinkageId(moLinkageId); aMolinkagedetail.setDiscount(payBean.get(j).getDiscountAmount()); aMolinkagedetail.setMoTransactionId(moTransactionId); moLinkageDetailID = (Integer) aSession.save(aMolinkagedetail); Vebill aVebill = new Vebill(); aVebill = (Vebill) aSession.get(Vebill.class, payBean.get(j).getVebillID()); BigDecimal appliedAmount = aVebill.getAppliedAmount(); BigDecimal billAmount = aVebill.getBillAmount(); appliedAmount = appliedAmount.add(payBean.get(j).getApplyingAmount()) .add(payBean.get(j).getDiscountAmount()); aVebill.setAppliedAmount(appliedAmount); aVebill.setCreditUsed("0"); if (appliedAmount.compareTo(billAmount) == 0) aVebill.setTransactionStatus(2); else aVebill.setTransactionStatus(1); aSession.update(aVebill); /**Created by: Leo ID:110 * Date:04/07/2015 * Purpose: To store payment history */ if (payBean.get(j).getApplyingAmount().signum() > 0) { VeBillPaymentHistory aVeBillPaymentHistory = new VeBillPaymentHistory(); aVeBillPaymentHistory.setVeBillID(payBean.get(j).getVebillID()); aVeBillPaymentHistory.setCheckNo("" + chkno); aVeBillPaymentHistory.setDatePaid(theMotransaction.getTransactionDate()); aVeBillPaymentHistory.setAmountVal(payBean.get(j).getApplyingAmount()); aSession.save(aVeBillPaymentHistory); } //added by prasant if (payBean.get(j).getApplyingAmount().signum() < 0) { System.out.println( "======================================================================================================="); System.out.println( "Normal Payment To store payment history when amount is credit chk:" + chkno + "Amount" + payBean.get(j).getApplyingAmount()); System.out.println( "======================================================================================================="); VeBillPaymentHistory aVeBillPaymentHistory = new VeBillPaymentHistory(); aVeBillPaymentHistory.setVeBillID(payBean.get(j).getVebillID()); aVeBillPaymentHistory.setCheckNo("" + chkno); aVeBillPaymentHistory.setDatePaid(theMotransaction.getTransactionDate()); aVeBillPaymentHistory.setAmountVal(payBean.get(j).getApplyingAmount()); aSession.save(aVeBillPaymentHistory); } //end } Movendorchecktemp amoVendorCheckTemp = new Movendorchecktemp(); amoVendorCheckTemp.setMoTransactionId(moTransactionId); aSession.save(amoVendorCheckTemp); chkno++; } else { int veBilllistCount = payBeanlist.size() / 25; // "segment spliting" for pdf and generate new check no for each page if ((payBeanlist.size() % 25) > 0) // add 1 segment if remainder comes veBilllistCount += 1; int valSublist = 0; for (int cb = 1; cb <= veBilllistCount; cb++) { valSublist = (cb - 1) * 25; // calculation part for picking data from arralist. balAmount = new BigDecimal(0); ArrayList<VendorPayBean> payBean = new ArrayList<VendorPayBean>(); balAmount = balAmount.add(totalAmount[i].negate()); Motransaction aMotransaction = new Motransaction(); aMotransaction.setRxMasterId(rxMasterID[i]); aMotransaction.setRxAddressId(rxAddressID[i]); aMotransaction.setTransactionDate(theMotransaction.getTransactionDate()); aMotransaction.setMoAccountId(theMotransaction.getMoAccountId()); aMotransaction.setPrinted(theMotransaction.getPrinted()); aMotransaction.setCoAccountId(theMotransaction.getCoAccountId()); aMotransaction.setReference("" + chkno); aMotransaction.setMoTransactionTypeId(theMotransaction.getMoTransactionTypeId()); if (cb == 1) { aMotransaction.setUniquechkRef("" + chkno); aMotransaction.setDescription("Vendor Write Checks"); aMotransaction.setCheckType(theMotransaction.getCheckType()); aMotransaction.setAmount(totalAmount[i].negate()); balcalculationAmount = balcalculationAmount.add(balAmount); // for each Amount aMotransaction.setBalance(theMotransaction.getBalance().add(balcalculationAmount)); aMotransaction.setVoid_((byte) 0); aMotransaction.setPageflagVoid(false); } else { aMotransaction.setUniquechkRef("" + (chkno - (cb - 1))); aMotransaction.setDescription("***VOID***"); aMotransaction.setStatus(true); aMotransaction.setAmount(BigDecimal.ZERO); aMotransaction.setVoid_((byte) 0); aMotransaction.setPageflagVoid(true); balcalculationAmount = balcalculationAmount.add(BigDecimal.ZERO); // for each Amount aMotransaction.setBalance(theMotransaction.getBalance().add(balcalculationAmount)); } aMotransaction.setReconciled((byte) 0); aMotransaction.setDirectDeposit((byte) 0); aMotransaction.setTempRec((byte) 0); moTransactionId = (Integer) aSession.save(aMotransaction); Iterator<?> aIterator = null; if (cb * 25 < payBeanlist.size()) // pick data from list using index aIterator = aQuery4.list().subList(valSublist, cb * 25).iterator(); else aIterator = aQuery4.list().subList(valSublist, payBeanlist.size()).iterator(); while (aIterator.hasNext()) { Object[] aObj = (Object[]) aIterator.next(); VendorPayBean aPayBean = new VendorPayBean(); aPayBean.setVebillpayId((Integer) aObj[0]); aPayBean.setVebillID((Integer) aObj[1]); aPayBean.setApplyingAmount((BigDecimal) aObj[2]); aPayBean.setDiscountAmount((BigDecimal) aObj[3]); payBean.add(aPayBean); WritecheckDetails wcObj = new WritecheckDetails(); wcObj.setWcDetailsID(1); wcObj.setMoAccountID(theMotransaction.getMoAccountId()); wcObj.setMoTransactionId(moTransactionId); wcObj.setMoTransactionDate(theMotransaction.getTransactionDate()); wcObj.setMoTransAmount(totalAmount[i].negate()); wcObj.setMoLinkappliedAmount((BigDecimal) aObj[2]); wcObj.setMoLinkdiscount((BigDecimal) aObj[3]); wcObj.setCheckno("" + chkno); wcObj.setUserID(userID); wcObj.setRxMasterID(rxMasterID[i]); wcObj.setRxAddressID(rxAddressID[i]); wcObj.setVeBillID((Integer) aObj[1]); wcObj.setVeBillDate((Date) aObj[4]); wcObj.setInvoiceNumber((String) aObj[5]); wcObj.setVeBillAmount((BigDecimal) aObj[6]); wcObj.setVeBillAppliedAmt((BigDecimal) aObj[7]); wcObj.setPoNumber((String) aObj[8]); wcObj.setVeBillBalance( ((BigDecimal) aObj[6] != null ? (BigDecimal) aObj[6] : BigDecimal.ZERO) .subtract(((BigDecimal) aObj[2] != null ? (BigDecimal) aObj[2] : BigDecimal.ZERO).add( (BigDecimal) aObj[3] != null ? (BigDecimal) aObj[3] : BigDecimal.ZERO))); if (valSublist > 0) wcObj.setVoidStatus(1); else wcObj.setVoidStatus(0); aSession.save(wcObj); } /*String billtoRxmasterQuery = "SELECT vb.veBillID FROM veBillPay as vp INNER JOIN veBill as vb on vp.veBillID = vb.veBillID WHERE vb.rxMasterID ="+rxMasterID[i]+";"; List<?> billList = aSession.createSQLQuery(billtoRxmasterQuery).list();*/ for (j = 0; j < payBean.size(); j++) { Molinkagedetail aMolinkagedetail = new Molinkagedetail(); aMolinkagedetail.setVeBillId(payBean.get(j).getVebillID()); aMolinkagedetail.setAmount(payBean.get(j).getApplyingAmount()); aMolinkagedetail.setMoLinkageId(moLinkageId); aMolinkagedetail.setDiscount(payBean.get(j).getDiscountAmount()); aMolinkagedetail.setMoTransactionId(moTransactionId); moLinkageDetailID = (Integer) aSession.save(aMolinkagedetail); Vebill aVebill = new Vebill(); aVebill = (Vebill) aSession.get(Vebill.class, payBean.get(j).getVebillID()); BigDecimal appliedAmount = aVebill.getAppliedAmount(); BigDecimal billAmount = aVebill.getBillAmount(); appliedAmount = appliedAmount.add(payBean.get(j).getApplyingAmount()) .add(payBean.get(j).getDiscountAmount()); aVebill.setAppliedAmount(appliedAmount); aVebill.setCreditUsed("0"); if (appliedAmount.compareTo(billAmount) == 0) aVebill.setTransactionStatus(2); else aVebill.setTransactionStatus(1); aSession.update(aVebill); /**Created by: Leo ID:110 * Date:04/07/2015 * Purpose: To store payment history */ if (payBean.get(j).getApplyingAmount().signum() > 0) { VeBillPaymentHistory aVeBillPaymentHistory = new VeBillPaymentHistory(); aVeBillPaymentHistory.setVeBillID(payBean.get(j).getVebillID()); aVeBillPaymentHistory.setCheckNo("" + chkno); aVeBillPaymentHistory.setDatePaid(theMotransaction.getTransactionDate()); aVeBillPaymentHistory.setAmountVal(payBean.get(j).getApplyingAmount()); aSession.save(aVeBillPaymentHistory); } } Movendorchecktemp amoVendorCheckTemp = new Movendorchecktemp(); amoVendorCheckTemp.setMoTransactionId(moTransactionId); aSession.save(amoVendorCheckTemp); chkno++; } } } /**Inserting GlTransaction*/ payingVendorBillDiscount1(theMotransaction.getMoAccountId(), checkNumber, yearID, periodID, userName, theMotransaction.getTransactionDate(), userID); /** Delete VeBillPay **/ String rxMasterIds = StringUtils.join(rxMasterID, ','); if (rxMasterID.length > 0) { vendorPayBeanQuery = "DELETE FROM veBillPay WHERE veBillPayID IN (SELECT * FROM (SELECT vP.veBillPayID FROM veBillPay vP,veBill v WHERE vP.moAccountId=" + theMotransaction.getMoAccountId() + " AND vP.userID = " + userID + " AND vP.veBillID = v.veBillID AND v.rxMasterID IN (" + rxMasterIds + ")) AS subQuery)"; aSession.createSQLQuery(vendorPayBeanQuery).executeUpdate(); } BigDecimal totalamount = new BigDecimal(0); for (i = 0; i < totalAmount.length; i++) { if (totalAmount[i] != null) totalamount = totalamount.add(totalAmount[i]); } aMoaccount = (MoAccount) aSession.get(MoAccount.class, theMotransaction.getMoAccountId()); aMoaccount.setNextCheckNumber(chkno); //BigDecimal openBalance = aMoaccount.getOpenBalance(); /*openBalance = openBalance.subtract(totalamount); aMoaccount.setOpenBalance(openBalance);*/ BigDecimal substractions = aMoaccount.getSubtractions(); substractions = substractions.add(totalamount); aMoaccount.setSubtractions(substractions); aSession.update(aMoaccount); aTransaction.commit(); } else // Credit Payment { /**Created by: Leo ID:110 * Date:04/06/2015 * Purpose: for credit payments */ String creditVeBillID = ""; for (i = 0; i < rxMasterID1.size(); i++) { // iterate credit rxMasterIDs balAmount = new BigDecimal(0); ArrayList<VendorPayBean> payBean = new ArrayList<VendorPayBean>(); BigDecimal pickNegativeAmt = new BigDecimal(0); vendorPayBeanQuery = "SELECT veBillPay.veBillPayID, veBillPay.veBillID, veBillPay.ApplyingAmount, veBillPay.DiscountAmount " + "FROM veBill LEFT JOIN veBillPay ON veBill.veBillID = veBillPay.veBillID " + "WHERE veBillPay.ApplyingAmount<>0 AND veBillPay.moAccountId=" + theMotransaction.getMoAccountId() + " and veBillPay.userID = " + userID + " And veBill.rxMasterID= " + rxMasterID1.get(i) + " ORDER BY veBill.InvoiceNumber, veBill.BillDate;"; Query aQuery4 = aSession.createSQLQuery(vendorPayBeanQuery); // get All veBillPay Details Iterator<?> aIterator = aQuery4.list().iterator(); while (aIterator.hasNext()) { Object[] aObj = (Object[]) aIterator.next(); VendorPayBean aPayBean = new VendorPayBean(); aPayBean.setVebillpayId((Integer) aObj[0]); aPayBean.setVebillID((Integer) aObj[1]); aPayBean.setApplyingAmount((BigDecimal) aObj[2]); aPayBean.setDiscountAmount((BigDecimal) aObj[3]); if (aPayBean.getApplyingAmount().signum() < 0) { pickNegativeAmt = pickNegativeAmt.add(aPayBean.getApplyingAmount()); //sum of negative Amount only if (creditVeBillID.equals("")) // Get All veBill IDs creditVeBillID = "" + (Integer) aObj[1]; else creditVeBillID = creditVeBillID + "," + (Integer) aObj[1]; } payBean.add(aPayBean); } balAmount = balAmount.add(pickNegativeAmt.negate().add(creditAmtUsed.get(i))); // sum of all applying amt without credit Amount for (j = 0; j < payBean.size(); j++) { // Iterate veBill IDs Vebill aVebill = new Vebill(); aVebill = (Vebill) aSession.get(Vebill.class, payBean.get(j).getVebillID()); BigDecimal appliedAmount = aVebill.getAppliedAmount(); BigDecimal billAmount = aVebill.getBillAmount(); itsLogger.info(payBean.get(j).getApplyingAmount()); /** * Note: Credit bill don't update check no. credit used bills only need check no. */ if (payBean.get(j).getApplyingAmount().signum() < 0) // check whether Applying Amt is in negative value { if (payBean.get(j).getApplyingAmount().negate().compareTo(balAmount) == 1) // check credit amount is greater or not { appliedAmount = appliedAmount.add(balAmount.negate()) .add(payBean.get(j).getDiscountAmount()); aVebill.setAppliedAmount(appliedAmount); } else { appliedAmount = appliedAmount.add(payBean.get(j).getApplyingAmount()) .add(payBean.get(j).getDiscountAmount()); aVebill.setAppliedAmount(appliedAmount); balAmount = balAmount.add(payBean.get(j).getApplyingAmount()); } aVebill.setCreditUsed("0"); itsLogger.info(balAmount); } else { /**Created by: Leo ID:110 * Date:04/07/2015 * Purpose: To store payment history */ appliedAmount = appliedAmount.add(payBean.get(j).getApplyingAmount()) .add(payBean.get(j).getDiscountAmount()); VeBillPaymentHistory aVeBillPaymentHistory = new VeBillPaymentHistory(); aVeBillPaymentHistory.setVeBillID(payBean.get(j).getVebillID()); aVeBillPaymentHistory.setCheckNo("" + chkno); aVeBillPaymentHistory.setDatePaid(theMotransaction.getTransactionDate()); aVeBillPaymentHistory.setAmountVal(appliedAmount); aSession.save(aVeBillPaymentHistory); aVebill.setAppliedAmount(appliedAmount); if (aVebill.getCreditUsed() != null && !aVebill.getCreditUsed().equals("0")) aVebill.setCreditUsed(aVebill.getCreditUsed() + "," + creditVeBillID); else aVebill.setCreditUsed("" + creditVeBillID); itsLogger.info(appliedAmount); } if (appliedAmount.compareTo(billAmount) == 0) aVebill.setTransactionStatus(2); else aVebill.setTransactionStatus(1); aSession.update(aVebill); } Movendorchecktemp amoVendorCheckTemp = new Movendorchecktemp(); amoVendorCheckTemp.setMoTransactionId(moTransactionId); aSession.save(amoVendorCheckTemp); chkno++; } aMoaccount = (MoAccount) aSession.get(MoAccount.class, theMotransaction.getMoAccountId()); aMoaccount.setNextCheckNumber(chkno); aSession.update(aMoaccount); aTransaction.commit(); } if (rxMasterID.length > 0) { aPrintBean.setReference("Success"); } else { aPrintBean.setReference("Error"); } } catch (Exception e) { itsLogger.error(e.getMessage(), e); aTransaction.rollback(); if (rxMasterID.length > 0) { aPrintBean.setReference("Success"); } else { aPrintBean.setReference("Error"); } BankingException aBankingException = new BankingException(e.getMessage(), e); throw aBankingException; } finally { aSession.flush(); aSession.close(); deletetemCheck = null; billArrayQuery = null; rxAddressIDQuery = null; vendorPayBeanQuery = null; totalAmountQuery = null; } return aPrintBean; }