List of usage examples for java.math BigDecimal signum
public int signum()
From source file:org.egov.wtms.application.service.WaterConnectionDetailsService.java
public BigDecimal getTotalAmountTillPreviousFinYear(WaterConnectionDetails waterConnectionDetails) { EgDemand currentDemand = waterTaxUtils.getCurrentDemand(waterConnectionDetails).getDemand(); BigDecimal balance = ZERO; if (currentDemand != null) { List<Object> instVsAmt = connectionDemandService .getDmdCollAmtInstallmentWiseUptoPreviousFinYear(currentDemand); for (Object object : instVsAmt) { Object[] ddObject = (Object[]) object; BigDecimal dmdAmt = new BigDecimal((Double) ddObject[2]); BigDecimal collAmt = ZERO; if (ddObject[2] != null) collAmt = new BigDecimal((Double) ddObject[3]); balance = balance.add(dmdAmt.subtract(collAmt)); }/*from ww w.j av a 2 s . com*/ } if (balance.signum() < 0) balance = ZERO; return balance; }
From source file:org.openbravo.erpCommon.ad_forms.Fact.java
/** * Balance Accounting Currency. If the accounting currency is not balanced, if Currency balancing * is enabled create a new line using the currency balancing account with zero source balance or * adjust the line with the largest balance sheet account or if no balance sheet account exist, * the line with the largest amount//from w w w . j av a2 s.c om * * @return FactLine */ public FactLine balanceAccounting(ConnectionProvider conn) { BigDecimal diff = getAcctBalance(); log4jFact.debug("balanceAccounting - Balance=" + diff); FactLine line = null; // Create Currency Entry if (m_acctSchema.isCurrencyBalancing()) { if (m_lines.size() == 0) { log4jFact.error("balanceAccounting failed."); return null; } FactLine fl = (FactLine) m_lines.get(0); line = new FactLine(m_doc.AD_Table_ID, m_doc.Record_ID, "", fl.m_Fact_Acct_Group_ID, fl.m_SeqNo, fl.m_DocBaseType); line.setDocumentInfo(m_doc, null); line.setJournalInfo(m_doc.GL_Category_ID); line.setPostingType(m_postingType); // Amount line.setAmtSource(m_doc.C_Currency_ID, ZERO.toString(), ZERO.toString()); line.convert(m_acctSchema.getC_Currency_ID(), m_doc.DateAcct, m_acctSchema.getCurrencyRateType(), conn); if (diff.compareTo(ZERO) < 0) line.setAmtAcct(diff.abs().toString(), ZERO.toString()); else line.setAmtAcct(ZERO.toString(), diff.abs().toString()); line.setAccount(m_acctSchema, m_acctSchema.getCurrencyBalancing_Acct()); log4jFact.debug("balanceAccounting - " + line.toString()); log4jFact.debug("************* fact - balanceAccounting - m_lines.size() - " + m_lines.size()); m_lines.add(line); } else { // Adjust biggest (Balance Sheet) line amount BigDecimal BSamount = ZERO; FactLine BSline = null; BigDecimal PLamount = ZERO; FactLine PLline = null; int signum = diff.signum(); // Find line for (int i = 0; i < m_lines.size(); i++) { FactLine l = (FactLine) m_lines.get(i); BigDecimal amt = l.getAccountingBalance(); // amt = amt.abs(); if (l.isBalanceSheet() && ((amt.compareTo(BSamount) > 0 && signum != 1)) || ((amt.compareTo(BSamount) < 0 && signum == 1))) { BSamount = amt; BSline = l; } else if (!l.isBalanceSheet() && ((amt.compareTo(BSamount) > 0 && signum != 1)) || ((amt.compareTo(BSamount) < 0 && signum == 1))) { PLamount = amt; PLline = l; } } if (BSline != null) line = BSline; else line = PLline; if (line == null) log4jFact.error("balanceAccounting - No Line found"); else { log4jFact.debug("Adjusting Amt=" + diff.toString() + "; Line=" + line.toString()); line.currencyCorrect(diff); log4jFact.debug("balanceAccounting - " + line.toString()); } } // correct biggest amount // Debug info only this.isAcctBalanced(); return line; }
From source file:net.pms.util.Rational.java
/** * Returns a {@link Rational} whose value is {@code (this / value)}. * * @param value the value by which this {@link Rational} is to be divided. * @return The division result./* www . j a v a 2 s . co m*/ */ @Nullable public Rational divide(@Nullable BigDecimal value) { if (value == null) { return null; } if (isNaN()) { return NaN; } if (value.signum() == 0) { if (signum() == 0) { return NaN; } return signum() > 0 ? POSITIVE_INFINITY : NEGATIVE_INFINITY; } if (signum() == 0 || isInfinite() || BigDecimal.ONE.equals(value.abs())) { return value.signum() < 0 ? negate() : this; } return divide(valueOf(value)); }
From source file:net.pms.util.Rational.java
/** * Returns a {@link Rational} whose value is {@code (this + value)}. * * @param value the value to be added to this {@link Rational}. * @return The addition result./*from ww w. j a v a 2 s . co m*/ */ @Nullable public Rational add(@Nullable BigDecimal value) { if (value == null) { return null; } if (isNaN()) { return NaN; } if (isInfinite() || value.signum() == 0) { return this; } return add(valueOf(value)); }
From source file:org.openbravo.costing.AverageCostAdjustment.java
@Override protected void getRelatedTransactionsByAlgorithm() { // Search all transactions after the date of the adjusted line and recalculate the costs of them // to adjust differences MaterialTransaction basetrx = getTransaction(); // Transactions of closing inventories are managed by generic CostAdjustmentProcess adjusting // the cost of the related opening inventory. if (basetrx.getPhysicalInventoryLine() != null && basetrx.getPhysicalInventoryLine().getRelatedInventory() != null) { return;/*from ww w . j a v a 2s. com*/ } BigDecimal signMultiplier = new BigDecimal(basetrx.getMovementQuantity().signum()); Date trxDate = basetrx.getTransactionProcessDate(); BigDecimal adjustmentBalance = BigDecimal.ZERO; BigDecimal unitCostAdjustmentBalance = BigDecimal.ZERO; // Initialize adjustment balance looping through all cost adjustment lines of current // transaction. log.debug("Initialize adjustment balance"); CostAdjustmentLine baseCAL = getCostAdjLine(); for (CostAdjustmentLine costAdjLine : getTrxAdjustmentLines(basetrx)) { if (costAdjLine.isSource() && !costAdjLine.isRelatedTransactionAdjusted() && !costAdjLine.getId().equals(strCostAdjLineId)) { searchRelatedTransactionCosts(costAdjLine); } costAdjLine.setRelatedTransactionAdjusted(Boolean.TRUE); if (!costAdjLine.getId().equals(strCostAdjLineId)) { costAdjLine.setParentCostAdjustmentLine(baseCAL); } OBDal.getInstance().save(costAdjLine); // If the cost adjustment line has Transaction Costs those adjustment amount are included // in the Current Value Amount and not in the Adjustment Balance if (!costAdjLine.getTransactionCostList().isEmpty()) { continue; } BigDecimal adjustmentAmt = costAdjLine.getAdjustmentAmount(); if (!strCostCurrencyId.equals(costAdjLine.getCurrency().getId())) { adjustmentAmt = FinancialUtils.getConvertedAmount(adjustmentAmt, costAdjLine.getCurrency(), getCostCurrency(), costAdjLine.getAccountingDate(), getCostOrg(), FinancialUtils.PRECISION_STANDARD); } adjustmentBalance = adjustmentBalance.add(adjustmentAmt.multiply(signMultiplier)); if (costAdjLine.isUnitCost()) { unitCostAdjustmentBalance = unitCostAdjustmentBalance.add(adjustmentAmt); } } // Initialize current stock qty and value amt. BigDecimal currentStock = CostAdjustmentUtils.getStockOnTransactionDate(getCostOrg(), basetrx, getCostDimensions(), isManufacturingProduct, areBackdatedTrxFixed); BigDecimal currentValueAmt = CostAdjustmentUtils.getValuedStockOnTransactionDate(getCostOrg(), basetrx, getCostDimensions(), isManufacturingProduct, areBackdatedTrxFixed, getCostCurrency()); log.debug( "Adjustment balance: " + adjustmentBalance.toPlainString() + ", current stock {}, current value {}", currentStock.toPlainString(), currentValueAmt.toPlainString()); // Initialize current unit cost including the cost adjustments. Costing costing = AverageAlgorithm.getProductCost(trxDate, basetrx.getProduct(), getCostDimensions(), getCostOrg()); if (costing == null) { throw new OBException("@NoAvgCostDefined@ @Organization@: " + getCostOrg().getName() + ", @Product@: " + basetrx.getProduct().getName() + ", @Date@: " + OBDateUtils.formatDate(trxDate)); } BigDecimal cost = null; // If current stock is zero the cost is not modified until a related transaction that modifies // the stock is found. if (currentStock.signum() != 0) { cost = currentValueAmt.add(adjustmentBalance).divide(currentStock, costCurPrecission, RoundingMode.HALF_UP); } log.debug("Starting average cost {}", cost == null ? "not cost" : cost.toPlainString()); if (cost != null && (AverageAlgorithm.modifiesAverage(trxType) || !baseCAL.isBackdatedTrx())) { BigDecimal trxUnitCost = CostAdjustmentUtils.getTrxCost(basetrx, true, getCostCurrency()); BigDecimal trxPrice = null; if (basetrx.getMovementQuantity().signum() == 0) { trxPrice = BigDecimal.ZERO; } else { trxPrice = trxUnitCost.add(unitCostAdjustmentBalance).divide(basetrx.getMovementQuantity().abs(), costCurPrecission, RoundingMode.HALF_UP); } if (checkNegativeStockCorrection && currentStock.compareTo(basetrx.getMovementQuantity()) < 0 && cost.compareTo(trxPrice) != 0 && !baseCAL.isNegativeStockCorrection() && AverageAlgorithm.modifiesAverage(trxType)) { // stock was negative and cost different than trx price then Negative Stock Correction // is added BigDecimal trxSignMultiplier = new BigDecimal(basetrx.getMovementQuantity().signum()); BigDecimal negCorrAmt = trxPrice.multiply(currentStock) .setScale(stdCurPrecission, RoundingMode.HALF_UP).subtract(currentValueAmt) .subtract(adjustmentBalance); adjustmentBalance = adjustmentBalance.add(negCorrAmt.multiply(trxSignMultiplier)); // If there is a difference insert a cost adjustment line. CostAdjustmentLine newCAL = insertCostAdjustmentLine(basetrx, negCorrAmt, null); newCAL.setNegativeStockCorrection(Boolean.TRUE); newCAL.setRelatedTransactionAdjusted(Boolean.TRUE); newCAL.setUnitCost(Boolean.FALSE); OBDal.getInstance().save(newCAL); cost = trxPrice; log.debug("Negative stock correction. Amount: {}, new cost {}", negCorrAmt.toPlainString(), cost.toPlainString()); } if (basetrx.getMaterialMgmtCostingList().size() == 0) { Date newDate = new Date(); Date dateTo = costing.getEndingDate(); costing.setEndingDate(newDate); OBDal.getInstance().save(costing); Costing newCosting = OBProvider.getInstance().get(Costing.class); newCosting.setCost(cost); newCosting.setCurrency( (Currency) OBDal.getInstance().getProxy(Currency.ENTITY_NAME, strCostCurrencyId)); newCosting.setStartingDate(newDate); newCosting.setEndingDate(dateTo); newCosting.setInventoryTransaction(basetrx); newCosting.setProduct(basetrx.getProduct()); if (isManufacturingProduct) { newCosting.setOrganization( (Organization) OBDal.getInstance().getProxy(Organization.ENTITY_NAME, "0")); } else { newCosting.setOrganization( (Organization) OBDal.getInstance().getProxy(Organization.ENTITY_NAME, strCostOrgId)); } newCosting.setQuantity(basetrx.getMovementQuantity()); newCosting.setTotalMovementQuantity(currentStock); newCosting.setPrice(cost); newCosting.setCostType("AVA"); newCosting.setManual(Boolean.FALSE); newCosting.setPermanent(Boolean.TRUE); newCosting.setProduction(trxType == TrxType.ManufacturingProduced); newCosting.setWarehouse((Warehouse) getCostDimensions().get(CostDimension.Warehouse)); OBDal.getInstance().save(newCosting); OBDal.getInstance().flush(); } else { Costing curCosting = basetrx.getMaterialMgmtCostingList().get(0); if (curCosting.getCost().compareTo(cost) != 0 || curCosting.getTotalMovementQuantity().compareTo(currentStock) != 0) { curCosting.setPermanent(Boolean.FALSE); OBDal.getInstance().save(curCosting); OBDal.getInstance().flush(); // Update existing costing if (curCosting.getCost().compareTo(cost) != 0) { if (curCosting.getOriginalCost() == null) { curCosting.setOriginalCost(curCosting.getCost()); } curCosting.setCost(cost); curCosting.setPrice(trxPrice); } curCosting.setTotalMovementQuantity(currentStock); curCosting.setPermanent(Boolean.TRUE); OBDal.getInstance().flush(); OBDal.getInstance().save(curCosting); } } } // Modify isManufacturingProduct flag in case it has changed at some point. isManufacturingProduct = ((String) DalUtil.getId(costing.getOrganization())).equals("0"); ScrollableResults trxs = getRelatedTransactions(); String strCurrentCurId = strCostCurrencyId; try { while (trxs.next()) { MaterialTransaction trx = (MaterialTransaction) trxs.get()[0]; log.debug("Process related transaction {}", trx.getIdentifier()); BigDecimal trxSignMultiplier = new BigDecimal(trx.getMovementQuantity().signum()); BigDecimal trxAdjAmt = BigDecimal.ZERO; BigDecimal trxUnitCostAdjAmt = BigDecimal.ZERO; if (StringUtils.isNotEmpty(bdCostingId) && !isBackdatedTransaction(trx)) { // If there is a backdated source adjustment pending modify the dates of its m_costing. updateBDCostingTimeRange(trx); // This update is done only on the first related transaction. bdCostingId = ""; } if (!strCurrentCurId.equals(trx.getCurrency().getId())) { Currency curCurrency = OBDal.getInstance().get(Currency.class, strCurrentCurId); Organization costOrg = getCostOrg(); currentValueAmt = FinancialUtils.getConvertedAmount(currentValueAmt, curCurrency, trx.getCurrency(), trx.getMovementDate(), costOrg, FinancialUtils.PRECISION_STANDARD); if (cost != null) { cost = FinancialUtils.getConvertedAmount(cost, curCurrency, trx.getCurrency(), trx.getMovementDate(), costOrg, FinancialUtils.PRECISION_COSTING); } strCurrentCurId = trx.getCurrency().getId(); } List<CostAdjustmentLine> existingAdjLines = getTrxAdjustmentLines(trx); for (CostAdjustmentLine existingCAL : existingAdjLines) { if (existingCAL.isSource() && !existingCAL.isRelatedTransactionAdjusted()) { searchRelatedTransactionCosts(existingCAL); } if (existingCAL.getTransactionCostList().isEmpty() && !existingCAL.isRelatedTransactionAdjusted()) { BigDecimal adjustmentAmt = existingCAL.getAdjustmentAmount(); if (!strCurrentCurId.equals(existingCAL.getCurrency().getId())) { Currency curCurrency = OBDal.getInstance().get(Currency.class, strCurrentCurId); adjustmentAmt = FinancialUtils.getConvertedAmount(adjustmentAmt, existingCAL.getCurrency(), curCurrency, existingCAL.getAccountingDate(), getCostOrg(), FinancialUtils.PRECISION_STANDARD); } trxAdjAmt = trxAdjAmt.add(adjustmentAmt); adjustmentBalance = adjustmentBalance.add(adjustmentAmt.multiply(trxSignMultiplier)); if (existingCAL.isUnitCost()) { trxUnitCostAdjAmt = trxUnitCostAdjAmt.add(adjustmentAmt); } } existingCAL.setRelatedTransactionAdjusted(Boolean.TRUE); existingCAL.setParentCostAdjustmentLine((CostAdjustmentLine) OBDal.getInstance() .getProxy(CostAdjustmentLine.ENTITY_NAME, strCostAdjLineId)); OBDal.getInstance().save(existingCAL); } log.debug("Current trx adj amount of existing CALs {}", trxAdjAmt.toPlainString()); BigDecimal trxCost = CostAdjustmentUtils.getTrxCost(trx, false, OBDal.getInstance().get(Currency.class, strCurrentCurId)); BigDecimal trxUnitCost = CostAdjustmentUtils.getTrxCost(trx, true, OBDal.getInstance().get(Currency.class, strCurrentCurId)); currentValueAmt = currentValueAmt.add(trxCost.multiply(trxSignMultiplier)); currentStock = currentStock.add(trx.getMovementQuantity()); log.debug("Updated current stock {} and, current value {}", currentStock.toPlainString(), currentValueAmt.toPlainString()); TrxType currentTrxType = TrxType.getTrxType(trx); if (AverageAlgorithm.modifiesAverage(currentTrxType)) { // Recalculate average, if current stock is zero the average is not modified if (currentStock.signum() != 0) { cost = currentValueAmt.add(adjustmentBalance).divide(currentStock, costCurPrecission, RoundingMode.HALF_UP); } if (cost == null) { continue; } log.debug("New average cost: {}", cost.toPlainString()); Costing curCosting = trx.getMaterialMgmtCostingList().get(0); BigDecimal trxPrice = null; if (trx.getMovementQuantity().signum() == 0) { trxPrice = BigDecimal.ZERO; } else { trxPrice = trxUnitCost.add(trxUnitCostAdjAmt).divide(trx.getMovementQuantity().abs(), costCurPrecission, RoundingMode.HALF_UP); } if (checkNegativeStockCorrection && currentStock.compareTo(trx.getMovementQuantity()) < 0 && cost.compareTo(trxPrice) != 0) { // stock was negative and cost different than trx price then Negative Stock Correction // is added BigDecimal negCorrAmt = trxPrice.multiply(currentStock) .setScale(stdCurPrecission, RoundingMode.HALF_UP).subtract(currentValueAmt) .subtract(adjustmentBalance); adjustmentBalance = adjustmentBalance.add(negCorrAmt.multiply(trxSignMultiplier)); trxAdjAmt = trxAdjAmt.add(negCorrAmt.multiply(trxSignMultiplier)); // If there is a difference insert a cost adjustment line. CostAdjustmentLine newCAL = insertCostAdjustmentLine(trx, negCorrAmt, null); newCAL.setNegativeStockCorrection(Boolean.TRUE); newCAL.setRelatedTransactionAdjusted(Boolean.TRUE); newCAL.setUnitCost(Boolean.FALSE); OBDal.getInstance().save(newCAL); cost = trxPrice; log.debug("Negative stock correction. Amount: {}, new cost {}", negCorrAmt.toPlainString(), cost.toPlainString()); } if (curCosting.getCost().compareTo(cost) == 0 && StringUtils.isEmpty(bdCostingId) && curCosting.getTotalMovementQuantity().compareTo(currentStock) == 0) { // new cost hasn't changed and total movement qty is equal to current stock, following // transactions will have the same cost, so no more // related transactions are needed to include. // If bdCosting is not empty it is needed to loop through the next related transaction // to set the new time ringe of the costing. log.debug("New cost matches existing cost. Adjustment finished."); return; } else { // Update existing costing curCosting.setPermanent(Boolean.FALSE); OBDal.getInstance().save(curCosting); OBDal.getInstance().flush(); if (curCosting.getCost().compareTo(cost) != 0) { if (curCosting.getOriginalCost() == null) { curCosting.setOriginalCost(curCosting.getCost()); } curCosting.setPrice(trxPrice); curCosting.setCost(cost); } curCosting.setTotalMovementQuantity(currentStock); curCosting.setPermanent(Boolean.TRUE); OBDal.getInstance().save(curCosting); } } else if (cost != null && !isVoidedTrx(trx, currentTrxType)) { if (!trx.isCostPermanent()) { // Check current trx unit cost matches new expected cost BigDecimal expectedCost = cost.multiply(trx.getMovementQuantity().abs()) .setScale(stdCurPrecission, RoundingMode.HALF_UP); BigDecimal unitCost = CostAdjustmentUtils.getTrxCost(trx, true, OBDal.getInstance().get(Currency.class, strCurrentCurId)); unitCost = unitCost.add(trxAdjAmt); log.debug("Is adjustment needed? Expected {} vs Current {}", expectedCost.toPlainString(), unitCost.toPlainString()); if (expectedCost.compareTo(unitCost) != 0) { trxAdjAmt = trxAdjAmt.add(expectedCost.subtract(unitCost).multiply(trxSignMultiplier)); trxUnitCostAdjAmt = trxUnitCostAdjAmt.add(expectedCost.subtract(unitCost)); adjustmentBalance = adjustmentBalance .add(expectedCost.subtract(unitCost).multiply(trxSignMultiplier)); // If there is a difference insert a cost adjustment line. CostAdjustmentLine newCAL = insertCostAdjustmentLine(trx, expectedCost.subtract(unitCost), null); newCAL.setRelatedTransactionAdjusted(Boolean.TRUE); OBDal.getInstance().save(newCAL); log.debug("Adjustment added. Amount {}.", expectedCost.subtract(unitCost).toPlainString()); } } if (trx.getMaterialMgmtCostingList().size() != 0) { Costing curCosting = trx.getMaterialMgmtCostingList().get(0); if (currentStock.signum() != 0) { cost = currentValueAmt.add(adjustmentBalance).divide(currentStock, costCurPrecission, RoundingMode.HALF_UP); } BigDecimal trxPrice = null; if (trx.getMovementQuantity().signum() == 0) { trxPrice = BigDecimal.ZERO; } else { trxPrice = trxUnitCost.add(trxUnitCostAdjAmt).divide(trx.getMovementQuantity().abs(), costCurPrecission, RoundingMode.HALF_UP); } if (curCosting.getCost().compareTo(cost) != 0 || curCosting.getTotalMovementQuantity().compareTo(currentStock) != 0) { curCosting.setPermanent(Boolean.FALSE); OBDal.getInstance().save(curCosting); OBDal.getInstance().flush(); if (curCosting.getCost().compareTo(cost) != 0) { if (curCosting.getOriginalCost() == null) { curCosting.setOriginalCost(curCosting.getCost()); } curCosting.setPrice(trxPrice); curCosting.setCost(cost); } curCosting.setTotalMovementQuantity(currentStock); curCosting.setPermanent(Boolean.TRUE); OBDal.getInstance().save(curCosting); } } } OBDal.getInstance().flush(); OBDal.getInstance().getSession().clear(); } } finally { trxs.close(); } if (getCostingRule().getEndingDate() == null && cost != null) { // This is the current costing rule. Check if current average cost needs to be updated. Costing currentCosting = AverageAlgorithm.getProductCost(new Date(), basetrx.getProduct(), getCostDimensions(), getCostOrg()); if (currentCosting == null) { throw new OBException("@NoAvgCostDefined@ @Organization@: " + getCostOrg().getName() + ", @Product@: " + basetrx.getProduct().getName() + ", @Date@: " + OBDateUtils.formatDate(new Date())); } if (currentCosting.getCost().compareTo(cost) != 0) { basetrx = getTransaction(); Date newDate = new Date(); Date dateTo = currentCosting.getEndingDate(); currentCosting.setEndingDate(newDate); OBDal.getInstance().save(currentCosting); Costing newCosting = OBProvider.getInstance().get(Costing.class); newCosting.setCost(cost); newCosting.setCurrency( (Currency) OBDal.getInstance().getProxy(Currency.ENTITY_NAME, strCurrentCurId)); newCosting.setStartingDate(newDate); newCosting.setEndingDate(dateTo); newCosting.setInventoryTransaction(null); newCosting.setProduct(basetrx.getProduct()); if (isManufacturingProduct) { newCosting.setOrganization( (Organization) OBDal.getInstance().getProxy(Organization.ENTITY_NAME, "0")); } else { newCosting.setOrganization( (Organization) OBDal.getInstance().getProxy(Organization.ENTITY_NAME, strCostOrgId)); } newCosting.setQuantity(null); newCosting.setTotalMovementQuantity(currentStock); newCosting.setPrice(cost); newCosting.setCostType("AVA"); newCosting.setManual(Boolean.FALSE); newCosting.setPermanent(Boolean.TRUE); newCosting.setProduction(trxType == TrxType.ManufacturingProduced); newCosting.setWarehouse((Warehouse) getCostDimensions().get(CostDimension.Warehouse)); OBDal.getInstance().save(newCosting); } } }
From source file:org.ofbiz.accounting.invoice.InvoiceServices.java
public static Map<String, Object> createCommissionInvoices(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"); List<String> salesInvoiceIds = UtilGenerics.checkList(context.get("invoiceIds")); List<Map<String, String>> invoicesCreated = FastList.newInstance(); Map<String, List<Map<String, Object>>> commissionParties = FastMap.newInstance(); for (String salesInvoiceId : salesInvoiceIds) { List<String> salesRepPartyIds = UtilGenerics.checkList(context.get("partyIds")); BigDecimal amountTotal = InvoiceWorker.getInvoiceTotal(delegator, salesInvoiceId); if (amountTotal.signum() == 0) { Debug.logWarning("Invoice [" + salesInvoiceId + "] has an amount total of [" + amountTotal + "], so no commission invoice will be created", module); return ServiceUtil.returnError(UtilProperties.getMessage(resource, "AccountingInvoiceCommissionZeroInvoiceAmount", locale)); }/*from w w w.j av a 2s.co m*/ BigDecimal appliedFraction = amountTotal.divide(amountTotal, 12, ROUNDING); GenericValue invoice = null; boolean isReturn = false; List<String> billFromVendorInvoiceRoles = new ArrayList<String>(); List<GenericValue> invoiceItems = new ArrayList<GenericValue>(); try { List<EntityExpr> invoiceRoleConds = UtilMisc.toList( EntityCondition.makeCondition("invoiceId", EntityOperator.EQUALS, salesInvoiceId), EntityCondition.makeCondition("roleTypeId", EntityOperator.EQUALS, "BILL_FROM_VENDOR")); EntityQuery roleQuery = EntityQuery.use(delegator).select("partyId").from("InvoiceRole") .where(invoiceRoleConds); billFromVendorInvoiceRoles = EntityUtil.getFieldListFromEntityList(roleQuery.queryList(), "partyId", true); invoiceRoleConds = UtilMisc.toList( EntityCondition.makeCondition("invoiceId", EntityOperator.EQUALS, salesInvoiceId), EntityCondition.makeCondition("roleTypeId", EntityOperator.EQUALS, "SALES_REP")); // if the receiving parties is empty then we will create commission invoices for all sales agent associated to sales invoice. if (UtilValidate.isEmpty(salesRepPartyIds)) { salesRepPartyIds = EntityUtil.getFieldListFromEntityList( roleQuery.where(invoiceRoleConds).queryList(), "partyId", true); if (UtilValidate.isEmpty(salesRepPartyIds)) { return ServiceUtil.returnError(UtilProperties.getMessage(resource, "No party found with role sales representative for sales invoice " + salesInvoiceId, locale)); } } else { List<String> salesInvoiceRolePartyIds = EntityUtil.getFieldListFromEntityList( roleQuery.where(invoiceRoleConds).queryList(), "partyId", true); if (UtilValidate.isNotEmpty(salesInvoiceRolePartyIds)) { salesRepPartyIds = UtilGenerics.checkList( CollectionUtils.intersection(salesRepPartyIds, salesInvoiceRolePartyIds)); } } invoice = EntityQuery.use(delegator).from("Invoice").where("invoiceId", salesInvoiceId).queryOne(); String invoiceTypeId = invoice.getString("invoiceTypeId"); if ("CUST_RTN_INVOICE".equals(invoiceTypeId)) { isReturn = true; } else if (!"SALES_INVOICE".equals(invoiceTypeId)) { Debug.logWarning("This type of invoice has no commission; returning success", module); return ServiceUtil.returnError( UtilProperties.getMessage(resource, "AccountingInvoiceCommissionInvalid", locale)); } invoiceItems = EntityQuery.use(delegator).from("InvoiceItem").where("invoiceId", salesInvoiceId) .queryList(); } catch (GenericEntityException e) { return ServiceUtil.returnError(e.getMessage()); } // Map of commission Lists (of Maps) for each party. // Determine commissions for various parties. for (GenericValue invoiceItem : invoiceItems) { BigDecimal amount = ZERO; BigDecimal quantity = ZERO; quantity = invoiceItem.getBigDecimal("quantity"); amount = invoiceItem.getBigDecimal("amount"); amount = isReturn ? amount.negate() : amount; String productId = invoiceItem.getString("productId"); String invoiceItemSeqId = invoiceItem.getString("invoiceItemSeqId"); String invoiceId = invoiceItem.getString("invoiceId"); // Determine commission parties for this invoiceItem if (UtilValidate.isNotEmpty(productId)) { Map<String, Object> resultMap = null; try { resultMap = dispatcher.runSync("getCommissionForProduct", UtilMisc.<String, Object>toMap("productId", productId, "invoiceId", invoiceId, "invoiceItemSeqId", invoiceItemSeqId, "invoiceItemTypeId", invoiceItem.getString("invoiceItemTypeId"), "amount", amount, "quantity", quantity, "userLogin", userLogin)); } catch (GenericServiceException e) { return ServiceUtil.returnError(e.getMessage()); } // build a Map of partyIds (both to and from) in a commission and the amounts // Note that getCommissionForProduct returns a List of Maps with a lot values. See services.xml definition for reference. List<Map<String, Object>> itemCommissions = UtilGenerics .checkList(resultMap.get("commissions")); if (UtilValidate.isNotEmpty(itemCommissions)) { for (Map<String, Object> commissionMap : itemCommissions) { commissionMap.put("invoice", invoice); commissionMap.put("appliedFraction", appliedFraction); if (!billFromVendorInvoiceRoles.contains(commissionMap.get("partyIdFrom")) || !salesRepPartyIds.contains(commissionMap.get("partyIdTo"))) { continue; } String partyIdFromTo = (String) commissionMap.get("partyIdFrom") + (String) commissionMap.get("partyIdTo"); if (!commissionParties.containsKey(partyIdFromTo)) { commissionParties.put(partyIdFromTo, UtilMisc.toList(commissionMap)); } else { (commissionParties.get(partyIdFromTo)).add(commissionMap); } } } } } } Timestamp now = UtilDateTime.nowTimestamp(); // Create invoice for each commission receiving party for (Map.Entry<String, List<Map<String, Object>>> commissionParty : commissionParties.entrySet()) { List<GenericValue> toStore = FastList.newInstance(); List<Map<String, Object>> commList = commissionParty.getValue(); // get the billing parties if (UtilValidate.isEmpty(commList)) { continue; } // From and To are reversed between commission and invoice String partyIdBillTo = (String) (commList.get(0)).get("partyIdFrom"); String partyIdBillFrom = (String) (commList.get(0)).get("partyIdTo"); GenericValue invoice = (GenericValue) (commList.get(0)).get("invoice"); BigDecimal appliedFraction = (BigDecimal) (commList.get(0)).get("appliedFraction"); Long days = (Long) (commList.get(0)).get("days"); // create the invoice record // To and From are in commission's sense, opposite for invoice Map<String, Object> createInvoiceMap = FastMap.newInstance(); createInvoiceMap.put("partyId", partyIdBillTo); createInvoiceMap.put("partyIdFrom", partyIdBillFrom); createInvoiceMap.put("invoiceDate", now); // if there were days associated with the commission agreement, then set a dueDate for the invoice. if (days != null) { createInvoiceMap.put("dueDate", UtilDateTime.getDayEnd(now, days)); } createInvoiceMap.put("invoiceTypeId", "COMMISSION_INVOICE"); // start with INVOICE_IN_PROCESS, in the INVOICE_READY we can't change the invoice (or shouldn't be able to...) createInvoiceMap.put("statusId", "INVOICE_IN_PROCESS"); createInvoiceMap.put("currencyUomId", invoice.getString("currencyUomId")); createInvoiceMap.put("userLogin", userLogin); // store the invoice first Map<String, Object> createInvoiceResult = null; try { createInvoiceResult = dispatcher.runSync("createInvoice", createInvoiceMap); } catch (GenericServiceException e) { return ServiceUtil.returnError( UtilProperties.getMessage(resource, "AccountingInvoiceCommissionError", locale), null, null, createInvoiceResult); } String invoiceId = (String) createInvoiceResult.get("invoiceId"); // create the bill-from (or pay-to) contact mech as the primary PAYMENT_LOCATION of the party from the store GenericValue partyContactMechPurpose = null; try { partyContactMechPurpose = EntityQuery.use(delegator).from("PartyContactMechPurpose") .where("partyId", partyIdBillTo, "contactMechPurposeTypeId", "BILLING_LOCATION") .queryFirst(); } catch (GenericEntityException e) { return ServiceUtil.returnError(e.getMessage()); } if (partyContactMechPurpose != null) { GenericValue invoiceContactMech = delegator.makeValue("InvoiceContactMech", UtilMisc.toMap("invoiceId", invoiceId, "contactMechId", partyContactMechPurpose.getString("contactMechId"), "contactMechPurposeTypeId", "BILLING_LOCATION")); toStore.add(invoiceContactMech); } try { partyContactMechPurpose = EntityQuery.use(delegator).from("PartyContactMechPurpose") .where("partyId", partyIdBillTo, "contactMechPurposeTypeId", "PAYMENT_LOCATION") .queryFirst(); } catch (GenericEntityException e) { return ServiceUtil.returnError(e.getMessage()); } if (partyContactMechPurpose != null) { GenericValue invoiceContactMech = delegator.makeValue("InvoiceContactMech", UtilMisc.toMap("invoiceId", invoiceId, "contactMechId", partyContactMechPurpose.getString("contactMechId"), "contactMechPurposeTypeId", "PAYMENT_LOCATION")); toStore.add(invoiceContactMech); } // create the item records for (Map<String, Object> commissionMap : commList) { BigDecimal elemAmount = ((BigDecimal) commissionMap.get("commission")).multiply(appliedFraction); BigDecimal quantity = (BigDecimal) commissionMap.get("quantity"); String invoiceIdFrom = (String) commissionMap.get("invoiceId"); String invoiceItemSeqIdFrom = (String) commissionMap.get("invoiceItemSeqId"); elemAmount = elemAmount.setScale(DECIMALS, ROUNDING); Map<String, Object> resMap = null; try { resMap = dispatcher.runSync("createInvoiceItem", UtilMisc.toMap("invoiceId", invoiceId, "productId", commissionMap.get("productId"), "invoiceItemTypeId", "COMM_INV_ITEM", "quantity", quantity, "amount", elemAmount, "userLogin", userLogin)); dispatcher.runSync("createInvoiceItemAssoc", UtilMisc.toMap("invoiceIdFrom", invoiceIdFrom, "invoiceItemSeqIdFrom", invoiceItemSeqIdFrom, "invoiceIdTo", invoiceId, "invoiceItemSeqIdTo", resMap.get("invoiceItemSeqId"), "invoiceItemAssocTypeId", "COMMISSION_INVOICE", "partyIdFrom", partyIdBillFrom, "partyIdTo", partyIdBillTo, "quantity", quantity, "amount", elemAmount, "userLogin", userLogin)); } catch (GenericServiceException e) { return ServiceUtil.returnError(e.getMessage()); } if (ServiceUtil.isError(resMap)) { return ServiceUtil.returnError( UtilProperties.getMessage(resource, "AccountingInvoiceCommissionErrorItem", locale), null, null, resMap); } } // store value objects try { delegator.storeAll(toStore); } catch (GenericEntityException e) { Debug.logError(e, "Entity/data problem creating commission invoice: " + e.toString(), module); return ServiceUtil.returnError( UtilProperties.getMessage(resource, "AccountingInvoiceCommissionEntityDataProblem", UtilMisc.toMap("reason", e.toString()), locale)); } invoicesCreated.add(UtilMisc.<String, String>toMap("commissionInvoiceId", invoiceId, "salesRepresentative ", partyIdBillFrom)); } String invCreated = new Integer(invoicesCreated.size()).toString(); Map<String, Object> result = ServiceUtil.returnSuccess(UtilProperties.getMessage(resource, "AccountingCommissionInvoicesCreated", UtilMisc.toMap("invoicesCreated", invCreated), locale)); Debug.logInfo("Created Commission invoices for each commission receiving parties " + invCreated, module); result.put("invoicesCreated", invoicesCreated); return result; }
From source file:org.ofbiz.accounting.invoice.InvoiceServices.java
public static Map<String, Object> checkInvoicePaymentApplications(DispatchContext ctx, Map<String, Object> context) { Delegator delegator = ctx.getDelegator(); LocalDispatcher dispatcher = ctx.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)); }/* w ww .j a va 2 s . c o m*/ String invoiceId = (String) context.get("invoiceId"); GenericValue invoice = null; try { invoice = EntityQuery.use(delegator).from("Invoice").where("invoiceId", invoiceId).queryOne(); } catch (GenericEntityException e) { Debug.logError(e, "Problem getting Invoice for Invoice ID" + invoiceId, module); return ServiceUtil.returnError(UtilProperties.getMessage(resource, "AccountingInvoiceNotFound", UtilMisc.toMap("invoiceId", invoiceId), locale)); } // Ignore invoices that aren't ready yet if (!invoice.getString("statusId").equals("INVOICE_READY")) { return ServiceUtil.returnSuccess(); } // Get the payment applications that can be used to pay the invoice List<GenericValue> paymentAppl = null; try { paymentAppl = EntityQuery.use(delegator).from("PaymentAndApplication").where("invoiceId", invoiceId) .queryList(); // For each payment application, select only those that are RECEIVED or SENT based on whether the payment is a RECEIPT or DISBURSEMENT respectively for (Iterator<GenericValue> iter = paymentAppl.iterator(); iter.hasNext();) { GenericValue payment = iter.next(); if ("PMNT_RECEIVED".equals(payment.get("statusId")) && UtilAccounting.isReceipt(payment)) { continue; // keep } if ("PMNT_SENT".equals(payment.get("statusId")) && UtilAccounting.isDisbursement(payment)) { continue; // keep } // all other cases, remove the payment application iter.remove(); } } catch (GenericEntityException e) { Debug.logError(e, "Problem getting PaymentApplication(s) for Invoice ID " + invoiceId, module); return ServiceUtil.returnError(UtilProperties.getMessage(resource, "AccountingProblemGettingPaymentApplication", UtilMisc.toMap("invoiceId", invoiceId), locale)); } Map<String, BigDecimal> payments = FastMap.newInstance(); Timestamp paidDate = null; for (GenericValue payAppl : paymentAppl) { payments.put(payAppl.getString("paymentId"), payAppl.getBigDecimal("amountApplied")); // paidDate will be the last date (chronologically) of all the Payments applied to this invoice Timestamp paymentDate = payAppl.getTimestamp("effectiveDate"); if (paymentDate != null) { if ((paidDate == null) || (paidDate.before(paymentDate))) { paidDate = paymentDate; } } } BigDecimal totalPayments = ZERO; for (BigDecimal amount : payments.values()) { if (amount == null) amount = ZERO; totalPayments = totalPayments.add(amount).setScale(DECIMALS, ROUNDING); } if (totalPayments.signum() == 1) { BigDecimal invoiceTotal = InvoiceWorker.getInvoiceTotal(delegator, invoiceId); if (Debug.verboseOn()) { Debug.logVerbose("Invoice #" + invoiceId + " total: " + invoiceTotal, module); Debug.logVerbose("Total payments : " + totalPayments, module); } if (totalPayments.compareTo(invoiceTotal) >= 0) { // this checks that totalPayments is greater than or equal to invoiceTotal // this invoice is paid Map<String, Object> svcCtx = UtilMisc.toMap("statusId", "INVOICE_PAID", "invoiceId", invoiceId, "paidDate", paidDate, "userLogin", userLogin); try { dispatcher.runSync("setInvoiceStatus", svcCtx); } catch (GenericServiceException e) { Debug.logError(e, "Problem changing invoice status to INVOICE_PAID" + svcCtx, module); return ServiceUtil.returnError( UtilProperties.getMessage(resource, "AccountingProblemChangingInvoiceStatusTo", UtilMisc.toMap("newStatus", "INVOICE_PAID"), locale)); } } } else { Debug.logInfo("No payments found for Invoice #" + invoiceId, module); } return ServiceUtil.returnSuccess(); }
From source file:org.apache.ofbiz.accounting.invoice.InvoiceServices.java
public static Map<String, Object> createCommissionInvoices(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"); List<String> salesInvoiceIds = UtilGenerics.checkList(context.get("invoiceIds")); List<Map<String, String>> invoicesCreated = new LinkedList<Map<String, String>>(); Map<String, List<Map<String, Object>>> commissionParties = new HashMap<String, List<Map<String, Object>>>(); for (String salesInvoiceId : salesInvoiceIds) { List<String> salesRepPartyIds = UtilGenerics.checkList(context.get("partyIds")); BigDecimal amountTotal = InvoiceWorker.getInvoiceTotal(delegator, salesInvoiceId); if (amountTotal.signum() == 0) { Debug.logWarning("Invoice [" + salesInvoiceId + "] has an amount total of [" + amountTotal + "], so no commission invoice will be created", module); return ServiceUtil.returnError(UtilProperties.getMessage(resource, "AccountingInvoiceCommissionZeroInvoiceAmount", locale)); }/*from www . j a v a 2 s . c o m*/ BigDecimal appliedFraction = amountTotal.divide(amountTotal, 12, ROUNDING); GenericValue invoice = null; boolean isReturn = false; List<String> billFromVendorInvoiceRoles = new ArrayList<String>(); List<GenericValue> invoiceItems = new ArrayList<GenericValue>(); try { List<EntityExpr> invoiceRoleConds = UtilMisc.toList( EntityCondition.makeCondition("invoiceId", EntityOperator.EQUALS, salesInvoiceId), EntityCondition.makeCondition("roleTypeId", EntityOperator.EQUALS, "BILL_FROM_VENDOR")); EntityQuery roleQuery = EntityQuery.use(delegator).select("partyId").from("InvoiceRole") .where(invoiceRoleConds); billFromVendorInvoiceRoles = EntityUtil.getFieldListFromEntityList(roleQuery.queryList(), "partyId", true); invoiceRoleConds = UtilMisc.toList( EntityCondition.makeCondition("invoiceId", EntityOperator.EQUALS, salesInvoiceId), EntityCondition.makeCondition("roleTypeId", EntityOperator.EQUALS, "SALES_REP")); // if the receiving parties is empty then we will create commission invoices for all sales agent associated to sales invoice. if (UtilValidate.isEmpty(salesRepPartyIds)) { salesRepPartyIds = EntityUtil.getFieldListFromEntityList( roleQuery.where(invoiceRoleConds).queryList(), "partyId", true); if (UtilValidate.isEmpty(salesRepPartyIds)) { return ServiceUtil.returnError(UtilProperties.getMessage(resource, "No party found with role sales representative for sales invoice " + salesInvoiceId, locale)); } } else { List<String> salesInvoiceRolePartyIds = EntityUtil.getFieldListFromEntityList( roleQuery.where(invoiceRoleConds).queryList(), "partyId", true); if (UtilValidate.isNotEmpty(salesInvoiceRolePartyIds)) { salesRepPartyIds = UtilGenerics.checkList( CollectionUtils.intersection(salesRepPartyIds, salesInvoiceRolePartyIds)); } } invoice = EntityQuery.use(delegator).from("Invoice").where("invoiceId", salesInvoiceId).queryOne(); String invoiceTypeId = invoice.getString("invoiceTypeId"); if ("CUST_RTN_INVOICE".equals(invoiceTypeId)) { isReturn = true; } else if (!"SALES_INVOICE".equals(invoiceTypeId)) { Debug.logWarning("This type of invoice has no commission; returning success", module); return ServiceUtil.returnError( UtilProperties.getMessage(resource, "AccountingInvoiceCommissionInvalid", locale)); } invoiceItems = EntityQuery.use(delegator).from("InvoiceItem").where("invoiceId", salesInvoiceId) .queryList(); } catch (GenericEntityException e) { return ServiceUtil.returnError(e.getMessage()); } // Map of commission Lists (of Maps) for each party. // Determine commissions for various parties. for (GenericValue invoiceItem : invoiceItems) { BigDecimal amount = ZERO; BigDecimal quantity = ZERO; quantity = invoiceItem.getBigDecimal("quantity"); amount = invoiceItem.getBigDecimal("amount"); amount = isReturn ? amount.negate() : amount; String productId = invoiceItem.getString("productId"); String invoiceItemSeqId = invoiceItem.getString("invoiceItemSeqId"); String invoiceId = invoiceItem.getString("invoiceId"); // Determine commission parties for this invoiceItem if (UtilValidate.isNotEmpty(productId)) { Map<String, Object> resultMap = null; try { resultMap = dispatcher.runSync("getCommissionForProduct", UtilMisc.<String, Object>toMap("productId", productId, "invoiceId", invoiceId, "invoiceItemSeqId", invoiceItemSeqId, "invoiceItemTypeId", invoiceItem.getString("invoiceItemTypeId"), "amount", amount, "quantity", quantity, "userLogin", userLogin)); } catch (GenericServiceException e) { return ServiceUtil.returnError(e.getMessage()); } // build a Map of partyIds (both to and from) in a commission and the amounts // Note that getCommissionForProduct returns a List of Maps with a lot values. See services.xml definition for reference. List<Map<String, Object>> itemCommissions = UtilGenerics .checkList(resultMap.get("commissions")); if (UtilValidate.isNotEmpty(itemCommissions)) { for (Map<String, Object> commissionMap : itemCommissions) { commissionMap.put("invoice", invoice); commissionMap.put("appliedFraction", appliedFraction); if (!billFromVendorInvoiceRoles.contains(commissionMap.get("partyIdFrom")) || !salesRepPartyIds.contains(commissionMap.get("partyIdTo"))) { continue; } String partyIdFromTo = (String) commissionMap.get("partyIdFrom") + (String) commissionMap.get("partyIdTo"); if (!commissionParties.containsKey(partyIdFromTo)) { commissionParties.put(partyIdFromTo, UtilMisc.toList(commissionMap)); } else { (commissionParties.get(partyIdFromTo)).add(commissionMap); } } } } } } Timestamp now = UtilDateTime.nowTimestamp(); // Create invoice for each commission receiving party for (Map.Entry<String, List<Map<String, Object>>> commissionParty : commissionParties.entrySet()) { List<GenericValue> toStore = new LinkedList<GenericValue>(); List<Map<String, Object>> commList = commissionParty.getValue(); // get the billing parties if (UtilValidate.isEmpty(commList)) { continue; } // From and To are reversed between commission and invoice String partyIdBillTo = (String) (commList.get(0)).get("partyIdFrom"); String partyIdBillFrom = (String) (commList.get(0)).get("partyIdTo"); GenericValue invoice = (GenericValue) (commList.get(0)).get("invoice"); BigDecimal appliedFraction = (BigDecimal) (commList.get(0)).get("appliedFraction"); Long days = (Long) (commList.get(0)).get("days"); // create the invoice record // To and From are in commission's sense, opposite for invoice Map<String, Object> createInvoiceMap = new HashMap<String, Object>(); createInvoiceMap.put("partyId", partyIdBillTo); createInvoiceMap.put("partyIdFrom", partyIdBillFrom); createInvoiceMap.put("invoiceDate", now); // if there were days associated with the commission agreement, then set a dueDate for the invoice. if (days != null) { createInvoiceMap.put("dueDate", UtilDateTime.getDayEnd(now, days)); } createInvoiceMap.put("invoiceTypeId", "COMMISSION_INVOICE"); // start with INVOICE_IN_PROCESS, in the INVOICE_READY we can't change the invoice (or shouldn't be able to...) createInvoiceMap.put("statusId", "INVOICE_IN_PROCESS"); createInvoiceMap.put("currencyUomId", invoice.getString("currencyUomId")); createInvoiceMap.put("userLogin", userLogin); // store the invoice first Map<String, Object> createInvoiceResult = null; try { createInvoiceResult = dispatcher.runSync("createInvoice", createInvoiceMap); } catch (GenericServiceException e) { return ServiceUtil.returnError( UtilProperties.getMessage(resource, "AccountingInvoiceCommissionError", locale), null, null, createInvoiceResult); } String invoiceId = (String) createInvoiceResult.get("invoiceId"); // create the bill-from (or pay-to) contact mech as the primary PAYMENT_LOCATION of the party from the store GenericValue partyContactMechPurpose = null; try { partyContactMechPurpose = EntityQuery.use(delegator).from("PartyContactMechPurpose") .where("partyId", partyIdBillTo, "contactMechPurposeTypeId", "BILLING_LOCATION") .queryFirst(); } catch (GenericEntityException e) { return ServiceUtil.returnError(e.getMessage()); } if (partyContactMechPurpose != null) { GenericValue invoiceContactMech = delegator.makeValue("InvoiceContactMech", UtilMisc.toMap("invoiceId", invoiceId, "contactMechId", partyContactMechPurpose.getString("contactMechId"), "contactMechPurposeTypeId", "BILLING_LOCATION")); toStore.add(invoiceContactMech); } try { partyContactMechPurpose = EntityQuery.use(delegator).from("PartyContactMechPurpose") .where("partyId", partyIdBillTo, "contactMechPurposeTypeId", "PAYMENT_LOCATION") .queryFirst(); } catch (GenericEntityException e) { return ServiceUtil.returnError(e.getMessage()); } if (partyContactMechPurpose != null) { GenericValue invoiceContactMech = delegator.makeValue("InvoiceContactMech", UtilMisc.toMap("invoiceId", invoiceId, "contactMechId", partyContactMechPurpose.getString("contactMechId"), "contactMechPurposeTypeId", "PAYMENT_LOCATION")); toStore.add(invoiceContactMech); } // create the item records for (Map<String, Object> commissionMap : commList) { BigDecimal elemAmount = ((BigDecimal) commissionMap.get("commission")).multiply(appliedFraction); BigDecimal quantity = (BigDecimal) commissionMap.get("quantity"); String invoiceIdFrom = (String) commissionMap.get("invoiceId"); String invoiceItemSeqIdFrom = (String) commissionMap.get("invoiceItemSeqId"); elemAmount = elemAmount.setScale(DECIMALS, ROUNDING); Map<String, Object> resMap = null; try { resMap = dispatcher.runSync("createInvoiceItem", UtilMisc.toMap("invoiceId", invoiceId, "productId", commissionMap.get("productId"), "invoiceItemTypeId", "COMM_INV_ITEM", "quantity", quantity, "amount", elemAmount, "userLogin", userLogin)); dispatcher.runSync("createInvoiceItemAssoc", UtilMisc.toMap("invoiceIdFrom", invoiceIdFrom, "invoiceItemSeqIdFrom", invoiceItemSeqIdFrom, "invoiceIdTo", invoiceId, "invoiceItemSeqIdTo", resMap.get("invoiceItemSeqId"), "invoiceItemAssocTypeId", "COMMISSION_INVOICE", "partyIdFrom", partyIdBillFrom, "partyIdTo", partyIdBillTo, "quantity", quantity, "amount", elemAmount, "userLogin", userLogin)); } catch (GenericServiceException e) { return ServiceUtil.returnError(e.getMessage()); } if (ServiceUtil.isError(resMap)) { return ServiceUtil.returnError( UtilProperties.getMessage(resource, "AccountingInvoiceCommissionErrorItem", locale), null, null, resMap); } } // store value objects try { delegator.storeAll(toStore); } catch (GenericEntityException e) { Debug.logError(e, "Entity/data problem creating commission invoice: " + e.toString(), module); return ServiceUtil.returnError( UtilProperties.getMessage(resource, "AccountingInvoiceCommissionEntityDataProblem", UtilMisc.toMap("reason", e.toString()), locale)); } invoicesCreated.add(UtilMisc.<String, String>toMap("commissionInvoiceId", invoiceId, "salesRepresentative ", partyIdBillFrom)); } String invCreated = Integer.toString(invoicesCreated.size()); Map<String, Object> result = ServiceUtil.returnSuccess(UtilProperties.getMessage(resource, "AccountingCommissionInvoicesCreated", UtilMisc.toMap("invoicesCreated", invCreated), locale)); Debug.logInfo("Created Commission invoices for each commission receiving parties " + invCreated, module); result.put("invoicesCreated", invoicesCreated); return result; }
From source file:org.apache.ofbiz.accounting.invoice.InvoiceServices.java
public static Map<String, Object> checkInvoicePaymentApplications(DispatchContext ctx, Map<String, Object> context) { Delegator delegator = ctx.getDelegator(); LocalDispatcher dispatcher = ctx.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)); }/*w ww.j a va 2 s . co m*/ String invoiceId = (String) context.get("invoiceId"); GenericValue invoice = null; try { invoice = EntityQuery.use(delegator).from("Invoice").where("invoiceId", invoiceId).queryOne(); } catch (GenericEntityException e) { Debug.logError(e, "Problem getting Invoice for Invoice ID" + invoiceId, module); return ServiceUtil.returnError(UtilProperties.getMessage(resource, "AccountingInvoiceNotFound", UtilMisc.toMap("invoiceId", invoiceId), locale)); } // Ignore invoices that aren't ready yet if (!invoice.getString("statusId").equals("INVOICE_READY")) { return ServiceUtil.returnSuccess(); } // Get the payment applications that can be used to pay the invoice List<GenericValue> paymentAppl = null; try { paymentAppl = EntityQuery.use(delegator).from("PaymentAndApplication").where("invoiceId", invoiceId) .queryList(); // For each payment application, select only those that are RECEIVED or SENT based on whether the payment is a RECEIPT or DISBURSEMENT respectively for (Iterator<GenericValue> iter = paymentAppl.iterator(); iter.hasNext();) { GenericValue payment = iter.next(); if ("PMNT_RECEIVED".equals(payment.get("statusId")) && UtilAccounting.isReceipt(payment)) { continue; // keep } if ("PMNT_SENT".equals(payment.get("statusId")) && UtilAccounting.isDisbursement(payment)) { continue; // keep } // all other cases, remove the payment application iter.remove(); } } catch (GenericEntityException e) { Debug.logError(e, "Problem getting PaymentApplication(s) for Invoice ID " + invoiceId, module); return ServiceUtil.returnError(UtilProperties.getMessage(resource, "AccountingProblemGettingPaymentApplication", UtilMisc.toMap("invoiceId", invoiceId), locale)); } Map<String, BigDecimal> payments = new HashMap<String, BigDecimal>(); Timestamp paidDate = null; for (GenericValue payAppl : paymentAppl) { payments.put(payAppl.getString("paymentId"), payAppl.getBigDecimal("amountApplied")); // paidDate will be the last date (chronologically) of all the Payments applied to this invoice Timestamp paymentDate = payAppl.getTimestamp("effectiveDate"); if (paymentDate != null) { if ((paidDate == null) || (paidDate.before(paymentDate))) { paidDate = paymentDate; } } } BigDecimal totalPayments = ZERO; for (BigDecimal amount : payments.values()) { if (amount == null) amount = ZERO; totalPayments = totalPayments.add(amount).setScale(DECIMALS, ROUNDING); } if (totalPayments.signum() == 1) { BigDecimal invoiceTotal = InvoiceWorker.getInvoiceTotal(delegator, invoiceId); if (Debug.verboseOn()) { Debug.logVerbose("Invoice #" + invoiceId + " total: " + invoiceTotal, module); Debug.logVerbose("Total payments : " + totalPayments, module); } if (totalPayments.compareTo(invoiceTotal) >= 0) { // this checks that totalPayments is greater than or equal to invoiceTotal // this invoice is paid Map<String, Object> svcCtx = UtilMisc.toMap("statusId", "INVOICE_PAID", "invoiceId", invoiceId, "paidDate", paidDate, "userLogin", userLogin); try { dispatcher.runSync("setInvoiceStatus", svcCtx); } catch (GenericServiceException e) { Debug.logError(e, "Problem changing invoice status to INVOICE_PAID" + svcCtx, module); return ServiceUtil.returnError( UtilProperties.getMessage(resource, "AccountingProblemChangingInvoiceStatusTo", UtilMisc.toMap("newStatus", "INVOICE_PAID"), locale)); } } } else { Debug.logInfo("No payments found for Invoice #" + invoiceId, module); } return ServiceUtil.returnSuccess(); }
From source file:nl.strohalm.cyclos.services.transactions.PaymentServiceImpl.java
private Validator getPaymentValidator(final DoPaymentDTO payment) { final Validator validator = new Validator("transfer"); Collection<TransactionContext> possibleContexts = new ArrayList<TransactionContext>(); possibleContexts.add(TransactionContext.PAYMENT); if (LoggedUser.isWebService() || LoggedUser.isSystem()) { possibleContexts.add(TransactionContext.AUTOMATIC); } else {/*from ww w . j a v a 2s . c om*/ possibleContexts.add(TransactionContext.SELF_PAYMENT); } validator.property("context").required().anyOf(possibleContexts); validator.property("to").required().key("payment.recipient"); // as currency is maybe not set on the DTO, we get it from the TT in stead of directly from the DTO final TransferType tt = fetchService.fetch(payment.getTransferType(), Relationships.TRANSACTION_FEES, RelationshipHelper.nested(TransferType.Relationships.FROM, TransferType.Relationships.TO, AccountType.Relationships.CURRENCY, Currency.Relationships.A_RATE_PARAMETERS), RelationshipHelper.nested(TransferType.Relationships.FROM, TransferType.Relationships.TO, AccountType.Relationships.CURRENCY, Currency.Relationships.D_RATE_PARAMETERS)); final Currency currency = tt == null ? null : tt.getCurrency(); if (currency != null && (currency.isEnableARate() || currency.isEnableDRate())) { // if the date is not null at this moment, it is in the past, which is not allowed with rates. if (payment.getDate() != null) { validator.general(new NoPastDateWithRatesValidator()); } } else { validator.property("date").key("payment.manualDate").past(); } validator.property("ticket").add(new TicketValidation()); addAmountValidator(validator, tt); validator.property("transferType").key("transfer.type").required(); validator.property("description").maxLength(1000); validator.general(new SchedulingValidator()); validator.general(new PendingContractValidator()); if (payment.getTransferType() != null && payment.getTo() != null && payment.getAmount() != null) { /* * For user validation, we need to check if the transaction amount is high enough to cover all fees. This depends on all fees, but only in * case of fixed fees it makes sense to increase the transaction amount. The formula for this is: given transactionamount > (sum of fixed * fees )/ (1 minus sum of percentage fees expressed as fractions). This of course only applies for fees with deductAmount; fees which are * not deducted are excluded from this calculation. */ final TransactionFeePreviewDTO preview = transactionFeeService.preview(payment.getFrom(), payment.getTo(), tt, payment.getAmount()); final Property amount = validator.property("amount"); final Collection<? extends TransactionFee> fees = preview.getFees().keySet(); BigDecimal sumOfFixedFees = BigDecimal.ZERO; BigDecimal sumOfPercentageFees = BigDecimal.ZERO; for (final TransactionFee fee : fees) { if (fee.isDeductAmount()) { if (fee.getChargeType() == ChargeType.FIXED) { sumOfFixedFees = sumOfFixedFees.add(preview.getFees().get(fee)); } else { sumOfPercentageFees = sumOfPercentageFees.add(preview.getFees().get(fee)); } } } // Show a warning if there are fixed fees and if the amount is not enough to cover them if (sumOfFixedFees.signum() == 1) { final int scale = LocalSettings.MAX_PRECISION; final MathContext mc = new MathContext(scale); final BigDecimal sumOfPercentages = sumOfPercentageFees.divide(payment.getAmount(), mc); final BigDecimal minimalAmount = sumOfFixedFees.divide((BigDecimal.ONE.subtract(sumOfPercentages)), mc); amount.comparable(minimalAmount, ">", new ValidationError("errors.greaterThan", messageResolver.message("transactionFee.invalidChargeValue", minimalAmount))); } else if (preview.getFinalAmount().signum() == -1) { validator.general(new FinalAmountValidator()); } // Custom fields validator.chained(new DelegatingValidator(new DelegatingValidator.DelegateSource() { @Override public Validator getValidator() { return paymentCustomFieldService.getValueValidator(payment.getTransferType()); } })); } return validator; }