/* * 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.wtms.application.service.collection; import static org.egov.wtms.utils.constants.WaterTaxConstants.DMD_STATUS_CHEQUE_BOUNCED; import java.math.BigDecimal; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import org.apache.log4j.Logger; import org.egov.collection.entity.ReceiptDetail; import org.egov.collection.integration.models.BillReceiptInfo; import org.egov.collection.integration.models.BillReceiptInfoImpl; import org.egov.collection.integration.models.ReceiptAccountInfo; import org.egov.collection.integration.models.ReceiptAmountInfo; import org.egov.collection.integration.models.ReceiptInstrumentInfo; import org.egov.collection.integration.services.CollectionIntegrationService; import org.egov.commons.CFinancialYear; import org.egov.commons.Installment; import org.egov.commons.dao.ChartOfAccountsHibernateDAO; import org.egov.commons.dao.FinancialYearDAO; import org.egov.commons.dao.FunctionHibernateDAO; import org.egov.demand.dao.DemandGenericDao; import org.egov.demand.dao.EgBillDao; import org.egov.demand.integration.TaxCollection; import org.egov.demand.model.EgBill; import org.egov.demand.model.EgBillDetails; import org.egov.demand.model.EgDemand; import org.egov.demand.model.EgDemandDetails; import org.egov.demand.model.EgDemandReason; import org.egov.demand.model.EgDemandReasonMaster; import org.egov.infra.admin.master.entity.AppConfigValues; import org.egov.infra.admin.master.entity.Module; import org.egov.infra.admin.master.service.ModuleService; import org.egov.infra.exception.ApplicationRuntimeException; import org.egov.infra.workflow.entity.StateHistory; import org.egov.infra.workflow.matrix.entity.WorkFlowMatrix; import org.egov.infra.workflow.service.SimpleWorkflowService; import org.egov.pims.commons.Position; import org.egov.ptis.client.util.PropertyTaxUtil; import org.egov.ptis.constants.PropertyTaxConstants; import org.egov.wtms.application.entity.WaterConnectionDetails; import org.egov.wtms.application.entity.WaterDemandConnection; import org.egov.wtms.application.rest.CollectionApportioner; import org.egov.wtms.application.service.WaterConnectionDetailsService; import org.egov.wtms.application.service.WaterConnectionSmsAndEmailService; import org.egov.wtms.application.workflow.ApplicationWorkflowCustomDefaultImpl; import org.egov.wtms.masters.entity.enums.ConnectionStatus; import org.egov.wtms.masters.entity.enums.ConnectionType; import org.egov.wtms.utils.WaterTaxUtils; import org.egov.wtms.utils.constants.WaterTaxConstants; import org.hibernate.Session; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Service @Transactional(readOnly = true) public class WaterTaxCollection extends TaxCollection { private static final Logger LOGGER = Logger.getLogger(WaterTaxCollection.class); @Autowired private EgBillDao egBillDAO; @Autowired private ModuleService moduleService; @Autowired private WaterConnectionDetailsService waterConnectionDetailsService; private final WaterTaxUtils waterTaxUtils; @Autowired @Qualifier("workflowService") private SimpleWorkflowService<WaterConnectionDetails> waterConnectionWorkflowService; @Autowired private WaterConnectionSmsAndEmailService waterConnectionSmsAndEmailService; @Autowired private ConnectionBillService connectionBillService; @Autowired private CollectionIntegrationService collectionService; @PersistenceContext private EntityManager entityManager; @Autowired private FinancialYearDAO financialYearDAO; @Autowired private FunctionHibernateDAO functionDAO; @Autowired private DemandGenericDao demandGenericDAO; @Autowired private ChartOfAccountsHibernateDAO chartOfAccountsDAO; @Autowired private PropertyTaxUtil propertyTaxUtil; public Session getCurrentSession() { return entityManager.unwrap(Session.class); } @Autowired public WaterTaxCollection(final WaterTaxUtils waterTaxUtils) { this.waterTaxUtils = waterTaxUtils; } @Override @Transactional public void updateDemandDetails(final BillReceiptInfo billRcptInfo) throws ApplicationRuntimeException { final BigDecimal totalAmount = billRcptInfo.getTotalAmount(); final EgDemand demand = getCurrentDemand(Long.valueOf(billRcptInfo.getBillReferenceNum())); final String indexNo = ((BillReceiptInfoImpl) billRcptInfo).getReceiptMisc().getReceiptHeader() .getConsumerCode(); try { if (LOGGER.isDebugEnabled()) { LOGGER.debug("updateDemandDetails : Demand before proceeding : " + demand); LOGGER.debug("updateDemandDetails : collection back update started for property : " + indexNo + " and receipt event is " + billRcptInfo.getEvent() + ". Total Receipt amount is." + totalAmount + " with receipt no." + billRcptInfo.getReceiptNum()); } if (billRcptInfo.getEvent().equals(EVENT_RECEIPT_CREATED)) { updateCollForRcptCreate(demand, billRcptInfo, totalAmount); updateWaterConnectionDetails(demand); updateWaterTaxIndexes(demand); } else if (billRcptInfo.getEvent().equals(EVENT_RECEIPT_CANCELLED)) { updateCollectionForRcptCancel(demand, billRcptInfo); updateWaterConnDetailsStatus(demand, billRcptInfo); updateWaterTaxIndexes(demand); } else if (billRcptInfo.getEvent().equals(EVENT_INSTRUMENT_BOUNCED)) { updateCollForChequeBounce(demand, billRcptInfo); updateWaterTaxIndexes(demand); } if (LOGGER.isDebugEnabled()) LOGGER.debug("updateDemandDetails : Demand after processed : " + demand); } catch (final Exception e) { throw new ApplicationRuntimeException("Error occured during back update of DCB : " + e.getMessage(), e); } } private void updateCollForChequeBounce(final EgDemand demand, final BillReceiptInfo billRcptInfo) { LOGGER.debug("reconcileCollForChequeBounce : Updating Collection Started For Demand : " + demand + " with BillReceiptInfo - " + billRcptInfo); cancelBill(Long.valueOf(billRcptInfo.getBillReferenceNum())); demand.setStatus(DMD_STATUS_CHEQUE_BOUNCED); updateDmdDetForRcptCancelAndCheckBounce(demand, billRcptInfo); LOGGER.debug("reconcileCollForChequeBounce : Updating Collection finished For Demand : " + demand); } @Transactional private void updateDmdDetForRcptCancelAndCheckBounce(final EgDemand demand, final BillReceiptInfo billRcptInfo) { LOGGER.debug("Entering method updateDmdDetForRcptCancelAndCheckBounce"); String installment = ""; for (final ReceiptAccountInfo rcptAccInfo : billRcptInfo.getAccountDetails()) if (rcptAccInfo.getCrAmount() != null && rcptAccInfo.getCrAmount().compareTo(BigDecimal.ZERO) == 1 && !rcptAccInfo.getIsRevenueAccount()) { final String[] desc = rcptAccInfo.getDescription().split("-", 2); final String reason = desc[0].trim(); final String[] installsplit = desc[1].split("#"); installment = installsplit[0].trim(); for (final EgDemandDetails demandDetail : demand.getEgDemandDetails()) if (reason.equalsIgnoreCase(demandDetail.getEgDemandReason().getEgDemandReasonMaster() .getReasonMaster()) && installment.equalsIgnoreCase(demandDetail.getEgDemandReason().getEgInstallmentMaster() .getDescription())) { for (final ReceiptInstrumentInfo instrumentHeader : billRcptInfo.getInstrumentDetails()) { if (instrumentHeader != null) { demandDetail.setAmtCollected(demandDetail.getAmtCollected().subtract( instrumentHeader.getInstrumentAmount())); if (demand.getAmtCollected() != null && demand.getAmtCollected().compareTo(BigDecimal.ZERO) > 0 && demandDetail.getEgDemandReason().getEgDemandReasonMaster().getIsDemand()) demand.setAmtCollected(demand.getAmtCollected().subtract( instrumentHeader.getInstrumentAmount())); } LOGGER.info("Deducted Collected amount Rs." + rcptAccInfo.getCrAmount() + " for tax : " + reason + " and installment : " + installment); break; } break; } break; } updateReceiptStatusWhenCancelled(billRcptInfo.getReceiptNum()); LOGGER.debug("Exiting method updateDmdDetForRcptCancelAndCheckBounce"); } /** * @param demand Updates WaterConnectionDetails Object once Collection Is done. send Record move to Commissioner and Send SMS * and Email after Collection */ @Transactional public void updateWaterConnectionDetails(final EgDemand demand) { final WaterConnectionDetails waterConnectionDetails = waterConnectionDetailsService .getWaterConnectionDetailsByDemand(demand); if (!waterConnectionDetails.getConnectionStatus().equals(ConnectionStatus.ACTIVE)) { waterConnectionDetails.setStatus(waterTaxUtils.getStatusByCodeAndModuleType( WaterTaxConstants.APPLICATION_STATUS_FEEPAID, WaterTaxConstants.MODULETYPE)); Long approvalPosition = Long.valueOf(0); final WorkFlowMatrix wfmatrix = waterConnectionWorkflowService.getWfMatrix(waterConnectionDetails .getStateType(), null, null, WaterTaxConstants.NEW_CONNECTION_MATRIX_ADDL_RULE, waterConnectionDetails.getCurrentState().getValue(), null); final Position posobj = waterTaxUtils.getCityLevelCommissionerPosition(wfmatrix.getNextDesignation(), waterConnectionDetails.getConnection().getPropertyIdentifier()); if (posobj != null) approvalPosition = posobj.getId(); final ApplicationWorkflowCustomDefaultImpl applicationWorkflowCustomDefaultImpl = waterConnectionDetailsService .getInitialisedWorkFlowBean(); applicationWorkflowCustomDefaultImpl.createCommonWorkflowTransition(waterConnectionDetails, approvalPosition, WaterTaxConstants.FEE_COLLECTION_COMMENT, WaterTaxConstants.NEW_CONNECTION_MATRIX_ADDL_RULE, null); waterConnectionSmsAndEmailService.sendSmsAndEmail(waterConnectionDetails, null); waterConnectionDetailsService.saveAndFlushWaterConnectionDetail(waterConnectionDetails); } } @Transactional private void updateCollForRcptCreate(final EgDemand demand, final BillReceiptInfo billRcptInfo, final BigDecimal totalAmount) { if (LOGGER.isDebugEnabled()) LOGGER.debug("updateCollForRcptCreate : Updating Collection Started For Demand : " + demand + " with BillReceiptInfo - " + billRcptInfo); try { updateDemandDetailForReceiptCreate(billRcptInfo.getAccountDetails(), demand, billRcptInfo, totalAmount); } catch (final Exception e) { throw new ApplicationRuntimeException( "Error occured during back update of DCB : updateCollForRcptCreate() " + e.getMessage(), e); } } @Transactional private void updateDemandDetailForReceiptCreate(final Set<ReceiptAccountInfo> accountDetails, final EgDemand demand, final BillReceiptInfo billRcptInfo, final BigDecimal totalAmount) { final StringBuilder query = new StringBuilder( "select dmdet FROM EgDemandDetails dmdet left join fetch dmdet.egDemandReason dmdRsn ") .append("left join fetch dmdRsn.egDemandReasonMaster dmdRsnMstr left join fetch dmdRsn.egInstallmentMaster installment ") .append("WHERE dmdet.egDemand.id = :demand"); final List<EgDemandDetails> demandDetailList = getCurrentSession().createQuery(query.toString()) .setLong("demand", demand.getId()).list(); final Map<String, Map<String, EgDemandDetails>> installmentWiseDemandDetailsByReason = new HashMap<String, Map<String, EgDemandDetails>>(); Map<String, EgDemandDetails> demandDetailByReason = null; EgDemandReason dmdRsn = null; String installmentDesc = null; for (final EgDemandDetails dmdDtls : demandDetailList) if (dmdDtls.getAmount().compareTo(BigDecimal.ZERO) > 0 || dmdDtls.getEgDemandReason().getEgDemandReasonMaster().getCode() .equalsIgnoreCase(WaterTaxConstants.DEMANDRSN_CODE_ADVANCE)) { dmdRsn = dmdDtls.getEgDemandReason(); installmentDesc = dmdRsn.getEgInstallmentMaster().getDescription(); demandDetailByReason = new HashMap<String, EgDemandDetails>(0); if (installmentWiseDemandDetailsByReason.get(installmentDesc) == null) { demandDetailByReason.put(dmdRsn.getEgDemandReasonMaster().getReasonMaster(), dmdDtls); installmentWiseDemandDetailsByReason.put(installmentDesc, demandDetailByReason); } installmentWiseDemandDetailsByReason.get(installmentDesc).put( dmdRsn.getEgDemandReasonMaster().getReasonMaster(), dmdDtls); } else if (LOGGER.isDebugEnabled()) LOGGER.debug("saveCollectionDetails - demand detail amount is zero " + dmdDtls); EgDemandDetails demandDetail = null; final Map<String, Installment> currInstallments = new HashMap<String, Installment>(); final Installment currFirstHalf = propertyTaxUtil.getInstallmentsForCurrYear(new Date()) .get(PropertyTaxConstants.CURRENTYEAR_FIRST_HALF); final Installment currSecondHalf = propertyTaxUtil.getInstallmentsForCurrYear(new Date()) .get(PropertyTaxConstants.CURRENTYEAR_SECOND_HALF); currInstallments.put(WaterTaxConstants.CURRENTYEAR_FIRST_HALF, currFirstHalf); currInstallments.put(WaterTaxConstants.CURRENTYEAR_FIRST_HALF, currSecondHalf); for (final ReceiptAccountInfo rcptAccInfo : accountDetails) if (rcptAccInfo.getDescription() != null && !rcptAccInfo.getDescription().isEmpty()) if (rcptAccInfo.getCrAmount() != null && rcptAccInfo.getCrAmount().compareTo(BigDecimal.ZERO) == 1) { final String[] desc = rcptAccInfo.getDescription().split("-", 2); final String[] installsplit = desc[1].split("#"); final String reason = desc[0].trim(); final String instDesc = installsplit[0].trim(); if (reason.equalsIgnoreCase(WaterTaxConstants.DEMANDRSN_REASON_ADVANCE)) demandDetail = installmentWiseDemandDetailsByReason.get( currInstallments.get(WaterTaxConstants.CURRENTYEAR_FIRST_HALF).getDescription()).get( reason); else demandDetail = installmentWiseDemandDetailsByReason.get(instDesc).get(reason); if (rcptAccInfo.getGlCode().equalsIgnoreCase(WaterTaxConstants.GLCODE_FOR_ADVANCE)) { if (demandDetail != null) demandDetail.setAmtCollected(demandDetail.getAmtCollected().add(rcptAccInfo.getCrAmount())); else { demandDetail = insertAdvanceCollection(WaterTaxConstants.DEMANDRSN_CODE_ADVANCE, rcptAccInfo.getCrAmount(), currInstallments.get(WaterTaxConstants.CURRENTYEAR_FIRST_HALF)); demand.addEgDemandDetails(demandDetail); getCurrentSession().flush(); if (installmentWiseDemandDetailsByReason.get(currInstallments.get( WaterTaxConstants.CURRENTYEAR_FIRST_HALF).getDescription()) == null) { final Map<String, EgDemandDetails> reasonAndDemandDetail = new HashMap<String, EgDemandDetails>(); reasonAndDemandDetail.put(WaterTaxConstants.DEMANDRSN_REASON_ADVANCE, demandDetail); installmentWiseDemandDetailsByReason .put(currInstallments.get(WaterTaxConstants.CURRENTYEAR_FIRST_HALF) .getDescription(), reasonAndDemandDetail); } else installmentWiseDemandDetailsByReason .get(currInstallments.get(WaterTaxConstants.CURRENTYEAR_FIRST_HALF) .getDescription()).put(WaterTaxConstants.DEMANDRSN_REASON_ADVANCE, demandDetail); } } else { demandDetail.addCollectedWithOnePaisaTolerance(rcptAccInfo.getCrAmount()); if (demandDetail.getEgDemandReason().getEgDemandReasonMaster().getIsDemand()) demand.addCollected(rcptAccInfo.getCrAmount()); } persistCollectedReceipts(demandDetail, billRcptInfo.getReceiptNum(), totalAmount, billRcptInfo.getReceiptDate(), demandDetail.getAmtCollected()); if (LOGGER.isDebugEnabled()) LOGGER.debug("Persisted demand and receipt details for tax : " + reason + " installment : " + instDesc + " with receipt No : " + billRcptInfo.getReceiptNum() + " for Rs. " + rcptAccInfo.getCrAmount()); } } /** * Method used to insert advance collection in EgDemandDetail table. * * @see createDemandDetails() -- EgDemand Details are created * @return New EgDemandDetails Object */ public EgDemandDetails insertAdvanceCollection(final String demandReason, final BigDecimal advanceCollectionAmount, final Installment installment) { EgDemandDetails demandDetail = null; if (advanceCollectionAmount != null && advanceCollectionAmount.compareTo(BigDecimal.ZERO) > 0) { final EgDemandReasonMaster egDemandReasonMaster = demandGenericDAO.getDemandReasonMasterByCode( WaterTaxConstants.DEMANDRSN_CODE_ADVANCE, module()); if (egDemandReasonMaster == null) throw new ApplicationRuntimeException( " Advance Demand reason Master is null in method insertAdvanceCollection"); final EgDemandReason egDemandReason = demandGenericDAO.getDmdReasonByDmdReasonMsterInstallAndMod( egDemandReasonMaster, installment, module()); if (egDemandReason == null) throw new ApplicationRuntimeException( " Advance Demand reason is null in method insertAdvanceCollection "); demandDetail = createDemandDetails(egDemandReason, advanceCollectionAmount, BigDecimal.ZERO); } return demandDetail; } public EgDemandDetails createDemandDetails(final EgDemandReason egDemandReason, final BigDecimal amtCollected, final BigDecimal dmdAmount) { return EgDemandDetails.fromReasonAndAmounts(dmdAmount, egDemandReason, amtCollected); } @Override protected Module module() { return moduleService.getModuleByName(WaterTaxConstants.EGMODULE_NAME); } public EgDemand getCurrentDemand(final Long billId) { final EgBill egBill = egBillDAO.findById(billId, false); WaterConnectionDetails waterconndet = null; EgDemand demand = null; if (egBill.getEgDemand() != null && egBill.getEgDemand().getIsHistory() != null && egBill.getEgDemand().getIsHistory().equals(WaterTaxConstants.DEMANDISHISTORY)) demand = egBill.getEgDemand(); else { waterconndet = waterConnectionDetailsService.getWaterConnectionDetailsByDemand(egBill.getEgDemand()); for (final WaterDemandConnection waterDemand : waterconndet.getWaterDemandConnection()) if (waterDemand != null && waterDemand.getDemand() != null && waterDemand.getDemand().getIsHistory().equals(WaterTaxConstants.DEMANDISHISTORY)) demand = waterDemand.getDemand(); } return demand; } // Receipt cancellation ,updating bill,demanddetails,demand @Transactional private void updateCollectionForRcptCancel(final EgDemand demand, final BillReceiptInfo billRcptInfo) { LOGGER.debug("reconcileCollForRcptCancel : Updating Collection Started For Demand : " + demand + " with BillReceiptInfo - " + billRcptInfo); try { cancelBill(Long.valueOf(billRcptInfo.getBillReferenceNum())); updateDmdDetForRcptCancel(demand, billRcptInfo); LOGGER.debug("reconcileCollForRcptCancel : Updating Collection finished For Demand : " + demand); } catch (final Exception e) { throw new ApplicationRuntimeException("Error occured during back update of DCB : " + e.getMessage(), e); } } @Transactional private void cancelBill(final Long billId) { if (billId != null) { final EgBill egBill = egBillDAO.findById(billId, false); egBill.setIs_Cancelled("Y"); } } @Transactional private void updateDmdDetForRcptCancel(final EgDemand demand, final BillReceiptInfo billRcptInfo) { LOGGER.debug("Entering method updateDmdDetForRcptCancel"); String installment = ""; for (final ReceiptAccountInfo rcptAccInfo : billRcptInfo.getAccountDetails()) if (rcptAccInfo.getCrAmount() != null && rcptAccInfo.getCrAmount().compareTo(BigDecimal.ZERO) == 1 && !rcptAccInfo.getIsRevenueAccount()) { final String[] desc = rcptAccInfo.getDescription().split("-", 2); final String reason = desc[0].trim(); final String[] installsplit = desc[1].split("#"); installment = installsplit[0].trim(); for (final EgDemandDetails demandDetail : demand.getEgDemandDetails()) if (reason.equalsIgnoreCase(demandDetail.getEgDemandReason().getEgDemandReasonMaster() .getReasonMaster()) && installment.equalsIgnoreCase(demandDetail.getEgDemandReason().getEgInstallmentMaster() .getDescription())) { if (demandDetail.getAmtCollected().compareTo(rcptAccInfo.getCrAmount()) < 0) throw new ApplicationRuntimeException( "updateDmdDetForRcptCancel : Exception while updating cancel receipt, " + "to be deducted amount " + rcptAccInfo.getCrAmount() + " is greater than the collected amount " + demandDetail.getAmtCollected() + " for demandDetail " + demandDetail); demandDetail .setAmtCollected(demandDetail.getAmtCollected().subtract(rcptAccInfo.getCrAmount())); if (demand.getAmtCollected() != null && demand.getAmtCollected().compareTo(BigDecimal.ZERO) > 0 && demandDetail.getEgDemandReason().getEgDemandReasonMaster().getIsDemand()) demand.setAmtCollected(demand.getAmtCollected().subtract(rcptAccInfo.getCrAmount())); LOGGER.info("Deducted Collected amount Rs." + rcptAccInfo.getCrAmount() + " for tax : " + reason + " and installment : " + installment); } } updateReceiptStatusWhenCancelled(billRcptInfo.getReceiptNum()); LOGGER.debug("Exiting method updateDmdDetForRcptCancel"); } @Transactional private void updateWaterConnDetailsStatus(final EgDemand demand, final BillReceiptInfo billRcptInfo) { final WaterConnectionDetails waterConnectionDetails = waterConnectionDetailsService .getWaterConnectionDetailsByDemand(demand); StateHistory stateHistory = null; if (waterConnectionDetails.getStatus().getCode().equalsIgnoreCase(WaterTaxConstants.APPLICATION_STATUS_FEEPAID)) { waterConnectionDetails.setStatus(waterTaxUtils.getStatusByCodeAndModuleType( WaterTaxConstants.APPLICATION_STATUS_ESTIMATENOTICEGEN, WaterTaxConstants.MODULETYPE)); Long approvalPosition = Long.valueOf(0); if (!waterConnectionDetails.getStateHistory().isEmpty() && waterConnectionDetails.getStateHistory() != null) Collections.reverse(waterConnectionDetails.getStateHistory()); stateHistory = waterConnectionDetails.getStateHistory().get(0); final Position owner = stateHistory.getOwnerPosition(); if (owner != null) approvalPosition = owner.getId(); final ApplicationWorkflowCustomDefaultImpl applicationWorkflowCustomDefaultImpl = waterConnectionDetailsService .getInitialisedWorkFlowBean(); applicationWorkflowCustomDefaultImpl.createCommonWorkflowTransition(waterConnectionDetails, approvalPosition, "Receipt Cancelled", WaterTaxConstants.NEW_CONNECTION_MATRIX_ADDL_RULE, null); } } private void updateWaterTaxIndexes(final EgDemand demand) { final WaterConnectionDetails waterConnectionDetails = waterConnectionDetailsService .getWaterConnectionDetailsByDemand(demand); final String sourceChannel = null; waterConnectionDetailsService.updateIndexes(waterConnectionDetails, sourceChannel); } @Override @Transactional public void apportionCollection(final String billRefNo, final BigDecimal amtPaid, final List<ReceiptDetail> receiptDetails) { final CollectionApportioner apportioner = new CollectionApportioner(); final Map<String, BigDecimal> instDemand = getInstDemand(receiptDetails); apportioner.apportion(amtPaid, receiptDetails, instDemand); } public Map<String, BigDecimal> getInstDemand(final List<ReceiptDetail> receiptDetails) { final Map<String, BigDecimal> retMap = new HashMap<String, BigDecimal>(); String installment = ""; String[] desc; final List<AppConfigValues> demandreasonGlcode =waterTaxUtils.getAppConfigValueByModuleNameAndKeyName(WaterTaxConstants.MODULE_NAME, WaterTaxConstants.DEMANDREASONANDGLCODEMAP); Map<String, String> demandReasonGlCodePairmap = new HashMap<String, String>(); Set<String>demandReasonGlocdeSet=new HashSet<String>(); for (AppConfigValues appConfig : demandreasonGlcode) { String rows[] = appConfig.getValue().split("="); demandReasonGlCodePairmap.put(rows[0], rows[1]); demandReasonGlocdeSet.add(rows[1]); } for (final ReceiptDetail rd : receiptDetails) { final String glCode = rd.getAccounthead().getGlcode(); installment = ""; desc = rd.getDescription().split("-", 2); final String[] installsplit = desc[1].split("#"); installment = installsplit[0].trim(); if (demandReasonGlCodePairmap.containsValue(glCode)) if (retMap.get(installment) == null) retMap.put(installment, rd.getCramountToBePaid()); else retMap.put(installment, retMap.get(installment).add(rd.getCramountToBePaid())); if (demandReasonGlocdeSet.contains(glCode)) prepareTaxMap(retMap, installment, rd, "FULLTAX"); } return retMap; } /** * @param retMap * @param installment * @param rd */ private void prepareTaxMap(final Map<String, BigDecimal> retMap, final String installment, final ReceiptDetail rd, final String type) { if (retMap.get(installment + type) == null) retMap.put(installment + type, rd.getCramountToBePaid()); else retMap.put(installment + type, retMap.get(installment + type).add(rd.getCramountToBePaid())); } @Override public List<ReceiptDetail> reconstructReceiptDetail(final String billReferenceNumber, final BigDecimal actualAmountPaid, final List<ReceiptDetail> receiptDetailList) { final Long billID = Long.valueOf(billReferenceNumber); final List<EgBillDetails> billDetails = new ArrayList<EgBillDetails>(0); final EgBill bill = connectionBillService.updateBillWithLatest(billID); LOGGER.debug("Reconstruct consumer code :" + bill.getConsumerId() + ", with bill reference number: " + billReferenceNumber + ", for Amount Paid :" + actualAmountPaid); final CollectionApportioner apportioner = new CollectionApportioner(); billDetails.addAll(bill.getEgBillDetails()); return apportioner.reConstruct(actualAmountPaid, billDetails, functionDAO, chartOfAccountsDAO , financialYearDAO); } @Override public String constructAdditionalInfoForReceipt(final BillReceiptInfo billReceiptInfo) { StringBuilder additionalInfo = new StringBuilder("Paid From"); final SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy"); final EgBill egBill = egBillDAO.findById(Long.valueOf(billReceiptInfo.getBillReferenceNum()), false); final BigDecimal amounttobeCalc = egBill.getTotalAmount().subtract(egBill.getTotalCollectedAmount()); final List<ReceiptDetail> reciptDetailList = collectionService .getReceiptDetailListByReceiptNumber(billReceiptInfo.getReceiptNum()); for (final EgBillDetails billDet : egBill.getEgBillDetails()) { if (billDet.getOrderNo() == 1) { additionalInfo.append(" ") .append(formatter.format(billDet.getEgDemandReason().getEgInstallmentMaster().getFromDate())) .append(" To "); if (egBill.getEgBillDetails().size() == 1) { additionalInfo.append(formatter.format(billDet.getEgDemandReason().getEgInstallmentMaster() .getToDate())); break; } } if (egBill.getEgBillDetails().size() > 1) if (billDet.getCrAmount().compareTo(BigDecimal.ZERO) == 1 && reciptDetailList.get(0).getOrdernumber().equals(Long.valueOf(billDet.getOrderNo()))) { additionalInfo.append(formatter.format(billDet.getEgDemandReason().getEgInstallmentMaster() .getToDate())); break; } } if (amounttobeCalc.compareTo(BigDecimal.ZERO) == 1) additionalInfo = additionalInfo.append(" (Partialy)"); return additionalInfo.toString(); } @Override public ReceiptAmountInfo receiptAmountBifurcation(final BillReceiptInfo billReceiptInfo) { final ReceiptAmountInfo receiptAmountInfo = new ReceiptAmountInfo(); final SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy"); final EgBill egBill = egBillDAO.findById(Long.valueOf(billReceiptInfo.getBillReferenceNum()), false); final List<EgBillDetails> billDetails = new ArrayList<EgBillDetails>(egBill.getEgBillDetails()); final CFinancialYear financialyear = financialYearDAO.getFinancialYearByDate(new Date()); BigDecimal currentInstallmentAmount = BigDecimal.ZERO; BigDecimal advanceInstallmentAmount = BigDecimal.ZERO; BigDecimal arrearAmount = BigDecimal.ZERO; final WaterConnectionDetails waterConnectionDetails = waterConnectionDetailsService .getWaterConnectionDetailsByDemand(egBill.getEgDemand()); final List<ReceiptDetail> reciptDetailList = collectionService .getReceiptDetailListByReceiptNumber(billReceiptInfo.getReceiptNum()); for (final ReceiptAccountInfo rcptAccInfo : billReceiptInfo.getAccountDetails()) if (rcptAccInfo.getCrAmount() != null && rcptAccInfo.getCrAmount().compareTo(BigDecimal.ZERO) == 1) { final String[] desc = rcptAccInfo.getDescription().split("-", 2); final String[] installsplit = desc[1].split("#"); final String[] installsplit1 = installsplit[0].split("-"); if (waterConnectionDetails != null && (waterConnectionDetails.getConnectionType().equals(ConnectionType.NON_METERED) || waterConnectionDetails .getConnectionStatus().equals(ConnectionStatus.INPROGRESS))) { if (installsplit1[0].trim().equals( financialyear != null ? financialyear.getFinYearRange().split("-")[0] : null)) currentInstallmentAmount = currentInstallmentAmount.add(rcptAccInfo.getCrAmount()); else if (rcptAccInfo.getDescription().contains("Advance")) advanceInstallmentAmount = advanceInstallmentAmount.add(rcptAccInfo.getCrAmount()); else arrearAmount = arrearAmount.add(rcptAccInfo.getCrAmount()); } else if (installsplit[0].split("/")[1].split("-")[1].trim().equals( financialyear.getFinYearRange().split("-")[1].trim())) currentInstallmentAmount = currentInstallmentAmount.add(rcptAccInfo.getCrAmount()); else if (rcptAccInfo.getDescription().contains("Advance")) advanceInstallmentAmount = advanceInstallmentAmount.add(rcptAccInfo.getCrAmount()); else arrearAmount = arrearAmount.add(rcptAccInfo.getCrAmount()); } for (final EgBillDetails billDet : egBill.getEgBillDetails()) { if (billDet.getOrderNo() == 1) { receiptAmountInfo.setInstallmentFrom(formatter.format(billDet.getEgDemandReason() .getEgInstallmentMaster().getFromDate())); if (billDetails.size() == 1) { receiptAmountInfo.setInstallmentTo(formatter.format(billDet.getEgDemandReason() .getEgInstallmentMaster().getToDate())); break; } } if (egBill.getEgBillDetails().size() > 1) if (billDet.getCrAmount().compareTo(BigDecimal.ZERO) == 1 && reciptDetailList.get(0).getOrdernumber().equals(Long.valueOf(billDet.getOrderNo()))) { receiptAmountInfo.setInstallmentTo(formatter.format(billDet.getEgDemandReason() .getEgInstallmentMaster().getToDate())); break; } } receiptAmountInfo.setArrearsAmount(arrearAmount); receiptAmountInfo.setAdvanceAmount(advanceInstallmentAmount); receiptAmountInfo.setCurrentInstallmentAmount(currentInstallmentAmount); return receiptAmountInfo; } }