/* * 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.works.contractorbill.service; import java.io.IOException; import java.math.BigDecimal; import java.util.ArrayList; 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 javax.script.ScriptContext; import javax.servlet.http.HttpServletRequest; import org.egov.commons.Accountdetailtype; import org.egov.commons.CChartOfAccounts; import org.egov.commons.CFinancialYear; import org.egov.commons.dao.ChartOfAccountsHibernateDAO; import org.egov.commons.dao.EgwStatusHibernateDAO; import org.egov.commons.dao.FinancialYearHibernateDAO; import org.egov.eis.entity.Assignment; import org.egov.eis.service.AssignmentService; import org.egov.eis.service.PositionMasterService; import org.egov.infra.admin.master.entity.User; import org.egov.infra.script.service.ScriptService; import org.egov.infra.security.utils.SecurityUtils; import org.egov.infra.validation.exception.ValidationException; import org.egov.infra.workflow.matrix.entity.WorkFlowMatrix; import org.egov.infra.workflow.service.SimpleWorkflowService; import org.egov.model.bills.EgBillPayeedetails; import org.egov.model.bills.EgBilldetails; import org.egov.model.bills.EgBillregistermis; import org.egov.pims.commons.Position; import org.egov.services.voucher.VoucherService; import org.egov.works.contractorbill.entity.ContractorBillRegister; import org.egov.works.contractorbill.entity.SearchRequestContractorBill; import org.egov.works.contractorbill.entity.enums.BillTypes; import org.egov.works.contractorbill.repository.ContractorBillRegisterRepository; import org.egov.works.lineestimate.entity.DocumentDetails; import org.egov.works.lineestimate.entity.LineEstimateDetails; import org.egov.works.lineestimate.service.LineEstimateService; import org.egov.works.mb.service.MBHeaderService; import org.egov.works.milestone.entity.TrackMilestone; import org.egov.works.milestone.service.TrackMilestoneService; import org.egov.works.models.measurementbook.MBHeader; import org.egov.works.models.workorder.WorkOrder; import org.egov.works.models.workorder.WorkOrderEstimate; import org.egov.works.utils.WorksConstants; import org.egov.works.utils.WorksUtils; import org.hibernate.Criteria; import org.hibernate.Session; import org.hibernate.criterion.CriteriaSpecification; import org.hibernate.criterion.MatchMode; import org.hibernate.criterion.Restrictions; import org.joda.time.DateTime; import org.slf4j.Logger; import org.slf4j.LoggerFactory; 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; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; import org.springframework.web.multipart.MultipartFile; @Service @Transactional(readOnly = true) public class ContractorBillRegisterService { private static final Logger LOG = LoggerFactory.getLogger(ContractorBillRegisterService.class); @PersistenceContext private EntityManager entityManager; private final ContractorBillRegisterRepository contractorBillRegisterRepository; @Autowired private EgwStatusHibernateDAO egwStatusHibernateDAO; @Autowired private WorksUtils worksUtils; @Autowired private FinancialYearHibernateDAO financialYearHibernateDAO; @Autowired @Qualifier("workflowService") private SimpleWorkflowService<ContractorBillRegister> contractorBillRegisterWorkflowService; @Autowired private AssignmentService assignmentService; @Autowired private SecurityUtils securityUtils; @Autowired private PositionMasterService positionMasterService; @Autowired private LineEstimateService lineEstimateService; private final ScriptService scriptExecutionService; @Autowired private VoucherService voucherService; @Autowired private MBHeaderService mbHeaderService; @Autowired private ChartOfAccountsHibernateDAO chartOfAccountsHibernateDAO; @Autowired private TrackMilestoneService trackMilestoneService; public Session getCurrentSession() { return entityManager.unwrap(Session.class); } @Autowired public ContractorBillRegisterService(final ContractorBillRegisterRepository contractorBillRegisterRepository, final ScriptService scriptExecutionService) { this.contractorBillRegisterRepository = contractorBillRegisterRepository; this.scriptExecutionService = scriptExecutionService; } public ContractorBillRegister getContractorBillById(final Long id) { return contractorBillRegisterRepository.findOne(id); } public Integer getMaxSequenceNumberByWorkOrder(final WorkOrderEstimate workOrderEstimate) { return contractorBillRegisterRepository.findMaxBillSequenceNumberByWorkOrder( workOrderEstimate.getEstimate().getLineEstimateDetails().getProjectCode().getCode()); } public ContractorBillRegister getContractorBillByBillNumber(final String billNumber) { return contractorBillRegisterRepository.findByBillnumber(billNumber); } @Transactional public ContractorBillRegister create(final ContractorBillRegister contractorBillRegister, final LineEstimateDetails lineEstimateDetails, final MultipartFile[] files, final Long approvalPosition, final String approvalComent, final String additionalRule, final String workFlowAction) throws IOException { contractorBillRegister.setStatus(egwStatusHibernateDAO.getStatusByModuleAndCode(WorksConstants.CONTRACTORBILL, ContractorBillRegister.BillStatus.CREATED.toString())); contractorBillRegister.setBillstatus(contractorBillRegister.getStatus().getCode()); contractorBillRegister.setExpendituretype(WorksConstants.BILL_EXPENDITURE_TYPE); final EgBillregistermis egBillRegisterMis = setEgBillRegisterMis(contractorBillRegister, lineEstimateDetails); contractorBillRegister.setEgBillregistermis(egBillRegisterMis); try { checkBudgetAndGenerateBANumber(contractorBillRegister); } catch (final ValidationException e) { throw new ValidationException(e.getErrors()); } ContractorBillRegister savedContractorBillRegister = contractorBillRegisterRepository.save(contractorBillRegister); createContractorBillRegisterWorkflowTransition(savedContractorBillRegister, approvalPosition, approvalComent, additionalRule, workFlowAction); savedContractorBillRegister = contractorBillRegisterRepository.save(contractorBillRegister); populateAndSaveMBHeader(savedContractorBillRegister); final List<DocumentDetails> documentDetails = worksUtils.getDocumentDetails(files, savedContractorBillRegister, WorksConstants.CONTRACTORBILL); if (!documentDetails.isEmpty()) { savedContractorBillRegister.setDocumentDetails(documentDetails); worksUtils.persistDocuments(documentDetails); } return savedContractorBillRegister; } @Transactional public ContractorBillRegister updateContractorBillRegister( final ContractorBillRegister contractorBillRegister, final Long approvalPosition, final String approvalComent, final String additionalRule, final String workFlowAction, final String mode, final MultipartFile[] files) throws ValidationException, IOException { ContractorBillRegister updatedContractorBillRegister = null; if (contractorBillRegister.getStatus().getCode().equals(ContractorBillRegister.BillStatus.REJECTED.toString())) { if (workFlowAction.equalsIgnoreCase(WorksConstants.FORWARD_ACTION.toString())) populateAndSaveMBHeader(contractorBillRegister); else if (workFlowAction.equalsIgnoreCase(WorksConstants.CANCEL_ACTION)) cancelMBHeader(contractorBillRegister); updatedContractorBillRegister = update(contractorBillRegister, files); contractorBillRegisterStatusChange(updatedContractorBillRegister, workFlowAction, mode); } else { contractorBillRegisterStatusChange(contractorBillRegister, workFlowAction, mode); if (workFlowAction.equalsIgnoreCase(WorksConstants.ACTION_APPROVE)) { contractorBillRegister.setApprovedDate(new Date()); contractorBillRegister.setApprovedBy(securityUtils.getCurrentUser()); contractorBillRegister.getEgBillregistermis().setSourcePath( "/egworks/contractorbill/view/" + contractorBillRegister.getId()); approveMBHeader(contractorBillRegister); } } updatedContractorBillRegister = contractorBillRegisterRepository.save(contractorBillRegister); updatedContractorBillRegister.setBillstatus(updatedContractorBillRegister.getStatus().getCode()); createContractorBillRegisterWorkflowTransition(updatedContractorBillRegister, approvalPosition, approvalComent, additionalRule, workFlowAction); updatedContractorBillRegister = contractorBillRegisterRepository.save(contractorBillRegister); return updatedContractorBillRegister; } private ContractorBillRegister update(final ContractorBillRegister contractorBillRegister, final MultipartFile[] files) throws IOException { final List<DocumentDetails> documentDetails = worksUtils.getDocumentDetails(files, contractorBillRegister, WorksConstants.CONTRACTORBILL); if (!documentDetails.isEmpty()) { contractorBillRegister.setDocumentDetails(documentDetails); worksUtils.persistDocuments(documentDetails); } return contractorBillRegisterRepository.save(contractorBillRegister); } public Set<EgBilldetails> removeDeletedBillDetails(final Set<EgBilldetails> set, final String removedBillDetailsIds) { final Set<EgBilldetails> details = new HashSet<EgBilldetails>(); if (null != removedBillDetailsIds) { final String[] ids = removedBillDetailsIds.split(","); final List<String> strList = new ArrayList<String>(); for (final String str : ids) strList.add(str); for (final EgBilldetails line : set) if (line.getId() != null) { if (!strList.contains(line.getId().toString())) details.add(line); } else details.add(line); } else return set; return details; } private EgBillregistermis setEgBillRegisterMis(final ContractorBillRegister contractorBillRegister, final LineEstimateDetails lineEstimateDetails) { final EgBillregistermis egBillRegisterMis = contractorBillRegister.getEgBillregistermis(); egBillRegisterMis.setEgBillregister(contractorBillRegister); egBillRegisterMis.setPayto(contractorBillRegister.getWorkOrder().getContractor().getName()); egBillRegisterMis.setFieldid(lineEstimateDetails.getLineEstimate().getWard()); if (lineEstimateDetails.getLineEstimate().getFund() != null) egBillRegisterMis.setFund(lineEstimateDetails.getLineEstimate().getFund()); if (lineEstimateDetails.getLineEstimate().getFunction() != null) egBillRegisterMis.setFunction(lineEstimateDetails.getLineEstimate().getFunction()); if (lineEstimateDetails.getLineEstimate().getScheme() != null) egBillRegisterMis.setScheme(lineEstimateDetails.getLineEstimate().getScheme()); if (lineEstimateDetails.getLineEstimate().getSubScheme() != null) egBillRegisterMis.setSubScheme(lineEstimateDetails.getLineEstimate().getSubScheme()); egBillRegisterMis.setEgDepartment(lineEstimateDetails.getLineEstimate().getExecutingDepartment()); final CFinancialYear financialYear = financialYearHibernateDAO .getFinancialYearByDate(contractorBillRegister.getBilldate()); egBillRegisterMis.setFinancialyear(financialYear); egBillRegisterMis.setLastupdatedtime(new Date()); return egBillRegisterMis; } public Long getApprovalPositionByMatrixDesignation(final ContractorBillRegister contractorBillRegister, Long approvalPosition, final String additionalRule, final String mode, final String workFlowAction) { final WorkFlowMatrix wfmatrix = contractorBillRegisterWorkflowService.getWfMatrix(contractorBillRegister .getStateType(), null, null, additionalRule, contractorBillRegister.getCurrentState().getValue(), null); if (contractorBillRegister.getStatus() != null && contractorBillRegister.getStatus().getCode() != null) if (contractorBillRegister.getStatus().getCode().equals(ContractorBillRegister.BillStatus.CREATED.toString()) && contractorBillRegister.getState() != null && !contractorBillRegister.getState().getHistory().isEmpty()) if (mode.equals("edit") || workFlowAction.equals(WorksConstants.REJECT_ACTION)) approvalPosition = contractorBillRegister.getState().getOwnerPosition().getId(); else approvalPosition = worksUtils.getApproverPosition(wfmatrix.getNextDesignation(), contractorBillRegister.getState(), contractorBillRegister.getCreatedBy().getId()); if (workFlowAction.equals(WorksConstants.CANCEL_ACTION) && wfmatrix.getNextState().equals(WorksConstants.WF_STATE_CREATED)) approvalPosition = null; return approvalPosition; } public void createContractorBillRegisterWorkflowTransition(final ContractorBillRegister contractorBillRegister, final Long approvalPosition, final String approvalComent, final String additionalRule, final String workFlowAction) { if (LOG.isDebugEnabled()) LOG.debug(" Create WorkFlow Transition Started ..."); final User user = securityUtils.getCurrentUser(); final DateTime currentDate = new DateTime(); Position pos = null; Assignment wfInitiator = null; final String currState = ""; final String natureOfwork = WorksConstants.WORKFLOWTYPE_CBR_DISPLAYNAME; if (null != contractorBillRegister.getId()) wfInitiator = assignmentService.getPrimaryAssignmentForUser(contractorBillRegister.getCreatedBy().getId()); if (WorksConstants.REJECT_ACTION.toString().equalsIgnoreCase(workFlowAction)) { final String stateValue = WorksConstants.WF_STATE_REJECTED; contractorBillRegister.transition(true).withSenderName(user.getUsername() + "::" + user.getName()) .withComments(approvalComent) .withStateValue(stateValue).withDateInfo(currentDate.toDate()) .withOwner(wfInitiator.getPosition()) .withNextAction("") .withNatureOfTask(natureOfwork); } else { if (null != approvalPosition && approvalPosition != -1 && !approvalPosition.equals(Long.valueOf(0))) pos = positionMasterService.getPositionById(approvalPosition); WorkFlowMatrix wfmatrix = null; if (null == contractorBillRegister.getState()) { wfmatrix = contractorBillRegisterWorkflowService.getWfMatrix(contractorBillRegister.getStateType(), null, null, additionalRule, currState, null); contractorBillRegister.transition().start().withSenderName(user.getUsername() + "::" + user.getName()) .withComments(approvalComent) .withStateValue(wfmatrix.getNextState()).withDateInfo(new Date()).withOwner(pos) .withNextAction(wfmatrix.getNextAction()) .withNatureOfTask(natureOfwork); } else if (WorksConstants.CANCEL_ACTION.toString().equalsIgnoreCase(workFlowAction)) { final String stateValue = WorksConstants.WF_STATE_CANCELLED; wfmatrix = contractorBillRegisterWorkflowService.getWfMatrix(contractorBillRegister.getStateType(), null, null, additionalRule, contractorBillRegister.getCurrentState().getValue(), null); contractorBillRegister.transition(true).withSenderName(user.getUsername() + "::" + user.getName()) .withComments(approvalComent) .withStateValue(stateValue).withDateInfo(currentDate.toDate()).withOwner(pos) .withNextAction("") .withNatureOfTask(natureOfwork); } else { wfmatrix = contractorBillRegisterWorkflowService.getWfMatrix(contractorBillRegister.getStateType(), null, null, additionalRule, contractorBillRegister.getCurrentState().getValue(), null); contractorBillRegister.transition(true).withSenderName(user.getUsername() + "::" + user.getName()) .withComments(approvalComent) .withStateValue(wfmatrix.getNextState()).withDateInfo(new Date()).withOwner(pos) .withNextAction(wfmatrix.getNextAction()) .withNatureOfTask(natureOfwork); } } if (LOG.isDebugEnabled()) LOG.debug(" WorkFlow Transition Completed ..."); } public void contractorBillRegisterStatusChange(final ContractorBillRegister contractorBillRegister, final String workFlowAction, final String mode) throws ValidationException { if (null != contractorBillRegister && null != contractorBillRegister.getStatus() && null != contractorBillRegister.getStatus().getCode()) if (contractorBillRegister.getStatus().getCode().equals(ContractorBillRegister.BillStatus.CREATED.toString()) && contractorBillRegister.getState() != null && workFlowAction.equalsIgnoreCase(WorksConstants.ACTION_APPROVE)) contractorBillRegister.setStatus(egwStatusHibernateDAO.getStatusByModuleAndCode(WorksConstants.CONTRACTORBILL, ContractorBillRegister.BillStatus.APPROVED.toString())); else if (workFlowAction.equals(WorksConstants.REJECT_ACTION)) contractorBillRegister.setStatus(egwStatusHibernateDAO.getStatusByModuleAndCode(WorksConstants.CONTRACTORBILL, ContractorBillRegister.BillStatus.REJECTED.toString())); else if (contractorBillRegister.getStatus().getCode() .equals(ContractorBillRegister.BillStatus.REJECTED.toString()) && workFlowAction.equals(WorksConstants.CANCEL_ACTION)) contractorBillRegister.setStatus(egwStatusHibernateDAO.getStatusByModuleAndCode(WorksConstants.CONTRACTORBILL, ContractorBillRegister.BillStatus.CANCELLED.toString())); else if (contractorBillRegister.getStatus().getCode() .equals(ContractorBillRegister.BillStatus.REJECTED.toString()) && workFlowAction.equals(WorksConstants.FORWARD_ACTION)) contractorBillRegister.setStatus(egwStatusHibernateDAO.getStatusByModuleAndCode(WorksConstants.CONTRACTORBILL, ContractorBillRegister.BillStatus.CREATED.toString())); } public List<ContractorBillRegister> searchContractorBill(final SearchRequestContractorBill searchRequestContractorBill) { // TODO Need TO handle in single query final Criteria criteria = entityManager.unwrap(Session.class).createCriteria(ContractorBillRegister.class) .createAlias("workOrder", "cbrwo") .createAlias("cbrwo.contractor", "cbrwocont"); if (searchRequestContractorBill != null) { if (searchRequestContractorBill.getBillFromDate() != null) criteria.add(Restrictions.ge("billdate", searchRequestContractorBill.getBillFromDate())); if (searchRequestContractorBill.getBillToDate() != null) criteria.add(Restrictions.le("billdate", searchRequestContractorBill.getBillToDate())); if (searchRequestContractorBill.getBillType() != null) criteria.add(Restrictions.eq("billtype", searchRequestContractorBill.getBillType())); if (searchRequestContractorBill.getBillNumber() != null) criteria.add(Restrictions.ilike("billnumber", searchRequestContractorBill.getBillNumber(), MatchMode.ANYWHERE)); if (searchRequestContractorBill.getStatus() != null) criteria.add(Restrictions.eq("billstatus", searchRequestContractorBill.getStatus())); if (searchRequestContractorBill.getWorkIdentificationNumber() != null) { final List<String> estimateNumbersforWIN = lineEstimateService .getEstimateNumbersForWorkIdentificationNumber(searchRequestContractorBill.getWorkIdentificationNumber()); if (estimateNumbersforWIN.isEmpty()) estimateNumbersforWIN.add(""); criteria.add(Restrictions.in("cbrwo.estimateNumber", estimateNumbersforWIN)); } if (searchRequestContractorBill.getContractorName() != null) criteria.add(Restrictions.eq("cbrwocont.name", searchRequestContractorBill.getContractorName()).ignoreCase()); if (searchRequestContractorBill.getDepartment() != null) { final List<String> estimateNumbers = lineEstimateService .getEstimateNumberForDepartment(searchRequestContractorBill.getDepartment()); if (estimateNumbers.isEmpty()) estimateNumbers.add(""); criteria.add(Restrictions.in("cbrwo.estimateNumber", estimateNumbers)); } if (searchRequestContractorBill.isSpillOverFlag()) { final List<String> estimateNumbersforSpillOverFlag = lineEstimateService .getEstimateNumbersForSpillOverFlag(searchRequestContractorBill.isSpillOverFlag()); criteria.add(Restrictions.in("cbrwo.estimateNumber", estimateNumbersforSpillOverFlag)); } } criteria.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY); return criteria.list(); } public List<String> findWorkIdentificationNumbersToSearchContractorBill(final String code) { final List<String> workIdNumbers = contractorBillRegisterRepository .findWorkIdentificationNumberToSearchContractorBill("%" + code + "%"); return workIdNumbers; } public List<String> getApprovedContractorsForCreateContractorBill(final String contractorname) { final List<String> results = contractorBillRegisterRepository.findContractorForContractorBill("%" + contractorname + "%", WorksConstants.APPROVED); return results; } public BigDecimal getTotalBillAmountByWorkOrder(final WorkOrder workOrder) { return contractorBillRegisterRepository.findSumOfBillAmountByWorkOrderAndStatus(workOrder, ContractorBillRegister.BillStatus.CANCELLED.toString()); } public ContractorBillRegister checkBudgetAndGenerateBANumber(final ContractorBillRegister contractorBill) { final ScriptContext scriptContext = ScriptService.createContext("voucherService", voucherService, "bill", contractorBill); scriptExecutionService.executeScript("egf.bill.budgetcheck", scriptContext); return contractorBill; } private void populateAndSaveMBHeader(final ContractorBillRegister contractorBillRegister) { final MBHeader mbHeader = contractorBillRegister.getMbHeader(); MBHeader existingMBHeader = null; if (contractorBillRegister.getMbHeader() != null && contractorBillRegister.getMbHeader().getId() != null) existingMBHeader = mbHeaderService.getMBHeaderById(contractorBillRegister.getMbHeader().getId()); if (existingMBHeader != null) { mbHeader.setCreatedBy(existingMBHeader.getCreatedBy()); mbHeader.setCreatedDate(existingMBHeader.getCreatedDate()); } mbHeader.setMbAmount(contractorBillRegister.getBillamount()); mbHeader.setEgwStatus(egwStatusHibernateDAO.getStatusByModuleAndCode(WorksConstants.MBHEADER, MBHeader.MeasurementBookStatus.CREATED.toString())); mbHeader.setEgBillregister(contractorBillRegister); mbHeader.setWorkOrderEstimate(contractorBillRegister.getWorkOrderEstimate()); mbHeaderService.create(mbHeader); } private void approveMBHeader(final ContractorBillRegister contractorBillRegister) { final MBHeader mbHeader = mbHeaderService.getMBHeaderById(contractorBillRegister.getMbHeader().getId()); mbHeader.setEgwStatus(egwStatusHibernateDAO.getStatusByModuleAndCode(WorksConstants.MBHEADER, MBHeader.MeasurementBookStatus.APPROVED.toString())); mbHeaderService.create(mbHeader); } private void cancelMBHeader(final ContractorBillRegister contractorBillRegister) { final MBHeader mbHeader = mbHeaderService.getMBHeaderById(contractorBillRegister.getMbHeader().getId()); mbHeaderService.cancel(mbHeader); } public BigDecimal getTotalBillAmountByWorkOrderAndNotContractorBillRegister(final WorkOrder workOrder, final Long id) { return contractorBillRegisterRepository.findSumOfBillAmountByWorkOrderAndStatusAndNotContractorBillRegister(workOrder, ContractorBillRegister.BillStatus.CANCELLED.toString(), id); } public List<ContractorBillRegister> searchContractorBillsToCancel( final SearchRequestContractorBill searchRequestContractorBill) { // TODO Need TO handle in single query final Criteria criteria = entityManager.unwrap(Session.class).createCriteria(ContractorBillRegister.class) .createAlias("workOrder", "cbrwo") .createAlias("cbrwo.contractor", "cbrwocont"); if (searchRequestContractorBill != null) { if (searchRequestContractorBill.getBillNumber() != null) criteria.add(Restrictions.ilike("billnumber", searchRequestContractorBill.getBillNumber(), MatchMode.ANYWHERE)); if (searchRequestContractorBill.getStatus() != null) criteria.add(Restrictions.eq("billstatus", searchRequestContractorBill.getStatus())); if (searchRequestContractorBill.getWorkIdentificationNumber() != null) { final List<String> estimateNumbersforWIN = lineEstimateService .getEstimateNumbersForWorkIdentificationNumber(searchRequestContractorBill.getWorkIdentificationNumber()); if (estimateNumbersforWIN.isEmpty()) estimateNumbersforWIN.add(""); criteria.add(Restrictions.in("cbrwo.estimateNumber", estimateNumbersforWIN)); } if (searchRequestContractorBill.getDepartment() != null) { final List<String> estimateNumbers = lineEstimateService .getEstimateNumberForDepartment(searchRequestContractorBill.getDepartment()); if (estimateNumbers.isEmpty()) estimateNumbers.add(""); criteria.add(Restrictions.in("cbrwo.estimateNumber", estimateNumbers)); } if (searchRequestContractorBill.getWorkOrderNumber() != null) { final List<String> workOrderNumbers = contractorBillRegisterRepository .findWorkOrderNumbersToCancel("%" + searchRequestContractorBill.getWorkOrderNumber() + "%", ContractorBillRegister.BillStatus.APPROVED.toString()); if (workOrderNumbers.isEmpty()) workOrderNumbers.add(""); criteria.add(Restrictions.in("cbrwo.workOrderNumber", workOrderNumbers)); } } criteria.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY); return criteria.list(); } public List<String> findWorkIdentificationNumbersToSearchContractorBillToCancel(final String code) { final List<String> workIdNumbers = contractorBillRegisterRepository .findWorkIdentificationNumberToSearchContractorBillToCancel("%" + code + "%", ContractorBillRegister.BillStatus.APPROVED.toString()); return workIdNumbers; } public List<String> findBillNumbersToSearchContractorBillToCancel(final String billNumber) { final List<String> workIdNumbers = contractorBillRegisterRepository .findBillNumberToSearchContractorBillToCancel("%" + billNumber + "%", ContractorBillRegister.BillStatus.APPROVED.toString()); return workIdNumbers; } @Transactional public ContractorBillRegister cancel(final ContractorBillRegister contractorBillRegister) { contractorBillRegister.setStatus(egwStatusHibernateDAO.getStatusByModuleAndCode(WorksConstants.CONTRACTORBILL, ContractorBillRegister.BillStatus.CANCELLED.toString())); contractorBillRegister.setBillstatus(ContractorBillRegister.BillStatus.CANCELLED.toString()); final List<MBHeader> mbHeaders = mbHeaderService.getMBHeadersByContractorBill(contractorBillRegister); for (final MBHeader mbHeader : mbHeaders) mbHeaderService.cancel(mbHeader); return contractorBillRegisterRepository.save(contractorBillRegister); } public EgBillPayeedetails getEgPayeeDetails(final EgBilldetails billDetails, final Integer accountsDetailTypeId, final BigDecimal amount, final boolean isDebit, final Integer accountsDetailKeyId) { final EgBillPayeedetails egBillPaydetail = new EgBillPayeedetails(); egBillPaydetail.setAccountDetailKeyId(accountsDetailKeyId); egBillPaydetail.setAccountDetailTypeId(accountsDetailTypeId); if (isDebit) egBillPaydetail.setDebitAmount(amount); else egBillPaydetail.setCreditAmount(amount); egBillPaydetail.setEgBilldetailsId(billDetails); egBillPaydetail.setLastUpdatedTime(new Date()); return egBillPaydetail; } public List<Map<String, Object>> getBillDetailsMap(final ContractorBillRegister contractorBillRegister, final Model model) { final List<Map<String, Object>> billDetailsList = new ArrayList<Map<String, Object>>(); Map<String, Object> billDetails = new HashMap<String, Object>(); final List<CChartOfAccounts> contractorPayableAccountList = chartOfAccountsHibernateDAO .getAccountCodeByPurposeName(WorksConstants.CONTRACTOR_NETPAYABLE_PURPOSE); final List<CChartOfAccounts> contractorRefundAccountList = chartOfAccountsHibernateDAO .getAccountCodeByListOfPurposeName(WorksConstants.CONTRACTOR_REFUND_PURPOSE); for (final EgBilldetails egBilldetails : contractorBillRegister.getEgBilldetailes()) { final CChartOfAccounts coa = chartOfAccountsHibernateDAO .findById(egBilldetails.getGlcodeid().longValue(), false); if (egBilldetails.getDebitamount() != null) { billDetails = new HashMap<String, Object>(); billDetails.put("id", egBilldetails.getId()); billDetails.put("glcodeId", coa.getId()); billDetails.put("glcode", coa.getGlcode()); billDetails.put("accountHead", coa.getName()); billDetails.put("amount", egBilldetails.getDebitamount()); billDetails.put("isDebit", true); billDetails.put("isNetPayable", false); if (!contractorRefundAccountList.isEmpty() && contractorRefundAccountList.contains(coa)) { final String amounts = getTotalDebitAndCreditAmountByAccountCode( contractorBillRegister.getWorkOrderEstimate().getId(), new BigDecimal(coa.getId()), contractorBillRegister.getId() != null ? contractorBillRegister.getId() : -1); final String[] creditDebitAmounts = amounts.split(","); billDetails.put("withHeldAmount", creditDebitAmounts[0]); billDetails.put("RefundedAmount", creditDebitAmounts[1]); billDetails.put("isRefund", true); } else billDetails.put("isRefund", false); } else if (egBilldetails.getCreditamount() != null) { billDetails = new HashMap<String, Object>(); billDetails.put("id", egBilldetails.getId()); billDetails.put("glcodeId", coa.getId()); billDetails.put("glcode", coa.getGlcode()); billDetails.put("accountHead", coa.getName()); billDetails.put("amount", egBilldetails.getCreditamount()); billDetails.put("isDebit", false); if (contractorPayableAccountList != null && !contractorPayableAccountList.isEmpty() && contractorPayableAccountList.contains(coa)) { billDetails.put("isNetPayable", true); model.addAttribute("netPayableAccountId", egBilldetails.getId()); model.addAttribute("netPayableAccountCode", coa.getId()); model.addAttribute("netPayableAmount", egBilldetails.getCreditamount()); } else billDetails.put("isNetPayable", false); } billDetailsList.add(billDetails); } return billDetailsList; } public boolean checkForDuplicateAccountCodes(final ContractorBillRegister contractorBillRegister) { final Set<Long> glCodeIdSet = new HashSet<Long>(); for (final EgBilldetails egBilldetails : contractorBillRegister.getEgBilldetailes()) if (egBilldetails.getGlcodeid() != null && !contractorBillRegister.getRefundBillDetails().contains(egBilldetails)) { if (glCodeIdSet.contains(egBilldetails.getGlcodeid().longValue())) return false; glCodeIdSet.add(egBilldetails.getGlcodeid().longValue()); } return true; } public boolean validateDuplicateRefundAccountCodes(final ContractorBillRegister contractorBillRegister) { final Set<Long> glCodeIdSet = new HashSet<Long>(); for (final EgBilldetails egBilldetails : contractorBillRegister.getEgBilldetailes()) if (egBilldetails.getGlcodeid() != null && egBilldetails.getDebitamount() != null) { if (glCodeIdSet.contains(egBilldetails.getGlcodeid().longValue())) return false; glCodeIdSet.add(egBilldetails.getGlcodeid().longValue()); } return true; } public void validateTotalDebitAndCreditAmount(final ContractorBillRegister contractorBillRegister, final BindingResult resultBinder) { BigDecimal totalDebitAmount = BigDecimal.ZERO; BigDecimal totalCreditAmount = BigDecimal.ZERO; for (final EgBilldetails egBilldetails : contractorBillRegister.getEgBilldetailes()) { if (egBilldetails.getDebitamount() != null && !(BigDecimal.ZERO.compareTo(egBilldetails.getDebitamount()) == 0)) totalDebitAmount = totalDebitAmount.add(egBilldetails.getDebitamount()); if (egBilldetails.getCreditamount() != null && !(BigDecimal.ZERO.compareTo(egBilldetails.getCreditamount()) == 0)) totalCreditAmount = totalCreditAmount.add(egBilldetails.getCreditamount()); } if (!(totalDebitAmount.compareTo(totalCreditAmount) == 0)) resultBinder.reject("error.total.debitamount.creditamount.notequal", "error.total.debitamount.creditamount.notequal"); } public void validateRefundAmount(final ContractorBillRegister contractorBillRegister, final BindingResult resultBinder) { int index = 0; for (final EgBilldetails egBillDetail : contractorBillRegister.getRefundBillDetails()) { if (egBillDetail.getGlcodeid() != null && egBillDetail.getDebitamount() == null) resultBinder.rejectValue("refundBillDetails[" + index + "].debitamount", "error.refundamount.required"); if (egBillDetail.getDebitamount() != null && egBillDetail.getGlcodeid() == null) resultBinder.rejectValue("refundBillDetails[" + index + "].glcodeid", "error.refundaccountcode.required"); if (egBillDetail.getGlcodeid() != null && egBillDetail.getDebitamount() != null) { final CChartOfAccounts coa = chartOfAccountsHibernateDAO .findById(egBillDetail.getGlcodeid().longValue(), false); final String amounts = getTotalDebitAndCreditAmountByAccountCode( contractorBillRegister.getWorkOrderEstimate().getId(), new BigDecimal(coa.getId()), contractorBillRegister.getId() != null ? contractorBillRegister.getId() : -1); if (!org.apache.commons.lang.StringUtils.isBlank(amounts)) { final String[] creditDebitAmounts = amounts.split(","); BigDecimal withheldAmount = BigDecimal.ZERO; BigDecimal refundedAmount = BigDecimal.ZERO; if (!creditDebitAmounts[0].equals("0")) withheldAmount = new BigDecimal(creditDebitAmounts[0]); if (!creditDebitAmounts[1].equals("0")) refundedAmount = new BigDecimal(creditDebitAmounts[1]); if (withheldAmount.equals("0")) resultBinder.reject("error.contractorBill.nowithheldtorefund", new String[] { coa.getGlcode() }, null); else { final BigDecimal validRefundAmount = egBillDetail.getDebitamount().add(refundedAmount); final BigDecimal diffAmount = validRefundAmount.subtract(withheldAmount); if (validRefundAmount.compareTo(new BigDecimal(creditDebitAmounts[0])) == 1 && !contractorBillRegister.getWorkOrderEstimate().getEstimate().getLineEstimateDetails() .getLineEstimate().isSpillOverFlag()) resultBinder.reject("error.contractorBill.validate.refundAmount", new String[] { coa.getGlcode(), diffAmount.toString() }, null); } } } index++; } } public EgBilldetails getBillDetails(final ContractorBillRegister billregister, final EgBilldetails egBilldetails, final LineEstimateDetails lineEstimateDetails, final BindingResult resultBinder, final HttpServletRequest request) { egBilldetails.setFunctionid(new BigDecimal(lineEstimateDetails.getLineEstimate().getFunction().getId())); boolean isDebit = false; CChartOfAccounts coa = null; if (!(BigDecimal.ZERO.compareTo(egBilldetails.getGlcodeid()) == 0)) coa = chartOfAccountsHibernateDAO.findById(egBilldetails.getGlcodeid().longValue(), false); if (coa != null && coa.getId() != null) egBilldetails.setGlcodeid(BigDecimal.valueOf(coa.getId())); if (egBilldetails.getDebitamount() != null && !(BigDecimal.ZERO.compareTo(egBilldetails.getDebitamount()) == 0)) { egBilldetails.setDebitamount(egBilldetails.getDebitamount()); isDebit = true; } else if (egBilldetails.getCreditamount() != null && !(BigDecimal.ZERO.compareTo(egBilldetails.getCreditamount()) == 0)) egBilldetails.setCreditamount(egBilldetails.getCreditamount()); else if (!org.apache.commons.lang.StringUtils.isBlank(request.getParameter("netPayableAccountCode")) && request.getParameter("netPayableAccountCode").toString().equals(egBilldetails.getGlcodeid())) resultBinder.reject("error.contractorbill.accountdetails.amount.required", "error.contractorbill.accountdetails.amount.required"); egBilldetails.setEgBillregister(billregister); final List<CChartOfAccounts> contractorRefundAccountList = chartOfAccountsHibernateDAO .getAccountCodeByListOfPurposeName(WorksConstants.CONTRACTOR_REFUND_PURPOSE); if (coa != null && coa.getGlcode() != null) { Accountdetailtype projectCodeAccountDetailType = null; Accountdetailtype contractorAccountDetailType = null; if (isDebit && !contractorRefundAccountList.isEmpty() && !contractorRefundAccountList.contains(coa)) { projectCodeAccountDetailType = chartOfAccountsHibernateDAO.getAccountDetailTypeIdByName(coa.getGlcode(), WorksConstants.PROJECTCODE); if (projectCodeAccountDetailType == null) resultBinder.reject("error.contractorBill.validate.glcode.for.projectcode.subledger", new String[] { coa.getGlcode() }, null); } final List<Accountdetailtype> detailCode = chartOfAccountsHibernateDAO .getAccountdetailtypeListByGLCode(coa.getGlcode()); if (detailCode != null && !detailCode.isEmpty()) { if (isDebit && !contractorRefundAccountList.isEmpty() && !contractorRefundAccountList.contains(coa)) { if (projectCodeAccountDetailType != null) egBilldetails.addEgBillPayeedetail(getEgPayeeDetails(egBilldetails, projectCodeAccountDetailType.getId(), egBilldetails.getDebitamount(), isDebit, Integer.valueOf(lineEstimateDetails.getProjectCode().getId().toString()))); } else { contractorAccountDetailType = chartOfAccountsHibernateDAO.getAccountDetailTypeIdByName( coa.getGlcode(), WorksConstants.ACCOUNTDETAIL_TYPE_CONTRACTOR); if (contractorAccountDetailType != null) egBilldetails.getEgBillPaydetailes().add(getEgPayeeDetails(egBilldetails, contractorAccountDetailType.getId(), isDebit ? egBilldetails.getDebitamount() : egBilldetails.getCreditamount(), isDebit, Integer.valueOf(billregister.getWorkOrder().getContractor().getId().toString()))); } if (projectCodeAccountDetailType == null && contractorAccountDetailType == null) resultBinder.reject("error.contractorbill.validate.glcode.for.subledger", new String[] { coa.getGlcode() }, null); } } egBilldetails.setLastupdatedtime(new Date()); return egBilldetails; } public String getTotalDebitAndCreditAmountByAccountCode(final Long workOrderEstimateId, final BigDecimal glCodeId, final Long contractorBillId) { return contractorBillRegisterRepository.findSumOfDebitByAccountCodeForWorkOrder(workOrderEstimateId, glCodeId, ContractorBillRegister.BillStatus.APPROVED.toString(), contractorBillId); } public void validateMileStonePercentage(final ContractorBillRegister contractorBillRegister, final BindingResult resultBinder) { TrackMilestone trackMileStone = null; if (contractorBillRegister.getBilltype().equalsIgnoreCase(BillTypes.Final_Bill.toString())) { trackMileStone = trackMilestoneService .getCompletionPercentageToCreateContractorFinalBill(contractorBillRegister.getWorkOrderEstimate().getId()); if (trackMileStone == null) resultBinder.reject("error.contractor.finalbill.milestonepercentage", "error.contractor.finalbill.milestonepercentage"); } else { trackMileStone = trackMilestoneService .getMinimumPercentageToCreateContractorBill(contractorBillRegister.getWorkOrderEstimate().getId()); if (trackMileStone == null) resultBinder.reject("error.contractorbil.milestone.percentage", "error.contractorbil.milestone.percentage"); } } public void validateZeroCreditAndDebitAmount(final ContractorBillRegister contractorBillRegister, final BindingResult resultBinder) { for (final EgBilldetails egBillDetail : contractorBillRegister.getEgBilldetailes()) if (egBillDetail.getCreditamount() != null && BigDecimal.ZERO.compareTo(egBillDetail.getCreditamount()) == 0 || egBillDetail.getDebitamount() != null && BigDecimal.ZERO.compareTo(egBillDetail.getDebitamount()) == 0) { resultBinder.reject("error.creditordebitamount.zero", "error.creditordebitamount.zero"); break; } } }