/* * 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. */ /** * @author nayeem * * Generates the demand notice or the bill that is sent to the assessee giving the break up of the tax amounts that is due to NMC */ package org.egov.ptis.actions.bills; import com.opensymphony.xwork2.validator.annotations.Validations; import org.apache.commons.io.FileUtils; import org.apache.log4j.Logger; import org.apache.struts2.convention.annotation.Action; import org.apache.struts2.convention.annotation.ParentPackage; import org.apache.struts2.convention.annotation.Result; import org.apache.struts2.convention.annotation.Results; import org.egov.commons.Installment; import org.egov.commons.dao.InstallmentDao; import org.egov.demand.model.EgBill; import org.egov.infra.admin.master.service.ModuleService; import org.egov.infra.config.core.ApplicationThreadLocals; import org.egov.infra.exception.ApplicationRuntimeException; import org.egov.infra.filestore.entity.FileStoreMapper; import org.egov.infra.filestore.service.FileStoreService; import org.egov.infra.reporting.engine.ReportConstants.FileFormat; import org.egov.infra.reporting.engine.ReportOutput; import org.egov.infra.reporting.engine.ReportService; import org.egov.infra.reporting.viewer.ReportViewerUtil; import org.egov.infra.workflow.entity.StateAware; import org.egov.infra.workflow.service.WorkflowService; import org.egov.infstr.services.PersistenceService; import org.egov.ptis.actions.common.PropertyTaxBaseAction; import org.egov.ptis.bean.ReportInfo; import org.egov.ptis.client.bill.PTBillServiceImpl; import org.egov.ptis.client.util.PropertyTaxNumberGenerator; import org.egov.ptis.constants.PropertyTaxConstants; import org.egov.ptis.domain.dao.property.BasicPropertyDAO; import org.egov.ptis.domain.entity.property.BasicProperty; import org.egov.ptis.domain.entity.property.Property; import org.egov.ptis.domain.entity.property.PropertyImpl; import org.egov.ptis.domain.service.bill.BillService; import org.egov.ptis.domain.service.property.PropertyService; import org.egov.ptis.notice.PtNotice; import org.egov.ptis.service.DemandBill.DemandBillService; import org.egov.ptis.service.utils.PropertyTaxCommonUtils; import org.hibernate.Query; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.ApplicationContext; import java.io.File; import java.io.InputStream; import java.math.BigDecimal; import java.math.BigInteger; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; import static org.egov.ptis.constants.PropertyTaxConstants.APPCONFIG_CLIENT_SPECIFIC_DMD_BILL; import static org.egov.ptis.constants.PropertyTaxConstants.BILLTYPE_MANUAL; import static org.egov.ptis.constants.PropertyTaxConstants.FILESTORE_MODULE_NAME; import static org.egov.ptis.constants.PropertyTaxConstants.NOTICE_TYPE_BILL; import static org.egov.ptis.constants.PropertyTaxConstants.PTMODULENAME; import static org.egov.ptis.constants.PropertyTaxConstants.QUERY_DEMAND_BILL_STATUS; import static org.egov.ptis.constants.PropertyTaxConstants.STRING_EMPTY; @ParentPackage("egov") @Validations @Results({ @Result(name = BillGenerationAction.BILL, location = "billGeneration-bill.jsp"), @Result(name = BillGenerationAction.STATUS_BILLGEN, location = "billGeneration-billsGenStatus.jsp"), @Result(name = BillGenerationAction.ACK, location = "billGeneration-ack.jsp"), @Result(name = BillGenerationAction.COMMON_FORM, location = "searchProperty-commonForm.jsp") }) public class BillGenerationAction extends PropertyTaxBaseAction { /** * */ private static final long serialVersionUID = -6600897692089941070L; private final Logger LOGGER = Logger.getLogger(getClass()); protected static final String COMMON_FORM = "commonForm"; public static final String BILL = "bill"; public static final String STATUS_BILLGEN = "billsGenStatus"; private static final String STATUS_BILLGEN_BY_PARTNO = "statusByPartNo"; public static final String ACK = "ack"; private ReportService reportService; private PersistenceService<BasicProperty, Long> basicPropertyService; private PersistenceService<Property, Long> propertyImplService; private PropertyTaxNumberGenerator propertyTaxNumberGenerator; private PTBillServiceImpl ptBillServiceImpl; private PropertyService propService; private BillService billService; private String indexNumber; private String ackMessage; private String reportId; private String billNo; private BasicProperty basicProperty; private PropertyImpl property; private Map<String, Map<String, BigDecimal>> reasonwiseDues; private List<ReportInfo> reportInfos = new ArrayList<ReportInfo>(); InputStream billPDF; private String wardNum; @Autowired private ModuleService moduleDao; @Autowired private InstallmentDao installmentDAO; @Autowired private BasicPropertyDAO basicPropertyDAO; @Autowired @Qualifier("fileStoreService") protected FileStoreService fileStoreService; @Autowired private ApplicationContext beanProvider; @Autowired private PropertyTaxCommonUtils propertyTaxCommonUtils; @Autowired private ReportViewerUtil reportViewerUtil; @Override public StateAware getModel() { return null; } public BillGenerationAction() { } /** * Called to generate the bill * * @return String */ @Action(value = "/bills/billGeneration-generateBill") public String generateBill() { if (LOGGER.isDebugEnabled()) LOGGER.debug("Entered into generateBill, Index Number :" + indexNumber); try { if (basicPropertyDAO != null) basicProperty = basicPropertyDAO.getBasicPropertyByPropertyID(indexNumber); if (basicProperty.getProperty().getIsExemptedFromTax()) { addActionError(getText("error.msg.taxExempted")); return COMMON_FORM; } property = (PropertyImpl) basicProperty.getProperty(); final EgBill egBill = (EgBill) persistenceService.find("FROM EgBill WHERE module = ? " + "AND egBillType.code = ? AND consumerId = ? AND is_history = 'N'", moduleDao.getModuleByName(PTMODULENAME), BILLTYPE_MANUAL, basicProperty.getUpicNo()); ReportOutput reportOutput = null; if (egBill == null) reportOutput = getBillService().generateBill(basicProperty, ApplicationThreadLocals.getUserId().intValue()); else { final String query = "SELECT notice FROM EgBill bill, PtNotice notice left join notice.basicProperty bp " + "WHERE bill.is_History = 'N' " + "AND bill.egBillType.code = ? " + "AND bill.billNo = notice.noticeNo " + "AND notice.noticeType = ? " + "AND bp = ?"; final PtNotice ptNotice = (PtNotice) persistenceService.find(query, BILLTYPE_MANUAL, NOTICE_TYPE_BILL, basicProperty); reportOutput = new ReportOutput(); // Reading from filestore by passing filestoremapper object if (ptNotice != null && ptNotice.getFileStore() != null) { final FileStoreMapper fsm = ptNotice.getFileStore(); final File file = fileStoreService.fetch(fsm, FILESTORE_MODULE_NAME); final byte[] bFile = FileUtils.readFileToByteArray(file); reportOutput.setReportOutputData(bFile); reportOutput.setReportFormat(FileFormat.PDF); } } reportId = reportViewerUtil.addReportToTempCache(reportOutput); if (LOGGER.isDebugEnabled()) { LOGGER.debug("generateBill: ReportId: " + reportId); LOGGER.debug("Exit from generateBill"); } if (property.getStatus().equals(PropertyTaxConstants.STATUS_DEMAND_INACTIVE)) { property.setStatus(PropertyTaxConstants.STATUS_ISACTIVE); propertyImplService.persist(property); } } catch (final Exception e) { throw new ApplicationRuntimeException("Bill Generation Exception : " + e); } return BILL; } @Action(value = "/bills/billGeneration-generateDemandBill") public String generateDemandBill() { String clientSpecificDmdBill = propertyTaxCommonUtils.getAppConfigValue(APPCONFIG_CLIENT_SPECIFIC_DMD_BILL, PTMODULENAME); if ("Y".equalsIgnoreCase(clientSpecificDmdBill)) { DemandBillService demandBillService = (DemandBillService) beanProvider.getBean("demandBillService"); ReportOutput reportOutput = demandBillService.generateDemandBill(indexNumber); reportId = reportViewerUtil.addReportToTempCache(reportOutput); } else { generateBill(); } return BILL; } @SuppressWarnings("unchecked") @Action(value = "/bills/billGeneration-billsGenStatus") public String billsGenStatus() { ReportInfo reportInfo; Integer totalProps = 0; Integer totalBillsGen = 0; final Installment currInst = installmentDAO.getInsatllmentByModuleForGivenDate(ptBillServiceImpl.getModule(), new Date()); final StringBuilder propQueryString = new StringBuilder(); propQueryString .append("select bndry.boundaryNum,bndry.name, count(bndry.boundaryNum) ") .append("from Boundary bndry, PropertyID pid left join pid.basicProperty bp where bp.upicNo is not null and bp.active = true and ") .append("bp.source = 'M' and pid.ward.id = bndry.id ") .append("and bp.id not in (select basicProperty from PropertyStatusValues group by basicProperty having count(basicProperty) > 0 ) ") .append(" and bp.id in (select basicProperty from PropertyImpl where status = 'A' and isExemptedFromTax = false ) ") .append("group by bndry.name, bndry.boundaryNum ").append("order by bndry.boundaryNum, bndry.name"); final Query billQuery = getPersistenceService().getSession().getNamedQuery(QUERY_DEMAND_BILL_STATUS); billQuery.setDate("FromDate", currInst.getFromDate()); billQuery.setDate("ToDate", currInst.getToDate()); final List<Object> billList = billQuery.list(); LOGGER.info("billList : " + billList); final Query propQuery = getPersistenceService().getSession().createQuery(propQueryString.toString()); final List<Object> propList = propQuery.list(); LOGGER.info("propList : " + propList); for (final Object props : propList) { reportInfo = new ReportInfo(); final Object[] propObj = (Object[]) props; reportInfo.setWardNo(String.valueOf(propObj[0]) + '-' + String.valueOf(propObj[1])); reportInfo.setTotalNoProps(Integer.valueOf(((Long) propObj[2]).toString())); reportInfo.setTotalGenBills(0); String propWardNo = String.valueOf(propObj[0]); String wardNo; for (final Object bills : billList) { final Object[] billObj = (Object[]) bills; wardNo = String.valueOf(billObj[0]); if (propWardNo.equals(wardNo)) { reportInfo.setTotalGenBills(Integer.valueOf(((Long) billObj[1]).toString())); break; } } totalProps = totalProps + reportInfo.getTotalNoProps(); totalBillsGen = totalBillsGen + reportInfo.getTotalGenBills(); getReportInfos().add(reportInfo); } final ReportInfo reportInfoCount = new ReportInfo(); reportInfoCount.setWardNo("Total :"); reportInfoCount.setTotalNoProps(totalProps); reportInfoCount.setTotalGenBills(totalBillsGen); getReportInfos().add(reportInfoCount); return STATUS_BILLGEN; } @SuppressWarnings("unchecked") @Action(value = "/bills/billGeneration-billGenStatusByPartNo") public String billGenStatusByPartNo() { LOGGER.debug("Entered into billGenStatusByPartNo, wardNum=" + wardNum); ReportInfo reportInfo; Integer totalProps = 0; Integer totalBillsGen = 0; final Installment currInst = propertyTaxCommonUtils.getCurrentInstallment(); final StringBuilder billQueryString = new StringBuilder(); final StringBuilder propQueryString = new StringBuilder(); billQueryString.append("select bp.partNo, count(bp.partNo) ") .append("from EgBill bill, Boundary bndry, PtNotice notice left join notice.basicProperty bp ") .append("where bp.propertyID.ward.id=bndry.id ").append("and bndry.boundaryNum = :bndryNum ") .append("and bill.is_History = 'N' ").append("and :FromDate <= bill.issueDate ") .append("and :ToDate >= bill.issueDate ").append("and bill.egBillType.code = :BillType ") .append("and bill.billNo = notice.noticeNo ").append("and notice.noticeType = 'Bill' ") .append("and notice.fileStore is not null ").append("group by bp.partNo ").append("order by bp.partNo"); propQueryString.append("select bp.partNo, count(bp.partNo) ") .append("from Boundary bndry, PropertyID pid left join pid.basicProperty bp ") .append("where bp.active = true and pid.ward.id = bndry.id ") .append("and bndry.boundaryNum = :bndryNum ").append("group by bp.partNo ") .append("order by bp.partNo"); final Query billQuery = getPersistenceService().getSession().createQuery(billQueryString.toString()); billQuery.setBigInteger("bndryNum", new BigInteger(wardNum)); billQuery.setDate("FromDate", currInst.getFromDate()); billQuery.setDate("ToDate", currInst.getToDate()); billQuery.setString("BillType", BILLTYPE_MANUAL); final List<Object> billList = billQuery.list(); final Query propQuery = getPersistenceService().getSession().createQuery(propQueryString.toString()); propQuery.setBigInteger("bndryNum", new BigInteger(wardNum)); final List<Object> propList = propQuery.list(); for (final Object props : propList) { reportInfo = new ReportInfo(); final Object[] propObj = (Object[]) props; reportInfo.setPartNo(String.valueOf(propObj[0])); reportInfo.setTotalNoProps(Integer.valueOf(((Long) propObj[1]).toString())); reportInfo.setTotalGenBills(0); String partNo; for (final Object bills : billList) { final Object[] billObj = (Object[]) bills; partNo = String.valueOf(billObj[0]); if (reportInfo.getPartNo().equals(partNo)) { reportInfo.setTotalGenBills(Integer.valueOf(((Long) billObj[1]).toString())); break; } } totalProps = totalProps + reportInfo.getTotalNoProps(); totalBillsGen = totalBillsGen + reportInfo.getTotalGenBills(); getReportInfos().add(reportInfo); } final ReportInfo reportInfoCount = new ReportInfo(); reportInfoCount.setPartNo("Total :"); reportInfoCount.setTotalNoProps(totalProps); reportInfoCount.setTotalGenBills(totalBillsGen); getReportInfos().add(reportInfoCount); LOGGER.debug("Exiting from billGenStatusByPartNo"); return STATUS_BILLGEN_BY_PARTNO; } @Action(value = "/bills/billGeneration-cancelBill") public String cancelBill() { final EgBill egBill = (EgBill) persistenceService.find("FROM EgBill " + "WHERE module = ? " + "AND egBillType.code = ? " + "AND SUBSTRING(consumerId, 1, (LOCATE('(', consumerId)-1)) = ? " + "AND is_history = 'N'", moduleDao.getModuleByName(PTMODULENAME), BILLTYPE_MANUAL, indexNumber); if (egBill == null) { setAckMessage("There is no active Bill exist for index no : " + indexNumber); return ACK; } else { egBill.setIs_History("Y"); egBill.setIs_Cancelled("Y"); egBill.setModifiedDate(new Date()); final BasicProperty basicProperty = basicPropertyDAO.getBasicPropertyByPropertyID(indexNumber); basicProperty.setIsBillCreated(PropertyTaxConstants.STATUS_BILL_NOTCREATED); basicProperty.setBillCrtError(STRING_EMPTY); basicPropertyService.update(basicProperty); setAckMessage("Bill successfully cancelled for index no : " + indexNumber); } return ACK; } public String getReportId() { return reportId; } @Override public String getIndexNumber() { return indexNumber; } @Override public void setIndexNumber(final String indexNumber) { this.indexNumber = indexNumber; } public String getAckMessage() { return ackMessage; } public void setAckMessage(final String ackMessage) { this.ackMessage = ackMessage; } public ReportService getReportService() { return reportService; } public void setReportService(final ReportService reportService) { this.reportService = reportService; } public String getBillNo() { return billNo; } public void setBillNo(final String billNo) { this.billNo = billNo; } public PropertyTaxNumberGenerator getPropertyTaxNumberGenerator() { return propertyTaxNumberGenerator; } public void setPropertyTaxNumberGenerator(final PropertyTaxNumberGenerator propertyTaxNumberGenerator) { this.propertyTaxNumberGenerator = propertyTaxNumberGenerator; } public Map<String, Map<String, BigDecimal>> getReasonwiseDues() { return reasonwiseDues; } public void setReasonwiseDues(final Map<String, Map<String, BigDecimal>> reasonwiseDues) { this.reasonwiseDues = reasonwiseDues; } public PersistenceService<BasicProperty, Long> getBasicPropertyService() { return basicPropertyService; } public void setPropertyImplService(final PersistenceService<Property, Long> propertyImplService) { this.propertyImplService = propertyImplService; } public void setbasicPropertyService(final PersistenceService<BasicProperty, Long> basicPropertyService) { this.basicPropertyService = basicPropertyService; } public BasicProperty getBasicProperty() { return basicProperty; } public void setBasicProperty(final BasicProperty basicProperty) { this.basicProperty = basicProperty; } public void setPropertyWorkflowService(final WorkflowService<PropertyImpl> propertyWorkflowService) { } public PropertyService getPropService() { return propService; } public void setPropService(final PropertyService propService) { this.propService = propService; } public BillService getBillService() { return billService; } public void setBillService(final BillService billService) { this.billService = billService; } public List<ReportInfo> getReportInfos() { return reportInfos; } public void setReportInfos(final List<ReportInfo> reportInfos) { this.reportInfos = reportInfos; } public String getWardNum() { return wardNum; } public void setWardNum(final String wardNum) { this.wardNum = wardNum; } public PTBillServiceImpl getPtBillServiceImpl() { return ptBillServiceImpl; } public void setPtBillServiceImpl(final PTBillServiceImpl ptBillServiceImpl) { this.ptBillServiceImpl = ptBillServiceImpl; } }