List of usage examples for java.math BigDecimal subtract
public BigDecimal subtract(BigDecimal subtrahend)
From source file:org.egov.works.web.actions.estimate.EstimatePDFGenerator.java
private PdfPTable createBudgetDetailsForEstimateTable(final AbstractEstimate estimate) throws DocumentException { try {/* w w w . ja va 2 s. co m*/ final PdfPTable estBudgetDetailsTable = new PdfPTable(4); estBudgetDetailsTable.setWidthPercentage(75); estBudgetDetailsTable.setWidths(new float[] { 0.6f, 1f, 0.5f, 1f }); BigDecimal totalGrant; BigDecimal budgetAvailable; BigDecimal balOnHand; BigDecimal amtAppropriated = BigDecimal.ZERO; BigDecimal totGrantafterMultiFactor = BigDecimal.ZERO; BigDecimal totalUtilizedAmt; BigDecimal amtAppropriatedsofar = BigDecimal.ZERO; worksService.getAccountdetailtypeByName("DEPOSITCODE"); AbstractEstimateAppropriation latestAbstractEstimateAppropriation; if (abstractEstimateAppropriationList != null && !abstractEstimateAppropriationList.isEmpty()) { latestAbstractEstimateAppropriation = abstractEstimateAppropriationList .get(abstractEstimateAppropriationList.size() - 1); if (latestAbstractEstimateAppropriation != null) if (estimate.getDepositCode() == null) { if (latestAbstractEstimateAppropriation.getBudgetUsage().getConsumedAmount() != 0) { final Department dept = getDeptFromBudgtAppropriationNo( latestAbstractEstimateAppropriation.getBudgetUsage().getAppropriationnumber()); totalGrant = abstractEstimateService.getTotalGrantForYearAsOnDate( estimate.getFinancialDetails().get(0), latestAbstractEstimateAppropriation.getBudgetUsage().getFinancialYearId() .longValue(), Integer.parseInt(dept.getId().toString()), latestAbstractEstimateAppropriation.getBudgetUsage().getUpdatedTime()); final BigDecimal planningBudgetPerc = abstractEstimateService .getPlanningBudgetPercentage(estimate.getFinancialDetails().get(0), latestAbstractEstimateAppropriation.getBudgetUsage() .getFinancialYearId().longValue(), Integer.parseInt(dept.getId().toString())); if (planningBudgetPerc != null && planningBudgetPerc.compareTo(BigDecimal.ZERO) != 0) { totGrantafterMultiFactor = totalGrant .multiply(planningBudgetPerc.divide(new BigDecimal(100))); appValue = planningBudgetPerc.divide(new BigDecimal(100)).toString(); } budgetAvailable = latestAbstractEstimateAppropriation.getBalanceAvailable(); balOnHand = budgetAvailable.add(new BigDecimal( latestAbstractEstimateAppropriation.getBudgetUsage().getConsumedAmount())); amtAppropriated = totGrantafterMultiFactor.subtract(balOnHand); } } else if (latestAbstractEstimateAppropriation.getDepositWorksUsage().getConsumedAmount() .doubleValue() != 0) { totalUtilizedAmt = depositWorksUsageService.getTotalUtilizedAmountForDepositWorks( latestAbstractEstimateAppropriation.getAbstractEstimate().getFinancialDetails() .get(0), latestAbstractEstimateAppropriation.getDepositWorksUsage().getCreatedDate()); if (totalUtilizedAmt == null) totalUtilizedAmt = BigDecimal.ZERO; amtAppropriatedsofar = totalUtilizedAmt.subtract( latestAbstractEstimateAppropriation.getDepositWorksUsage().getConsumedAmount()); } } addRow(estBudgetDetailsTable, true, centerPara("Estimate Date"), centerPara(DateUtils.getFormattedDate(estimate.getEstimateDate(), "dd/MM/yyyy")), centerPara("Fund"), centerPara(estimate.getFinancialDetails().isEmpty() ? "" : estimate.getFinancialDetails().get(0).getFund().getName())); if (estimate.getDepositCode() == null) { addRow(estBudgetDetailsTable, true, centerPara("Function "), centerPara(estimate.getFinancialDetails().isEmpty() ? "" : estimate.getFinancialDetails().get(0).getFunction().getName()), centerPara("Budget Head"), centerPara(estimate.getFinancialDetails().isEmpty() ? "" : estimate.getFinancialDetails().get(0).getBudgetGroup().getName())); addRow(estBudgetDetailsTable, true, centerPara("Amount Appropriated so far"), centerPara(amtAppropriated == null ? "" : toCurrency(amtAppropriated.doubleValue())), centerPara("Estimate Amount"), centerPara(toCurrency(estimate.getTotalAmount().getValue()))); } else { addRow(estBudgetDetailsTable, true, centerPara("Function "), centerPara(estimate.getFinancialDetails().isEmpty() ? "" : estimate.getFinancialDetails().get(0).getFunction().getName()), centerPara("Deposit COA/Deposit Code"), centerPara(estimate.getFinancialDetails().isEmpty() ? "" : estimate.getFinancialDetails().get(0).getCoa().getGlcode().concat("-") .concat(estimate.getFinancialDetails().get(0).getCoa().getName()) .concat(" / ").concat(estimate.getDepositCode().getCode()))); addRow(estBudgetDetailsTable, true, centerPara("Amount Appropriated so far"), centerPara( amtAppropriatedsofar == null ? "" : toCurrency(amtAppropriatedsofar.doubleValue())), centerPara("Estimate Amount"), makePara(toCurrency(estimate.getTotalAmount().getValue()), Element.ALIGN_RIGHT)); } return estBudgetDetailsTable; } catch (final Exception e) { throw new ApplicationRuntimeException("Exception occured while estimate details method 2 " + e); } }
From source file:org.egov.ptis.domain.service.property.PropertyExternalService.java
public AssessmentDetails getDuesForProperty(final HttpServletRequest request, String assessmentNo, String oldAssessmentNo) { AssessmentDetails assessmentDetails = new AssessmentDetails(); BasicProperty basicProperty = fetchBasicProperty(assessmentNo, oldAssessmentNo); if (basicProperty != null) { assessmentDetails.setPropertyID(basicProperty.getUpicNo()); assessmentDetails.setOldAssessmentNo(basicProperty.getOldMuncipalNum()); assessmentDetails.setPropertyAddress(basicProperty.getAddress().toString()); assessmentDetails.setOwners(basicProperty.getFullOwnerName()); assessmentDetails.setStatus(basicProperty.getActive()); Property property = basicProperty.getProperty(); if (property != null) { assessmentDetails.setExempted(property.getIsExemptedFromTax()); if (!property.getIsExemptedFromTax()) { Map<String, BigDecimal> dmdCollMap = ptDemandDAO.getDemandIncludingPenaltyCollMap(property); if (!dmdCollMap.isEmpty()) { BigDecimal totalDemand = dmdCollMap.get(ARR_DMD_STR) .add(dmdCollMap.get(CURR_FIRSTHALF_DMD_STR)) .add(dmdCollMap.get(CURR_SECONDHALF_DMD_STR)); BigDecimal totalColl = dmdCollMap.get(ARR_COLL_STR) .add(dmdCollMap.get(CURR_FIRSTHALF_COLL_STR)) .add(dmdCollMap.get(CURR_SECONDHALF_COLL_STR)); assessmentDetails.setPropertyDue(totalDemand.subtract(totalColl)); }//from ww w.ja v a2s. co m } } String restURL = format(PropertyTaxConstants.WTMS_TAXDUE_RESTURL, WebUtils.extractRequestDomainURL(request, false), basicProperty.getUpicNo()); Map<String, Object> taxDetails = simpleRestClient.getRESTResponseAsMap(restURL); if (!taxDetails.isEmpty()) { assessmentDetails.setWaterTaxDue(BigDecimal.valueOf((double) taxDetails.get(WATER_TAX_DUES))); assessmentDetails.setConnectionCount( Double.valueOf(taxDetails.get("connectionCount").toString()).intValue()); } restURL = format(PropertyTaxConstants.STMS_TAXDUE_RESTURL, WebUtils.extractRequestDomainURL(request, false), basicProperty.getUpicNo()); taxDetails = simpleRestClient.getRESTResponseAsMap(restURL); if (!taxDetails.isEmpty()) assessmentDetails.setSewerageDue(BigDecimal.valueOf((double) taxDetails.get("totalTaxDue"))); } return assessmentDetails; }
From source file:org.egov.services.payment.PaymentService.java
public List<PaymentBean> getMiscBillList(final Paymentheader header) { if (LOGGER.isDebugEnabled()) LOGGER.debug("Starting getMiscBillList..."); List<PaymentBean> paymentBeanList = null; final Query query = getSession().createSQLQuery( "select mb.billvhId as billId,mb.billnumber as billNumber,mb.billdate as billDate,mb.paidto as payTo,mb.amount as netAmt, " + " mb.passedamount as passedAmt,mb.paidamount as paymentAmt,br.expendituretype as expType from miscbilldetail mb, eg_billregister br , eg_billregistermis mis " + " where mb.payvhid=" + header.getVoucherheader().getId() + " and br.id= mis.billid and mis.voucherheaderid=billvhid order by mb.paidto,mb.BILLDATE") .addScalar("billId", BigDecimalType.INSTANCE).addScalar("billNumber").addScalar("billDate") .addScalar("payTo").addScalar("netAmt", BigDecimalType.INSTANCE) .addScalar("passedAmt", BigDecimalType.INSTANCE).addScalar("paymentAmt", BigDecimalType.INSTANCE) .addScalar("expType").setResultTransformer(Transformers.aliasToBean(PaymentBean.class)); paymentBeanList = query.list();/*from w w w .j av a 2 s . c o m*/ BigDecimal earlierAmt; for (final PaymentBean bean : paymentBeanList) { bean.setIsSelected(true); earlierAmt = (BigDecimal) persistenceService.find( " select sum(paidamount) from Miscbilldetail where billVoucherHeader.id=?" + " and payVoucherHeader.status not in(?,?)", bean.getCsBillId(), FinancialConstants.CANCELLEDVOUCHERSTATUS, FinancialConstants.REVERSEDVOUCHERSTATUS); if (earlierAmt == null) earlierAmt = BigDecimal.ZERO; bean.setEarlierPaymentAmt(earlierAmt.subtract(bean.getPaymentAmt())); bean.setPayableAmt(bean.getNetAmt().subtract(bean.getEarlierPaymentAmt())); } if (LOGGER.isDebugEnabled()) LOGGER.debug("Completed getMiscBillList."); return paymentBeanList; }
From source file:och.front.service.FrontAppTest.java
private void test_billing_payBill() throws Exception { pushToSecurityContext_SYSTEM_USER(); try {/* www . j ava 2 s .c o m*/ BigDecimal balance = billing.getUserBalance(userId1); List<PaymentExt> payments = billing.getPayments(userId1, 100, 0); String desc = "test bill"; BigDecimal delta = TEN; billing.payBill(userId1, delta, new Date(), SYSTEM_OUT_CORRECTION, desc); BigDecimal newBalance = billing.getUserBalance(userId1); assertEquals(balance.subtract(TEN).doubleValue(), newBalance.doubleValue(), 0.01); List<PaymentExt> newPayments = billing.getPayments(userId1, 100, 0); assertEquals(payments.size() + 1, newPayments.size()); PaymentExt item = newPayments.get(0); assertEquals(desc, item.details); assertEquals(PaymentType.SYSTEM_OUT_CORRECTION, item.payType); } finally { popUserFromSecurityContext(); } }
From source file:org.egov.adtax.service.AdvertisementDemandService.java
/** * Update demand details of current or latest year data on renewal. Assumption: There is no partial payment collected for * selected year./*from ww w . j a v a 2s .c o m*/ * * @param advertisementPermitDetail * @param demand * @return */ public EgDemand updateDemandOnRenewal(final AdvertisementPermitDetail advertisementPermitDetail, final EgDemand demand) { if (demand != null) { final List<EgDemandDetails> removableDemandDetailList = new ArrayList<>(); final Installment installment = demand.getEgInstallmentMaster(); BigDecimal totalDemandAmount = BigDecimal.ZERO; Boolean enchroachmentFeeAlreadyExistInDemand = false; /* * EgDemandReason pendingTaxReason = getDemandReasonByCodeAndInstallment( * AdvertisementTaxConstants.DEMANDREASON_ARREAR_ADVERTISEMENTTAX, installment); */ final EgDemandReason encroachmentFeeReason = getDemandReasonByCodeAndInstallment( AdvertisementTaxConstants.DEMANDREASON_ENCROCHMENTFEE, installment); final EgDemandReason taxReason = getDemandReasonByCodeAndInstallment( AdvertisementTaxConstants.DEMANDREASON_ADVERTISEMENTTAX, installment); for (final EgDemandDetails dmdDtl : demand.getEgDemandDetails()) { // Assumption: tax amount is mandatory. if (dmdDtl.getEgDemandReason().getId() == taxReason.getId() && advertisementPermitDetail.getTaxAmount().compareTo(BigDecimal.ZERO) >= 0) { totalDemandAmount = totalDemandAmount .add(advertisementPermitDetail.getTaxAmount().subtract(dmdDtl.getAmount())); dmdDtl.setAmount( advertisementPermitDetail.getTaxAmount().setScale(0, BigDecimal.ROUND_HALF_UP)); } /* * if (dmdDtl.getEgDemandReason().getId() == pendingTaxReason.getId() && * advertisementPermitDetail.getAdvertisement().getPendingTax()!=null && * advertisementPermitDetail.getAdvertisement().getPendingTax().compareTo(BigDecimal.ZERO) > 0) { // TODO: Also * check whether fully collected ? totalDemandAmount = * totalDemandAmount.add(advertisementPermitDetail.getAdvertisement().getPendingTax().subtract(dmdDtl.getAmount()) * ); dmdDtl.setAmount(advertisementPermitDetail.getAdvertisement().getPendingTax().setScale(0, * BigDecimal.ROUND_HALF_UP)); } */ // Encroachment fee may not mandatory. If already part of demand if (dmdDtl.getEgDemandReason().getId() == encroachmentFeeReason.getId()) { enchroachmentFeeAlreadyExistInDemand = true; if (advertisementPermitDetail.getEncroachmentFee() != null && advertisementPermitDetail.getEncroachmentFee().compareTo(BigDecimal.ZERO) > 0) { totalDemandAmount = totalDemandAmount .add(advertisementPermitDetail.getEncroachmentFee().subtract(dmdDtl.getAmount())); dmdDtl.setAmount(advertisementPermitDetail.getEncroachmentFee().setScale(0, BigDecimal.ROUND_HALF_UP)); // update encroachment fee.. } else { totalDemandAmount = totalDemandAmount.subtract(dmdDtl.getAmount()); // demand.removeEgDemandDetails(dmdDtl); removableDemandDetailList.add(dmdDtl); // delete demand detail } } } if (!enchroachmentFeeAlreadyExistInDemand && advertisementPermitDetail.getEncroachmentFee() != null && advertisementPermitDetail.getEncroachmentFee().compareTo(BigDecimal.ZERO) > 0) { demand.addEgDemandDetails( createDemandDetails(advertisementPermitDetail.getEncroachmentFee(), getDemandReasonByCodeAndInstallment( AdvertisementTaxConstants.DEMANDREASON_ENCROCHMENTFEE, installment), BigDecimal.ZERO)); totalDemandAmount = totalDemandAmount.add(advertisementPermitDetail.getEncroachmentFee()); } for (final EgDemandDetails removableDmdDtl : removableDemandDetailList) demand.removeEgDemandDetails(removableDmdDtl); demand.addBaseDemand(totalDemandAmount.setScale(0, BigDecimal.ROUND_HALF_UP)); } return demand; }
From source file:org.egov.ptis.domain.service.property.PropertyExternalService.java
private PropertyTaxDetails getPropertyTaxDetails(final BasicProperty basicProperty, String category) { final PropertyTaxDetails propertyTaxDetails = new PropertyTaxDetails(); final ErrorDetails errorDetails = new ErrorDetails(); if (null != basicProperty) { final String assessmentNo = basicProperty.getUpicNo(); if (!basicProperty.isActive()) { errorDetails.setErrorCode(PROPERTY_DEACTIVATE_ERR_CODE); errorDetails.setErrorMessage(PROPERTY_DEACTIVATE_ERR_MSG); propertyTaxDetails.setErrorDetails(errorDetails); } else {// w w w.j av a 2 s . c o m final Set<PropertyStatusValues> statusValues = basicProperty.getPropertyStatusValuesSet(); if (null != statusValues && !statusValues.isEmpty()) for (final PropertyStatusValues statusValue : statusValues) if (statusValue.getPropertyStatus().getStatusCode() == MARK_DEACTIVE) { errorDetails.setErrorCode(PROPERTY_MARK_DEACTIVATE_ERR_CODE); errorDetails.setErrorMessage(PROPERTY_MARK_DEACTIVATE_ERR_MSG); } } final Property property = basicProperty.getProperty(); ptDemandDAO.getDemandCollMap(property); if (!StringUtils.isBlank(category)) { String propType = property.getPropertyDetail().getPropertyTypeMaster().getCode(); if (CATEGORY_TYPE_PROPERTY_TAX.equals(category)) { if (propType.equals(OWNERSHIP_TYPE_VAC_LAND)) { errorDetails.setErrorCode(THIRD_PARTY_ERR_CODE_PROPERTY_TAX_ASSESSMENT_NOT_FOUND); errorDetails.setErrorMessage(THIRD_PARTY_ERR_MSG_PROPERTY_TAX_ASSESSMENT_NOT_FOUND); propertyTaxDetails.setErrorDetails(errorDetails); return propertyTaxDetails; } } else if (CATEGORY_TYPE_VACANTLAND_TAX.equals(category)) { if (!propType.equals(OWNERSHIP_TYPE_VAC_LAND)) { errorDetails.setErrorCode(THIRD_PARTY_ERR_CODE_VACANTLAND_ASSESSMENT_NOT_FOUND); errorDetails.setErrorMessage(THIRD_PARTY_ERR_MSG_VACANTLAND_ASSESSMENT_NOT_FOUND); propertyTaxDetails.setErrorDetails(errorDetails); return propertyTaxDetails; } } else { errorDetails.setErrorCode(THIRD_PARTY_ERR_CODE_WRONG_CATEGORY); errorDetails.setErrorMessage(THIRD_PARTY_ERR_MSG_WRONG_CATEGORY); propertyTaxDetails.setErrorDetails(errorDetails); return propertyTaxDetails; } } final List<PropertyOwnerInfo> propOwnerInfos = property.getBasicProperty().getPropertyOwnerInfo(); propertyTaxDetails.setOwnerDetails(new ArrayList<OwnerDetails>(0)); OwnerDetails ow; for (int i = 0; i < propOwnerInfos.size(); i++) { final PropertyOwnerInfo propOwnerInfo = propOwnerInfos.get(i); final String ownerName = propOwnerInfo.getOwner().getName(); if (null != ownerName && ownerName.trim().length() != 0) { ow = new OwnerDetails(); ow.setOwnerName(ownerName); ow.setMobileNo(propOwnerInfo.getOwner().getMobileNumber()); propertyTaxDetails.getOwnerDetails().add(ow); } } propertyTaxDetails.setPropertyAddress(property.getBasicProperty().getAddress().toString()); propertyTaxDetails.setAssessmentNo(property.getBasicProperty().getUpicNo()); propertyTaxDetails.setOldAssessmentNo(property.getBasicProperty().getOldMuncipalNum()); propertyTaxDetails.setLocalityName(property.getBasicProperty().getPropertyID().getLocality().getName()); propertyTaxBillable.setBasicProperty(basicProperty); propertyTaxBillable.setLevyPenalty(Boolean.TRUE); Map<Installment, PenaltyAndRebate> calculatedPenalty = propertyTaxBillable.getCalculatedPenalty(); final List<Object> list = ptDemandDAO.getPropertyTaxDetails(assessmentNo); if (!list.isEmpty()) propertyTaxDetails.setTaxDetails(new ArrayList<RestPropertyTaxDetails>(0)); else { return propertyTaxDetails; } String loopInstallment = ""; RestPropertyTaxDetails arrearDetails = null; BigDecimal total = BigDecimal.ZERO; for (final Object record : list) { final Object[] data = (Object[]) record; final String taxType = (String) data[0]; final String installment = (String) data[1]; final Double dmd = (Double) data[2]; final Double col = (Double) data[3]; final BigDecimal demand = BigDecimal.valueOf(dmd.doubleValue()); final BigDecimal collection = BigDecimal.valueOf(col.doubleValue()); if (loopInstallment.isEmpty()) { loopInstallment = installment; arrearDetails = new RestPropertyTaxDetails(); arrearDetails.setInstallment(installment); } if (loopInstallment.equals(installment)) { if (DEMANDRSN_CODE_PENALTY_FINES.equalsIgnoreCase(taxType)) arrearDetails.setPenalty(demand.subtract(collection)); else if (DEMANDRSN_CODE_CHQ_BOUNCE_PENALTY.equalsIgnoreCase(taxType)) arrearDetails.setChqBouncePenalty(demand.subtract(collection)); else total = total.add(demand.subtract(collection)); } else { arrearDetails.setTaxAmount(total); arrearDetails.setTotalAmount(total.add(arrearDetails.getChqBouncePenalty())); propertyTaxDetails.getTaxDetails().add(arrearDetails); loopInstallment = installment; arrearDetails = new RestPropertyTaxDetails(); arrearDetails.setInstallment(installment); total = BigDecimal.ZERO; if (DEMANDRSN_CODE_PENALTY_FINES.equalsIgnoreCase(taxType)) arrearDetails.setPenalty(demand.subtract(collection)); else if (DEMANDRSN_CODE_CHQ_BOUNCE_PENALTY.equalsIgnoreCase(taxType)) arrearDetails.setChqBouncePenalty(demand.subtract(collection)); else total = total.add(demand.subtract(collection)); } } if (arrearDetails != null) { arrearDetails.setTaxAmount(total); arrearDetails.setTotalAmount(total.add(arrearDetails.getChqBouncePenalty())); propertyTaxDetails.getTaxDetails().add(arrearDetails); } Set<Installment> keySet = calculatedPenalty.keySet(); // for all years data for (RestPropertyTaxDetails details : propertyTaxDetails.getTaxDetails()) { // loop trough the penalty for (Installment inst : keySet) { if (inst.getDescription().equalsIgnoreCase(details.getInstallment())) { details.setPenalty(calculatedPenalty.get(inst).getPenalty()); details.setRebate(calculatedPenalty.get(inst).getRebate()); details.setTotalAmount( details.getTotalAmount().add(calculatedPenalty.get(inst).getPenalty())); if (details.getRebate() != null) { details.setTotalAmount(details.getTotalAmount().subtract(details.getRebate())); } break; } } } } return propertyTaxDetails; }
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 ww. j av a 2s. 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:com.ibm.soatf.component.soap.builder.SampleXmlUtil.java
private String formatDecimal(String start, SchemaType sType) { BigDecimal result = new BigDecimal(start); XmlDecimal xmlD;// w w w . j a va2s . com xmlD = (XmlDecimal) sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE); BigDecimal min = xmlD != null ? xmlD.getBigDecimalValue() : null; xmlD = (XmlDecimal) sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE); BigDecimal max = xmlD != null ? xmlD.getBigDecimalValue() : null; boolean minInclusive = true, maxInclusive = true; xmlD = (XmlDecimal) sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE); if (xmlD != null) { BigDecimal minExcl = xmlD.getBigDecimalValue(); if (min == null || min.compareTo(minExcl) < 0) { min = minExcl; minInclusive = false; } } xmlD = (XmlDecimal) sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE); if (xmlD != null) { BigDecimal maxExcl = xmlD.getBigDecimalValue(); if (max == null || max.compareTo(maxExcl) > 0) { max = maxExcl; maxInclusive = false; } } xmlD = (XmlDecimal) sType.getFacet(SchemaType.FACET_TOTAL_DIGITS); int totalDigits = -1; if (xmlD != null) { totalDigits = xmlD.getBigDecimalValue().intValue(); StringBuilder sb = new StringBuilder(totalDigits); for (int i = 0; i < totalDigits; i++) sb.append('9'); BigDecimal digitsLimit = new BigDecimal(sb.toString()); if (max != null && max.compareTo(digitsLimit) > 0) { max = digitsLimit; maxInclusive = true; } digitsLimit = digitsLimit.negate(); if (min != null && min.compareTo(digitsLimit) < 0) { min = digitsLimit; minInclusive = true; } } int sigMin = min == null ? 1 : result.compareTo(min); int sigMax = max == null ? -1 : result.compareTo(max); boolean minOk = sigMin > 0 || sigMin == 0 && minInclusive; boolean maxOk = sigMax < 0 || sigMax == 0 && maxInclusive; // Compute the minimum increment xmlD = (XmlDecimal) sType.getFacet(SchemaType.FACET_FRACTION_DIGITS); int fractionDigits = -1; BigDecimal increment; if (xmlD == null) increment = new BigDecimal(1); else { fractionDigits = xmlD.getBigDecimalValue().intValue(); if (fractionDigits > 0) { StringBuilder sb = new StringBuilder("0."); for (int i = 1; i < fractionDigits; i++) sb.append('0'); sb.append('1'); increment = new BigDecimal(sb.toString()); } else increment = new BigDecimal(1); } if (minOk && maxOk) { // OK } else if (minOk && !maxOk) { // TOO BIG if (maxInclusive) result = max; else result = max.subtract(increment); } else if (!minOk && maxOk) { // TOO SMALL if (minInclusive) result = min; else result = min.add(increment); } else { // MIN > MAX!! } // We have the number // Adjust the scale according to the totalDigits and fractionDigits int digits = 0; BigDecimal ONE = new BigDecimal(BigInteger.ONE); for (BigDecimal n = result; n.abs().compareTo(ONE) >= 0; digits++) n = n.movePointLeft(1); if (fractionDigits > 0) if (totalDigits >= 0) result.setScale(Math.max(fractionDigits, totalDigits - digits)); else result.setScale(fractionDigits); else if (fractionDigits == 0) result.setScale(0); return result.toString(); }
From source file:com.centeractive.ws.builder.soap.SampleXmlUtil.java
private String formatDecimal(String start, SchemaType sType) { BigDecimal result = new BigDecimal(start); XmlDecimal xmlD;/*from w w w . j av a 2 s. c o m*/ xmlD = (XmlDecimal) sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE); BigDecimal min = xmlD != null ? xmlD.getBigDecimalValue() : null; xmlD = (XmlDecimal) sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE); BigDecimal max = xmlD != null ? xmlD.getBigDecimalValue() : null; boolean minInclusive = true, maxInclusive = true; xmlD = (XmlDecimal) sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE); if (xmlD != null) { BigDecimal minExcl = xmlD.getBigDecimalValue(); if (min == null || min.compareTo(minExcl) < 0) { min = minExcl; minInclusive = false; } } xmlD = (XmlDecimal) sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE); if (xmlD != null) { BigDecimal maxExcl = xmlD.getBigDecimalValue(); if (max == null || max.compareTo(maxExcl) > 0) { max = maxExcl; maxInclusive = false; } } xmlD = (XmlDecimal) sType.getFacet(SchemaType.FACET_TOTAL_DIGITS); int totalDigits = -1; if (xmlD != null) { totalDigits = xmlD.getBigDecimalValue().intValue(); StringBuffer sb = new StringBuffer(totalDigits); for (int i = 0; i < totalDigits; i++) sb.append('9'); BigDecimal digitsLimit = new BigDecimal(sb.toString()); if (max != null && max.compareTo(digitsLimit) > 0) { max = digitsLimit; maxInclusive = true; } digitsLimit = digitsLimit.negate(); if (min != null && min.compareTo(digitsLimit) < 0) { min = digitsLimit; minInclusive = true; } } int sigMin = min == null ? 1 : result.compareTo(min); int sigMax = max == null ? -1 : result.compareTo(max); boolean minOk = sigMin > 0 || sigMin == 0 && minInclusive; boolean maxOk = sigMax < 0 || sigMax == 0 && maxInclusive; // Compute the minimum increment xmlD = (XmlDecimal) sType.getFacet(SchemaType.FACET_FRACTION_DIGITS); int fractionDigits = -1; BigDecimal increment; if (xmlD == null) increment = new BigDecimal(1); else { fractionDigits = xmlD.getBigDecimalValue().intValue(); if (fractionDigits > 0) { StringBuffer sb = new StringBuffer("0."); for (int i = 1; i < fractionDigits; i++) sb.append('0'); sb.append('1'); increment = new BigDecimal(sb.toString()); } else increment = new BigDecimal(1); } if (minOk && maxOk) { // OK } else if (minOk && !maxOk) { // TOO BIG if (maxInclusive) result = max; else result = max.subtract(increment); } else if (!minOk && maxOk) { // TOO SMALL if (minInclusive) result = min; else result = min.add(increment); } else { // MIN > MAX!! } // We have the number // Adjust the scale according to the totalDigits and fractionDigits int digits = 0; BigDecimal ONE = new BigDecimal(BigInteger.ONE); for (BigDecimal n = result; n.abs().compareTo(ONE) >= 0; digits++) n = n.movePointLeft(1); if (fractionDigits > 0) if (totalDigits >= 0) result.setScale(Math.max(fractionDigits, totalDigits - digits)); else result.setScale(fractionDigits); else if (fractionDigits == 0) result.setScale(0); return result.toString(); }
From source file:org.kuali.kpme.tklm.time.rules.overtime.weekly.service.WeeklyOvertimeRuleServiceImpl.java
/** * Applies overtime additions to the indicated TimeBlock. * * @param timeBlock The time block to apply the overtime on. * @param overtimeEarnCode The overtime earn code to apply overtime to. * @param convertFromEarnCodes The other earn codes on the time block. * @param overtimeHours The overtime hours to apply. * * @return the amount of overtime hours remaining to be applied. *///w ww . j a v a 2 s.c o m protected BigDecimal applyPositiveOvertimeOnTimeBlock(TimeBlockBo timeBlock, String overtimeEarnCode, Set<String> convertFromEarnCodes, BigDecimal overtimeHours) { BigDecimal applied = BigDecimal.ZERO; List<TimeHourDetailBo> timeHourDetails = timeBlock.getTimeHourDetails(); List<TimeHourDetailBo> newTimeHourDetails = new ArrayList<TimeHourDetailBo>(); LOG.info("INITIAL block; " + timeBlock.getTkTimeBlockId() + "overtimeHours = " + overtimeHours + " overall timeblock hours = " + timeBlock.getHours() + " earnCode = " + timeBlock.getEarnCode() + " OT = " + overtimeEarnCode + " convertFrom = " + convertFromEarnCodes + " startDate = " + timeBlock.getBeginDateTime()); for (TimeHourDetailBo timeHourDetail : timeHourDetails) { LOG.info("EC = " + timeHourDetail.getEarnCode() + " hours = " + timeHourDetail.getHours()); } EarnCodeContract earnCodeObj = HrServiceLocator.getEarnCodeService().getEarnCode(overtimeEarnCode, timeBlock.getEndDateTime().toLocalDate()); BigDecimal toApply = BigDecimal.ZERO; toApply = toApply.add(timeBlock.getHours()); BigDecimal otApplied = BigDecimal.ZERO; BigDecimal newOtActual = BigDecimal.ZERO; BigDecimal maxOtToConvert = BigDecimal.ZERO; BigDecimal existingOtActualHours = BigDecimal.ZERO; BigDecimal newOt = BigDecimal.ZERO; TimeHourDetailBo overtimeTimeHourDetail = null; List<TimeHourDetailBo> toConvert = new ArrayList<TimeHourDetailBo>(); BigDecimal regularHours = BigDecimal.ZERO; for (TimeHourDetailBo timeHourDetail : timeHourDetails) { if (convertFromEarnCodes.contains(timeHourDetail.getEarnCode())) { maxOtToConvert = maxOtToConvert.add(timeHourDetail.getHours()); toConvert.add(timeHourDetail); regularHours = regularHours.add(timeHourDetail.getHours()); } else if (timeHourDetail.getEarnCode().equals(overtimeEarnCode)) { overtimeTimeHourDetail = timeHourDetail; } else { regularHours = regularHours.add(timeHourDetail.getHours()); } } LOG.info("regularHours = " + regularHours + " maxOtToConvert = " + maxOtToConvert + " overtimeHours = " + overtimeHours); //this is the actual hours of overtime worked before any multiplying factor. existingOtActualHours = timeBlock.getHours().subtract(regularHours); LOG.info("actual OT Hours = " + existingOtActualHours); if (overtimeHours.compareTo(BigDecimal.ZERO) <= 0) { /* if (existingOtActualHours.compareTo(BigDecimal.ZERO) == 0) { return BigDecimal.ZERO; } else { */ LOG.info("actual OT hours neq zero"); if (existingOtActualHours.compareTo(BigDecimal.ZERO) != 0) { //handle this case Friday morning if (toConvert.size() > 0) { toConvert.get(0).setHours(toConvert.get(0).getHours().add(existingOtActualHours)); } else { TimeHourDetailBo newTimeHourDetail = new TimeHourDetailBo(); newTimeHourDetail.setTkTimeBlockId(timeBlock.getTkTimeBlockId()); newTimeHourDetail.setEarnCode(convertFromEarnCodes.iterator().next()); newTimeHourDetail.setHours(existingOtActualHours); timeBlock.addTimeHourDetail(newTimeHourDetail); //Friday //timeHourDetails.get(0).setHours(existingOtActualHours); } } newOtActual = BigDecimal.ZERO; //could this be a problem?? newOt = BigDecimal.ZERO; } else if (overtimeHours.compareTo(existingOtActualHours) <= 0) // new overtime is less than old overtime { //subtract from existing OT until existing OT is zero, if necessary add to toConvert List until the difference is ZERO //newOtToAdd = existingOt BigDecimal newOtToRemove = existingOtActualHours.subtract(overtimeHours); newOtActual = overtimeHours; newOt = earnCodeObj.getInflateFactor().multiply(overtimeHours, HrConstants.MATH_CONTEXT) .setScale(HrConstants.BIG_DECIMAL_SCALE, BigDecimal.ROUND_HALF_UP); if (toConvert.size() > 0) { toConvert.get(0).setHours(toConvert.get(0).getHours().add(newOtToRemove)); } else { // LOG.debug("hitting problem case"); // timeHourDetails.get(0).setHours(timeHourDetails.get(0).getHours().add(newOtToRemove)); TimeHourDetailBo newTimeHourDetail = new TimeHourDetailBo(); newTimeHourDetail.setTkTimeBlockId(timeBlock.getTkTimeBlockId()); // newTimeHourDetail.setEarnCode(timeBlock.getEarnCode()); newTimeHourDetail.setEarnCode(convertFromEarnCodes.iterator().next()); newTimeHourDetail.setHours(newOtToRemove); timeBlock.addTimeHourDetail(newTimeHourDetail); } LOG.info("overtimeHours <= existingOtActualHours: " + overtimeHours + " vs " + existingOtActualHours + "newOtActual = " + newOtActual + " newOt = " + newOt); } else if (overtimeHours.compareTo(existingOtActualHours) > 0) //new overtime is greater than old overtime { //add difference to OT, up to maxOtToConvert. remove from toConvert as necessary BigDecimal newOtToAdd = overtimeHours.subtract(existingOtActualHours); BigDecimal toReduce = newOtToAdd; if (newOtToAdd.compareTo(maxOtToConvert) >= 0) { newOtToAdd = maxOtToConvert; } LOG.info("newOtToAdd: " + newOtToAdd); for (TimeHourDetailBo timeHourDetailBo : toConvert) { BigDecimal existingHours = timeHourDetailBo.getHours(); if (toReduce.compareTo(existingHours) >= 0) { timeHourDetailBo.setHours(BigDecimal.ZERO); toReduce = toReduce.subtract(existingHours); } else if (toReduce.compareTo(BigDecimal.ZERO) > 0) { timeHourDetailBo.setHours(timeHourDetailBo.getHours().subtract(toReduce)); toReduce = toReduce.subtract(toReduce); } } newOtActual = existingOtActualHours.add(newOtToAdd); newOt = earnCodeObj.getInflateFactor().multiply(newOtActual, HrConstants.MATH_CONTEXT) .setScale(HrConstants.BIG_DECIMAL_SCALE, BigDecimal.ROUND_HALF_UP); LOG.info("overtimeHours > existingOtActualHours: " + overtimeHours + " vs " + existingOtActualHours + "newOtActual = " + newOtActual + " newOt = " + newOt); } if (overtimeTimeHourDetail != null) { overtimeTimeHourDetail.setHours(newOt); } else { TimeHourDetailBo newTimeHourDetail = new TimeHourDetailBo(); newTimeHourDetail.setTkTimeBlockId(timeBlock.getTkTimeBlockId()); newTimeHourDetail.setEarnCode(overtimeEarnCode); newTimeHourDetail.setHours(newOt); timeBlock.addTimeHourDetail(newTimeHourDetail); } LOG.info("COMPLETE block; " + timeBlock.getTkTimeBlockId() + " overall timeblock hours = " + timeBlock.getHours() + " earnCode = " + timeBlock.getEarnCode() + " OT = " + overtimeEarnCode + " convertFrom = " + convertFromEarnCodes); for (TimeHourDetailBo timeHourDetail : timeHourDetails) { LOG.info("EC = " + timeHourDetail.getEarnCode() + " hours = " + timeHourDetail.getHours()); } LOG.info("returning " + overtimeHours.subtract(newOtActual)); return overtimeHours.subtract(newOtActual); /* if (changeMade) { } else { return overtimeHours; } */ }