Example usage for java.math BigDecimal setScale

List of usage examples for java.math BigDecimal setScale

Introduction

In this page you can find the example usage for java.math BigDecimal setScale.

Prototype

@Deprecated(since = "9")
public BigDecimal setScale(int newScale, int roundingMode) 

Source Link

Document

Returns a BigDecimal whose scale is the specified value, and whose unscaled value is determined by multiplying or dividing this BigDecimal 's unscaled value by the appropriate power of ten to maintain its overall value.

Usage

From source file:org.egov.adtax.service.AdvertisementDemandService.java

public EgDemand updateDemand(final AdvertisementPermitDetail advertisementPermitDetail, EgDemand demand) {
    final Installment installment = getCurrentInstallment();
    BigDecimal totalDemandAmount = BigDecimal.ZERO;

    // Boolean calculateTax=true;
    Boolean enchroachmentFeeAlreadyExistInDemand = false;
    final List<EgDemandDetails> removableDemandDetailList = new ArrayList<>();

    // EgDemand demand = advertisement.getDemandId();
    if (demand == null)
        demand = createDemand(advertisementPermitDetail);
    else {/*w w  w.j  a v  a 2 s.  c  om*/
        final EgDemandReason pendingTaxReason = getDemandReasonByCodeAndInstallment(
                AdvertisementTaxConstants.DEMANDREASON_ARREAR_ADVERTISEMENTTAX, installment);
        final EgDemandReason encroachmentFeeReason = getDemandReasonByCodeAndInstallment(
                AdvertisementTaxConstants.DEMANDREASON_ENCROCHMENTFEE, installment);
        final EgDemandReason taxReason = getDemandReasonByCodeAndInstallment(
                AdvertisementTaxConstants.DEMANDREASON_ADVERTISEMENTTAX, installment);
        /*
         * if (advertisementPermitDetail.getTaxAmount() != null ||
         * advertisementPermitDetail.getAdvertisement().getPendingTax() != null) { if
         * (advertisementPermitDetail.getAdvertisement().getPendingTax() != null) taxAmount =
         * taxAmount.add(advertisementPermitDetail.getAdvertisement().getPendingTax()); if
         * (advertisementPermitDetail.getTaxAmount() != null) taxAmount =
         * taxAmount.add(advertisementPermitDetail.getTaxAmount()); }
         */
        for (final EgDemandDetails dmdDtl : demand.getEgDemandDetails()) {
            // Assumption: tax amount is mandatory.
            if (dmdDtl.getEgDemandReason().getId() == taxReason.getId()
                    && advertisementPermitDetail.getTaxAmount().compareTo(BigDecimal.ZERO) > 0) {
                // TODO: Also check whether fully collected ?
                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
            // then
            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
                }

            }
        }
        for (final EgDemandDetails removableDmdDtl : removableDemandDetailList)
            demand.removeEgDemandDetails(removableDmdDtl);
        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());
            // TODO: CHECK WHETHER FULLY PAID IN LEGACY HANDLED.
        }
        demand.addBaseDemand(totalDemandAmount.setScale(0, BigDecimal.ROUND_HALF_UP));

    }
    return demand;

}

From source file:controllers.core.RoadmapController.java

/**
 * Return the HTML fragment of the KPIs for "scenario simulator".
 * //from  w w  w .  ja  v a  2 s .co  m
 * @throws AccountManagementException
 */
@Restrict({ @Group(IMafConstants.ROADMAP_SIMULATOR_PERMISSION) })
public Result simulatorKpisFragment() throws AccountManagementException {

    List<String> ids = FilterConfig.getIdsFromRequest(request());

    BigDecimal allocation = BigDecimal.ZERO;
    BigDecimal allocationConfirmed = BigDecimal.ZERO;
    BigDecimal allocationNotConfirmed = BigDecimal.ZERO;

    BigDecimal budget = BigDecimal.ZERO;
    BigDecimal budgetCapex = BigDecimal.ZERO;
    BigDecimal budgetOpex = BigDecimal.ZERO;

    BigDecimal forecast = BigDecimal.ZERO;
    BigDecimal forecastCapex = BigDecimal.ZERO;
    BigDecimal forecastOpex = BigDecimal.ZERO;

    BigDecimal engaged = BigDecimal.ZERO;
    BigDecimal engagedCapex = BigDecimal.ZERO;
    BigDecimal engagedOpex = BigDecimal.ZERO;

    for (String idString : ids) {

        Long id = Long.valueOf(idString);

        PortfolioEntry portfolioEntry = PortfolioEntryDao.getPEById(id);

        // allocation
        BigDecimal entryAllocatedActorDaysConfirmed = PortfolioEntryResourcePlanDAO
                .getPEPlanAllocatedActorAsDaysByPEAndConfirmed(portfolioEntry, true);
        BigDecimal entryAllocatedActorDaysNotConfirmed = PortfolioEntryResourcePlanDAO
                .getPEPlanAllocatedActorAsDaysByPEAndConfirmed(portfolioEntry, false);
        BigDecimal entryAllocatedOrgUnitDaysConfirmed = PortfolioEntryResourcePlanDAO
                .getPEResourcePlanAllocatedOrgUnitAsDaysByPE(portfolioEntry, true);
        BigDecimal entryAllocatedOrgUnitDaysNotConfirmed = PortfolioEntryResourcePlanDAO
                .getPEResourcePlanAllocatedOrgUnitAsDaysByPE(portfolioEntry, false);
        BigDecimal entryAllocatedCompetencyDaysConfirmed = PortfolioEntryResourcePlanDAO
                .getPEResourcePlanAllocatedCompetencyAsDaysByPortfolioEntry(portfolioEntry, true);
        BigDecimal entryAllocatedCompetencyDaysNotConfirmed = PortfolioEntryResourcePlanDAO
                .getPEResourcePlanAllocatedCompetencyAsDaysByPortfolioEntry(portfolioEntry, false);

        BigDecimal entryAllocationDaysConfirmed = entryAllocatedActorDaysConfirmed
                .add(entryAllocatedOrgUnitDaysConfirmed).add(entryAllocatedCompetencyDaysConfirmed);
        BigDecimal entryAllocationDaysNotConfirmed = entryAllocatedActorDaysNotConfirmed
                .add(entryAllocatedOrgUnitDaysNotConfirmed).add(entryAllocatedCompetencyDaysNotConfirmed);

        allocation = allocation.add(entryAllocationDaysConfirmed).add(entryAllocationDaysNotConfirmed);
        allocationConfirmed = allocationConfirmed.add(entryAllocationDaysConfirmed);
        allocationNotConfirmed = allocationNotConfirmed.add(entryAllocationDaysNotConfirmed);

        if (getSecurityService().restrict(IMafConstants.PORTFOLIO_ENTRY_VIEW_FINANCIAL_INFO_ALL_PERMISSION)) {

            // budget
            Double entryBudgetCapex = PortfolioEntryDao.getPEAsBudgetAmountByOpex(id, false);
            Double entryBudgetOpex = PortfolioEntryDao.getPEAsBudgetAmountByOpex(id, true);

            budget = budget.add(new BigDecimal(entryBudgetCapex + entryBudgetOpex));
            budgetCapex = budgetCapex.add(new BigDecimal(entryBudgetCapex));
            budgetOpex = budgetOpex.add(new BigDecimal(entryBudgetOpex));

            // forecast
            Double entryCostToCompleteCapex = PortfolioEntryDao
                    .getPEAsCostToCompleteAmountByOpex(this.getPreferenceManagerPlugin(), id, false);
            Double entryCostToCompleteOpex = PortfolioEntryDao
                    .getPEAsCostToCompleteAmountByOpex(this.getPreferenceManagerPlugin(), id, true);
            Double entryEngagedCapex = PortfolioEntryDao
                    .getPEAsEngagedAmountByOpex(this.getPreferenceManagerPlugin(), id, false);
            Double entryEngagedOpex = PortfolioEntryDao
                    .getPEAsEngagedAmountByOpex(this.getPreferenceManagerPlugin(), id, true);

            forecast = forecast.add(new BigDecimal(
                    entryCostToCompleteCapex + entryCostToCompleteOpex + entryEngagedCapex + entryEngagedOpex));
            forecastCapex = forecastCapex.add(new BigDecimal(entryCostToCompleteCapex + entryEngagedCapex));
            forecastOpex = forecastOpex.add(new BigDecimal(entryCostToCompleteOpex + entryEngagedOpex));

            // engaged
            engaged = engaged.add(new BigDecimal(entryEngagedCapex + entryEngagedOpex));
            engagedCapex = engagedCapex.add(new BigDecimal(entryEngagedCapex));
            engagedOpex = engagedOpex.add(new BigDecimal(entryEngagedOpex));

        }

    }

    budget = budget.setScale(2, RoundingMode.HALF_UP);
    budgetCapex = budgetCapex.setScale(2, RoundingMode.HALF_UP);
    budgetOpex = budgetOpex.setScale(2, RoundingMode.HALF_UP);

    forecast = forecast.setScale(2, RoundingMode.HALF_UP);
    forecastCapex = forecastCapex.setScale(2, RoundingMode.HALF_UP);
    forecastOpex = forecastOpex.setScale(2, RoundingMode.HALF_UP);

    engaged = engaged.setScale(2, RoundingMode.HALF_UP);
    engagedCapex = engagedCapex.setScale(2, RoundingMode.HALF_UP);
    engagedOpex = engagedOpex.setScale(2, RoundingMode.HALF_UP);

    return ok(views.html.core.roadmap.roadmap_simulator_kpis_fragment.render(allocation, allocationConfirmed,
            allocationNotConfirmed, budget, budgetCapex, budgetOpex, forecast, forecastCapex, forecastOpex,
            engaged, engagedCapex, engagedOpex));

}

From source file:org.apache.ofbiz.accounting.invoice.InvoiceServices.java

private static BigDecimal calcHeaderAdj(Delegator delegator, GenericValue adj, String invoiceTypeId,
        String invoiceId, String invoiceItemSeqId, BigDecimal divisor, BigDecimal multiplier,
        BigDecimal baseAmount, int decimals, int rounding, GenericValue userLogin, LocalDispatcher dispatcher,
        Locale locale) {/*from  w w  w  . ja  va 2  s. c o  m*/
    BigDecimal adjAmount = ZERO;
    if (adj.get("amount") != null) {

        // pro-rate the amount
        BigDecimal amount = ZERO;
        if ("DONATION_ADJUSTMENT".equals(adj.getString("orderAdjustmentTypeId"))) {
            amount = baseAmount;
        } else if (divisor.signum() != 0) { // make sure the divisor is not 0 to avoid NaN problems; just leave the amount as 0 and skip it in essense
            // multiply first then divide to avoid rounding errors
            amount = baseAmount.multiply(multiplier).divide(divisor, decimals, rounding);
        }
        if (amount.signum() != 0) {
            Map<String, Object> createInvoiceItemContext = new HashMap<String, Object>();
            createInvoiceItemContext.put("invoiceId", invoiceId);
            createInvoiceItemContext.put("invoiceItemSeqId", invoiceItemSeqId);
            createInvoiceItemContext.put("invoiceItemTypeId", getInvoiceItemType(delegator,
                    adj.getString("orderAdjustmentTypeId"), null, invoiceTypeId, "INVOICE_ADJ"));
            createInvoiceItemContext.put("description", adj.get("description"));
            createInvoiceItemContext.put("quantity", BigDecimal.ONE);
            createInvoiceItemContext.put("amount", amount);
            createInvoiceItemContext.put("overrideGlAccountId", adj.get("overrideGlAccountId"));
            createInvoiceItemContext.put("taxAuthPartyId", adj.get("taxAuthPartyId"));
            createInvoiceItemContext.put("taxAuthGeoId", adj.get("taxAuthGeoId"));
            createInvoiceItemContext.put("taxAuthorityRateSeqId", adj.get("taxAuthorityRateSeqId"));
            createInvoiceItemContext.put("userLogin", userLogin);

            Map<String, Object> createInvoiceItemResult = null;
            try {
                createInvoiceItemResult = dispatcher.runSync("createInvoiceItem", createInvoiceItemContext);
            } catch (GenericServiceException e) {
                Debug.logError(e, "Service/other problem creating InvoiceItem from order header adjustment",
                        module);
                return adjAmount;
            }
            if (ServiceUtil.isError(createInvoiceItemResult)) {
                return adjAmount;
            }

            // Create the OrderAdjustmentBilling record
            Map<String, Object> createOrderAdjustmentBillingContext = new HashMap<String, Object>();
            createOrderAdjustmentBillingContext.put("orderAdjustmentId", adj.getString("orderAdjustmentId"));
            createOrderAdjustmentBillingContext.put("invoiceId", invoiceId);
            createOrderAdjustmentBillingContext.put("invoiceItemSeqId", invoiceItemSeqId);
            createOrderAdjustmentBillingContext.put("amount", amount);
            createOrderAdjustmentBillingContext.put("userLogin", userLogin);

            try {
                dispatcher.runSync("createOrderAdjustmentBilling", createOrderAdjustmentBillingContext);
            } catch (GenericServiceException e) {
                return adjAmount;
            }

        }
        amount = amount.setScale(decimals, rounding);
        adjAmount = amount;
    } else if (adj.get("sourcePercentage") != null) {
        // pro-rate the amount
        BigDecimal percent = adj.getBigDecimal("sourcePercentage");
        percent = percent.divide(new BigDecimal(100), 100, rounding);
        BigDecimal amount = ZERO;
        // make sure the divisor is not 0 to avoid NaN problems; just leave the amount as 0 and skip it in essense
        if (divisor.signum() != 0) {
            // multiply first then divide to avoid rounding errors
            amount = percent.multiply(divisor);
        }
        if (amount.signum() != 0) {
            Map<String, Object> createInvoiceItemContext = new HashMap<String, Object>();
            createInvoiceItemContext.put("invoiceId", invoiceId);
            createInvoiceItemContext.put("invoiceItemSeqId", invoiceItemSeqId);
            createInvoiceItemContext.put("invoiceItemTypeId", getInvoiceItemType(delegator,
                    adj.getString("orderAdjustmentTypeId"), null, invoiceTypeId, "INVOICE_ADJ"));
            createInvoiceItemContext.put("description", adj.get("description"));
            createInvoiceItemContext.put("quantity", BigDecimal.ONE);
            createInvoiceItemContext.put("amount", amount);
            createInvoiceItemContext.put("overrideGlAccountId", adj.get("overrideGlAccountId"));
            createInvoiceItemContext.put("taxAuthPartyId", adj.get("taxAuthPartyId"));
            createInvoiceItemContext.put("taxAuthGeoId", adj.get("taxAuthGeoId"));
            createInvoiceItemContext.put("taxAuthorityRateSeqId", adj.get("taxAuthorityRateSeqId"));
            createInvoiceItemContext.put("userLogin", userLogin);

            Map<String, Object> createInvoiceItemResult = null;
            try {
                createInvoiceItemResult = dispatcher.runSync("createInvoiceItem", createInvoiceItemContext);
            } catch (GenericServiceException e) {
                Debug.logError(e, "Service/other problem creating InvoiceItem from order header adjustment",
                        module);
                return adjAmount;
            }
            if (ServiceUtil.isError(createInvoiceItemResult)) {
                return adjAmount;
            }

            // Create the OrderAdjustmentBilling record
            Map<String, Object> createOrderAdjustmentBillingContext = new HashMap<String, Object>();
            createOrderAdjustmentBillingContext.put("orderAdjustmentId", adj.getString("orderAdjustmentId"));
            createOrderAdjustmentBillingContext.put("invoiceId", invoiceId);
            createOrderAdjustmentBillingContext.put("invoiceItemSeqId", invoiceItemSeqId);
            createOrderAdjustmentBillingContext.put("amount", amount);
            createOrderAdjustmentBillingContext.put("userLogin", userLogin);

            try {
                dispatcher.runSync("createOrderAdjustmentBilling", createOrderAdjustmentBillingContext);
            } catch (GenericServiceException e) {
                return adjAmount;
            }

        }
        amount = amount.setScale(decimals, rounding);
        adjAmount = amount;
    }

    Debug.logInfo("adjAmount: " + adjAmount + ", divisor: " + divisor + ", multiplier: " + multiplier
            + ", invoiceTypeId: " + invoiceTypeId + ", invoiceId: " + invoiceId + ", itemSeqId: "
            + invoiceItemSeqId + ", decimals: " + decimals + ", rounding: " + rounding + ", adj: " + adj,
            module);
    return adjAmount;
}

From source file:org.egov.billsaccounting.services.CreateVoucher.java

public void validateTransaction(final List<HashMap<String, Object>> accountcodedetails,
        final List<HashMap<String, Object>> subledgerdetails) throws ApplicationRuntimeException, Exception {
    if (LOGGER.isDebugEnabled())
        LOGGER.debug("START | validateTransaction");
    // List<Transaxtion> transaxtionList = new ArrayList<Transaxtion>();
    BigDecimal totaldebitAmount = BigDecimal.valueOf(0);
    BigDecimal totalcreditAmount = BigDecimal.valueOf(0);
    final Map<String, BigDecimal> accDetAmtMap = new HashMap<String, BigDecimal>();
    for (final HashMap<String, Object> accDetailMap : accountcodedetails) {

        String glcode = null;/*from  w w  w.ja v a  2s . c  o  m*/

        final BigDecimal debitAmount = new BigDecimal(accDetailMap.get(VoucherConstant.DEBITAMOUNT).toString());
        final BigDecimal creditAmount = new BigDecimal(
                accDetailMap.get(VoucherConstant.CREDITAMOUNT).toString());

        totaldebitAmount = totaldebitAmount.add(debitAmount);
        totalcreditAmount = totalcreditAmount.add(creditAmount);
        if (accDetailMap.containsKey(VoucherConstant.GLCODE)
                && null != accDetailMap.get(VoucherConstant.GLCODE)) {
            glcode = accDetailMap.get(VoucherConstant.GLCODE).toString();
            if (null == chartOfAccountsDAO.getCChartOfAccountsByGlCode(glcode))
                throw new ApplicationRuntimeException("Not a valid account code" + glcode);
        } else
            throw new ApplicationRuntimeException("glcode is missing or null");
        if (debitAmount.compareTo(BigDecimal.ZERO) != 0 && creditAmount.compareTo(BigDecimal.ZERO) != 0)
            throw new ApplicationRuntimeException(
                    "Both debit amount and credit amount cannot be greater than zero");
        if (debitAmount.compareTo(BigDecimal.ZERO) == 0 && creditAmount.compareTo(BigDecimal.ZERO) == 0)
            throw new ApplicationRuntimeException("debit and credit both amount is Zero");
        if (null != accDetailMap.get(VoucherConstant.FUNCTIONCODE)
                && "" != accDetailMap.get(VoucherConstant.FUNCTIONCODE)) {
            final String functionCode = accDetailMap.get(VoucherConstant.FUNCTIONCODE).toString();
            if (null == functionDAO.getFunctionByCode(functionCode))
                throw new ApplicationRuntimeException("not a valid function code");
        }
        if (debitAmount.compareTo(BigDecimal.ZERO) != 0) {
            if (null != accDetAmtMap.get(VoucherConstant.DEBIT + glcode)) {
                final BigDecimal accountCodeTotDbAmt = accDetAmtMap.get(VoucherConstant.DEBIT + glcode)
                        .add(debitAmount);
                accDetAmtMap.put(VoucherConstant.DEBIT + glcode, accountCodeTotDbAmt);
            } else
                accDetAmtMap.put(VoucherConstant.DEBIT + glcode, debitAmount);

        } else if (creditAmount.compareTo(BigDecimal.ZERO) != 0)
            if (null != accDetAmtMap.get(VoucherConstant.CREDIT + glcode)) {
                final BigDecimal accountCodeTotCrAmt = accDetAmtMap.get(VoucherConstant.CREDIT + glcode)
                        .add(creditAmount);
                accDetAmtMap.put(VoucherConstant.CREDIT + glcode, accountCodeTotCrAmt);
            } else
                accDetAmtMap.put(VoucherConstant.CREDIT + glcode, creditAmount);
    }
    if (LOGGER.isDebugEnabled())
        LOGGER.debug("Total Debit  amount   :" + totaldebitAmount);
    if (LOGGER.isDebugEnabled())
        LOGGER.debug("Total Credit amount   :" + totalcreditAmount);
    totaldebitAmount = totaldebitAmount.setScale(2, BigDecimal.ROUND_HALF_UP);
    totalcreditAmount = totalcreditAmount.setScale(2, BigDecimal.ROUND_HALF_UP);
    if (LOGGER.isDebugEnabled())
        LOGGER.debug("Total Debit  amount after round off :" + totaldebitAmount);
    if (LOGGER.isDebugEnabled())
        LOGGER.debug("Total Credit amount after round off :" + totalcreditAmount);
    if (totaldebitAmount.compareTo(totalcreditAmount) != 0)
        throw new ApplicationRuntimeException("total debit and total credit amount is not matching");
    final Map<String, BigDecimal> subledAmtmap = new HashMap<String, BigDecimal>();
    for (final HashMap<String, Object> subdetailDetailMap : subledgerdetails) {
        String glcode = null;
        String detailtypeid = null;
        String detailKeyId = null;
        if (null != subdetailDetailMap.get(VoucherConstant.GLCODE)) {
            glcode = subdetailDetailMap.get(VoucherConstant.GLCODE).toString();
            if (null == chartOfAccountsDAO.getCChartOfAccountsByGlCode(glcode))
                throw new ApplicationRuntimeException("not a valid glcode");
        } else
            throw new ApplicationRuntimeException("glcode is missing");
        final Query querytds = persistenceService.getSession()
                .createQuery("select t.id from Recovery t where " + "t.chartofaccounts.glcode=:glcode");
        querytds.setString("glcode", glcode);
        querytds.setCacheable(true);
        if (null != querytds.list() && querytds.list().size() > 0
                && null == subdetailDetailMap.get(VoucherConstant.TDSID)
                && null != subdetailDetailMap.get(VoucherConstant.CREDITAMOUNT)
                && new BigDecimal(subdetailDetailMap.get(VoucherConstant.CREDITAMOUNT).toString())
                        .compareTo(BigDecimal.ZERO) != 0) {
            /*
             * Commenting out throw ApplicationRuntimeException since we are
             * using the same API for create Journal Voucher. There we are
             * not setting the TDS id..
             */
            // throw new
            // ApplicationRuntimeException("Recovery detail is missing for glcode :"+glcode);
        }
        // validate the glcode is a subledger code or not.

        final Query query = persistenceService.getSession()
                .createQuery("from CChartOfAccountDetail cd,CChartOfAccounts c where "
                        + "cd.glCodeId = c.id and c.glcode=:glcode");

        query.setString(VoucherConstant.GLCODE, glcode);
        query.setCacheable(true);
        if (null == query.list() || query.list().size() == 0)
            throw new ApplicationRuntimeException("This code is not a control code" + glcode);

        // validate subledger Detailtypeid

        if (null != subdetailDetailMap.get(VoucherConstant.DETAILTYPEID)) {
            detailtypeid = subdetailDetailMap.get(VoucherConstant.DETAILTYPEID).toString();
            final Session session = persistenceService.getSession();
            final Query qry = session.createQuery("from CChartOfAccountDetail cd,CChartOfAccounts c where "
                    + "cd.glCodeId = c.id and c.glcode=:glcode and cd.detailTypeId.id=:detailTypeId");
            qry.setString(VoucherConstant.GLCODE, glcode);
            qry.setInteger("detailTypeId", Integer.valueOf(detailtypeid));
            qry.setCacheable(true);
            if (null == qry.list() || qry.list().size() == 0)
                throw new ApplicationRuntimeException(
                        "The subledger type mapped to this account code is not correct " + glcode);
        } else
            throw new ApplicationRuntimeException("Subledger type value is missing for account code " + glcode);

        if (null != subdetailDetailMap.get(VoucherConstant.DETAILKEYID)) {
            detailKeyId = subdetailDetailMap.get(VoucherConstant.DETAILKEYID).toString();
            final Session session = persistenceService.getSession();
            final Query qry = session.createQuery(
                    "from Accountdetailkey adk where adk.accountdetailtype.id=:detailtypeid and adk.detailkey=:detailkey");
            qry.setInteger(VoucherConstant.DETAILTYPEID, Integer.valueOf(detailtypeid));
            qry.setInteger("detailkey", Integer.valueOf(detailKeyId));
            qry.setCacheable(true);
            if (null == qry.list() || qry.list().size() == 0)
                throw new ApplicationRuntimeException("Subledger data is not valid for account code " + glcode);
        } else
            throw new ApplicationRuntimeException("detailkeyid is missing");

        if (null != subdetailDetailMap.get(VoucherConstant.DEBITAMOUNT)
                && new BigDecimal(subdetailDetailMap.get(VoucherConstant.DEBITAMOUNT).toString())
                        .compareTo(BigDecimal.ZERO) != 0) {
            final BigDecimal dbtAmount = new BigDecimal(
                    subdetailDetailMap.get(VoucherConstant.DEBITAMOUNT).toString());
            if (null != subledAmtmap.get(VoucherConstant.DEBIT + glcode))
                subledAmtmap.put(VoucherConstant.DEBIT + glcode,
                        subledAmtmap.get(VoucherConstant.DEBIT + glcode).add(dbtAmount));
            else
                subledAmtmap.put(VoucherConstant.DEBIT + glcode, dbtAmount);

        } else if (null != subdetailDetailMap.get(VoucherConstant.CREDITAMOUNT)
                && new BigDecimal(subdetailDetailMap.get(VoucherConstant.CREDITAMOUNT).toString())
                        .compareTo(BigDecimal.ZERO) != 0) {
            final BigDecimal creditAmt = new BigDecimal(
                    subdetailDetailMap.get(VoucherConstant.CREDITAMOUNT).toString());
            if (null != subledAmtmap.get(VoucherConstant.CREDIT + glcode))
                subledAmtmap.put(VoucherConstant.CREDIT + glcode,
                        subledAmtmap.get(VoucherConstant.CREDIT + glcode).add(creditAmt));
            else
                subledAmtmap.put(VoucherConstant.CREDIT + glcode, creditAmt);

        } else
            throw new ApplicationRuntimeException(
                    "Incorrect Sub ledger amount supplied for glcode : " + glcode);

    }

    for (final HashMap<String, Object> accDetailMap : accountcodedetails) {

        final String glcode = accDetailMap.get(VoucherConstant.GLCODE).toString();

        if (null != subledAmtmap.get(VoucherConstant.DEBIT + glcode))
            // changed since equals does considers decimal values eg 20.0 is
            // not equal to 2
            if (subledAmtmap.get(VoucherConstant.DEBIT + glcode)
                    .compareTo(accDetAmtMap.get(VoucherConstant.DEBIT + glcode)) != 0)
                throw new ApplicationRuntimeException(
                        "Total of subleger debit amount is not matching with the account code amount "
                                + glcode);
        if (null != subledAmtmap.get(VoucherConstant.CREDIT + glcode))
            // changed since equals does considers decimal values eg 20.0 is
            // not equal to 2
            if (subledAmtmap.get(VoucherConstant.CREDIT + glcode)
                    .compareTo(accDetAmtMap.get(VoucherConstant.CREDIT + glcode)) != 0)
                throw new ApplicationRuntimeException(
                        "Total of subleger credit amount is not matching with the account code amount "
                                + glcode);

    }
    if (LOGGER.isDebugEnabled())
        LOGGER.debug("END | validateTransaction");

}

From source file:org.egov.adtax.service.AdvertisementDemandService.java

public EgDemand updateDemandForLegacyEntry(final AdvertisementPermitDetail advertisementPermitDetail,
        EgDemand demand) {//ww  w . j av a  2  s .  c  o  m
    final Installment installment = getCurrentInstallment();
    BigDecimal totalDemandAmount = BigDecimal.ZERO;

    Boolean taxFullyPaidForCurrentYear = false;

    if (advertisementPermitDetail.getAdvertisement() != null
            && advertisementPermitDetail.getAdvertisement().getLegacy()
            && advertisementPermitDetail.getAdvertisement().getTaxPaidForCurrentYear())
        taxFullyPaidForCurrentYear = true;

    Boolean enchroachmentFeeAlreadyExistInDemand = false;
    Boolean arrearsTaxalreadyExistInDemand = false;
    Boolean taxalreadyExistInDemand = false;
    final List<EgDemandDetails> deleteDmdDtl = new ArrayList<>();
    if (demand == null)
        demand = createDemand(advertisementPermitDetail);
    else {
        final 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())
            if (dmdDtl.getEgDemandReason().getId() == taxReason.getId()) {
                taxalreadyExistInDemand = true;
                if (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 (taxFullyPaidForCurrentYear)
                        dmdDtl.setAmtCollected(advertisementPermitDetail.getTaxAmount() != null
                                ? advertisementPermitDetail.getTaxAmount()
                                : BigDecimal.ZERO);
                    else
                        dmdDtl.setAmtCollected(BigDecimal.ZERO);
                } else {
                    totalDemandAmount = totalDemandAmount.subtract(dmdDtl.getAmount());
                    deleteDmdDtl.add(dmdDtl);
                    // demand.removeEgDemandDetails(dmdDtl);
                }
            } else if (dmdDtl.getEgDemandReason().getId() == pendingTaxReason.getId()) {
                arrearsTaxalreadyExistInDemand = true;
                if (advertisementPermitDetail.getAdvertisement().getPendingTax() != null
                        && advertisementPermitDetail.getAdvertisement().getPendingTax()
                                .compareTo(BigDecimal.ZERO) > 0) {

                    totalDemandAmount = totalDemandAmount.add(advertisementPermitDetail.getAdvertisement()
                            .getPendingTax().subtract(dmdDtl.getAmount()));
                    dmdDtl.setAmount(advertisementPermitDetail.getAdvertisement().getPendingTax().setScale(0,
                            BigDecimal.ROUND_HALF_UP));

                    /*
                     * if (taxFullyPaidForCurrentYear) {
                     * dmdDtl.setAmtCollected((advertisementPermitDetail.getAdvertisement().getPendingTax() != null ?
                     * (advertisementPermitDetail .getAdvertisement().getPendingTax()) : BigDecimal.ZERO)); } else
                     */
                    dmdDtl.setAmtCollected(BigDecimal.ZERO);
                } else {
                    totalDemandAmount = totalDemandAmount.subtract(dmdDtl.getAmount());
                    deleteDmdDtl.add(dmdDtl);
                }
            } else 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));

                    if (taxFullyPaidForCurrentYear)
                        dmdDtl.setAmtCollected(advertisementPermitDetail.getEncroachmentFee() != null
                                ? advertisementPermitDetail.getEncroachmentFee()
                                : BigDecimal.ZERO);
                    else
                        dmdDtl.setAmtCollected(BigDecimal.ZERO);

                    // update encroachment fee.. // Encroachment fee may not mandatory. If already part of demand
                } else {
                    totalDemandAmount = totalDemandAmount.subtract(dmdDtl.getAmount());
                    deleteDmdDtl.add(dmdDtl);
                    // delete demand detail
                }

            }

        for (final EgDemandDetails dmdDtls : deleteDmdDtl)
            demand.removeEgDemandDetails(dmdDtls);

        if (!enchroachmentFeeAlreadyExistInDemand && advertisementPermitDetail.getEncroachmentFee() != null
                && advertisementPermitDetail.getEncroachmentFee().compareTo(BigDecimal.ZERO) > 0) {
            demand.addEgDemandDetails(createDemandDetails(advertisementPermitDetail.getEncroachmentFee(),
                    getDemandReasonByCodeAndInstallment(AdvertisementTaxConstants.DEMANDREASON_ENCROCHMENTFEE,
                            installment),
                    taxFullyPaidForCurrentYear ? advertisementPermitDetail.getEncroachmentFee()
                            : BigDecimal.ZERO));
            totalDemandAmount = totalDemandAmount.add(advertisementPermitDetail.getEncroachmentFee());
            demand.setEgInstallmentMaster(installment);
        }
        if (!arrearsTaxalreadyExistInDemand
                && advertisementPermitDetail.getAdvertisement().getPendingTax() != null
                && advertisementPermitDetail.getAdvertisement().getPendingTax()
                        .compareTo(BigDecimal.ZERO) > 0) {
            demand.addEgDemandDetails(createDemandDetails(
                    advertisementPermitDetail.getAdvertisement().getPendingTax(),
                    getDemandReasonByCodeAndInstallment(
                            AdvertisementTaxConstants.DEMANDREASON_ARREAR_ADVERTISEMENTTAX, installment),
                    BigDecimal.ZERO));
            totalDemandAmount = totalDemandAmount
                    .add(advertisementPermitDetail.getAdvertisement().getPendingTax());
            demand.setEgInstallmentMaster(installment);
        }
        if (!taxalreadyExistInDemand && advertisementPermitDetail.getTaxAmount() != null
                && advertisementPermitDetail.getTaxAmount().compareTo(BigDecimal.ZERO) > 0) {
            demand.addEgDemandDetails(createDemandDetails(advertisementPermitDetail.getTaxAmount(),
                    getDemandReasonByCodeAndInstallment(AdvertisementTaxConstants.DEMANDREASON_ADVERTISEMENTTAX,
                            installment),
                    taxFullyPaidForCurrentYear ? advertisementPermitDetail.getTaxAmount() : BigDecimal.ZERO));
            totalDemandAmount = totalDemandAmount.add(advertisementPermitDetail.getTaxAmount());
            demand.setEgInstallmentMaster(installment);
        }
        demand.addBaseDemand(totalDemandAmount.setScale(0, BigDecimal.ROUND_HALF_UP));

    }
    return demand;

}

From source file:org.apache.ofbiz.accounting.invoice.InvoiceServices.java

public static Map<String, Object> createInvoiceForOrder(DispatchContext dctx, Map<String, Object> context) {
    Delegator delegator = dctx.getDelegator();
    LocalDispatcher dispatcher = dctx.getDispatcher();
    GenericValue userLogin = (GenericValue) context.get("userLogin");
    Locale locale = (Locale) context.get("locale");

    if (DECIMALS == -1 || ROUNDING == -1) {
        return ServiceUtil.returnError(
                UtilProperties.getMessage(resource, "AccountingAritmeticPropertiesNotConfigured", locale));
    }//w w w  .j av  a2s.co  m

    String orderId = (String) context.get("orderId");
    List<GenericValue> billItems = UtilGenerics.checkList(context.get("billItems"));
    String invoiceId = (String) context.get("invoiceId");

    if (UtilValidate.isEmpty(billItems)) {
        Debug.logVerbose("No order items to invoice; not creating invoice; returning success", module);
        return ServiceUtil
                .returnSuccess(UtilProperties.getMessage(resource, "AccountingNoOrderItemsToInvoice", locale));
    }

    try {
        GenericValue orderHeader = EntityQuery.use(delegator).from("OrderHeader").where("orderId", orderId)
                .queryOne();
        if (orderHeader == null) {
            return ServiceUtil
                    .returnError(UtilProperties.getMessage(resource, "AccountingNoOrderHeader", locale));
        }

        // figure out the invoice type
        String invoiceType = null;

        String orderType = orderHeader.getString("orderTypeId");
        if (orderType.equals("SALES_ORDER")) {
            invoiceType = "SALES_INVOICE";
        } else if (orderType.equals("PURCHASE_ORDER")) {
            invoiceType = "PURCHASE_INVOICE";
        }

        // Set the precision depending on the type of invoice
        int invoiceTypeDecimals = UtilNumber.getBigDecimalScale("invoice." + invoiceType + ".decimals");
        if (invoiceTypeDecimals == -1)
            invoiceTypeDecimals = DECIMALS;

        // Make an order read helper from the order
        OrderReadHelper orh = new OrderReadHelper(orderHeader);

        // get the product store
        GenericValue productStore = orh.getProductStore();

        // get the shipping adjustment mode (Y = Pro-Rate; N = First-Invoice)
        String prorateShipping = productStore != null ? productStore.getString("prorateShipping") : "Y";
        if (prorateShipping == null) {
            prorateShipping = "Y";
        }

        // get the billing parties
        String billToCustomerPartyId = orh.getBillToParty().getString("partyId");
        String billFromVendorPartyId = orh.getBillFromParty().getString("partyId");

        // get some price totals
        BigDecimal shippableAmount = orh.getShippableTotal(null);
        BigDecimal shippableQuantity = orh.getShippableQuantity(null);
        BigDecimal orderSubTotal = orh.getOrderItemsSubTotal();
        BigDecimal orderQuantity = orh.getTotalOrderItemsQuantity();

        // these variables are for pro-rating order amounts across invoices, so they should not be rounded off for maximum accuracy
        BigDecimal invoiceShipProRateAmount = ZERO;
        BigDecimal invoiceShippableQuantity = ZERO;
        BigDecimal invoiceSubTotal = ZERO;
        BigDecimal invoiceQuantity = ZERO;

        GenericValue billingAccount = orderHeader.getRelatedOne("BillingAccount", false);
        String billingAccountId = billingAccount != null ? billingAccount.getString("billingAccountId") : null;

        Timestamp invoiceDate = (Timestamp) context.get("eventDate");
        if (UtilValidate.isEmpty(invoiceDate)) {
            // TODO: ideally this should be the same time as when a shipment is sent and be passed in as a parameter
            invoiceDate = UtilDateTime.nowTimestamp();
        }
        // TODO: perhaps consider billing account net days term as well?
        Long orderTermNetDays = orh.getOrderTermNetDays();
        Timestamp dueDate = null;
        if (orderTermNetDays != null) {
            dueDate = UtilDateTime.getDayEnd(invoiceDate, orderTermNetDays);
        }

        // create the invoice record
        if (UtilValidate.isEmpty(invoiceId)) {
            Map<String, Object> createInvoiceContext = new HashMap<String, Object>();
            createInvoiceContext.put("partyId", billToCustomerPartyId);
            createInvoiceContext.put("partyIdFrom", billFromVendorPartyId);
            createInvoiceContext.put("billingAccountId", billingAccountId);
            createInvoiceContext.put("invoiceDate", invoiceDate);
            createInvoiceContext.put("dueDate", dueDate);
            createInvoiceContext.put("invoiceTypeId", invoiceType);
            // start with INVOICE_IN_PROCESS, in the INVOICE_READY we can't change the invoice (or shouldn't be able to...)
            createInvoiceContext.put("statusId", "INVOICE_IN_PROCESS");
            createInvoiceContext.put("currencyUomId", orderHeader.getString("currencyUom"));
            createInvoiceContext.put("userLogin", userLogin);

            // store the invoice first
            Map<String, Object> createInvoiceResult = dispatcher.runSync("createInvoice", createInvoiceContext);
            if (ServiceUtil.isError(createInvoiceResult)) {
                return ServiceUtil.returnError(
                        UtilProperties.getMessage(resource, "AccountingErrorCreatingInvoiceFromOrder", locale),
                        null, null, createInvoiceResult);
            }

            // call service, not direct entity op: delegator.create(invoice);
            invoiceId = (String) createInvoiceResult.get("invoiceId");
        }

        // order roles to invoice roles
        List<GenericValue> orderRoles = orderHeader.getRelated("OrderRole", null, null, false);
        Map<String, Object> createInvoiceRoleContext = new HashMap<String, Object>();
        createInvoiceRoleContext.put("invoiceId", invoiceId);
        createInvoiceRoleContext.put("userLogin", userLogin);
        for (GenericValue orderRole : orderRoles) {
            createInvoiceRoleContext.put("partyId", orderRole.getString("partyId"));
            createInvoiceRoleContext.put("roleTypeId", orderRole.getString("roleTypeId"));
            Map<String, Object> createInvoiceRoleResult = dispatcher.runSync("createInvoiceRole",
                    createInvoiceRoleContext);
            if (ServiceUtil.isError(createInvoiceRoleResult)) {
                return ServiceUtil.returnError(
                        UtilProperties.getMessage(resource, "AccountingErrorCreatingInvoiceFromOrder", locale),
                        null, null, createInvoiceRoleResult);
            }
        }

        // order terms to invoice terms.
        // TODO: it might be nice to filter OrderTerms to only copy over financial terms.
        List<GenericValue> orderTerms = orh.getOrderTerms();
        createInvoiceTerms(delegator, dispatcher, invoiceId, orderTerms, userLogin, locale);

        // billing accounts
        // List billingAccountTerms = null;
        // for billing accounts we will use related information
        if (billingAccount != null) {
            /*
             * jacopoc: billing account terms were already copied as order terms
             *          when the order was created.
            // get the billing account terms
            billingAccountTerms = billingAccount.getRelated("BillingAccountTerm", null, null, false);
                    
            // set the invoice terms as defined for the billing account
            createInvoiceTerms(delegator, dispatcher, invoiceId, billingAccountTerms, userLogin, locale);
            */
            // set the invoice bill_to_customer from the billing account
            List<GenericValue> billToRoles = billingAccount.getRelated("BillingAccountRole",
                    UtilMisc.toMap("roleTypeId", "BILL_TO_CUSTOMER"), null, false);
            for (GenericValue billToRole : billToRoles) {
                if (!(billToRole.getString("partyId").equals(billToCustomerPartyId))) {
                    createInvoiceRoleContext = UtilMisc.toMap("invoiceId", invoiceId, "partyId",
                            billToRole.get("partyId"), "roleTypeId", "BILL_TO_CUSTOMER", "userLogin",
                            userLogin);
                    Map<String, Object> createInvoiceRoleResult = dispatcher.runSync("createInvoiceRole",
                            createInvoiceRoleContext);
                    if (ServiceUtil.isError(createInvoiceRoleResult)) {
                        return ServiceUtil.returnError(
                                UtilProperties.getMessage(resource,
                                        "AccountingErrorCreatingInvoiceRoleFromOrder", locale),
                                null, null, createInvoiceRoleResult);
                    }
                }
            }

            // set the bill-to contact mech as the contact mech of the billing account
            if (UtilValidate.isNotEmpty(billingAccount.getString("contactMechId"))) {
                Map<String, Object> createBillToContactMechContext = UtilMisc.toMap("invoiceId", invoiceId,
                        "contactMechId", billingAccount.getString("contactMechId"), "contactMechPurposeTypeId",
                        "BILLING_LOCATION", "userLogin", userLogin);
                Map<String, Object> createBillToContactMechResult = dispatcher
                        .runSync("createInvoiceContactMech", createBillToContactMechContext);
                if (ServiceUtil.isError(createBillToContactMechResult)) {
                    return ServiceUtil.returnError(
                            UtilProperties.getMessage(resource,
                                    "AccountingErrorCreatingInvoiceContactMechFromOrder", locale),
                            null, null, createBillToContactMechResult);
                }
            }
        } else {
            List<GenericValue> billingLocations = orh.getBillingLocations();
            if (UtilValidate.isNotEmpty(billingLocations)) {
                for (GenericValue ocm : billingLocations) {
                    Map<String, Object> createBillToContactMechContext = UtilMisc.toMap("invoiceId", invoiceId,
                            "contactMechId", ocm.getString("contactMechId"), "contactMechPurposeTypeId",
                            "BILLING_LOCATION", "userLogin", userLogin);
                    Map<String, Object> createBillToContactMechResult = dispatcher
                            .runSync("createInvoiceContactMech", createBillToContactMechContext);
                    if (ServiceUtil.isError(createBillToContactMechResult)) {
                        return ServiceUtil.returnError(
                                UtilProperties.getMessage(resource,
                                        "AccountingErrorCreatingInvoiceContactMechFromOrder", locale),
                                null, null, createBillToContactMechResult);
                    }
                }
            } else {
                Debug.logWarning("No billing locations found for order [" + orderId
                        + "] and none were created for Invoice [" + invoiceId + "]", module);
            }
        }

        // get a list of the payment method types
        //DEJ20050705 doesn't appear to be used: List paymentPreferences = orderHeader.getRelated("OrderPaymentPreference", null, null, false);

        // create the bill-from (or pay-to) contact mech as the primary PAYMENT_LOCATION of the party from the store
        GenericValue payToAddress = null;
        if (invoiceType.equals("PURCHASE_INVOICE")) {
            // for purchase orders, the pay to address is the BILLING_LOCATION of the vendor
            GenericValue billFromVendor = orh.getPartyFromRole("BILL_FROM_VENDOR");
            if (billFromVendor != null) {
                List<GenericValue> billingContactMechs = billFromVendor.getRelatedOne("Party", false)
                        .getRelated("PartyContactMechPurpose",
                                UtilMisc.toMap("contactMechPurposeTypeId", "BILLING_LOCATION"), null, false);
                if (UtilValidate.isNotEmpty(billingContactMechs)) {
                    payToAddress = EntityUtil.getFirst(billingContactMechs);
                }
            }
        } else {
            // for sales orders, it is the payment address on file for the store
            payToAddress = PaymentWorker.getPaymentAddress(delegator, productStore.getString("payToPartyId"));
        }
        if (payToAddress != null) {
            Map<String, Object> createPayToContactMechContext = UtilMisc.toMap("invoiceId", invoiceId,
                    "contactMechId", payToAddress.getString("contactMechId"), "contactMechPurposeTypeId",
                    "PAYMENT_LOCATION", "userLogin", userLogin);
            Map<String, Object> createPayToContactMechResult = dispatcher.runSync("createInvoiceContactMech",
                    createPayToContactMechContext);
            if (ServiceUtil.isError(createPayToContactMechResult)) {
                return ServiceUtil.returnError(
                        UtilProperties.getMessage(resource,
                                "AccountingErrorCreatingInvoiceContactMechFromOrder", locale),
                        null, null, createPayToContactMechResult);
            }
        }

        // sequence for items - all OrderItems or InventoryReservations + all Adjustments
        int invoiceItemSeqNum = 1;
        String invoiceItemSeqId = UtilFormatOut.formatPaddedNumber(invoiceItemSeqNum,
                INVOICE_ITEM_SEQUENCE_ID_DIGITS);

        // create the item records
        for (GenericValue currentValue : billItems) {
            GenericValue itemIssuance = null;
            GenericValue orderItem = null;
            GenericValue shipmentReceipt = null;
            if ("ItemIssuance".equals(currentValue.getEntityName())) {
                itemIssuance = currentValue;
            } else if ("OrderItem".equals(currentValue.getEntityName())) {
                orderItem = currentValue;
            } else if ("ShipmentReceipt".equals(currentValue.getEntityName())) {
                shipmentReceipt = currentValue;
            } else {
                Debug.logError("Unexpected entity " + currentValue + " of type " + currentValue.getEntityName(),
                        module);
            }

            if (orderItem == null && itemIssuance != null) {
                orderItem = itemIssuance.getRelatedOne("OrderItem", false);
            } else if ((orderItem == null) && (shipmentReceipt != null)) {
                orderItem = shipmentReceipt.getRelatedOne("OrderItem", false);
            } else if ((orderItem == null) && (itemIssuance == null) && (shipmentReceipt == null)) {
                Debug.logError(
                        "Cannot create invoice when orderItem, itemIssuance, and shipmentReceipt are all null",
                        module);
                return ServiceUtil.returnError(UtilProperties.getMessage(resource,
                        "AccountingIllegalValuesPassedToCreateInvoiceService", locale));
            }
            GenericValue product = null;
            if (orderItem.get("productId") != null) {
                product = orderItem.getRelatedOne("Product", false);
            }

            // get some quantities
            BigDecimal billingQuantity = null;
            if (itemIssuance != null) {
                billingQuantity = itemIssuance.getBigDecimal("quantity");
                BigDecimal cancelQty = itemIssuance.getBigDecimal("cancelQuantity");
                if (cancelQty == null) {
                    cancelQty = ZERO;
                }
                billingQuantity = billingQuantity.subtract(cancelQty).setScale(DECIMALS, ROUNDING);
            } else if (shipmentReceipt != null) {
                billingQuantity = shipmentReceipt.getBigDecimal("quantityAccepted");
            } else {
                BigDecimal orderedQuantity = OrderReadHelper.getOrderItemQuantity(orderItem);
                BigDecimal invoicedQuantity = OrderReadHelper.getOrderItemInvoicedQuantity(orderItem);
                billingQuantity = orderedQuantity.subtract(invoicedQuantity);
                if (billingQuantity.compareTo(ZERO) < 0) {
                    billingQuantity = ZERO;
                }
            }
            if (billingQuantity == null)
                billingQuantity = ZERO;

            // check if shipping applies to this item.  Shipping is calculated for sales invoices, not purchase invoices.
            boolean shippingApplies = false;
            if ((product != null) && (ProductWorker.shippingApplies(product))
                    && (invoiceType.equals("SALES_INVOICE"))) {
                shippingApplies = true;
            }

            BigDecimal billingAmount = BigDecimal.ZERO;
            GenericValue OrderAdjustment = EntityUtil.getFirst(orderItem.getRelated("OrderAdjustment",
                    UtilMisc.toMap("orderAdjustmentTypeId", "VAT_TAX"), null, false));
            /* Apply formula to get actual product price to set amount in invoice item
            Formula is: productPrice = (productPriceWithTax.multiply(100)) / (orderAdj sourcePercentage + 100))
            product price = (43*100) / (20+100) = 35.83 (Here product price is 43 with VAT)
             */
            if (UtilValidate.isNotEmpty(OrderAdjustment)
                    && (OrderAdjustment.getBigDecimal("amount").signum() == 0)
                    && UtilValidate.isNotEmpty(OrderAdjustment.getBigDecimal("amountAlreadyIncluded"))
                    && OrderAdjustment.getBigDecimal("amountAlreadyIncluded").signum() != 0) {
                BigDecimal sourcePercentageTotal = OrderAdjustment.getBigDecimal("sourcePercentage")
                        .add(new BigDecimal(100));
                billingAmount = orderItem.getBigDecimal("unitPrice")
                        .divide(sourcePercentageTotal, 100, ROUNDING).multiply(new BigDecimal(100))
                        .setScale(invoiceTypeDecimals, ROUNDING);
            } else {
                billingAmount = orderItem.getBigDecimal("unitPrice").setScale(invoiceTypeDecimals, ROUNDING);
            }

            Map<String, Object> createInvoiceItemContext = new HashMap<String, Object>();
            createInvoiceItemContext.put("invoiceId", invoiceId);
            createInvoiceItemContext.put("invoiceItemSeqId", invoiceItemSeqId);
            createInvoiceItemContext.put("invoiceItemTypeId",
                    getInvoiceItemType(delegator, (orderItem.getString("orderItemTypeId")),
                            (product == null ? null : product.getString("productTypeId")), invoiceType,
                            "INV_FPROD_ITEM"));
            createInvoiceItemContext.put("description", orderItem.get("itemDescription"));
            createInvoiceItemContext.put("quantity", billingQuantity);
            createInvoiceItemContext.put("amount", billingAmount);
            createInvoiceItemContext.put("productId", orderItem.get("productId"));
            createInvoiceItemContext.put("productFeatureId", orderItem.get("productFeatureId"));
            createInvoiceItemContext.put("overrideGlAccountId", orderItem.get("overrideGlAccountId"));
            createInvoiceItemContext.put("userLogin", userLogin);

            String itemIssuanceId = null;
            if (itemIssuance != null && itemIssuance.get("inventoryItemId") != null) {
                itemIssuanceId = itemIssuance.getString("itemIssuanceId");
                createInvoiceItemContext.put("inventoryItemId", itemIssuance.get("inventoryItemId"));
            }
            // similarly, tax only for purchase invoices
            if ((product != null) && (invoiceType.equals("SALES_INVOICE"))) {
                createInvoiceItemContext.put("taxableFlag", product.get("taxable"));
            }

            Map<String, Object> createInvoiceItemResult = dispatcher.runSync("createInvoiceItem",
                    createInvoiceItemContext);
            if (ServiceUtil.isError(createInvoiceItemResult)) {
                return ServiceUtil
                        .returnError(
                                UtilProperties.getMessage(resource,
                                        "AccountingErrorCreatingInvoiceItemFromOrder", locale),
                                null, null, createInvoiceItemResult);
            }

            // this item total
            BigDecimal thisAmount = billingAmount.multiply(billingQuantity).setScale(invoiceTypeDecimals,
                    ROUNDING);

            // add to the ship amount only if it applies to this item
            if (shippingApplies) {
                invoiceShipProRateAmount = invoiceShipProRateAmount.add(thisAmount)
                        .setScale(invoiceTypeDecimals, ROUNDING);
                invoiceShippableQuantity = invoiceQuantity.add(billingQuantity).setScale(invoiceTypeDecimals,
                        ROUNDING);
            }

            // increment the invoice subtotal
            invoiceSubTotal = invoiceSubTotal.add(thisAmount).setScale(100, ROUNDING);

            // increment the invoice quantity
            invoiceQuantity = invoiceQuantity.add(billingQuantity).setScale(invoiceTypeDecimals, ROUNDING);

            // create the OrderItemBilling record
            Map<String, Object> createOrderItemBillingContext = new HashMap<String, Object>();
            createOrderItemBillingContext.put("invoiceId", invoiceId);
            createOrderItemBillingContext.put("invoiceItemSeqId", invoiceItemSeqId);
            createOrderItemBillingContext.put("orderId", orderItem.get("orderId"));
            createOrderItemBillingContext.put("orderItemSeqId", orderItem.get("orderItemSeqId"));
            createOrderItemBillingContext.put("itemIssuanceId", itemIssuanceId);
            createOrderItemBillingContext.put("quantity", billingQuantity);
            createOrderItemBillingContext.put("amount", billingAmount);
            createOrderItemBillingContext.put("userLogin", userLogin);
            if ((shipmentReceipt != null) && (shipmentReceipt.getString("receiptId") != null)) {
                createOrderItemBillingContext.put("shipmentReceiptId", shipmentReceipt.getString("receiptId"));
            }

            Map<String, Object> createOrderItemBillingResult = dispatcher.runSync("createOrderItemBilling",
                    createOrderItemBillingContext);
            if (ServiceUtil.isError(createOrderItemBillingResult)) {
                return ServiceUtil
                        .returnError(
                                UtilProperties.getMessage(resource,
                                        "AccountingErrorCreatingOrderItemBillingFromOrder", locale),
                                null, null, createOrderItemBillingResult);
            }

            if ("ItemIssuance".equals(currentValue.getEntityName())) {
                /* Find ShipmentItemBilling based on shipmentId, shipmentItemSeqId, invoiceId, invoiceItemSeqId as
                   because if any order item has multiple quantity and reserved by multiple inventories then there will be multiple invoice items.
                   In that case ShipmentItemBilling was creating only for one invoice item. Fixed under OFBIZ-6806.
                */
                List<GenericValue> shipmentItemBillings = EntityQuery.use(delegator).from("ShipmentItemBilling")
                        .where("shipmentId", currentValue.get("shipmentId"), "shipmentItemSeqId",
                                currentValue.get("shipmentItemSeqId"), "invoiceId", invoiceId,
                                "invoiceItemSeqId", invoiceItemSeqId)
                        .queryList();
                if (UtilValidate.isEmpty(shipmentItemBillings)) {

                    // create the ShipmentItemBilling record
                    GenericValue shipmentItemBilling = delegator.makeValue("ShipmentItemBilling",
                            UtilMisc.toMap("invoiceId", invoiceId, "invoiceItemSeqId", invoiceItemSeqId));
                    shipmentItemBilling.put("shipmentId", currentValue.get("shipmentId"));
                    shipmentItemBilling.put("shipmentItemSeqId", currentValue.get("shipmentItemSeqId"));
                    shipmentItemBilling.create();
                }
            }

            String parentInvoiceItemSeqId = invoiceItemSeqId;
            // increment the counter
            invoiceItemSeqNum++;
            invoiceItemSeqId = UtilFormatOut.formatPaddedNumber(invoiceItemSeqNum,
                    INVOICE_ITEM_SEQUENCE_ID_DIGITS);

            // Get the original order item from the DB, in case the quantity has been overridden
            GenericValue originalOrderItem = EntityQuery.use(delegator).from("OrderItem")
                    .where("orderId", orderId, "orderItemSeqId", orderItem.get("orderItemSeqId")).queryOne();

            // create the item adjustment as line items
            List<GenericValue> itemAdjustments = OrderReadHelper.getOrderItemAdjustmentList(orderItem,
                    orh.getAdjustments());
            for (GenericValue adj : itemAdjustments) {

                // Check against OrderAdjustmentBilling to see how much of this adjustment has already been invoiced
                BigDecimal adjAlreadyInvoicedAmount = null;
                try {
                    Map<String, Object> checkResult = dispatcher.runSync("calculateInvoicedAdjustmentTotal",
                            UtilMisc.toMap("orderAdjustment", adj));
                    adjAlreadyInvoicedAmount = (BigDecimal) checkResult.get("invoicedTotal");
                } catch (GenericServiceException e) {
                    Debug.logError(e, "Accounting trouble calling calculateInvoicedAdjustmentTotal service",
                            module);
                    return ServiceUtil.returnError(UtilProperties.getMessage(resource,
                            "AccountingTroubleCallingCalculateInvoicedAdjustmentTotalService", locale));
                }

                //                    if (adj.get("amount") == null) { TODO check usage with webPos. Was: fix a bug coming from POS in case of use of a discount (on item(s) or sale, item(s) here) and a cash amount higher than total (hence issuing change)
                //                        continue;
                //                    }
                // Set adjustment amount as amountAlreadyIncluded to continue invoice item creation process
                Boolean isTaxIncludedInPrice = adj.getString("orderAdjustmentTypeId").equals("VAT_TAX")
                        && UtilValidate.isNotEmpty(adj.getBigDecimal("amountAlreadyIncluded"))
                        && adj.getBigDecimal("amountAlreadyIncluded").signum() != 0;
                if ((adj.getBigDecimal("amount").signum() == 0) && isTaxIncludedInPrice) {
                    adj.set("amount", adj.getBigDecimal("amountAlreadyIncluded"));
                }
                // If the absolute invoiced amount >= the abs of the adjustment amount, the full amount has already been invoiced, so skip this adjustment
                if (adjAlreadyInvoicedAmount.abs().compareTo(
                        adj.getBigDecimal("amount").setScale(invoiceTypeDecimals, ROUNDING).abs()) > 0) {
                    continue;
                }

                BigDecimal originalOrderItemQuantity = OrderReadHelper.getOrderItemQuantity(originalOrderItem);
                BigDecimal amount = ZERO;
                if (originalOrderItemQuantity.signum() != 0) {
                    if (adj.get("amount") != null) {
                        if ("PROMOTION_ADJUSTMENT".equals(adj.getString("orderAdjustmentTypeId"))
                                && adj.get("productPromoId") != null) {
                            /* Find negative amountAlreadyIncluded in OrderAdjustment to subtract it from discounted amount.
                                                                  As we stored negative sales tax amount in order adjustment for discounted item.
                             */
                            List<EntityExpr> exprs = UtilMisc.toList(
                                    EntityCondition.makeCondition("orderId", EntityOperator.EQUALS,
                                            orderItem.getString("orderId")),
                                    EntityCondition.makeCondition("orderItemSeqId", EntityOperator.EQUALS,
                                            orderItem.getString("orderItemSeqId")),
                                    EntityCondition.makeCondition("orderAdjustmentTypeId",
                                            EntityOperator.EQUALS, "VAT_TAX"),
                                    EntityCondition.makeCondition("amountAlreadyIncluded",
                                            EntityOperator.LESS_THAN, BigDecimal.ZERO));
                            EntityCondition andCondition = EntityCondition.makeCondition(exprs,
                                    EntityOperator.AND);
                            GenericValue orderAdjustment = EntityUtil.getFirst(delegator
                                    .findList("OrderAdjustment", andCondition, null, null, null, false));
                            if (UtilValidate.isNotEmpty(orderAdjustment)) {
                                amount = adj.getBigDecimal("amount")
                                        .subtract(orderAdjustment.getBigDecimal("amountAlreadyIncluded"))
                                        .setScale(100, ROUNDING);
                            } else {
                                amount = adj.getBigDecimal("amount");
                            }
                        } else {
                            // pro-rate the amount
                            // set decimals = 100 means we don't round this intermediate value, which is very important
                            if (isTaxIncludedInPrice) {
                                BigDecimal priceWithTax = originalOrderItem.getBigDecimal("unitPrice");
                                // Get tax included in item price
                                amount = priceWithTax.subtract(billingAmount);
                                amount = amount.multiply(billingQuantity);
                                // get adjustment amount
                                /* Get tax amount of other invoice and calculate remaining amount need to store in invoice item(Handle case of of partial shipment and promotional item)
                                                                      to adjust tax amount in invoice item. 
                                 */
                                BigDecimal otherInvoiceTaxAmount = BigDecimal.ZERO;
                                GenericValue orderAdjBilling = EntityUtil.getFirst(delegator.findByAnd(
                                        "OrderAdjustmentBilling",
                                        UtilMisc.toMap("orderAdjustmentId", adj.getString("orderAdjustmentId")),
                                        null, false));
                                if (UtilValidate.isNotEmpty(orderAdjBilling)) {
                                    List<GenericValue> invoiceItems = delegator.findByAnd("InvoiceItem",
                                            UtilMisc.toMap("invoiceId", orderAdjBilling.getString("invoiceId"),
                                                    "invoiceItemTypeId", "ITM_SALES_TAX", "productId",
                                                    originalOrderItem.getString("productId")),
                                            null, isTaxIncludedInPrice);
                                    for (GenericValue invoiceItem : invoiceItems) {
                                        otherInvoiceTaxAmount = otherInvoiceTaxAmount
                                                .add(invoiceItem.getBigDecimal("amount"));
                                    }
                                    if (otherInvoiceTaxAmount.compareTo(BigDecimal.ZERO) > 0) {
                                        BigDecimal remainingAmount = adj.getBigDecimal("amountAlreadyIncluded")
                                                .subtract(otherInvoiceTaxAmount);
                                        amount = amount.min(remainingAmount);
                                    }
                                }
                                amount = amount.min(adj.getBigDecimal("amountAlreadyIncluded")).setScale(100,
                                        ROUNDING);
                            } else {
                                amount = adj.getBigDecimal("amount").divide(originalOrderItemQuantity, 100,
                                        ROUNDING);
                                amount = amount.multiply(billingQuantity);
                            }
                        }
                        // Tax needs to be rounded differently from other order adjustments
                        if (adj.getString("orderAdjustmentTypeId").equals("SALES_TAX")) {
                            amount = amount.setScale(TAX_DECIMALS, TAX_ROUNDING);
                        } else {
                            amount = amount.setScale(invoiceTypeDecimals, ROUNDING);
                        }
                    } else if (adj.get("sourcePercentage") != null) {
                        // pro-rate the amount
                        // set decimals = 100 means we don't round this intermediate value, which is very important
                        BigDecimal percent = adj.getBigDecimal("sourcePercentage");
                        percent = percent.divide(new BigDecimal(100), 100, ROUNDING);
                        amount = billingAmount.multiply(percent);
                        amount = amount.divide(originalOrderItemQuantity, 100, ROUNDING);
                        amount = amount.multiply(billingQuantity);
                        amount = amount.setScale(invoiceTypeDecimals, ROUNDING);
                    }
                }
                if (amount.signum() != 0) {
                    Map<String, Object> createInvoiceItemAdjContext = new HashMap<String, Object>();
                    createInvoiceItemAdjContext.put("invoiceId", invoiceId);
                    createInvoiceItemAdjContext.put("invoiceItemSeqId", invoiceItemSeqId);
                    createInvoiceItemAdjContext.put("invoiceItemTypeId", getInvoiceItemType(delegator,
                            adj.getString("orderAdjustmentTypeId"), null, invoiceType, "INVOICE_ITM_ADJ"));
                    createInvoiceItemAdjContext.put("quantity", BigDecimal.ONE);
                    createInvoiceItemAdjContext.put("amount", amount);
                    createInvoiceItemAdjContext.put("productId", orderItem.get("productId"));
                    createInvoiceItemAdjContext.put("productFeatureId", orderItem.get("productFeatureId"));
                    createInvoiceItemAdjContext.put("overrideGlAccountId", adj.get("overrideGlAccountId"));
                    createInvoiceItemAdjContext.put("parentInvoiceId", invoiceId);
                    createInvoiceItemAdjContext.put("parentInvoiceItemSeqId", parentInvoiceItemSeqId);
                    createInvoiceItemAdjContext.put("userLogin", userLogin);
                    createInvoiceItemAdjContext.put("taxAuthPartyId", adj.get("taxAuthPartyId"));
                    createInvoiceItemAdjContext.put("taxAuthGeoId", adj.get("taxAuthGeoId"));
                    createInvoiceItemAdjContext.put("taxAuthorityRateSeqId", adj.get("taxAuthorityRateSeqId"));

                    // some adjustments fill out the comments field instead
                    String description = (UtilValidate.isEmpty(adj.getString("description"))
                            ? adj.getString("comments")
                            : adj.getString("description"));
                    createInvoiceItemAdjContext.put("description", description);

                    // invoice items for sales tax are not taxable themselves
                    // TODO: This is not an ideal solution. Instead, we need to use OrderAdjustment.includeInTax when it is implemented
                    if (!(adj.getString("orderAdjustmentTypeId").equals("SALES_TAX"))) {
                        createInvoiceItemAdjContext.put("taxableFlag", product.get("taxable"));
                    }

                    // If the OrderAdjustment is associated to a ProductPromo,
                    // and the field ProductPromo.overrideOrgPartyId is set,
                    // copy the value to InvoiceItem.overrideOrgPartyId: this
                    // represent an organization override for the payToPartyId
                    if (UtilValidate.isNotEmpty(adj.getString("productPromoId"))) {
                        try {
                            GenericValue productPromo = adj.getRelatedOne("ProductPromo", false);
                            if (UtilValidate.isNotEmpty(productPromo.getString("overrideOrgPartyId"))) {
                                createInvoiceItemAdjContext.put("overrideOrgPartyId",
                                        productPromo.getString("overrideOrgPartyId"));
                            }
                        } catch (GenericEntityException e) {
                            Debug.logError(e, "Error looking up ProductPromo with id ["
                                    + adj.getString("productPromoId") + "]", module);
                        }
                    }

                    Map<String, Object> createInvoiceItemAdjResult = dispatcher.runSync("createInvoiceItem",
                            createInvoiceItemAdjContext);
                    if (ServiceUtil.isError(createInvoiceItemAdjResult)) {
                        return ServiceUtil.returnError(
                                UtilProperties.getMessage(resource,
                                        "AccountingErrorCreatingInvoiceItemFromOrder", locale),
                                null, null, createInvoiceItemAdjResult);
                    }

                    // Create the OrderAdjustmentBilling record
                    Map<String, Object> createOrderAdjustmentBillingContext = new HashMap<String, Object>();
                    createOrderAdjustmentBillingContext.put("orderAdjustmentId",
                            adj.getString("orderAdjustmentId"));
                    createOrderAdjustmentBillingContext.put("invoiceId", invoiceId);
                    createOrderAdjustmentBillingContext.put("invoiceItemSeqId", invoiceItemSeqId);
                    createOrderAdjustmentBillingContext.put("amount", amount);
                    createOrderAdjustmentBillingContext.put("userLogin", userLogin);

                    Map<String, Object> createOrderAdjustmentBillingResult = dispatcher
                            .runSync("createOrderAdjustmentBilling", createOrderAdjustmentBillingContext);
                    if (ServiceUtil.isError(createOrderAdjustmentBillingResult)) {
                        return ServiceUtil.returnError(
                                UtilProperties.getMessage(resource,
                                        "AccountingErrorCreatingOrderAdjustmentBillingFromOrder", locale),
                                null, null, createOrderAdjustmentBillingContext);
                    }

                    // this adjustment amount
                    BigDecimal thisAdjAmount = amount;

                    // adjustments only apply to totals when they are not tax or shipping adjustments
                    if (!"SALES_TAX".equals(adj.getString("orderAdjustmentTypeId"))
                            && !"SHIPPING_ADJUSTMENT".equals(adj.getString("orderAdjustmentTypeId"))) {
                        // increment the invoice subtotal
                        invoiceSubTotal = invoiceSubTotal.add(thisAdjAmount).setScale(100, ROUNDING);

                        // add to the ship amount only if it applies to this item
                        if (shippingApplies) {
                            invoiceShipProRateAmount = invoiceShipProRateAmount.add(thisAdjAmount)
                                    .setScale(invoiceTypeDecimals, ROUNDING);
                        }
                    }

                    // increment the counter
                    invoiceItemSeqNum++;
                    invoiceItemSeqId = UtilFormatOut.formatPaddedNumber(invoiceItemSeqNum,
                            INVOICE_ITEM_SEQUENCE_ID_DIGITS);
                }
            }
        }

        // create header adjustments as line items -- always to tax/shipping last
        Map<GenericValue, BigDecimal> shipAdjustments = new HashMap<GenericValue, BigDecimal>();
        Map<GenericValue, BigDecimal> taxAdjustments = new HashMap<GenericValue, BigDecimal>();

        List<GenericValue> headerAdjustments = orh.getOrderHeaderAdjustments();
        for (GenericValue adj : headerAdjustments) {

            // Check against OrderAdjustmentBilling to see how much of this adjustment has already been invoiced
            BigDecimal adjAlreadyInvoicedAmount = null;
            try {
                Map<String, Object> checkResult = dispatcher.runSync("calculateInvoicedAdjustmentTotal",
                        UtilMisc.toMap("orderAdjustment", adj));
                adjAlreadyInvoicedAmount = ((BigDecimal) checkResult.get("invoicedTotal"))
                        .setScale(invoiceTypeDecimals, ROUNDING);
            } catch (GenericServiceException e) {
                Debug.logError(e, "Accounting trouble calling calculateInvoicedAdjustmentTotal service",
                        module);
                return ServiceUtil.returnError(UtilProperties.getMessage(resource,
                        "AccountingTroubleCallingCalculateInvoicedAdjustmentTotalService", locale));
            }

            //                if (null == adj.get("amount")) { TODO check usage with webPos. Was: fix a bug coming from POS in case of use of a discount (on item(s) or sale, sale here) and a cash amount higher than total (hence issuing change)
            //                    continue;
            //                }
            // If the absolute invoiced amount >= the abs of the adjustment amount, the full amount has already been invoiced, so skip this adjustment
            if (adjAlreadyInvoicedAmount.abs().compareTo(
                    adj.getBigDecimal("amount").setScale(invoiceTypeDecimals, ROUNDING).abs()) >= 0) {
                continue;
            }

            if ("SHIPPING_CHARGES".equals(adj.getString("orderAdjustmentTypeId"))) {
                shipAdjustments.put(adj, adjAlreadyInvoicedAmount);
            } else if ("SALES_TAX".equals(adj.getString("orderAdjustmentTypeId"))) {
                taxAdjustments.put(adj, adjAlreadyInvoicedAmount);
            } else {
                // these will effect the shipping pro-rate (unless commented)
                // other adjustment type
                BigDecimal divisor = orderSubTotal;
                BigDecimal multiplier = invoiceSubTotal;
                if (BigDecimal.ZERO.compareTo(multiplier) == 0 && BigDecimal.ZERO.compareTo(divisor) == 0) {
                    // if multiplier and divisor are equal to zero then use the quantities instead of the amounts
                    // this is useful when the order has free items and misc charges
                    divisor = orderQuantity;
                    multiplier = invoiceQuantity;
                }

                calcHeaderAdj(delegator, adj, invoiceType, invoiceId, invoiceItemSeqId, divisor, multiplier,
                        adj.getBigDecimal("amount").setScale(invoiceTypeDecimals, ROUNDING),
                        invoiceTypeDecimals, ROUNDING, userLogin, dispatcher, locale);
                // invoiceShipProRateAmount += adjAmount;
                // do adjustments compound or are they based off subtotal? Here we will (unless commented)
                // invoiceSubTotal += adjAmount;

                // increment the counter
                invoiceItemSeqNum++;
                invoiceItemSeqId = UtilFormatOut.formatPaddedNumber(invoiceItemSeqNum,
                        INVOICE_ITEM_SEQUENCE_ID_DIGITS);
            }
        }

        // next do the shipping adjustments.  Note that we do not want to add these to the invoiceSubTotal or orderSubTotal for pro-rating tax later, as that would cause
        // numerator/denominator problems when the shipping is not pro-rated but rather charged all on the first invoice
        for (GenericValue adj : shipAdjustments.keySet()) {
            BigDecimal adjAlreadyInvoicedAmount = shipAdjustments.get(adj);

            if ("N".equalsIgnoreCase(prorateShipping)) {

                // Set the divisor and multiplier to 1 to avoid prorating
                BigDecimal divisor = BigDecimal.ONE;
                BigDecimal multiplier = BigDecimal.ONE;

                // The base amount in this case is the adjustment amount minus the total already invoiced for that adjustment, since
                //  it won't be prorated
                BigDecimal baseAmount = adj.getBigDecimal("amount").setScale(invoiceTypeDecimals, ROUNDING)
                        .subtract(adjAlreadyInvoicedAmount);
                calcHeaderAdj(delegator, adj, invoiceType, invoiceId, invoiceItemSeqId, divisor, multiplier,
                        baseAmount, invoiceTypeDecimals, ROUNDING, userLogin, dispatcher, locale);
            } else {

                // Pro-rate the shipping amount based on shippable information
                BigDecimal divisor = shippableAmount;
                BigDecimal multiplier = invoiceShipProRateAmount;
                if (BigDecimal.ZERO.compareTo(multiplier) == 0 && BigDecimal.ZERO.compareTo(divisor) == 0) {
                    // if multiplier and divisor are equal to zero then use the quantities instead of the amounts
                    // this is useful when the order has free items and shipping charges
                    divisor = shippableQuantity;
                    multiplier = invoiceShippableQuantity;
                }

                // The base amount in this case is the adjustment amount, since we want to prorate based on the full amount
                BigDecimal baseAmount = adj.getBigDecimal("amount").setScale(invoiceTypeDecimals, ROUNDING);
                calcHeaderAdj(delegator, adj, invoiceType, invoiceId, invoiceItemSeqId, divisor, multiplier,
                        baseAmount, invoiceTypeDecimals, ROUNDING, userLogin, dispatcher, locale);
            }

            // Increment the counter
            invoiceItemSeqNum++;
            invoiceItemSeqId = UtilFormatOut.formatPaddedNumber(invoiceItemSeqNum,
                    INVOICE_ITEM_SEQUENCE_ID_DIGITS);
        }

        // last do the tax adjustments
        String prorateTaxes = productStore != null ? productStore.getString("prorateTaxes") : "Y";
        if (prorateTaxes == null) {
            prorateTaxes = "Y";
        }
        for (Map.Entry<GenericValue, BigDecimal> entry : taxAdjustments.entrySet()) {
            GenericValue adj = entry.getKey();
            BigDecimal adjAlreadyInvoicedAmount = entry.getValue();
            BigDecimal adjAmount = null;

            if ("N".equalsIgnoreCase(prorateTaxes)) {

                // Set the divisor and multiplier to 1 to avoid prorating
                BigDecimal divisor = BigDecimal.ONE;
                BigDecimal multiplier = BigDecimal.ONE;

                // The base amount in this case is the adjustment amount minus the total already invoiced for that adjustment, since
                //  it won't be prorated
                BigDecimal baseAmount = adj.getBigDecimal("amount").setScale(TAX_DECIMALS, TAX_ROUNDING)
                        .subtract(adjAlreadyInvoicedAmount);
                adjAmount = calcHeaderAdj(delegator, adj, invoiceType, invoiceId, invoiceItemSeqId, divisor,
                        multiplier, baseAmount, TAX_DECIMALS, TAX_ROUNDING, userLogin, dispatcher, locale);
            } else {

                // Pro-rate the tax amount based on shippable information
                BigDecimal divisor = orderSubTotal;
                BigDecimal multiplier = invoiceSubTotal;

                // The base amount in this case is the adjustment amount, since we want to prorate based on the full amount
                BigDecimal baseAmount = adj.getBigDecimal("amount");
                adjAmount = calcHeaderAdj(delegator, adj, invoiceType, invoiceId, invoiceItemSeqId, divisor,
                        multiplier, baseAmount, TAX_DECIMALS, TAX_ROUNDING, userLogin, dispatcher, locale);
            }
            invoiceSubTotal = invoiceSubTotal.add(adjAmount).setScale(invoiceTypeDecimals, ROUNDING);

            // Increment the counter
            invoiceItemSeqNum++;
            invoiceItemSeqId = UtilFormatOut.formatPaddedNumber(invoiceItemSeqNum,
                    INVOICE_ITEM_SEQUENCE_ID_DIGITS);
        }

        // check for previous order payments
        List<GenericValue> orderPaymentPrefs = EntityQuery.use(delegator).from("OrderPaymentPreference").where(
                EntityCondition.makeCondition("orderId", EntityOperator.EQUALS, orderId),
                EntityCondition.makeCondition("statusId", EntityOperator.NOT_EQUAL, "PAYMENT_CANCELLED"))
                .queryList();
        List<GenericValue> currentPayments = new LinkedList<GenericValue>();
        for (GenericValue paymentPref : orderPaymentPrefs) {
            List<GenericValue> payments = paymentPref.getRelated("Payment", null, null, false);
            currentPayments.addAll(payments);
        }
        // apply these payments to the invoice if they have any remaining amount to apply
        for (GenericValue payment : currentPayments) {
            if ("PMNT_VOID".equals(payment.getString("statusId"))
                    || "PMNT_CANCELLED".equals(payment.getString("statusId"))) {
                continue;
            }
            BigDecimal notApplied = PaymentWorker.getPaymentNotApplied(payment);
            if (notApplied.signum() > 0) {
                Map<String, Object> appl = new HashMap<String, Object>();
                appl.put("paymentId", payment.get("paymentId"));
                appl.put("invoiceId", invoiceId);
                appl.put("billingAccountId", billingAccountId);
                appl.put("amountApplied", notApplied);
                appl.put("userLogin", userLogin);
                Map<String, Object> createPayApplResult = dispatcher.runSync("createPaymentApplication", appl);
                if (ServiceUtil.isError(createPayApplResult)) {
                    return ServiceUtil
                            .returnError(
                                    UtilProperties.getMessage(resource,
                                            "AccountingErrorCreatingInvoiceFromOrder", locale),
                                    null, null, createPayApplResult);
                }
            }
        }

        // Should all be in place now. Depending on the ProductStore.autoApproveInvoice setting, set status to INVOICE_READY (unless it's a purchase invoice, which we set to INVOICE_IN_PROCESS)
        String autoApproveInvoice = productStore != null ? productStore.getString("autoApproveInvoice") : "Y";
        if (!"N".equals(autoApproveInvoice)) {
            String nextStatusId = "PURCHASE_INVOICE".equals(invoiceType) ? "INVOICE_IN_PROCESS"
                    : "INVOICE_READY";
            Map<String, Object> setInvoiceStatusResult = dispatcher.runSync("setInvoiceStatus",
                    UtilMisc.<String, Object>toMap("invoiceId", invoiceId, "statusId", nextStatusId,
                            "userLogin", userLogin));
            if (ServiceUtil.isError(setInvoiceStatusResult)) {
                return ServiceUtil.returnError(
                        UtilProperties.getMessage(resource, "AccountingErrorCreatingInvoiceFromOrder", locale),
                        null, null, setInvoiceStatusResult);
            }
        }

        Map<String, Object> resp = ServiceUtil.returnSuccess();
        resp.put("invoiceId", invoiceId);
        resp.put("invoiceTypeId", invoiceType);
        return resp;
    } catch (GenericEntityException e) {
        Debug.logError(e, "Entity/data problem creating invoice from order items: " + e.toString(), module);
        return ServiceUtil.returnError(
                UtilProperties.getMessage(resource, "AccountingEntityDataProblemCreatingInvoiceFromOrderItems",
                        UtilMisc.toMap("reason", e.toString()), locale));
    } catch (GenericServiceException e) {
        Debug.logError(e, "Service/other problem creating invoice from order items: " + e.toString(), module);
        return ServiceUtil.returnError(UtilProperties.getMessage(resource,
                "AccountingServiceOtherProblemCreatingInvoiceFromOrderItems",
                UtilMisc.toMap("reason", e.toString()), locale));
    }
}

From source file:com.lp.server.fertigung.ejbfac.FertigungFacBean.java

@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public HashMap<Integer, StuecklistepositionDto> holeAlleLossollmaterialFuerStuecklistenAktualisierung(
        Integer stuecklisteIId, BigDecimal bdLosgroesse, int iEbene,
        HashMap<Integer, StuecklistepositionDto> hmPositionen, TheClientDto theClientDto) {
    iEbene++;//from  ww  w. j av  a 2  s .  c  o  m

    if (hmPositionen == null) {
        hmPositionen = new HashMap<Integer, StuecklistepositionDto>();
    }
    try {
        StuecklistepositionDto[] stkPos = getStuecklisteFac()
                .stuecklistepositionFindByStuecklisteIId(stuecklisteIId, theClientDto);

        StuecklisteDto stklDto = getStuecklisteFac().stuecklisteFindByPrimaryKey(stuecklisteIId, theClientDto);

        for (int i = 0; i < stkPos.length; i++) {
            // alle stuecklistenpositionen ins los uebernehmen

            // W02451
            if (stkPos[i].getArtikelIId() == 6093) {
                int u = 0;
            }

            // Einheit umrechnen
            ArtikelDto artikelDto = getArtikelFac().artikelFindByPrimaryKeySmall(stkPos[i].getArtikelIId(),
                    theClientDto);

            BigDecimal bdFaktor = getSystemFac().rechneUmInAndereEinheit(new BigDecimal(1),
                    stkPos[i].getEinheitCNr(), artikelDto.getEinheitCNr(), stkPos[i].getIId(), theClientDto);

            // nun die Dimensionen
            BigDecimal bdDimProdukt = new BigDecimal(1);
            EinheitDto einheitDto = getSystemFac().einheitFindByPrimaryKey(stkPos[i].getEinheitCNr(),
                    theClientDto);
            if (einheitDto.getIDimension().intValue() >= 1) {
                if (stkPos[i].getFDimension1() != null) {
                    bdDimProdukt = bdDimProdukt
                            .multiply(new BigDecimal(stkPos[i].getFDimension1().floatValue()));
                }
            }
            if (einheitDto.getIDimension().intValue() >= 2) {
                if (stkPos[i].getFDimension2() != null) {
                    bdDimProdukt = bdDimProdukt
                            .multiply(new BigDecimal(stkPos[i].getFDimension2().floatValue()));
                }
            }
            if (einheitDto.getIDimension().intValue() >= 3) {
                if (stkPos[i].getFDimension3() != null) {
                    bdDimProdukt = bdDimProdukt
                            .multiply(new BigDecimal(stkPos[i].getFDimension3().floatValue()));
                }
            }
            // verschnitt
            BigDecimal bdMenge = Helper.berechneMengeInklusiveVerschnitt(stkPos[i].getNMenge(),
                    artikelDto.getFVerschnittfaktor(), artikelDto.getFVerschnittbasis(), bdLosgroesse);

            // endgueltige Menge berechnen
            BigDecimal posMenge = bdMenge.multiply(bdDimProdukt).multiply(bdLosgroesse).multiply(bdFaktor)
                    .divide(new BigDecimal(stklDto.getIErfassungsfaktor().doubleValue()),
                            BigDecimal.ROUND_HALF_EVEN);

            if (posMenge.doubleValue() < 0.001 && posMenge.doubleValue() > 0.000001) {
                posMenge = new BigDecimal("0.001");
                posMenge = posMenge.setScale(3, BigDecimal.ROUND_HALF_EVEN);
            } else {
                posMenge = posMenge.setScale(3, BigDecimal.ROUND_HALF_EVEN);
            }

            stkPos[i].setNMenge(posMenge);

            StuecklisteDto stuecklisteDto = getStuecklisteFac()
                    .stuecklisteFindByMandantCNrArtikelIIdOhneExc(stkPos[i].getArtikelIId(), theClientDto);

            if (stuecklisteDto != null && stuecklisteDto.getStuecklisteartCNr()
                    .equals(StuecklisteFac.STUECKLISTEART_HILFSSTUECKLISTE)) {
                if (iEbene < 10) {
                    holeAlleLossollmaterialFuerStuecklistenAktualisierung(stuecklisteDto.getIId(), posMenge,
                            iEbene, hmPositionen, theClientDto);
                }

            } else {

                if (stkPos[i].getNMenge().doubleValue() > 0) {

                    if (hmPositionen.containsKey(stkPos[i].getArtikelIId())) {

                        StuecklistepositionDto p = hmPositionen.get(stkPos[i].getArtikelIId());
                        p.setNMenge(stkPos[i].getNMenge().add(p.getNMenge()));
                        hmPositionen.put(stkPos[i].getArtikelIId(), p);
                    } else {
                        hmPositionen.put(stkPos[i].getArtikelIId(), stkPos[i]);
                    }
                }

            }
        }
    } catch (RemoteException ex1) {
        throwEJBExceptionLPRespectOld(ex1);
    }

    return hmPositionen;

}

From source file:com.lp.server.fertigung.ejbfac.FertigungFacBean.java

private void erstelleLossollmaterial(Integer losIId, Integer stuecklisteIId, BigDecimal bdPositionsMenge,
        Integer lagerIId_Hauptlager, boolean bFlachdruecken, int iEbene, TheClientDto theClientDto) {
    iEbene++;//from   w w  w .  ja  va 2 s .  co  m
    try {
        StuecklistepositionDto[] stkPos = getStuecklisteFac()
                .stuecklistepositionFindByStuecklisteIId(stuecklisteIId, theClientDto);

        StuecklisteDto stklDto = getStuecklisteFac().stuecklisteFindByPrimaryKey(stuecklisteIId, theClientDto);

        for (int i = 0; i < stkPos.length; i++) {
            // alle stuecklistenpositionen ins los uebernehmen

            LossollmaterialDto losMatDto = new LossollmaterialDto();
            losMatDto.setArtikelIId(stkPos[i].getArtikelIId());
            losMatDto.setBNachtraeglich(Helper.boolean2Short(false));
            losMatDto.setCKommentar(stkPos[i].getCKommentar());
            losMatDto.setCPosition(stkPos[i].getCPosition());
            losMatDto.setFDimension1(stkPos[i].getFDimension1());
            losMatDto.setFDimension2(stkPos[i].getFDimension2());
            losMatDto.setFDimension3(stkPos[i].getFDimension3());
            losMatDto.setILfdnummer(stkPos[i].getILfdnummer());
            losMatDto.setIBeginnterminoffset(stkPos[i].getIBeginnterminoffset());
            losMatDto.setISort(stkPos[i].getISort());
            losMatDto.setLosIId(losIId);
            losMatDto.setMontageartIId(stkPos[i].getMontageartIId());
            // Einheit umrechnen
            ArtikelDto artikelDto = getArtikelFac().artikelFindByPrimaryKey(stkPos[i].getArtikelIId(),
                    theClientDto);
            losMatDto.setEinheitCNr(artikelDto.getEinheitCNr());
            BigDecimal bdFaktor = getSystemFac().rechneUmInAndereEinheit(new BigDecimal(1),
                    artikelDto.getEinheitCNr(), stkPos[i].getEinheitCNr(), stkPos[i].getIId(), theClientDto);

            // nun die Dimensionen
            BigDecimal bdDimProdukt = new BigDecimal(1);
            EinheitDto einheitDto = getSystemFac().einheitFindByPrimaryKey(stkPos[i].getEinheitCNr(),
                    theClientDto);
            if (einheitDto.getIDimension().intValue() >= 1) {
                if (stkPos[i].getFDimension1() != null) {
                    bdDimProdukt = bdDimProdukt
                            .multiply(new BigDecimal(stkPos[i].getFDimension1().floatValue()));
                }
            }
            if (einheitDto.getIDimension().intValue() >= 2) {
                if (stkPos[i].getFDimension2() != null) {
                    bdDimProdukt = bdDimProdukt
                            .multiply(new BigDecimal(stkPos[i].getFDimension2().floatValue()));
                }
            }
            if (einheitDto.getIDimension().intValue() >= 3) {
                if (stkPos[i].getFDimension3() != null) {
                    bdDimProdukt = bdDimProdukt
                            .multiply(new BigDecimal(stkPos[i].getFDimension3().floatValue()));
                }
            }
            // verschnitt
            BigDecimal bdMenge = Helper.berechneMengeInklusiveVerschnitt(stkPos[i].getNMenge(),
                    artikelDto.getFVerschnittfaktor(), artikelDto.getFVerschnittbasis(), bdPositionsMenge);

            // endgueltige Menge berechnen
            if (bdFaktor.doubleValue() != 0) {

                bdMenge = bdMenge.divide(bdFaktor, BigDecimal.ROUND_HALF_EVEN);

                BigDecimal losSollMenge = bdMenge.multiply(bdDimProdukt).multiply(bdPositionsMenge).divide(
                        new BigDecimal(stklDto.getIErfassungsfaktor().doubleValue()),
                        BigDecimal.ROUND_HALF_EVEN);

                if (losSollMenge.doubleValue() < 0.001 && losSollMenge.doubleValue() > 0.000001) {
                    losSollMenge = new BigDecimal("0.001");
                    losSollMenge = losSollMenge.setScale(3, BigDecimal.ROUND_HALF_EVEN);
                } else {
                    losSollMenge = losSollMenge.setScale(3, BigDecimal.ROUND_HALF_EVEN);
                }

                losMatDto.setNMenge(losSollMenge);

            }

            BigDecimal bdSollpreis = getLagerFac().getGemittelterGestehungspreisEinesLagers(
                    stkPos[i].getArtikelIId(), lagerIId_Hauptlager, theClientDto);
            losMatDto.setNSollpreis(bdSollpreis);
            // Datensatz speichern

            // Wenn Unterstueckliste und Hilfsstueckliste:

            StuecklisteDto stuecklisteDto = getStuecklisteFac()
                    .stuecklisteFindByMandantCNrArtikelIIdOhneExc(stkPos[i].getArtikelIId(), theClientDto);

            if (stuecklisteDto != null && stuecklisteDto.getArtikelIId() == 3376) {
                int u = 0;

            }

            if (stuecklisteDto != null && stuecklisteDto.getStuecklisteartCNr()
                    .equals(StuecklisteFac.STUECKLISTEART_HILFSSTUECKLISTE) && bFlachdruecken == true) {
                if (iEbene < 10) {
                    erstelleLossollmaterial(losIId, stuecklisteDto.getIId(), losMatDto.getNMenge(),
                            lagerIId_Hauptlager, true, iEbene, theClientDto);

                }

            } else {

                LossollmaterialDto lossollmaterialDto = createLossollmaterial(losMatDto, theClientDto);

                Integer iOriginal_IId = new Integer(lossollmaterialDto.getIId());

                // Ersatztypen anlegen
                PosersatzDto[] posersatzDtos = getStuecklisteFac()
                        .posersatzFindByStuecklistepositionIId(stkPos[i].getIId());
                if (iEbene < 10) {
                    for (int k = 0; k < posersatzDtos.length; k++) {

                        losMatDto.setArtikelIId(posersatzDtos[k].getArtikelIIdErsatz());
                        losMatDto.setNMenge(new BigDecimal(0));
                        losMatDto.setLossollmaterialIIdOriginal(iOriginal_IId);
                        createLossollmaterial(losMatDto, theClientDto);

                    }
                }
            }
        }
    } catch (RemoteException ex1) {
        throwEJBExceptionLPRespectOld(ex1);
    }
}

From source file:org.apache.ofbiz.accounting.invoice.InvoiceServices.java

public static Map<String, Object> createInvoicesFromShipments(DispatchContext dctx,
        Map<String, ? extends Object> context) {
    Delegator delegator = dctx.getDelegator();
    LocalDispatcher dispatcher = dctx.getDispatcher();
    List<String> shipmentIds = UtilGenerics.checkList(context.get("shipmentIds"));
    Locale locale = (Locale) context.get("locale");
    Boolean createSalesInvoicesForDropShipments = (Boolean) context.get("createSalesInvoicesForDropShipments");
    if (UtilValidate.isEmpty(createSalesInvoicesForDropShipments))
        createSalesInvoicesForDropShipments = Boolean.FALSE;

    boolean salesShipmentFound = false;
    boolean purchaseShipmentFound = false;
    boolean dropShipmentFound = false;

    List<String> invoicesCreated = new LinkedList<String>();

    //DEJ20060520: not used? planned to be used? List shipmentIdList = new LinkedList();
    for (String tmpShipmentId : shipmentIds) {
        try {/*from  www.j  ava 2 s  .c o m*/
            GenericValue shipment = EntityQuery.use(delegator).from("Shipment")
                    .where("shipmentId", tmpShipmentId).queryOne();
            if ((shipment.getString("shipmentTypeId") != null)
                    && (shipment.getString("shipmentTypeId").equals("PURCHASE_SHIPMENT"))) {
                purchaseShipmentFound = true;
            } else if ((shipment.getString("shipmentTypeId") != null)
                    && (shipment.getString("shipmentTypeId").equals("DROP_SHIPMENT"))) {
                dropShipmentFound = true;
            } else {
                salesShipmentFound = true;
            }
            if (purchaseShipmentFound && salesShipmentFound && dropShipmentFound) {
                return ServiceUtil.returnError(UtilProperties.getMessage(
                        resource, "AccountingShipmentsOfDifferentTypes", UtilMisc.toMap("tmpShipmentId",
                                tmpShipmentId, "shipmentTypeId", shipment.getString("shipmentTypeId")),
                        locale));
            }
        } catch (GenericEntityException e) {
            Debug.logError(e, "Trouble getting Shipment entity for shipment " + tmpShipmentId, module);
            return ServiceUtil
                    .returnError(UtilProperties.getMessage(resource, "AccountingTroubleGettingShipmentEntity",
                            UtilMisc.toMap("tmpShipmentId", tmpShipmentId), locale));
        }
    }
    EntityQuery shipmentQuery = EntityQuery.use(delegator)
            .where(EntityCondition.makeCondition("shipmentId", EntityOperator.IN, shipmentIds))
            .orderBy("shipmentId");
    // check the status of the shipment

    // get the items of the shipment.  They can come from ItemIssuance if the shipment were from a sales order, ShipmentReceipt
    // if it were a purchase order or from the order items of the (possibly linked) orders if the shipment is a drop shipment
    List<GenericValue> items = null;
    List<GenericValue> orderItemAssocs = null;
    try {
        if (purchaseShipmentFound) {
            items = shipmentQuery.from("ShipmentReceipt").queryList();
            // filter out items which have been received but are not actually owned by an internal organization, so they should not be on a purchase invoice
            Iterator<GenericValue> itemsIter = items.iterator();
            while (itemsIter.hasNext()) {
                GenericValue item = itemsIter.next();
                GenericValue inventoryItem = item.getRelatedOne("InventoryItem", false);
                GenericValue ownerPartyRole = EntityQuery.use(delegator).from("PartyRole").where("partyId",
                        inventoryItem.get("ownerPartyId"), "roleTypeId", "INTERNAL_ORGANIZATIO").cache()
                        .queryOne();
                if (UtilValidate.isEmpty(ownerPartyRole)) {
                    itemsIter.remove();
                }
            }
        } else if (dropShipmentFound) {

            List<GenericValue> shipments = shipmentQuery.from("Shipment").queryList();

            // Get the list of purchase order IDs related to the shipments
            List<String> purchaseOrderIds = EntityUtil.getFieldListFromEntityList(shipments, "primaryOrderId",
                    true);

            if (createSalesInvoicesForDropShipments) {

                // If a sales invoice is being created for a drop shipment, we have to reference the original sales order items
                // Get the list of the linked orderIds (original sales orders)
                orderItemAssocs = EntityQuery.use(delegator).from("OrderItemAssoc")
                        .where(EntityCondition.makeCondition("toOrderId", EntityOperator.IN, purchaseOrderIds))
                        .queryList();

                // Get only the order items which are indirectly related to the purchase order - this limits the list to the drop ship group(s)
                items = EntityUtil.getRelated("FromOrderItem", null, orderItemAssocs, false);
            } else {

                // If it's a purchase invoice being created, the order items for that purchase orders can be used directly
                items = EntityQuery.use(delegator).from("OrderItem")
                        .where(EntityCondition.makeCondition("orderId", EntityOperator.IN, purchaseOrderIds))
                        .queryList();
            }
        } else {
            items = shipmentQuery.from("ItemIssuance").queryList();
        }
    } catch (GenericEntityException e) {
        Debug.logError(e, "Problem getting issued items from shipments", module);
        return ServiceUtil.returnError(
                UtilProperties.getMessage(resource, "AccountingProblemGettingItemsFromShipments", locale));
    }
    if (items.size() == 0) {
        Debug.logInfo("No items issued for shipments", module);
        return ServiceUtil.returnSuccess();
    }

    // group items by order
    Map<String, List<GenericValue>> shippedOrderItems = new HashMap<String, List<GenericValue>>();
    for (GenericValue item : items) {
        String orderId = item.getString("orderId");
        String orderItemSeqId = item.getString("orderItemSeqId");
        List<GenericValue> itemsByOrder = shippedOrderItems.get(orderId);
        if (itemsByOrder == null) {
            itemsByOrder = new LinkedList<GenericValue>();
        }

        // check and make sure we haven't already billed for this issuance or shipment receipt
        List<EntityCondition> billFields = new LinkedList<EntityCondition>();
        billFields.add(EntityCondition.makeCondition("orderId", orderId));
        billFields.add(EntityCondition.makeCondition("orderItemSeqId", orderItemSeqId));
        billFields
                .add(EntityCondition.makeCondition("statusId", EntityOperator.NOT_EQUAL, "INVOICE_CANCELLED"));

        if (dropShipmentFound) {

            // Drop shipments have neither issuances nor receipts, so this check is meaningless
            itemsByOrder.add(item);
            shippedOrderItems.put(orderId, itemsByOrder);
            continue;
        } else if (item.getEntityName().equals("ItemIssuance")) {
            billFields.add(EntityCondition.makeCondition("itemIssuanceId", item.get("itemIssuanceId")));
        } else if (item.getEntityName().equals("ShipmentReceipt")) {
            billFields.add(EntityCondition.makeCondition("shipmentReceiptId", item.getString("receiptId")));
        }
        List<GenericValue> itemBillings = null;
        try {
            itemBillings = EntityQuery.use(delegator).from("OrderItemBillingAndInvoiceAndItem")
                    .where(billFields).queryList();
        } catch (GenericEntityException e) {
            Debug.logError(e, "Problem looking up OrderItemBilling records for " + billFields, module);
            return ServiceUtil.returnError(
                    UtilProperties.getMessage(resource, "AccountingProblemLookingUpOrderItemBilling",
                            UtilMisc.toMap("billFields", billFields), locale));
        }

        // if none found, then okay to bill
        if (itemBillings.size() == 0) {
            itemsByOrder.add(item);
        }

        // update the map with modified list
        shippedOrderItems.put(orderId, itemsByOrder);
    }

    // make sure we aren't billing items already invoiced i.e. items billed as digital (FINDIG)
    Set<String> orders = shippedOrderItems.keySet();
    for (String orderId : orders) {

        // we'll only use this list to figure out which ones to send
        List<GenericValue> billItems = shippedOrderItems.get(orderId);

        // a new list to be used to pass to the create invoice service
        List<GenericValue> toBillItems = new LinkedList<GenericValue>();

        // map of available quantities so we only have to calc once
        Map<String, BigDecimal> itemQtyAvail = new HashMap<String, BigDecimal>();

        // now we will check each issuance and make sure it hasn't already been billed
        for (GenericValue issue : billItems) {
            BigDecimal issueQty = ZERO;

            if (issue.getEntityName().equals("ShipmentReceipt")) {
                issueQty = issue.getBigDecimal("quantityAccepted");
            } else {
                issueQty = issue.getBigDecimal("quantity");
            }

            BigDecimal billAvail = itemQtyAvail.get(issue.getString("orderItemSeqId"));
            if (billAvail == null) {
                List<EntityCondition> lookup = new LinkedList<EntityCondition>();
                lookup.add(EntityCondition.makeCondition("orderId", orderId));
                lookup.add(EntityCondition.makeCondition("orderItemSeqId", issue.get("orderItemSeqId")));
                lookup.add(EntityCondition.makeCondition("statusId", EntityOperator.NOT_EQUAL,
                        "INVOICE_CANCELLED"));
                GenericValue orderItem = null;
                List<GenericValue> billed = null;
                BigDecimal orderedQty = null;
                try {
                    orderItem = issue.getEntityName().equals("OrderItem") ? issue
                            : issue.getRelatedOne("OrderItem", false);

                    // total ordered
                    orderedQty = orderItem.getBigDecimal("quantity");

                    if (dropShipmentFound && createSalesInvoicesForDropShipments.booleanValue()) {

                        // Override the issueQty with the quantity from the purchase order item
                        GenericValue orderItemAssoc = EntityUtil.getFirst(EntityUtil.filterByAnd(
                                orderItemAssocs, UtilMisc.toMap("orderId", issue.getString("orderId"),
                                        "orderItemSeqId", issue.getString("orderItemSeqId"))));
                        GenericValue purchaseOrderItem = orderItemAssoc.getRelatedOne("ToOrderItem", false);
                        orderItem.set("quantity", purchaseOrderItem.getBigDecimal("quantity"));
                        issueQty = purchaseOrderItem.getBigDecimal("quantity");
                    }
                    billed = EntityQuery.use(delegator).from("OrderItemBillingAndInvoiceAndItem").where(lookup)
                            .queryList();
                } catch (GenericEntityException e) {
                    Debug.logError(e, "Problem getting OrderItem/OrderItemBilling records " + lookup, module);
                    return ServiceUtil.returnError(UtilProperties.getMessage(resource,
                            "AccountingProblemGettingOrderItemOrderItemBilling",
                            UtilMisc.toMap("lookup", lookup), locale));
                }

                // add up the already billed total
                if (billed.size() > 0) {
                    BigDecimal billedQuantity = ZERO;
                    for (GenericValue oib : billed) {
                        BigDecimal qty = oib.getBigDecimal("quantity");
                        if (qty != null) {
                            billedQuantity = billedQuantity.add(qty).setScale(DECIMALS, ROUNDING);
                        }
                    }
                    BigDecimal leftToBill = orderedQty.subtract(billedQuantity).setScale(DECIMALS, ROUNDING);
                    billAvail = leftToBill;
                } else {
                    billAvail = orderedQty;
                }
            }

            // no available means we cannot bill anymore
            if (billAvail != null && billAvail.signum() == 1) { // this checks if billAvail is a positive non-zero number
                if (issueQty != null && issueQty.compareTo(billAvail) > 0) {
                    // can only bill some of the issuance; others have been billed already
                    if ("ShipmentReceipt".equals(issue.getEntityName())) {
                        issue.set("quantityAccepted", billAvail);
                    } else {
                        issue.set("quantity", billAvail);
                    }
                    billAvail = ZERO;
                } else {
                    // now have been billed
                    billAvail = billAvail.subtract(issueQty).setScale(DECIMALS, ROUNDING);
                }

                // okay to bill these items; but none else
                toBillItems.add(issue);
            }

            // update the available to bill quantity for the next pass
            itemQtyAvail.put(issue.getString("orderItemSeqId"), billAvail);
        }

        OrderReadHelper orh = new OrderReadHelper(delegator, orderId);

        GenericValue productStore = orh.getProductStore();
        String prorateShipping = productStore != null ? productStore.getString("prorateShipping") : "N";

        // If shipping charges are not prorated, the shipments need to be examined for additional shipping charges
        if ("N".equalsIgnoreCase(prorateShipping)) {

            // Get the set of filtered shipments
            List<GenericValue> invoiceableShipments = null;
            try {
                if (dropShipmentFound) {

                    List<String> invoiceablePrimaryOrderIds = null;
                    if (createSalesInvoicesForDropShipments) {

                        // If a sales invoice is being created for the drop shipment, we need to reference back to the original purchase order IDs

                        // Get the IDs for orders which have billable items
                        List<String> invoiceableLinkedOrderIds = EntityUtil
                                .getFieldListFromEntityList(toBillItems, "orderId", true);

                        // Get back the IDs of the purchase orders - this will be a list of the purchase order items which are billable by virtue of not having been
                        //  invoiced in a previous sales invoice
                        List<GenericValue> reverseOrderItemAssocs = EntityUtil
                                .filterByCondition(orderItemAssocs, EntityCondition.makeCondition("orderId",
                                        EntityOperator.IN, invoiceableLinkedOrderIds));
                        invoiceablePrimaryOrderIds = EntityUtil
                                .getFieldListFromEntityList(reverseOrderItemAssocs, "toOrderId", true);

                    } else {

                        // If a purchase order is being created for a drop shipment, the purchase order IDs can be used directly
                        invoiceablePrimaryOrderIds = EntityUtil.getFieldListFromEntityList(toBillItems,
                                "orderId", true);

                    }

                    // Get the list of shipments which are associated with the filtered purchase orders
                    if (!UtilValidate.isEmpty(invoiceablePrimaryOrderIds)) {
                        invoiceableShipments = EntityQuery.use(delegator).from("Shipment")
                                .where(UtilMisc.toList(
                                        EntityCondition.makeCondition("primaryOrderId", EntityOperator.IN,
                                                invoiceablePrimaryOrderIds),
                                        EntityCondition.makeCondition("shipmentId", EntityOperator.IN,
                                                shipmentIds)))
                                .queryList();
                    }
                } else {
                    List<String> invoiceableShipmentIds = EntityUtil.getFieldListFromEntityList(toBillItems,
                            "shipmentId", true);
                    if (UtilValidate.isNotEmpty(invoiceableShipmentIds)) {
                        invoiceableShipments = EntityQuery
                                .use(delegator).from("Shipment").where(EntityCondition
                                        .makeCondition("shipmentId", EntityOperator.IN, invoiceableShipmentIds))
                                .queryList();
                    }
                }
            } catch (GenericEntityException e) {
                Debug.logError(e, "Trouble calling createInvoicesFromShipments service", module);
                return ServiceUtil.returnError(UtilProperties.getMessage(resource,
                        "AccountingTroubleCallingCreateInvoicesFromShipmentsService", locale));
            }

            // Total the additional shipping charges for the shipments
            Map<GenericValue, BigDecimal> additionalShippingCharges = new HashMap<GenericValue, BigDecimal>();
            BigDecimal totalAdditionalShippingCharges = ZERO;
            if (UtilValidate.isNotEmpty(invoiceableShipments)) {
                for (GenericValue shipment : invoiceableShipments) {
                    if (shipment.get("additionalShippingCharge") == null)
                        continue;
                    BigDecimal shipmentAdditionalShippingCharges = shipment
                            .getBigDecimal("additionalShippingCharge").setScale(DECIMALS, ROUNDING);
                    additionalShippingCharges.put(shipment, shipmentAdditionalShippingCharges);
                    totalAdditionalShippingCharges = totalAdditionalShippingCharges
                            .add(shipmentAdditionalShippingCharges);
                }
            }

            // If the additional shipping charges are greater than zero, process them
            if (totalAdditionalShippingCharges.signum() == 1) {

                // Add an OrderAdjustment to the order for each additional shipping charge
                for (Map.Entry<GenericValue, BigDecimal> entry : additionalShippingCharges.entrySet()) {
                    GenericValue shipment = entry.getKey();
                    BigDecimal additionalShippingCharge = entry.getValue();
                    String shipmentId = shipment.getString("shipmentId");
                    Map<String, Object> createOrderAdjustmentContext = new HashMap<String, Object>();
                    createOrderAdjustmentContext.put("orderId", orderId);
                    createOrderAdjustmentContext.put("orderAdjustmentTypeId", "SHIPPING_CHARGES");
                    String addtlChargeDescription = shipment.getString("addtlShippingChargeDesc");
                    if (UtilValidate.isEmpty(addtlChargeDescription)) {
                        addtlChargeDescription = UtilProperties.getMessage(resource,
                                "AccountingAdditionalShippingChargeForShipment",
                                UtilMisc.toMap("shipmentId", shipmentId), locale);
                    }
                    createOrderAdjustmentContext.put("description", addtlChargeDescription);
                    createOrderAdjustmentContext.put("sourceReferenceId", shipmentId);
                    createOrderAdjustmentContext.put("amount", additionalShippingCharge);
                    createOrderAdjustmentContext.put("userLogin", context.get("userLogin"));
                    String shippingOrderAdjustmentId = null;
                    try {
                        Map<String, Object> createOrderAdjustmentResult = dispatcher
                                .runSync("createOrderAdjustment", createOrderAdjustmentContext);
                        shippingOrderAdjustmentId = (String) createOrderAdjustmentResult
                                .get("orderAdjustmentId");
                    } catch (GenericServiceException e) {
                        Debug.logError(e, "Trouble calling createOrderAdjustment service", module);
                        return ServiceUtil.returnError(UtilProperties.getMessage(resource,
                                "AccountingTroubleCallingCreateOrderAdjustmentService", locale));
                    }

                    // Obtain a list of OrderAdjustments due to tax on the shipping charges, if any
                    GenericValue billToParty = orh.getBillToParty();
                    GenericValue payToParty = orh.getBillFromParty();
                    GenericValue destinationContactMech = null;
                    try {
                        destinationContactMech = shipment.getRelatedOne("DestinationPostalAddress", false);
                    } catch (GenericEntityException e) {
                        Debug.logError(e,
                                "Trouble calling createInvoicesFromShipment service; invoice not created for shipment "
                                        + shipmentId,
                                module);
                        return ServiceUtil.returnError(UtilProperties.getMessage(resource,
                                "AccountingTroubleCallingCreateInvoicesFromShipmentService", locale));
                    }

                    List<Object> emptyList = new LinkedList<Object>();
                    Map<String, Object> calcTaxContext = new HashMap<String, Object>();
                    calcTaxContext.put("productStoreId", orh.getProductStoreId());
                    calcTaxContext.put("payToPartyId", payToParty.getString("partyId"));
                    calcTaxContext.put("billToPartyId", billToParty.getString("partyId"));
                    calcTaxContext.put("orderShippingAmount", totalAdditionalShippingCharges);
                    calcTaxContext.put("shippingAddress", destinationContactMech);

                    // These parameters don't matter if we're only worried about adjustments on the shipping charges
                    calcTaxContext.put("itemProductList", emptyList);
                    calcTaxContext.put("itemAmountList", emptyList);
                    calcTaxContext.put("itemPriceList", emptyList);
                    calcTaxContext.put("itemQuantityList", emptyList);
                    calcTaxContext.put("itemShippingList", emptyList);

                    Map<String, Object> calcTaxResult = null;
                    try {
                        calcTaxResult = dispatcher.runSync("calcTax", calcTaxContext);
                    } catch (GenericServiceException e) {
                        Debug.logError(e, "Trouble calling calcTaxService", module);
                        return ServiceUtil.returnError(UtilProperties.getMessage(resource,
                                "AccountingTroubleCallingCalcTaxService", locale));
                    }
                    List<GenericValue> orderAdjustments = UtilGenerics
                            .checkList(calcTaxResult.get("orderAdjustments"));

                    // If we have any OrderAdjustments due to tax on shipping, store them and add them to the total
                    if (orderAdjustments != null) {
                        for (GenericValue orderAdjustment : orderAdjustments) {
                            totalAdditionalShippingCharges = totalAdditionalShippingCharges
                                    .add(orderAdjustment.getBigDecimal("amount").setScale(DECIMALS, ROUNDING));
                            orderAdjustment.set("orderAdjustmentId", delegator.getNextSeqId("OrderAdjustment"));
                            orderAdjustment.set("orderId", orderId);
                            orderAdjustment.set("orderItemSeqId", "_NA_");
                            orderAdjustment.set("shipGroupSeqId", shipment.getString("primaryShipGroupSeqId"));
                            orderAdjustment.set("originalAdjustmentId", shippingOrderAdjustmentId);
                        }
                        try {
                            delegator.storeAll(orderAdjustments);
                        } catch (GenericEntityException e) {
                            Debug.logError(e, "Problem storing OrderAdjustments: " + orderAdjustments, module);
                            return ServiceUtil.returnError(UtilProperties.getMessage(resource,
                                    "AccountingProblemStoringOrderAdjustments",
                                    UtilMisc.toMap("orderAdjustments", orderAdjustments), locale));
                        }
                    }

                    // If part of the order was paid via credit card, try to charge it for the additional shipping
                    List<GenericValue> orderPaymentPreferences = null;
                    try {
                        orderPaymentPreferences = EntityQuery.use(delegator).from("OrderPaymentPreference")
                                .where("orderId", orderId, "paymentMethodTypeId", "CREDIT_CARD").queryList();
                    } catch (GenericEntityException e) {
                        Debug.logError(e, "Problem getting OrderPaymentPreference records", module);
                        return ServiceUtil.returnError(UtilProperties.getMessage(resource,
                                "AccountingProblemGettingOrderPaymentPreferences", locale));
                    }

                    //  Use the first credit card we find, for the sake of simplicity
                    String paymentMethodId = null;
                    GenericValue cardOrderPaymentPref = EntityUtil.getFirst(orderPaymentPreferences);
                    if (cardOrderPaymentPref != null) {
                        paymentMethodId = cardOrderPaymentPref.getString("paymentMethodId");
                    }

                    if (paymentMethodId != null) {

                        // Release all outstanding (not settled or cancelled) authorizations, while keeping a running
                        //  total of their amounts so that the total plus the additional shipping charges can be authorized again
                        //  all at once.
                        BigDecimal totalNewAuthAmount = totalAdditionalShippingCharges.setScale(DECIMALS,
                                ROUNDING);
                        for (GenericValue orderPaymentPreference : orderPaymentPreferences) {
                            if (!(orderPaymentPreference.getString("statusId").equals("PAYMENT_SETTLED")
                                    || orderPaymentPreference.getString("statusId")
                                            .equals("PAYMENT_CANCELLED"))) {
                                GenericValue authTransaction = PaymentGatewayServices
                                        .getAuthTransaction(orderPaymentPreference);
                                if (authTransaction != null && authTransaction.get("amount") != null) {

                                    // Update the total authorized amount
                                    totalNewAuthAmount = totalNewAuthAmount.add(authTransaction
                                            .getBigDecimal("amount").setScale(DECIMALS, ROUNDING));

                                    // Release the authorization for the OrderPaymentPreference
                                    Map<String, Object> prefReleaseResult = null;
                                    try {
                                        prefReleaseResult = dispatcher.runSync("releaseOrderPaymentPreference",
                                                UtilMisc.toMap("orderPaymentPreferenceId",
                                                        orderPaymentPreference
                                                                .getString("orderPaymentPreferenceId"),
                                                        "userLogin", context.get("userLogin")));
                                    } catch (GenericServiceException e) {
                                        Debug.logError(e,
                                                "Trouble calling releaseOrderPaymentPreference service",
                                                module);
                                        return ServiceUtil.returnError(UtilProperties.getMessage(resource,
                                                "AccountingTroubleCallingReleaseOrderPaymentPreferenceService",
                                                locale));
                                    }
                                    if (ServiceUtil.isError(prefReleaseResult)
                                            || ServiceUtil.isFailure(prefReleaseResult)) {
                                        String errMsg = ServiceUtil.getErrorMessage(prefReleaseResult);
                                        Debug.logError(errMsg, module);
                                        return ServiceUtil.returnError(errMsg);
                                    }
                                }
                            }
                        }

                        // Create a new OrderPaymentPreference for the order to handle the new (totalled) charge. Don't
                        //  set the maxAmount so that it doesn't interfere with other authorizations
                        Map<String, Object> serviceContext = UtilMisc.toMap("orderId", orderId,
                                "paymentMethodId", paymentMethodId, "paymentMethodTypeId", "CREDIT_CARD",
                                "userLogin", context.get("userLogin"));
                        String orderPaymentPreferenceId = null;
                        try {
                            Map<String, Object> result = dispatcher.runSync("createOrderPaymentPreference",
                                    serviceContext);
                            orderPaymentPreferenceId = (String) result.get("orderPaymentPreferenceId");
                        } catch (GenericServiceException e) {
                            Debug.logError(e, "Trouble calling createOrderPaymentPreference service", module);
                            return ServiceUtil.returnError(UtilProperties.getMessage(resource,
                                    "AccountingTroubleCallingCreateOrderPaymentPreferenceService", locale));
                        }

                        // Attempt to authorize the new orderPaymentPreference
                        Map<String, Object> authResult = null;
                        try {
                            // Use an overrideAmount because the maxAmount wasn't set on the OrderPaymentPreference
                            authResult = dispatcher.runSync("authOrderPaymentPreference",
                                    UtilMisc.toMap("orderPaymentPreferenceId", orderPaymentPreferenceId,
                                            "overrideAmount", totalNewAuthAmount, "userLogin",
                                            context.get("userLogin")));
                        } catch (GenericServiceException e) {
                            Debug.logError(e, "Trouble calling authOrderPaymentPreference service", module);
                            return ServiceUtil.returnError(UtilProperties.getMessage(resource,
                                    "AccountingTroubleCallingAuthOrderPaymentPreferenceService", locale));
                        }

                        // If the authorization fails, create the invoice anyway, but make a note of it
                        boolean authFinished = ((Boolean) authResult.get("finished")).booleanValue();
                        boolean authErrors = ((Boolean) authResult.get("errors")).booleanValue();
                        if (authErrors || !authFinished) {
                            String errMsg = UtilProperties.getMessage(resource,
                                    "AccountingUnableToAuthAdditionalShipCharges",
                                    UtilMisc.toMap("shipmentId", shipmentId, "paymentMethodId", paymentMethodId,
                                            "orderPaymentPreferenceId", orderPaymentPreferenceId),
                                    locale);
                            Debug.logError(errMsg, module);
                        }

                    }
                }
            }
        } else {
            Debug.logInfo(UtilProperties.getMessage(resource, "AccountingIgnoringAdditionalShipCharges",
                    UtilMisc.toMap("productStoreId", orh.getProductStoreId()), locale), module);
        }

        String invoiceId = null;
        GenericValue shipmentItemBilling = null;
        String shipmentId = shipmentIds.get(0);
        try {
            shipmentItemBilling = EntityQuery.use(delegator).from("ShipmentItemBilling")
                    .where("shipmentId", shipmentId).queryFirst();
        } catch (GenericEntityException e) {
            return ServiceUtil.returnError(
                    UtilProperties.getMessage(resource, "AccountingProblemGettingShipmentItemBilling", locale));
        }
        if (shipmentItemBilling != null) {
            invoiceId = shipmentItemBilling.getString("invoiceId");
        }

        // call the createInvoiceForOrder service for each order
        Map<String, Object> serviceContext = UtilMisc.toMap("orderId", orderId, "billItems", toBillItems,
                "invoiceId", invoiceId, "eventDate", context.get("eventDate"), "userLogin",
                context.get("userLogin"));
        try {
            Map<String, Object> result = dispatcher.runSync("createInvoiceForOrder", serviceContext);
            invoicesCreated.add((String) result.get("invoiceId"));
        } catch (GenericServiceException e) {
            Debug.logError(e, "Trouble calling createInvoiceForOrder service; invoice not created for shipment",
                    module);
            return ServiceUtil.returnError(UtilProperties.getMessage(resource,
                    "AccountingTroubleCallingCreateInvoiceForOrderService", locale));
        }
    }

    Map<String, Object> response = ServiceUtil.returnSuccess();
    response.put("invoicesCreated", invoicesCreated);
    return response;
}

From source file:ca.oson.json.Oson.java

private <E, R> String float2Json(FieldData objectDTO) {
    if (objectDTO == null || objectDTO.json2Java) {
        return null;
    }//from   w w w .j  a va2  s .  c  om

    E value = (E) objectDTO.valueToProcess;
    Class<E> returnType = objectDTO.returnType;

    if (value != null && returnType != null && (returnType == float.class || returnType == Float.class)) {
        Float valueToProcess = null;
        String valueToReturn = null;

        if (returnType == float.class) {
            valueToProcess = Float.valueOf((Float) value);
        } else {
            valueToProcess = (Float) value;
        }

        if (valueToProcess != null) {
            try {
                Function function = objectDTO.getSerializer();
                if (function != null) {
                    try {
                        if (function instanceof DataMapper2JsonFunction) {
                            DataMapper classData = new DataMapper(returnType, value, objectDTO.classMapper,
                                    objectDTO.level, getPrettyIndentation());
                            return ((DataMapper2JsonFunction) function).apply(classData);

                        } else if (function instanceof Float2JsonFunction) {
                            return ((Float2JsonFunction) function).apply(valueToProcess);

                        } else {

                            Object returnedValue = null;
                            if (function instanceof FieldData2JsonFunction) {
                                FieldData2JsonFunction f = (FieldData2JsonFunction) function;
                                FieldData fieldData = objectDTO.clone();
                                returnedValue = f.apply(fieldData);
                            } else {
                                returnedValue = function.apply(value);
                            }

                            if (returnedValue instanceof Optional) {
                                returnedValue = ObjectUtil.unwrap(returnedValue);
                            }

                            if (returnedValue == null) {
                                return null;

                            } else if (returnedValue instanceof Float) {
                                valueToProcess = (Float) returnedValue;

                            } else {
                                objectDTO.valueToProcess = returnedValue;
                                return object2String(objectDTO);
                            }

                        }

                    } catch (Exception e) {
                    }
                }

                if (valueToProcess != null) {
                    Long min = objectDTO.getMin();
                    Long max = objectDTO.getMax();

                    if (min != null && min.floatValue() > valueToProcess) {
                        valueToProcess = min.floatValue();
                    }

                    if (max != null && max.floatValue() < valueToProcess) {
                        valueToProcess = max.floatValue();
                    }

                    Integer precision = objectDTO.getPrecision();
                    Integer scale = objectDTO.getScale();

                    String result = null;

                    if (precision != null) {
                        if (scale != null) {
                            valueToProcess = (float) NumberUtil.setPrecision(valueToProcess, precision,
                                    getRoundingMode());
                            BigDecimal b = new BigDecimal(valueToProcess);

                            b = b.setScale(scale, getRoundingMode());
                            result = NumberUtil.toPlainString(b);

                        } else {
                            result = NumberUtil.precision2Json(valueToProcess, precision, getRoundingMode());
                        }

                    } else if (scale != null) {
                        BigDecimal b = new BigDecimal(valueToProcess);

                        b = b.setScale(scale, getRoundingMode());
                        result = NumberUtil.toPlainString(b);
                    } else {
                        result = NumberUtil.toPlainString(valueToProcess);
                    }

                    return NumberUtil.appendingFloatingZero(result, isAppendingFloatingZero());
                }

            } catch (Exception ex) {
                //ex.printStackTrace();
            }
        }
    }

    return float2JsonDefault(objectDTO);
}