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 #876 from egovernments/ISTE-229
Browse files Browse the repository at this point in the history
ISTE-229 Ledger Report
  • Loading branch information
pradeepkumarcm-egov authored Aug 5, 2024
2 parents 81979fc + 3a865a7 commit 8d4efdd
Show file tree
Hide file tree
Showing 10 changed files with 493 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package org.egov.waterconnection.repository;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
Expand Down Expand Up @@ -36,6 +40,7 @@
import org.egov.waterconnection.web.models.WaterConnection;
import org.egov.waterconnection.web.models.WaterConnectionRequest;
import org.egov.waterconnection.web.models.WaterConnectionResponse;
import org.egov.waterconnection.web.models.collection.Payment;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jdbc.core.JdbcTemplate;
Expand All @@ -50,6 +55,8 @@
public class WaterDaoImpl implements WaterDao {

@Autowired
private LedgerReportRowMapper ledgerReportRowMapper;
@Autowired
private DemandNotGeneratedRowMapper demandNotGeneratedRowMapper;

@Autowired
Expand Down Expand Up @@ -669,17 +676,70 @@ public List<InactiveConsumerReportData> getInactiveConsumerReport(Long monthStar
return inactiveConsumerReportList;
}

public List<ConsumersDemandNotGenerated> getConsumersByPreviousMeterReading(Long previousMeterReading, String tenantId)
{
StringBuilder query=new StringBuilder(wsQueryBuilder.DEMAND_NOT_GENERATED_QUERY);
public List<ConsumersDemandNotGenerated> getConsumersByPreviousMeterReading(Long previousMeterReading, String tenantId) {
StringBuilder query = new StringBuilder(wsQueryBuilder.DEMAND_NOT_GENERATED_QUERY);

List<Object> preparedStatement=new ArrayList<>();
List<Object> preparedStatement = new ArrayList<>();
preparedStatement.add(tenantId);
preparedStatement.add(previousMeterReading);
preparedStatement.add(tenantId);

log.info("Query for consumer demand not generated "+ query +" prepared statement "+ preparedStatement);
List<ConsumersDemandNotGenerated> consumersDemandNotGeneratedList=jdbcTemplate.query(query.toString(),preparedStatement.toArray(),demandNotGeneratedRowMapper);
log.info("Query for consumer demand not generated " + query + " prepared statement " + preparedStatement);
List<ConsumersDemandNotGenerated> consumersDemandNotGeneratedList = jdbcTemplate.query(query.toString(), preparedStatement.toArray(), demandNotGeneratedRowMapper);
return consumersDemandNotGeneratedList;
}

public List<Map<String, Object>> getLedgerReport(String consumercode, String tenantId, Integer offset, Integer limit, String year,RequestInfoWrapper requestInfoWrapper) {
String[] years = year.split("-");
if (years.length != 2) {
throw new IllegalArgumentException("Invalid fiscal year format");
}
int startYear = Integer.parseInt(years[0]);
int endYear = Integer.parseInt(years[1]);

LocalDate startDate = LocalDate.of(startYear, 4, 1);
LocalDate endDate = LocalDate.of(startYear + 1, 3, 31);

Long startDateTime = LocalDateTime.of(startDate.getYear(), startDate.getMonth(), startDate.getDayOfMonth(), 0, 0, 0)
.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
Long endDateTime = LocalDateTime.of(endDate, LocalTime.MAX).atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();

StringBuilder query = new StringBuilder(wsQueryBuilder.LEDGER_REPORT_QUERY);

List<Object> preparedStatement = new ArrayList<>();
preparedStatement.add(consumercode);
preparedStatement.add(tenantId);
preparedStatement.add(startDateTime);
preparedStatement.add(endDateTime);

Integer newlimit = wsConfiguration.getDefaultLimit();
Integer newoffset = wsConfiguration.getDefaultOffset();
if (limit == null && offset == null)
newlimit = wsConfiguration.getMaxLimit();
if (limit != null && limit <= wsConfiguration.getMaxLimit())
newlimit = limit;
if (limit != null && limit >= wsConfiguration.getMaxLimit())
newlimit = wsConfiguration.getMaxLimit();

if (offset != null)
newoffset = offset;

if (newlimit > 0) {
query.append(" offset ? limit ? ;");
preparedStatement.add(newoffset);
preparedStatement.add(newlimit);
}

log.info("Query of ledger report:" + query + "and prepared statement" + preparedStatement);
ledgerReportRowMapper.setTenantId(tenantId);
ledgerReportRowMapper.setRequestInfo(requestInfoWrapper);
ledgerReportRowMapper.setStartYear(startYear);
ledgerReportRowMapper.setEndYear(endYear);
ledgerReportRowMapper.setConsumerCode(consumercode);
List<Map<String, Object>> ledgerReportList= jdbcTemplate.query(query.toString(), preparedStatement.toArray(), ledgerReportRowMapper);
int fromIndex = Math.min(newoffset, ledgerReportList.size());
int toIndex = Math.min(fromIndex + newlimit, ledgerReportList.size());
return ledgerReportList.subList(fromIndex, toIndex);
// return ledgerReportList;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,26 @@ public class WsQueryBuilder {
"(select distinct consumercode from egbs_demand_v1 d inner join egbs_demanddetail_v1 dd on dd.demandid = d.id " +
"where dd.taxheadcode='10101' and d.status ='ACTIVE' and d.businessservice='WS' and " +
"d.tenantid=?) order by connectionno;";


public static final String LEDGER_REPORT_QUERY = "SELECT connectionholder.userid as uuid,conn.connectionno as connectionNo,conn.oldconnectionno," +
"dem.taxperiodfrom as startdate,dem.taxperiodto as enddate," +
"dem.createdtime as demandGenerationDate," +
"dd.taxheadcode as code,dd.taxamount as taxamount " +
"FROM eg_ws_connection conn INNER JOIN eg_ws_connectionholder connectionholder " +
"ON connectionholder.connectionid = conn.id " +
"INNER JOIN egbs_demand_v1 dem ON dem.consumercode = conn.connectionno INNER JOIN " +
"egbs_demanddetail_v1 dd ON dd.demandid = dem.id " +
"WHERE dem.consumercode = ? AND conn.tenantId = ? AND dem.status = 'ACTIVE' " +
"AND taxperiodfrom>=? AND taxperiodto<=? "+
"ORDER BY startdate";

public static final String TAX_AMOUNT_QUERY="SELECT SUM(taxamount) FROM egbs_demanddetail_v1 WHERE " +
"demandid IN (SELECT id FROM egbs_demand_v1 WHERE consumercode = ? AND taxperiodfrom < ? AND status='ACTIVE');";

public static final String TOTAL_AMOUNT_PAID_QUERY="SELECT SUM(totalamountpaid) FROM egcl_payment WHERE " +
"id IN (SELECT paymentid FROM egcl_paymentdetail WHERE billid IN " +
"(SELECT billid FROM egbs_billdetail_v1 WHERE consumercode = ?)) AND createdtime < ? AND paymentstatus!='CANCELLED';";

/**
*
* @param criteria The WaterCriteria
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,247 @@
package org.egov.waterconnection.repository.rowmapper;

import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.models.auth.In;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.egov.waterconnection.repository.ServiceRequestRepository;
import org.egov.waterconnection.repository.builder.WsQueryBuilder;
import org.egov.waterconnection.util.WaterServicesUtil;
import org.egov.waterconnection.web.models.*;
import org.egov.waterconnection.web.models.collection.Payment;
import org.egov.waterconnection.web.models.collection.PaymentResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.ResultSetExtractor;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.time.Instant;
import java.time.LocalDate;
import java.time.YearMonth;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.time.temporal.ChronoUnit;


@Slf4j
@Component
@Setter
public class LedgerReportRowMapper implements ResultSetExtractor<List<Map<String, Object>>> {

@Autowired
private WaterServicesUtil waterServiceUtil;

@Autowired
private ObjectMapper mapper;

@Autowired
private ServiceRequestRepository serviceRequestRepository;

@Autowired
private JdbcTemplate jdbcTemplate;

@Autowired
private WsQueryBuilder wsQueryBuilder;

String tenantId;
RequestInfoWrapper requestInfoWrapper;
Integer startYear;
Integer endYear;
String consumerCode;

public void setRequestInfo(RequestInfoWrapper requestInfoWrapper) {
this.requestInfoWrapper = requestInfoWrapper;
}

@Override
public List<Map<String, Object>> extractData(ResultSet resultSet) throws SQLException, DataAccessException {
List<Map<String, Object>> monthlyRecordsList = new ArrayList<>();
Map<String, LedgerReport> ledgerReports = new HashMap<>();
YearMonth startMonth = YearMonth.of(startYear, 4);
YearMonth endMonth;
YearMonth now = YearMonth.now();

if (startYear == now.getYear() || (startYear == now.getYear() - 1 && now.getMonthValue() <= 3)) {
endMonth = now;
} else {
endMonth = YearMonth.of(startYear + 1, 3);
}

YearMonth currentMonth = startMonth;

while (!currentMonth.isAfter(endMonth)) {
String monthAndYear = currentMonth.format(DateTimeFormatter.ofPattern("MMMM yyyy"));
LedgerReport ledgerReport = new LedgerReport();
ledgerReport.setDemand(new DemandLedgerReport());
ledgerReport.getDemand().setMonthAndYear(monthAndYear);
ledgerReport.getDemand().setConnectionNo(consumerCode);
ledgerReports.put(monthAndYear, ledgerReport);
currentMonth = currentMonth.plusMonths(1);
}

while (resultSet.next()) {
Long dateLong = resultSet.getLong("enddate");
LocalDate date = Instant.ofEpochMilli(dateLong).atZone(ZoneId.systemDefault()).toLocalDate();
String monthAndYear = date.format(DateTimeFormatter.ofPattern("MMMM yyyy"));

String code = resultSet.getString("code");

BigDecimal taxamount = resultSet.getBigDecimal("taxamount");

Long demandGenerationDateLong = resultSet.getLong("demandgenerationdate");
LocalDate demandGenerationDateLocal = Instant.ofEpochMilli(demandGenerationDateLong).atZone(ZoneId.systemDefault()).toLocalDate();

LedgerReport ledgerReport = ledgerReports.get(monthAndYear);

if (ledgerReport.getPayment() == null) {
ledgerReport.setPayment(new ArrayList<>());
}

if (code.equals("10102")) {
ledgerReport.getDemand().setArrears(taxamount != null ? taxamount : BigDecimal.ZERO);
ledgerReport.getDemand().setMonthAndYear(monthAndYear);
} else if (code.equals("WS_TIME_PENALTY") || code.equals("10201")) {
ledgerReport.getDemand().setPenalty(taxamount != null ? taxamount : BigDecimal.ZERO);
BigDecimal amount = ledgerReport.getDemand().getTaxamount() != null ? ledgerReport.getDemand().getTaxamount() : BigDecimal.ZERO;
ledgerReport.getDemand().setTotalForCurrentMonth((taxamount != null ? taxamount : BigDecimal.ZERO).add(amount));
ledgerReport.getDemand().setTotal_due_amount(ledgerReport.getDemand().getTotalForCurrentMonth().add(ledgerReport.getDemand().getArrears() != null ? ledgerReport.getDemand().getArrears() : BigDecimal.ZERO));
} else if (code.equals("10101")) {
ledgerReport.getDemand().setMonthAndYear(monthAndYear);
ledgerReport.getDemand().setDemandGenerationDate(demandGenerationDateLong);
ledgerReport.getDemand().setTaxamount(taxamount);
ledgerReport.getDemand().setTotalForCurrentMonth(ledgerReport.getDemand().getTaxamount().add(ledgerReport.getDemand().getPenalty() != null ? ledgerReport.getDemand().getPenalty() : BigDecimal.ZERO));
long dueDateMillis = demandGenerationDateLocal.plus(10, ChronoUnit.DAYS).atStartOfDay(ZoneId.systemDefault()).toInstant().toEpochMilli();
long penaltyAppliedDateMillis = demandGenerationDateLocal.plus(11, ChronoUnit.DAYS).atStartOfDay(ZoneId.systemDefault()).toInstant().toEpochMilli();
ledgerReport.getDemand().setDueDate(dueDateMillis);
ledgerReport.getDemand().setPenaltyAppliedDate(penaltyAppliedDateMillis);
Long startDate = resultSet.getLong("startdate");
String connectionno = resultSet.getString("connectionno");
BigDecimal taxAmountResult = getMonthlyTaxAmount(startDate, connectionno);
BigDecimal totalAmountPaidResult = getMonthlyTotalAmountPaid(startDate, connectionno);
ledgerReport.getDemand().setArrears(taxAmountResult.subtract(totalAmountPaidResult));
ledgerReport.getDemand().setTotal_due_amount(ledgerReport.getDemand().getTotalForCurrentMonth().add(ledgerReport.getDemand().getArrears()));
}
ledgerReport.getDemand().setConnectionNo(resultSet.getString("connectionno"));
ledgerReport.getDemand().setOldConnectionNo(resultSet.getString("oldconnectionno"));
ledgerReport.getDemand().setUserId(resultSet.getString("uuid"));
log.info("Data inserted into map " + ledgerReport.toString());
ledgerReports.put(monthAndYear, ledgerReport);
}
for (Map.Entry<String, LedgerReport> entry : ledgerReports.entrySet()) {
Map<String, Object> record = new HashMap<>();
record.put(entry.getKey(), entry.getValue());
monthlyRecordsList.add(record);
}
log.info("ledger report list" + monthlyRecordsList);
if (!monthlyRecordsList.isEmpty()) {
addPaymentToLedger(monthlyRecordsList);
}
monthlyRecordsList.sort(new Comparator<Map<String, Object>>() {
@Override
public int compare(Map<String, Object> o1, Map<String, Object> o2) {
String monthAndYear1 = (String) o1.keySet().iterator().next();
String monthAndYear2 = (String) o2.keySet().iterator().next();

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMMM yyyy", Locale.ENGLISH);
YearMonth yearMonth1 = YearMonth.parse(monthAndYear1, formatter);
YearMonth yearMonth2 = YearMonth.parse(monthAndYear2, formatter);

return yearMonth1.compareTo(yearMonth2);
}
});
return monthlyRecordsList;
}

public List<Payment> addPaymentDetails(String consumerCode) {
if(consumerCode==null)
return null;
String service = "WS";
StringBuilder URL = waterServiceUtil.getcollectionURL();
URL.append(service).append("/_search").append("?").append("consumerCodes=").append(consumerCode)
.append("&").append("tenantId=").append(tenantId);
Object response = serviceRequestRepository.fetchResult(URL, requestInfoWrapper);
log.info("line 226 response " + response.toString());
PaymentResponse paymentResponse = mapper.convertValue(response, PaymentResponse.class);
return paymentResponse.getPayments();
}

private void addPaymentToLedger(List<Map<String, Object>> monthlyRecordList) {
for (Map<String, Object> record : monthlyRecordList) {
LedgerReport ledgerReport = (LedgerReport) record.values().iterator().next();
if (ledgerReport.getDemand() == null) {
log.info("DemandLedgerReport is null for LedgerReport: {}", ledgerReport);
}
String consumerCode = ledgerReport.getDemand().getConnectionNo();
log.info("consumer code is " + consumerCode);
List<Payment> payments = addPaymentDetails(consumerCode);
boolean paymentMatched = false;
if(payments!=null)
{
for (Payment payment : payments) {
Long transactionDateLong = payment.getTransactionDate();
LocalDate transactionDate = Instant.ofEpochMilli(transactionDateLong).atZone(ZoneId.systemDefault()).toLocalDate();
String transactionMonthAndYear = transactionDate.format(DateTimeFormatter.ofPattern("MMMM yyyy"));
if (ledgerReport.getDemand().getMonthAndYear().equals(transactionMonthAndYear)) {
PaymentLedgerReport paymentLedgerReport = new PaymentLedgerReport();
paymentLedgerReport.setCollectionDate(transactionDateLong);
paymentLedgerReport.setReceiptNo(payment.getPaymentDetails().get(0).getReceiptNumber());
paymentLedgerReport.setPaid(payment.getTotalAmountPaid());
BigDecimal totalDueAmount=ledgerReport.getDemand().getTotal_due_amount();
if(totalDueAmount.equals(BigDecimal.ZERO))
{
paymentLedgerReport.setBalanceLeft(payment.getTotalDue().subtract(paymentLedgerReport.getPaid()));
}
else
{
paymentLedgerReport.setBalanceLeft(totalDueAmount.subtract(paymentLedgerReport.getPaid()));
}
if (ledgerReport.getPayment() == null) {
ledgerReport.setPayment(new ArrayList<>());
}
ledgerReport.getPayment().add(paymentLedgerReport);
paymentMatched = true;
}
}
}
if (!paymentMatched) {
PaymentLedgerReport defaultPaymentLedgerReport = new PaymentLedgerReport();
defaultPaymentLedgerReport.setCollectionDate(null);
defaultPaymentLedgerReport.setReceiptNo("N/A");
defaultPaymentLedgerReport.setPaid(BigDecimal.ZERO);
defaultPaymentLedgerReport.setBalanceLeft(ledgerReport.getDemand().getTotal_due_amount());

if (ledgerReport.getPayment() == null) {
ledgerReport.setPayment(new ArrayList<>());
}
ledgerReport.getPayment().add(defaultPaymentLedgerReport);
}
}
}

private BigDecimal getMonthlyTaxAmount(Long startDate, String consumerCode) {
StringBuilder taxAmountQuery = new StringBuilder(wsQueryBuilder.TAX_AMOUNT_QUERY);
List<Object> taxAmountParams = new ArrayList<>();
taxAmountParams.add(consumerCode);
taxAmountParams.add(startDate);
BigDecimal ans = jdbcTemplate.queryForObject(taxAmountQuery.toString(), taxAmountParams.toArray(), BigDecimal.class);
if (ans != null)
return ans;
return BigDecimal.ZERO;
}

private BigDecimal getMonthlyTotalAmountPaid(Long startDate, String consumerCode) {
StringBuilder totalAmountPaidQuery = new StringBuilder(wsQueryBuilder.TOTAL_AMOUNT_PAID_QUERY);
List<Object> totalAmountPaidParams = new ArrayList<>();
totalAmountPaidParams.add(consumerCode);
totalAmountPaidParams.add(startDate);
BigDecimal ans = jdbcTemplate.queryForObject(totalAmountPaidQuery.toString(), totalAmountPaidParams.toArray(), BigDecimal.class);
if (ans != null)
return ans;
return BigDecimal.ZERO;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.egov.waterconnection.service;

import java.util.List;
import java.util.Map;

import javax.validation.Valid;

Expand Down Expand Up @@ -54,4 +55,6 @@ List<CollectionReportData> collectionReport(String paymentStartDate, String paym
List<InactiveConsumerReportData> inactiveConsumerReport(String monthStartDate,String monthEndDate,String tenantId, @Valid Integer offset, @Valid Integer limit, RequestInfo requestInfo);

WaterConnectionResponse getConsumersWithDemandNotGenerated(String previousMeterReading, String tenantId,RequestInfo requestInfo);

List<Map<String, Object>> ledgerReport(String consumercode, String tenantId, Integer offset, Integer limit, String year,RequestInfoWrapper requestInfoWrapper);
}
Loading

0 comments on commit 8d4efdd

Please sign in to comment.