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

Develop #801

Merged
merged 16 commits into from
May 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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());
}
Comment on lines +536 to +540
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add error handling for message processing.

Consider wrapping the message processing logic in a try-catch block to handle potential exceptions gracefully. This will improve the robustness of the service, especially in cases where the message format might not be as expected or if the updateDemandAddPenalty method encounters an error.

+ try {
    DemandRequest demandRequest = mapper.convertValue(messageData, DemandRequest.class);
    demandService.updateDemandAddPenalty(demandRequest.getRequestInfo(), demandRequest.getDemands());
+ } catch (Exception e) {
+     log.error("Error processing message for adding penalty: ", e);
+ }
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
"${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());
}
"${egov.update.demand.add.penalty}" }, containerFactory = "kafkaListenerContainerFactory")
public void updateAddPenalty(HashMap<Object, Object> messageData) {
try {
DemandRequest demandRequest = mapper.convertValue(messageData, DemandRequest.class);
demandService.updateDemandAddPenalty(demandRequest.getRequestInfo(), demandRequest.getDemands());
} catch (Exception e) {
log.error("Error processing message for adding penalty: ", e);
}
}


}
Loading
Loading