Skip to content
This repository has been archived by the owner on Nov 26, 2024. It is now read-only.

Commit

Permalink
Merge pull request #799 from egovernments/PenaltyFix-5638
Browse files Browse the repository at this point in the history
PFM-5638: Added changes for penalty  as well as UI and PDF issues res…
  • Loading branch information
pradeepkumarcm-egov authored May 31, 2024
2 parents 44cf702 + 664f669 commit 1d24d0e
Show file tree
Hide file tree
Showing 25 changed files with 1,057 additions and 44 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package org.egov.demand.model;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.*;

import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class AggregatedDemandDetailResponse {

private List<Map<Long , List<DemandDetail>>> mapOfDemandDetailList;

private BigDecimal advanceAvailable;

private BigDecimal advanceAdjusted;

private BigDecimal remainingAdvance;

private BigDecimal currentmonthBill;

private BigDecimal currentMonthPenalty;

private BigDecimal currentmonthTotalDue;

private BigDecimal totalAreas;

private BigDecimal totalAreasWithPenalty;

private BigDecimal netdue;

private BigDecimal netDueWithPenalty;

private BigDecimal totalApplicablePenalty;
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,8 @@
import static org.egov.demand.util.Constants.ADVANCE_TAXHEAD_JSONPATH_CODE;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

import javax.validation.Valid;
Expand All @@ -60,16 +54,8 @@
import org.egov.demand.amendment.model.AmendmentUpdate;
import org.egov.demand.amendment.model.enums.AmendmentStatus;
import org.egov.demand.config.ApplicationProperties;
import org.egov.demand.model.ApportionDemandResponse;
import org.egov.demand.model.AuditDetails;
import org.egov.demand.model.*;
import org.egov.demand.model.BillV2.BillStatus;
import org.egov.demand.model.Demand;
import org.egov.demand.model.DemandApportionRequest;
import org.egov.demand.model.DemandCriteria;
import org.egov.demand.model.DemandDetail;
import org.egov.demand.model.DemandHistory;
import org.egov.demand.model.PaymentBackUpdateAudit;
import org.egov.demand.model.UpdateBillCriteria;
import org.egov.demand.repository.AmendmentRepository;
import org.egov.demand.repository.BillRepositoryV2;
import org.egov.demand.repository.DemandRepository;
Expand All @@ -95,6 +81,11 @@
import com.jayway.jsonpath.DocumentContext;

import lombok.extern.slf4j.Slf4j;
import org.egov.mdms.model.MasterDetail;
import org.egov.mdms.model.MdmsCriteria;
import org.egov.mdms.model.MdmsCriteriaReq;
import org.egov.mdms.model.ModuleDetail;
import static org.egov.demand.util.Constants.*;

@Service
@Slf4j
Expand Down Expand Up @@ -553,5 +544,214 @@ public DemandHistory getDemandHistory(@Valid DemandCriteria demandCriteria, Requ
return demandHistory;

}
public AggregatedDemandDetailResponse getAllDemands(DemandCriteria demandCriteria, RequestInfo requestInfo) {

//demandValidatorV1.validateDemandCriteria(demandCriteria, requestInfo);

UserSearchRequest userSearchRequest = null;
List<User> payers = null;
List<Demand> demands = null;

String userUri = applicationProperties.getUserServiceHostName()
.concat(applicationProperties.getUserServiceSearchPath());

/*
* user type is CITIZEN by default because only citizen can have demand or payer can be null
*/
String citizenTenantId = demandCriteria.getTenantId().split("\\.")[0];

/*
* If payer related data is provided first then user search has to be made first followed by demand search
*/

/*
* If no payer related data given then search demand first then enrich payer(user) data
*/
log.info("demandCriteria::"+demandCriteria);
demands = demandRepository.getDemands(demandCriteria);
log.info("demands:"+demands);
if (!demands.isEmpty()) {

Set<String> payerUuids = demands.stream().filter(demand -> null != demand.getPayer())
.map(demand -> demand.getPayer().getUuid()).collect(Collectors.toSet());

if (!CollectionUtils.isEmpty(payerUuids)) {

userSearchRequest = UserSearchRequest.builder().requestInfo(requestInfo).uuid(payerUuids).build();

payers = mapper.convertValue(serviceRequestRepository.fetchResult(userUri, userSearchRequest),
UserResponse.class).getUser();
}
}
log.info("demannds::"+demands);

if (!CollectionUtils.isEmpty(demands) && !CollectionUtils.isEmpty(payers))
demands = demandEnrichmentUtil.enrichPayer(demands, payers);

log.info("demannddddds::"+demands);
demands = demands.stream().filter(demand -> {
return demand.getStatus().equals(Demand.StatusEnum.ACTIVE);
}).collect(Collectors.toList());
List<Map<Long, List<DemandDetail>>> demandDetailsList = new ArrayList<>();

for (Demand demand : demands) {
log.info("Inside demand");
Map<Long, List<DemandDetail>> demandMap = new HashMap<>();
Long taxPeriodFrom = (Long) demand.getTaxPeriodFrom();
List<DemandDetail> demandDetails = demand.getDemandDetails();
List<DemandDetail> filteredDemandDetaillist = demandDetails.stream()
.filter(detail -> {
BigDecimal difference = detail.getTaxAmount().subtract(detail.getCollectionAmount());
return (difference.compareTo(BigDecimal.ZERO)) != 0;
}) // Filter condition
.collect(Collectors.toList());
log.info("Filtered List:"+filteredDemandDetaillist);
if(!filteredDemandDetaillist.isEmpty()) {
demandMap.put(taxPeriodFrom, filteredDemandDetaillist);
demandDetailsList.add(demandMap);
}
}
log.info("demandDetailsList:"+demandDetailsList);
// Sorting the list of maps based on the key in descending order
List<Map<Long, List<DemandDetail>>> sortedDemandDetailsList = demandDetailsList.stream()
.sorted((mapA, mapB) -> {
Long keyA = mapA.keySet().stream().findFirst().orElse(0L);
Long keyB = mapB.keySet().stream().findFirst().orElse(0L);
return keyB.compareTo(keyA); // Descending order
})
.collect(Collectors.toList());

log.info("Sorted map:"+sortedDemandDetailsList);

List<DemandDetail> currentMonthDemandDetailList = new ArrayList<>();
if (!sortedDemandDetailsList.isEmpty()) {
Map<Long, List<DemandDetail>> firstMap = sortedDemandDetailsList.get(0);
firstMap.forEach((key, value) -> {
currentMonthDemandDetailList.addAll(value); // Get all details from the first map
});
}
// Extract RemainingMonthDemandDetailList
List<DemandDetail> remainingMonthDemandDetailList = new ArrayList<>();
if (sortedDemandDetailsList.size() > 1) {
for (int i = 1; i < sortedDemandDetailsList.size(); i++) {
Map<Long, List<DemandDetail>> map = sortedDemandDetailsList.get(i);
map.forEach((key, value) -> {
remainingMonthDemandDetailList.addAll(value); // Collect all details from the other maps
});
}
}
log.info("currentMonthDemandDetailList"+currentMonthDemandDetailList);
log.info("remainingMonthDemandDetailList"+remainingMonthDemandDetailList);
BigDecimal currentmonthBill = BigDecimal.ZERO;
BigDecimal currentMonthPenalty = BigDecimal.ZERO;
BigDecimal currentmonthTotalDue = BigDecimal.ZERO;
BigDecimal advanceAvailable = BigDecimal.ZERO;
BigDecimal advanceAdjusted = BigDecimal.ZERO;
BigDecimal remainingAdvance = BigDecimal.ZERO;
BigDecimal totalAreas = BigDecimal.ZERO;
BigDecimal totalAreasWithPenalty = BigDecimal.ZERO;
BigDecimal netdue = BigDecimal.ZERO;
BigDecimal netDueWithPenalty = BigDecimal.ZERO;
BigDecimal totalApplicablePenalty =BigDecimal.ZERO;

currentmonthBill = currentMonthDemandDetailList.stream()
.filter(dd -> dd.getTaxHeadMasterCode().equals("10101")) // filter by taxHeadCode
.map(dd -> dd.getTaxAmount().subtract(dd.getCollectionAmount())) // map to the balance between taxAmount and collectedAmount
.reduce(BigDecimal.ZERO, BigDecimal::add);
log.info("currentMonthDemandDetailList::::"+currentMonthDemandDetailList);
currentMonthPenalty = currentMonthDemandDetailList.stream()
.filter(dd -> dd.getTaxHeadMasterCode().equals("WS_TIME_PENALTY")) // filter by taxHeadCode
.map(dd -> dd.getTaxAmount().subtract(dd.getCollectionAmount())) // map to the balance between taxAmount and collectedAmount
.reduce(BigDecimal.ZERO, BigDecimal::add);
log.info("currentMonthDemandDetailListafter::::"+currentMonthDemandDetailList);
log.info("currentMonthPenalty" + currentMonthPenalty);
currentmonthTotalDue = currentmonthBill.add(currentMonthPenalty);
if(currentMonthPenalty.equals(BigDecimal.ZERO)) {
List<MasterDetail> masterDetails = new ArrayList<>();
MasterDetail masterDetail = new MasterDetail("Penalty", "[?(@)]");
masterDetails.add(masterDetail);
ModuleDetail moduleDetail = ModuleDetail.builder().moduleName("ws-services-calculation").masterDetails(masterDetails).build();
List<ModuleDetail> moduleDetails = new ArrayList<>();
moduleDetails.add(moduleDetail);
MdmsCriteria mdmsCriteria = MdmsCriteria.builder().tenantId(demandCriteria.getTenantId())
.moduleDetails(moduleDetails)
.build();
MdmsCriteriaReq mdmsreq = MdmsCriteriaReq.builder().mdmsCriteria(mdmsCriteria).requestInfo(requestInfo).build();
DocumentContext mdmsData = util.getAttributeValues(mdmsreq);
if (!mdmsData.equals(null)) {
List<Map<String, Object>> paymentMasterDataList = mdmsData.read(PENALTY_PATH_CODE);
Map<String, Object> paymentMasterData = paymentMasterDataList.get(0);
Integer rate = (Integer) paymentMasterData.get("rate");
String penaltyType = String.valueOf(paymentMasterData.get("type"));
totalApplicablePenalty = currentmonthBill.multiply(new BigDecimal(rate).divide(new BigDecimal(100)));
totalApplicablePenalty = totalApplicablePenalty.setScale(0, RoundingMode.CEILING);
} else {
log.info("MDMS data is Null Penalty not connfigured");
}
}


//Tax headcode for WScharges,legacypenalty,legacyarea
List<String> taxHeadCodesToFilterWithoutPenalty = Arrays.asList("10102", "10201", "10101");

// Initialize the variable for the sum of taxAmount - collectedAmount for the filtered tax head codes
totalAreas = remainingMonthDemandDetailList.stream()
.filter(dd -> taxHeadCodesToFilterWithoutPenalty.contains(dd.getTaxHeadMasterCode())) // Filter by tax head codes
.map(dd -> dd.getTaxAmount().subtract(dd.getCollectionAmount())) // Calculate taxAmount - collectedAmount
.reduce(BigDecimal.ZERO, BigDecimal::add); // Sum all results

BigDecimal penaltyInRemainingMonth= remainingMonthDemandDetailList.stream()
.filter(dd -> dd.getTaxHeadMasterCode().equals("WS_TIME_PENALTY")) // filter by taxHeadCode
.map(dd -> dd.getTaxAmount().subtract(dd.getCollectionAmount())) // map to the balance between taxAmount and collectedAmount
.reduce(BigDecimal.ZERO, BigDecimal::add);

totalAreasWithPenalty = totalAreas.add(penaltyInRemainingMonth);



BigDecimal currentMonthAdvanceAvailable=currentMonthDemandDetailList.stream()
.filter(dd -> dd.getTaxHeadMasterCode().equals("WS_ADVANCE_CARRYFORWARD")) // filter by taxHeadCode
.map(dd -> dd.getTaxAmount()) // map to the balance between taxAmount and collectedAmount
.reduce(BigDecimal.ZERO, BigDecimal::add);
BigDecimal currentMonthAdvanceCollected= currentMonthDemandDetailList.stream()
.filter(dd -> dd.getTaxHeadMasterCode().equals("WS_ADVANCE_CARRYFORWARD")) // filter by taxHeadCode
.map(dd -> dd.getCollectionAmount()) // map to the balance between taxAmount and collectedAmount
.reduce(BigDecimal.ZERO, BigDecimal::add);
BigDecimal remainingMonthAdvanceAvailable = remainingMonthDemandDetailList.stream()
.filter(dd -> dd.getTaxHeadMasterCode().equals("WS_ADVANCE_CARRYFORWARD")) // filter by taxHeadCode
.map(dd -> dd.getTaxAmount()) // map to the balance between taxAmount and collectedAmount
.reduce(BigDecimal.ZERO, BigDecimal::add);
BigDecimal remainingMonthAdvanceCollected= remainingMonthDemandDetailList.stream()
.filter(dd -> dd.getTaxHeadMasterCode().equals("WS_ADVANCE_CARRYFORWARD")) // filter by taxHeadCode
.map(dd -> dd.getCollectionAmount()) // map to the balance between taxAmount and collectedAmount
.reduce(BigDecimal.ZERO, BigDecimal::add);
advanceAvailable = currentMonthAdvanceAvailable.add(remainingMonthAdvanceAvailable);
advanceAdjusted = currentMonthAdvanceCollected.add(remainingMonthAdvanceCollected);
remainingAdvance = advanceAvailable.subtract(advanceAdjusted);
//TODO:
if(remainingAdvance !=BigDecimal.ZERO && currentmonthBill !=BigDecimal.ZERO && advanceAdjusted.equals(BigDecimal.ZERO)) {
}

netdue = currentmonthBill.add(totalAreas).add(remainingAdvance);
netDueWithPenalty = currentmonthTotalDue.add(totalAreasWithPenalty).add(remainingAdvance);

//BigDecimal currentMonthBill
AggregatedDemandDetailResponse aggregatedDemandDetailResponse = AggregatedDemandDetailResponse.builder()
.mapOfDemandDetailList(sortedDemandDetailsList)
.currentmonthBill(currentmonthBill)
.currentMonthPenalty(currentMonthPenalty)
.currentmonthTotalDue(currentmonthTotalDue)
.totalAreas(totalAreas)
.totalAreasWithPenalty(totalAreasWithPenalty)
.netdue(netdue)
.netDueWithPenalty(netDueWithPenalty)
.advanceAdjusted(advanceAdjusted)
.advanceAvailable(advanceAvailable)
.remainingAdvance(remainingAdvance)
.totalApplicablePenalty(totalApplicablePenalty).build();


return aggregatedDemandDetailResponse;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -171,4 +171,6 @@ private Constants() {}
public static final String PAID_CANCEL_BILL_MSG = "You cannot cancel the bill in the workflow";

public static final String COUNT_REPLACE_CANCEL_BILL_MSG = "{count}";

public static final String PENALTY_PATH_CODE = "$.MdmsRes.ws-services-calculation.Penalty";
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@

import org.egov.common.contract.request.RequestInfo;
import org.egov.demand.config.ApplicationProperties;
import org.egov.demand.model.AggregatedDemandDetailResponse;
import org.egov.demand.model.Demand;
import org.egov.demand.model.DemandCriteria;
import org.egov.demand.model.DemandHistory;
Expand Down Expand Up @@ -162,5 +163,13 @@ public ResponseEntity<?> history(@RequestBody RequestInfoWrapper requestInfoWrap
responseInfo(responseFactory.getResponseInfo(requestInfo, HttpStatus.OK)).build();
return new ResponseEntity<>(response, HttpStatus.OK);
}

@PostMapping("_getAggregateDemandDetails")
public ResponseEntity<?> getAggregatedDemandDetails(@RequestBody RequestInfoWrapper requestInfoWrapper,
@ModelAttribute @Valid DemandCriteria demandCriteria) {

RequestInfo requestInfo = requestInfoWrapper.getRequestInfo();

AggregatedDemandDetailResponse demands = demandService.getAllDemands(demandCriteria, requestInfo);
return new ResponseEntity<>(demands, HttpStatus.OK);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -255,4 +255,16 @@ public class WSCalculationConfiguration {

@Value("${egov.save.demand.audit.from.wscal}")
private String saveDemandAudit;

@Value("${penalty.applicable.in.days}")
private Integer penaltyApplicableDays;

@Value("${penalty.start.threshold.time}")
private String penaltyStartThresholdTime;

@Value("${is.penalty.feature.enable}")
private boolean isPenaltyEnabled;

@Value("${egov.update.demand.add.penalty}")
private String updateAddPenaltytopic;
}
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,10 @@ public class WSCalculationConstant {

public static final String mGram_Consumer_Bill_Payment_combine = "mGram.consumer.billAndPayment.N";

public static final String JSONPATH_ROOT_FOR_ws_service_calculator = "$.MdmsRes.ws-services-calculation";

public static final String JSONPATH_ROOT_FOR_Penalty = "$.MdmsRes.ws-services-calculation.Penalty";




Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,7 @@
import org.egov.wscalculation.util.WSCalculationUtil;
import org.egov.wscalculation.validator.WSCalculationValidator;
import org.egov.wscalculation.validator.WSCalculationWorkflowValidator;
import org.egov.wscalculation.web.models.Action;
import org.egov.wscalculation.web.models.ActionItem;
import org.egov.wscalculation.web.models.BulkDemand;
import org.egov.wscalculation.web.models.CalculationCriteria;
import org.egov.wscalculation.web.models.CalculationReq;
import org.egov.wscalculation.web.models.Category;
import org.egov.wscalculation.web.models.Demand;
import org.egov.wscalculation.web.models.Event;
import org.egov.wscalculation.web.models.EventRequest;
import org.egov.wscalculation.web.models.OwnerInfo;
import org.egov.wscalculation.web.models.Recipient;
import org.egov.wscalculation.web.models.SMSRequest;
import org.egov.wscalculation.web.models.Source;
import org.egov.wscalculation.web.models.*;
import org.egov.wscalculation.web.models.users.UserDetailResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.annotation.KafkaListener;
Expand Down Expand Up @@ -544,5 +532,11 @@ public void generateBulkDemandForULB(HashMap<Object, Object> messageData) {
isSendMessage, isManual);

}
@KafkaListener(topics = {
"${egov.update.demand.add.penalty}" }, containerFactory = "kafkaListenerContainerFactory")
public void updateAddPenalty(HashMap<Object, Object> messageData) {
DemandRequest demandRequest = mapper.convertValue(messageData, DemandRequest.class);
demandService.updateDemandAddPenalty(demandRequest.getRequestInfo(), demandRequest.getDemands());
}

}
Loading

0 comments on commit 1d24d0e

Please sign in to comment.