/* * eGov suite of products aim to improve the internal efficiency,transparency, * accountability and the service delivery of the government organizations. * * Copyright (C) <2015> eGovernments Foundation * * The updated version of eGov suite of products as by eGovernments Foundation * is available at http://www.egovernments.org * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/ or * http://www.gnu.org/licenses/gpl.html . * * In addition to the terms of the GPL license to be adhered to in using this * program, the following additional terms are to be complied with: * * 1) All versions of this program, verbatim or modified must carry this * Legal Notice. * * 2) Any misrepresentation of the origin of the material is prohibited. It * is required that all modified versions of this material be marked in * reasonable ways as different from the original version. * * 3) This license does not grant any rights to any user of the program * with regards to rights under trademark law for use of the trade names * or trademarks of eGovernments Foundation. * * In case of any queries, you can reach eGovernments Foundation at contact@egovernments.org. */ package org.egov.stms.transactions.service; import static org.egov.stms.utils.constants.SewerageTaxConstants.FEES_ADVANCE_CODE; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.Date; import java.util.HashSet; import java.util.List; import java.util.Set; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import org.egov.commons.Installment; import org.egov.commons.dao.InstallmentDao; import org.egov.demand.dao.DemandGenericDao; import org.egov.demand.model.BillReceipt; import org.egov.demand.model.EgDemand; import org.egov.demand.model.EgDemandDetails; import org.egov.demand.model.EgDemandReason; import org.egov.infra.admin.master.service.ModuleService; import org.egov.infra.exception.ApplicationRuntimeException; import org.egov.stms.transactions.entity.SewerageApplicationDetails; import org.egov.stms.transactions.entity.SewerageConnectionFee; import org.egov.stms.transactions.entity.SewerageDemandConnection; import org.egov.stms.transactions.entity.SewerageDemandDetail; import org.egov.stms.utils.constants.SewerageTaxConstants; import org.hibernate.Query; import org.hibernate.Session; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Service @Transactional(readOnly = true) public class SewerageDemandService { @Autowired private InstallmentDao installmentDao; @Autowired private DemandGenericDao demandGenericDao; @Autowired private ModuleService moduleService; @PersistenceContext private EntityManager entityManager; private List<EgDemandDetails> detailList = new ArrayList<>(); public Session getCurrentSession() { return entityManager.unwrap(Session.class); } /** * @param demandReason * @param installment * @return */ public EgDemandReason getDemandReasonByCodeAndInstallment(final String demandReason, final Integer installment) { final Query demandQuery = getCurrentSession().getNamedQuery("DEMANDREASONBY_CODE_AND_INSTALLMENTID"); demandQuery.setParameter(0, demandReason); demandQuery.setParameter(1, installment); final EgDemandReason demandReasonObj = (EgDemandReason) demandQuery.uniqueResult(); return demandReasonObj; } /** * @param demandDetailSet * @param installment * @param totalDemandAmount * @return */ private EgDemand createDemand(final Set<EgDemandDetails> demandDetailSet, final Installment installment, final BigDecimal totalDemandAmount) { final EgDemand egDemand = new EgDemand(); egDemand.setEgInstallmentMaster(installment); egDemand.getEgDemandDetails().addAll(demandDetailSet); egDemand.setIsHistory("N"); egDemand.setCreateDate(new Date()); egDemand.setBaseDemand(totalDemandAmount.setScale(0, BigDecimal.ROUND_HALF_UP)); egDemand.setModifiedDate(new Date()); return egDemand; } /** * @return */ public Installment getCurrentInstallment() { return installmentDao.getInsatllmentByModuleForGivenDate( moduleService.getModuleByName(SewerageTaxConstants.MODULE_NAME), new Date()); } public Installment getNextInstallment() { Installment currentInstlalment = getCurrentInstallment(); if (currentInstlalment != null) { final Calendar calendar = Calendar.getInstance(); calendar.setTime(currentInstlalment.getToDate()); calendar.add(Calendar.DAY_OF_MONTH, 1); return installmentDao.getInsatllmentByModuleForGivenDate( moduleService.getModuleByName(SewerageTaxConstants.MODULE_NAME), calendar.getTime()); } return null; } public Installment getInstallmentByDescription(final String description) { return installmentDao.getInsatllmentByModuleAndDescription( moduleService.getModuleByName(SewerageTaxConstants.MODULE_NAME), description); } public Installment getInsatllmentByModuleForGivenDate(final Date installmentDate) { return installmentDao.getInsatllmentByModuleForGivenDate( moduleService.getModuleByName(SewerageTaxConstants.MODULE_NAME), installmentDate); } public List<Installment> getPreviousInstallment(final Date curentInstalmentEndate) { return installmentDao.fetchPreviousInstallmentsInDescendingOrderByModuleAndDate( moduleService.getModuleByName(SewerageTaxConstants.MODULE_NAME), curentInstalmentEndate, 1); } /** * @param demand * @param dmdAmount * @param egDemandReason * @param amtCollected * @return */ public EgDemandDetails createDemandDetails(EgDemand demand, final BigDecimal dmdAmount, final EgDemandReason egDemandReason, final BigDecimal amtCollected) { EgDemandDetails demandDetail = EgDemandDetails.fromReasonAndAmounts(dmdAmount.setScale(0, BigDecimal.ROUND_HALF_UP), egDemandReason, amtCollected); if (demandDetail != null) { demandDetail.setEgDemand(demand); return demandDetail; } return null; } public EgDemandDetails createDemandDetails(final BigDecimal dmdAmount, final EgDemandReason egDemandReason, final BigDecimal amtCollected) { return EgDemandDetails.fromReasonAndAmounts(dmdAmount.setScale(0, BigDecimal.ROUND_HALF_UP), egDemandReason, amtCollected); } /** * @param sewerageConnection * @return */ public Boolean checkAnyTaxIsPendingToCollect(final EgDemand demand) { Boolean pendingTaxCollection = false; if (demand != null) for (final EgDemandDetails demandDtl : demand.getEgDemandDetails()) if (demandDtl.getAmount().subtract(demandDtl.getAmtCollected()).compareTo(BigDecimal.ZERO) > 0) { pendingTaxCollection = true; break; } return pendingTaxCollection; } public BigDecimal checkForPendingTaxAmountToCollect(final EgDemand demand) { BigDecimal pendingTaxCollection = BigDecimal.ZERO; if (demand != null) { for (final EgDemandDetails demandDtl : demand.getEgDemandDetails()) { if (!demandDtl.getEgDemandReason().getEgDemandReasonMaster().getCode().equals(FEES_ADVANCE_CODE) && demandDtl.getAmount().subtract(demandDtl.getAmtCollected()).compareTo(BigDecimal.ZERO) > 0) { pendingTaxCollection = pendingTaxCollection.add(demandDtl.getAmount().subtract(demandDtl.getAmtCollected())); } } } return pendingTaxCollection; } public Boolean checkAnyTaxIsPendingToCollectExcludingAdvance(final EgDemand demand) { Boolean taxPendingForCollection = false; if (demand != null) for (final EgDemandDetails demandDtl : demand.getEgDemandDetails()) if (!demandDtl.getEgDemandReason().getEgDemandReasonMaster().getCode() .equalsIgnoreCase(SewerageTaxConstants.FEES_ADVANCE_CODE) && demandDtl.getAmount().subtract(demandDtl.getAmtCollected()).compareTo(BigDecimal.ZERO) > 0) { taxPendingForCollection = true; break; } return taxPendingForCollection; } /** * Check any tax pay pending for selected advertisement in selected installment * * @param advertisement * @param installment * @return */ public Boolean checkAnyTaxPendingForSelectedFinancialYear(final SewerageDemandConnection sewerageDemandConnection, final Installment installment) { Boolean pendingTaxCollection = false; if (sewerageDemandConnection != null && sewerageDemandConnection.getDemand() != null) for (final EgDemandDetails demandDtl : sewerageDemandConnection.getDemand().getEgDemandDetails()) if (demandDtl.getEgDemandReason().getEgInstallmentMaster().getId().equals(installment.getId()) && demandDtl.getAmount().subtract(demandDtl.getAmtCollected()).compareTo(BigDecimal.ZERO) > 0) { pendingTaxCollection = true; break; } return pendingTaxCollection; } /** * @param sewerageConnection * @return */ public boolean anyDemandPendingForCollection(final SewerageApplicationDetails sewerageApplicationDetails) { return checkAnyTaxIsPendingToCollect(sewerageApplicationDetails.getCurrentDemand()); } public List<EgDemandDetails> getDemandDetailByPassingDemandDemandReason(final EgDemand demand, final EgDemandReason demandReason) { return demandGenericDao.getDemandDetailsForDemandAndReasons(demand, Arrays.asList(demandReason)); } public List<BillReceipt> getBilReceiptsByDemand(final EgDemand demand) { List<BillReceipt> billReceiptList = new ArrayList<BillReceipt>(); billReceiptList = demandGenericDao.getBillReceipts(demand); return billReceiptList; } public EgDemand createDemandOnNewConnection(final List<SewerageConnectionFee> connectionFees, final SewerageApplicationDetails sewerageApplicationDetail) throws ApplicationRuntimeException { EgDemand demand = null; final Set<EgDemandDetails> demandDetailSet = new HashSet<EgDemandDetails>(); BigDecimal totalDemandAmount = BigDecimal.ZERO; if (sewerageApplicationDetail != null && sewerageApplicationDetail.getCurrentDemand() == null) { final Installment installment = getCurrentInstallment(); for (final SewerageConnectionFee fees : connectionFees) { final EgDemandReason pendingTaxReason = getDemandReasonByCodeAndInstallment(fees.getFeesDetail() .getCode(), installment.getId()); // TODO: CHECK CURRENT // INSTALLMENT // REQUIRED? if (pendingTaxReason != null) { demandDetailSet.add(createDemandDetails(BigDecimal.valueOf(fees.getAmount()), pendingTaxReason, BigDecimal.ZERO)); totalDemandAmount = totalDemandAmount.add(BigDecimal.valueOf(fees.getAmount())); } else throw new ApplicationRuntimeException("SEWERAGE.001"); } demand = createDemand(demandDetailSet, installment, totalDemandAmount); } return demand; } /** * @param sewerageDemandDetail * @param sewerageApplicationDetail * @return * @throws ApplicationRuntimeException */ public EgDemand createDemandOnLegacyConnection(final List<SewerageDemandDetail> sewerageDemandDetail, final SewerageApplicationDetails sewerageApplicationDetail) throws ApplicationRuntimeException { EgDemand demand = null; final Set<EgDemandDetails> demandDetailSet = new HashSet<EgDemandDetails>(); BigDecimal totalDemandAmount = BigDecimal.ZERO; BigDecimal totalCollectedAmount = BigDecimal.ZERO; if (sewerageApplicationDetail != null && sewerageApplicationDetail.getCurrentDemand() == null) { final Installment installment = getCurrentInstallment(); for (final SewerageDemandDetail sdd : sewerageDemandDetail) { final EgDemandReason pendingTaxReason = getDemandReasonByCodeAndInstallment(sdd.getReasonMaster(), sdd.getInstallmentId()); if (pendingTaxReason != null) { if (sdd.getActualAmount() == null) sdd.setActualAmount(BigDecimal.ZERO); if (sdd.getActualCollection() == null) sdd.setActualCollection(BigDecimal.ZERO); demandDetailSet.add(createDemandDetails(sdd.getActualAmount(), pendingTaxReason, sdd.getActualCollection())); totalDemandAmount = totalDemandAmount.add(sdd.getActualAmount()); totalCollectedAmount = totalCollectedAmount.add(sdd.getActualCollection()); } else throw new ApplicationRuntimeException("SEWERAGE.001"); } demand = createDemand(demandDetailSet, installment, totalDemandAmount); demand.setAmtCollected(totalCollectedAmount); } return demand; } /** * @param connectionFees * @param demand * @return */ public EgDemand updateDemand(final List<SewerageConnectionFee> connectionFees, final EgDemand demand) { final Installment installment = getCurrentInstallment(); BigDecimal totalDemandAmount = BigDecimal.ZERO; boolean demandDtlPresent; for (final SewerageConnectionFee scf : connectionFees) { demandDtlPresent = false; // used to decide over adding demandDetail // required or not for (final EgDemandDetails dmdDtl : demand.getEgDemandDetails()) { if (scf.getFeesDetail().getCode() .equalsIgnoreCase(dmdDtl.getEgDemandReason().getEgDemandReasonMaster().getCode())) { demandDtlPresent = true; totalDemandAmount = totalDemandAmount.subtract(dmdDtl.getAmount()); dmdDtl.setAmount(BigDecimal.valueOf(scf.getAmount())); totalDemandAmount = totalDemandAmount.add(BigDecimal.valueOf(scf.getAmount())); } } if (!demandDtlPresent) {// TODO: IF AMOUNT EQUAL TO ZERO CHECK // REQUIRED ? demand.addEgDemandDetails(createDemandDetails(BigDecimal.valueOf(scf.getAmount()), getDemandReasonByCodeAndInstallment(scf.getFeesDetail().getCode(), installment.getId()), BigDecimal.ZERO)); totalDemandAmount = totalDemandAmount.add(BigDecimal.valueOf(scf.getAmount())); } } demand.addBaseDemand(totalDemandAmount.setScale(0, BigDecimal.ROUND_HALF_UP)); return demand; } public EgDemand updateDemandOnChangeInClosets(SewerageApplicationDetails oldSewerageApplicationDetails, final List<SewerageConnectionFee> connectionFees, final EgDemand demand, Boolean updateOldSewerageApplicationAdvance) { final Installment installment = getCurrentInstallment(); BigDecimal totalDemandAmount = BigDecimal.ZERO;// (demand.getBaseDemand()!=null?demand.getBaseDemand(): BigDecimal.ZERO); // //TODO : CHECK THIS VARIABLE. BigDecimal oldDonationCharge = BigDecimal.ZERO; BigDecimal oldSewerageTax = BigDecimal.ZERO; BigDecimal oldApplicationAdvanceAmount = BigDecimal.ZERO; Boolean oldAdvanceUsedInSewerageTaxOrAddedAsAdvance = false; BigDecimal currentDonationCharge = BigDecimal.ZERO; BigDecimal currentSewerageTax = BigDecimal.ZERO; boolean demandDtlPresent = false; if (oldSewerageApplicationDetails != null) { for (final SewerageConnectionFee oldSewerageConnectionFee : oldSewerageApplicationDetails.getConnectionFees()) { if (oldSewerageConnectionFee.getFeesDetail().getCode() .equalsIgnoreCase(SewerageTaxConstants.FEES_SEWERAGETAX_CODE)) { oldSewerageTax = oldSewerageTax.add(BigDecimal.valueOf(oldSewerageConnectionFee.getAmount())); } if (oldSewerageConnectionFee.getFeesDetail().getCode() .equalsIgnoreCase(SewerageTaxConstants.FEES_DONATIONCHARGE_CODE)) { oldDonationCharge = oldDonationCharge.add(BigDecimal.valueOf(oldSewerageConnectionFee.getAmount())); } } // Check any advance amount present in old sewerage application. If yes, use advance amount and reset advance amount // as zero. This amount will be either // carry forward in new application demand or will adjust with current application sewerage tax. // On record approval only, adjust advance amount from earlier sewerage record. if (oldSewerageApplicationDetails.getCurrentDemand() != null && updateOldSewerageApplicationAdvance) { for (final EgDemandDetails dmdDtl : oldSewerageApplicationDetails.getCurrentDemand().getEgDemandDetails()) { if (dmdDtl.getEgDemandReason().getEgDemandReasonMaster().getCode() .equalsIgnoreCase(SewerageTaxConstants.FEES_ADVANCE_CODE)) { oldApplicationAdvanceAmount = oldApplicationAdvanceAmount.add(dmdDtl.getAmount()); dmdDtl.setAmount(BigDecimal.ZERO); dmdDtl.setAmtCollected(BigDecimal.ZERO); } } } } if (demand != null) { for (final EgDemandDetails dmdDtl : demand.getEgDemandDetails()) { if (dmdDtl.getEgDemandReason().getEgDemandReasonMaster().getCode() .equalsIgnoreCase(SewerageTaxConstants.FEES_ADVANCE_CODE)) { oldApplicationAdvanceAmount = oldApplicationAdvanceAmount.add(dmdDtl.getAmount()); // If current demand updated, then use advance amount in sewerage tax payment. } } } for (final SewerageConnectionFee scf : connectionFees) { if (scf.getFeesDetail().getCode().equalsIgnoreCase(SewerageTaxConstants.FEES_SEWERAGETAX_CODE)) { currentSewerageTax = currentSewerageTax.add(BigDecimal.valueOf(scf.getAmount())); } if (scf.getFeesDetail().getCode().equalsIgnoreCase(SewerageTaxConstants.FEES_DONATIONCHARGE_CODE)) { currentDonationCharge = currentDonationCharge.add(BigDecimal.valueOf(scf.getAmount())); } } // Compare previous tax deposit amount and sewerage tax. // if donation amount is less then previous detail , then do not create donation amount, else difference amount will be // added. // get sewerage tax of current tax, if amount paid, check if amount paid more, then adjust as advance. // if not paid, correct current tax. // if sewerage tax more, then add difference amount to current installment. // Get deposit amount,establishment charge and sewerage tax as current year tax. Update collected amount. for (final SewerageConnectionFee scf : connectionFees) { for (final EgDemandDetails dmdDtl : demand.getEgDemandDetails()) { if (scf.getFeesDetail().getCode() .equalsIgnoreCase(dmdDtl.getEgDemandReason().getEgDemandReasonMaster().getCode()) && !scf.getFeesDetail().getCode().equalsIgnoreCase(SewerageTaxConstants.FEE_INSPECTIONCHARGE)) { demandDtlPresent = true; if (scf.getFeesDetail().getCode().equalsIgnoreCase(SewerageTaxConstants.FEES_DONATIONCHARGE_CODE)) { // If donation chanrge more than earlier installment, then collect amount in this installment if (currentDonationCharge.compareTo(oldDonationCharge) > 0) { totalDemandAmount = totalDemandAmount.subtract(dmdDtl.getAmount().subtract(dmdDtl.getAmtCollected())); dmdDtl.setAmount(currentDonationCharge); dmdDtl.setAmtCollected(oldDonationCharge); totalDemandAmount = totalDemandAmount.add(currentDonationCharge.subtract(oldDonationCharge)); } } else if (scf.getFeesDetail().getCode().equalsIgnoreCase(SewerageTaxConstants.FEES_SEWERAGETAX_CODE)) { // Mean tax increased and diffence amount will be collected in this installment. if (currentSewerageTax.compareTo(oldSewerageTax) > 0) { totalDemandAmount = totalDemandAmount.subtract(dmdDtl.getAmount().subtract(dmdDtl.getAmtCollected())); dmdDtl.setAmount(currentSewerageTax); BigDecimal differenceAmount = currentSewerageTax.subtract(oldSewerageTax); if (oldApplicationAdvanceAmount.compareTo(BigDecimal.ZERO) > 0) { // Eg: 500 diff, 100 advance present. adjust 100 // as collected. if ((differenceAmount).compareTo(oldApplicationAdvanceAmount) > 0) { dmdDtl.setAmtCollected(oldSewerageTax.add(oldApplicationAdvanceAmount)); oldApplicationAdvanceAmount = BigDecimal.ZERO; oldAdvanceUsedInSewerageTaxOrAddedAsAdvance = true; createAdvanceDemandDetail(demand, oldApplicationAdvanceAmount);// reset advance as zero. } else { // Eg: 500 diff, 600 advance present. // adjust 500 as collected. dmdDtl.setAmtCollected(oldSewerageTax.add(differenceAmount)); oldApplicationAdvanceAmount = oldApplicationAdvanceAmount .subtract(differenceAmount); // Add remaining amount as advance. createAdvanceDemandDetail(demand, oldApplicationAdvanceAmount); oldAdvanceUsedInSewerageTaxOrAddedAsAdvance = true; } } else { dmdDtl.setAmtCollected(oldSewerageTax); totalDemandAmount = totalDemandAmount.add(differenceAmount); } // check sewerage tax, we need to adjust ? save remaining amount as advance for current demand. // if tax is less and advance also present.. then add amount into current demand.. } else if (oldSewerageTax.compareTo(BigDecimal.ZERO) > 0)// Mean, paid more amount in old installment. // Difference amount will be used as next // installment tax. { totalDemandAmount = totalDemandAmount.subtract(dmdDtl.getAmount().subtract(dmdDtl.getAmtCollected())); dmdDtl.setAmount(currentSewerageTax); dmdDtl.setAmtCollected(currentSewerageTax); totalDemandAmount = totalDemandAmount.add(currentSewerageTax); // Add remaining advance as current demand advance. if (oldSewerageTax.compareTo(currentSewerageTax) > 0 || (oldApplicationAdvanceAmount.compareTo(BigDecimal.ZERO) > 0)) { // Add amount to advance of next installment if not present in this transaction. // TODO: CHECK WHETHER WE NEED TO UPDATE ADVANCE OR ADD AS FRESH ONCE? createAdvanceDemandDetail(demand, (oldSewerageTax.subtract(currentSewerageTax)).add(oldApplicationAdvanceAmount)); oldAdvanceUsedInSewerageTaxOrAddedAsAdvance = true; } } } else { totalDemandAmount = totalDemandAmount.subtract(dmdDtl.getAmount()); dmdDtl.setAmount(BigDecimal.valueOf(scf.getAmount())); totalDemandAmount = totalDemandAmount.add(BigDecimal.valueOf(scf.getAmount())); } } } if (!demandDtlPresent && scf.getAmount() > 0 && !scf.getFeesDetail().getCode().equalsIgnoreCase(SewerageTaxConstants.FEE_INSPECTIONCHARGE)) { if (scf.getFeesDetail().getCode().equalsIgnoreCase(SewerageTaxConstants.FEES_DONATIONCHARGE_CODE)) { if (currentDonationCharge.compareTo(oldDonationCharge) > 0) { demand.addEgDemandDetails(createDemandDetails(currentDonationCharge, getDemandReasonByCodeAndInstallment(scf.getFeesDetail().getCode(), installment.getId()), oldDonationCharge)); totalDemandAmount = totalDemandAmount.add(currentDonationCharge.subtract(oldDonationCharge)); } } else if (scf.getFeesDetail().getCode().equalsIgnoreCase(SewerageTaxConstants.FEES_SEWERAGETAX_CODE)) { // Mean tax increased and diffence amount will be collected in this installment. if (currentSewerageTax.compareTo(oldSewerageTax) > 0) { BigDecimal differenceAmount = currentSewerageTax.subtract(oldSewerageTax); BigDecimal amoountCollected = oldSewerageTax; if (oldApplicationAdvanceAmount.compareTo(BigDecimal.ZERO) > 0) { // Eg: 500 diff, 100 advance present. adjust 100 // as collected. if ((differenceAmount).compareTo(oldApplicationAdvanceAmount) > 0) { amoountCollected = oldSewerageTax.add(oldApplicationAdvanceAmount); oldApplicationAdvanceAmount = BigDecimal.ZERO; oldAdvanceUsedInSewerageTaxOrAddedAsAdvance = true; createAdvanceDemandDetail(demand, oldApplicationAdvanceAmount);// reset advance as zero. } else { // Eg: 500 diff, 600 advance present. // adjust 500 as collected. amoountCollected = oldSewerageTax.add(differenceAmount); oldApplicationAdvanceAmount = oldApplicationAdvanceAmount .subtract(differenceAmount); // Add remaining amount as advance. createAdvanceDemandDetail(demand, oldApplicationAdvanceAmount); oldAdvanceUsedInSewerageTaxOrAddedAsAdvance = true; } } demand.addEgDemandDetails(createDemandDetails(currentSewerageTax, getDemandReasonByCodeAndInstallment(scf.getFeesDetail().getCode(), installment.getId()), amoountCollected)); totalDemandAmount = totalDemandAmount.add(currentSewerageTax.subtract(amoountCollected)); } else if (oldSewerageTax.compareTo(BigDecimal.ZERO) > 0)// Mean, paid more amount in old installment. // Difference amount will be used as next installment // tax. { if (oldSewerageTax.compareTo(currentSewerageTax) >= 0 || (oldApplicationAdvanceAmount.compareTo(BigDecimal.ZERO) > 0)) { demand.addEgDemandDetails(createDemandDetails(currentSewerageTax, getDemandReasonByCodeAndInstallment(scf.getFeesDetail().getCode(), installment.getId()), currentSewerageTax)); // Add amount to advance of next installment if not present in this transaction. createAdvanceDemandDetail(demand, (oldSewerageTax.subtract(currentSewerageTax)).add(oldApplicationAdvanceAmount)); totalDemandAmount = totalDemandAmount.add(((currentSewerageTax))); oldAdvanceUsedInSewerageTaxOrAddedAsAdvance = true; } } } else { demand.addEgDemandDetails(createDemandDetails(BigDecimal.valueOf(scf.getAmount()), getDemandReasonByCodeAndInstallment(scf.getFeesDetail().getCode(), installment.getId()), BigDecimal.ZERO)); totalDemandAmount = totalDemandAmount.add(BigDecimal.valueOf(scf.getAmount())); } } // TODO: oldApplicationAdvanceAmount ADD TO ADVANCE.. IF THERE IS NO CHANGES.. } if (updateOldSewerageApplicationAdvance && !detailList.isEmpty()) { demand.addEgDemandDetails(detailList.get(0)); } // Copy Advance from previous demand and add to current demand(iff there is no adjustment happened in sewerage tax if (!oldAdvanceUsedInSewerageTaxOrAddedAsAdvance && oldApplicationAdvanceAmount.compareTo(BigDecimal.ZERO) > 0) createAdvanceDemandDetail(demand, oldApplicationAdvanceAmount); demand.addBaseDemand(totalDemandAmount.setScale(0, BigDecimal.ROUND_HALF_UP)); return demand; } private void createAdvanceDemandDetail(EgDemand demand, BigDecimal amount) { // TODO : CHECK WHETHER APPLICATION IN SAME INSTALLMENT OR DIFFERENT ? // get next installment Installment nextInstallment = getNextInstallment(); Boolean advancePresent = false; for (final EgDemandDetails dmdDtl : demand.getEgDemandDetails()) { if (dmdDtl.getEgDemandReason().getEgDemandReasonMaster().getCode() .equalsIgnoreCase(SewerageTaxConstants.FEES_ADVANCE_CODE) && nextInstallment != null && nextInstallment.getDescription() .equalsIgnoreCase(dmdDtl.getEgDemandReason().getEgInstallmentMaster().getDescription())) { dmdDtl.getEgDemand().getBaseDemand().subtract(dmdDtl.getAmount()); dmdDtl.setAmount(amount); dmdDtl.getEgDemand().getBaseDemand().add(amount); advancePresent = true; } } if (!advancePresent) { detailList.clear(); detailList.add(createDemandDetails(demand, amount, getDemandReasonByCodeAndInstallment(SewerageTaxConstants.FEES_ADVANCE_CODE, nextInstallment.getId()), BigDecimal.ZERO)); } } }