/*
* 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.web.controller.contractorbill;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import org.apache.commons.lang3.StringUtils;
import org.egov.commons.CChartOfAccounts;
import org.egov.commons.dao.ChartOfAccountsHibernateDAO;
import org.egov.eis.web.contract.WorkflowContainer;
import org.egov.eis.web.controller.workflow.GenericWorkFlowController;
import org.egov.infra.admin.master.service.DepartmentService;
import org.egov.infra.exception.ApplicationException;
import org.egov.infra.exception.ApplicationRuntimeException;
import org.egov.infra.validation.exception.ValidationException;
import org.egov.model.bills.EgBilldetails;
import org.egov.works.contractorbill.entity.ContractorBillRegister;
import org.egov.works.contractorbill.entity.enums.BillTypes;
import org.egov.works.contractorbill.service.ContractorBillRegisterService;
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.models.measurementbook.MBHeader;
import org.egov.works.models.workorder.WorkOrder;
import org.egov.works.utils.WorksConstants;
import org.egov.works.utils.WorksUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
@Controller
@RequestMapping(value = "/contractorbill")
public class UpdateContractorBillController extends GenericWorkFlowController {
@Autowired
private LineEstimateService lineEstimateService;
@Autowired
private DepartmentService departmentService;
@Autowired
private WorksUtils worksUtils;
@Autowired
private ContractorBillRegisterService contractorBillRegisterService;
@Autowired
private ChartOfAccountsHibernateDAO chartOfAccountsHibernateDAO;
@Autowired
private MBHeaderService mbHeaderService;
@ModelAttribute
public ContractorBillRegister getContractorBillRegister(@PathVariable final String contractorBillRegisterId) {
final ContractorBillRegister contractorBillRegister = contractorBillRegisterService
.getContractorBillById(Long.parseLong(contractorBillRegisterId));
return contractorBillRegister;
}
@RequestMapping(value = "/update/{contractorBillRegisterId}", method = RequestMethod.GET)
public String updateContractorBillRegister(final Model model, @PathVariable final String contractorBillRegisterId,
final HttpServletRequest request) throws ApplicationException {
final ContractorBillRegister contractorBillRegister = getContractorBillRegister(contractorBillRegisterId);
// if
// (contractorBillRegister.getStatus().getCode().equals(ContractorBillRegister.BillStatus.REJECTED.toString()))
setDropDownValues(model);
model.addAttribute("createdbybydesignation",
worksUtils.getUserDesignation(contractorBillRegister.getCreatedBy()));
return loadViewData(model, request, contractorBillRegister);
}
@RequestMapping(value = "/update/{contractorBillRegisterId}", method = RequestMethod.POST)
public String update(@Valid @ModelAttribute("contractorBillRegister") ContractorBillRegister contractorBillRegister,
final BindingResult errors, final RedirectAttributes redirectAttributes, final Model model,
final HttpServletRequest request, @RequestParam("file") final MultipartFile[] files)
throws ApplicationException, IOException {
String mode = "";
String workFlowAction = "";
ContractorBillRegister updatedContractorBillRegister = null;
if (request.getParameter("mode") != null)
mode = request.getParameter("mode");
if (request.getParameter("workFlowAction") != null)
workFlowAction = request.getParameter("workFlowAction");
Long approvalPosition = 0l;
String approvalComment = "";
if (request.getParameter("approvalComent") != null)
approvalComment = request.getParameter("approvalComent");
if (request.getParameter("approvalPosition") != null && !request.getParameter("approvalPosition").isEmpty())
approvalPosition = Long.valueOf(request.getParameter("approvalPosition"));
// For Get Configured ApprovalPosition from workflow history
if (approvalPosition == null || approvalPosition.equals(Long.valueOf(0)))
approvalPosition = contractorBillRegisterService.getApprovalPositionByMatrixDesignation(
contractorBillRegister, approvalPosition, null, mode, workFlowAction);
if ((approvalPosition == null || approvalPosition.equals(Long.valueOf(0)))
&& request.getParameter("approvalPosition") != null
&& !request.getParameter("approvalPosition").isEmpty())
approvalPosition = Long.valueOf(request.getParameter("approvalPosition"));
try {
if (contractorBillRegister.getStatus().getCode()
.equals(ContractorBillRegister.BillStatus.REJECTED.toString())
&& workFlowAction.equals(WorksConstants.FORWARD_ACTION))
contractorBillRegisterService.checkBudgetAndGenerateBANumber(contractorBillRegister);
} catch (final ValidationException e) {
// TODO: Used ApplicationRuntimeException for time being since there
// is issue in session after
// checkBudgetAndGenerateBANumber API call. Needs to replace with
// errors.reject
throw new ApplicationRuntimeException("error.contractorbill.budgetcheck.insufficient.amount");
/*
* for (final ValidationError error : e.getErrors()) { if(error.getMessage().contains("Budget Check failed for ")) {
* errors.reject(messageSource.getMessage( "error.contractorbill.budgetcheck.insufficient.amount",null,null) +". "
* +error.getMessage()); } else errors.reject(error.getMessage()); }
*/
}
if (contractorBillRegister.getStatus().getCode().equals(ContractorBillRegister.BillStatus.REJECTED.toString())
&& workFlowAction.equals(WorksConstants.FORWARD_ACTION) && mode.equals("edit")) {
final WorkOrder workOrder = contractorBillRegister.getWorkOrder();
final LineEstimateDetails lineEstimateDetails = lineEstimateService
.findByEstimateNumber(workOrder.getEstimateNumber());
validateInput(contractorBillRegister, lineEstimateDetails, errors, request);
contractorBillRegister.getEgBilldetailes().clear();
contractorBillRegister = addBillDetails(contractorBillRegister, lineEstimateDetails, errors, request);
contractorBillRegister.setPassedamount(contractorBillRegister.getBillamount());
if (!contractorBillRegisterService.checkForDuplicateAccountCodes(contractorBillRegister))
errors.reject("error.contractorbill.duplicate.accountcodes", "error.contractorbill.duplicate.accountcodes");
if (!contractorBillRegisterService.validateDuplicateRefundAccountCodes(contractorBillRegister))
errors.reject("error.contractorbill.duplicate.refund.accountcodes",
"error.contractorbill.duplicate.refund.accountcodes");
contractorBillRegisterService.validateTotalDebitAndCreditAmount(contractorBillRegister, errors);
contractorBillRegisterService.validateRefundAmount(contractorBillRegister, errors);
contractorBillRegisterService.validateMileStonePercentage(contractorBillRegister, errors);
}
if (errors.hasErrors()) {
setDropDownValues(model);
return loadViewData(model, request, contractorBillRegister);
} else {
if (null != workFlowAction)
updatedContractorBillRegister = contractorBillRegisterService.updateContractorBillRegister(
contractorBillRegister, approvalPosition, approvalComment, null, workFlowAction, mode, files);
redirectAttributes.addFlashAttribute("contractorBillRegister", updatedContractorBillRegister);
final String pathVars = worksUtils.getPathVars(updatedContractorBillRegister.getStatus(),
updatedContractorBillRegister.getState(), updatedContractorBillRegister.getId(), approvalPosition);
return "redirect:/contractorbill/contractorbill-success?pathVars=" + pathVars + "&billNumber="
+ updatedContractorBillRegister.getBillnumber();
}
}
private void validateInput(final ContractorBillRegister contractorBillRegister,
final LineEstimateDetails lineEstimateDetails, final BindingResult resultBinder,
final HttpServletRequest request) {
BigDecimal totalBillAmountIncludingCurrentBill = contractorBillRegister.getBillamount();
final BigDecimal totalBillAmount = contractorBillRegisterService
.getTotalBillAmountByWorkOrderAndNotContractorBillRegister(contractorBillRegister.getWorkOrder(),
contractorBillRegister.getId());
if (totalBillAmount != null)
totalBillAmountIncludingCurrentBill = totalBillAmountIncludingCurrentBill.add(totalBillAmount);
if (lineEstimateDetails.getLineEstimate().isBillsCreated()
&& lineEstimateDetails.getGrossAmountBilled() != null)
totalBillAmountIncludingCurrentBill = totalBillAmountIncludingCurrentBill
.add(lineEstimateDetails.getGrossAmountBilled());
if (totalBillAmountIncludingCurrentBill.doubleValue() > contractorBillRegister.getWorkOrder()
.getWorkOrderAmount())
resultBinder.reject("error.contractorbill.totalbillamount.exceeds.workorderamount",
new String[] { String.valueOf(totalBillAmountIncludingCurrentBill),
String.valueOf(contractorBillRegister.getWorkOrder().getWorkOrderAmount()) },
null);
if (StringUtils.isBlank(contractorBillRegister.getBilltype()))
resultBinder.rejectValue("billtype", "error.billtype.required");
if (contractorBillRegister.getEgBillregistermis() != null
&& contractorBillRegister.getEgBillregistermis().getPartyBillDate() != null
&& contractorBillRegister.getEgBillregistermis().getPartyBillDate()
.before(contractorBillRegister.getWorkOrder().getWorkOrderDate()))
resultBinder.rejectValue("egBillregistermis.partyBillDate",
"error.validate.partybilldate.lessthan.loadate");
if (contractorBillRegister.getMbHeader() != null) {
if (StringUtils.isBlank(contractorBillRegister.getMbHeader().getMbRefNo()))
resultBinder.rejectValue("mbHeader.mbRefNo", "error.mbrefno.required");
if (contractorBillRegister.getMbHeader().getMbDate() == null)
resultBinder.rejectValue("mbHeader.mbDate", "error.mbdate.required");
if (contractorBillRegister.getMbHeader().getFromPageNo() == null)
resultBinder.rejectValue("mbHeader.fromPageNo", "error.frompageno.required");
if (contractorBillRegister.getMbHeader().getToPageNo() == null)
resultBinder.rejectValue("mbHeader.toPageNo", "error.topageno.required");
if (contractorBillRegister.getMbHeader().getFromPageNo() == 0
|| contractorBillRegister.getMbHeader().getToPageNo() == 0)
resultBinder.reject("error.validate.mb.pagenumbers.zero", "error.validate.mb.pagenumbers.zero");
if (contractorBillRegister.getMbHeader().getFromPageNo() != null
&& contractorBillRegister.getMbHeader().getToPageNo() != null && contractorBillRegister
.getMbHeader().getFromPageNo() > contractorBillRegister.getMbHeader().getToPageNo())
resultBinder.reject("error.validate.mb.frompagenumber.greaterthan.topagenumber",
"error.validate.mb.frompagenumber.greaterthan.topagenumber");
if (contractorBillRegister.getMbHeader().getMbDate() != null && contractorBillRegister.getMbHeader()
.getMbDate().before(contractorBillRegister.getWorkOrder().getWorkOrderDate()))
resultBinder.rejectValue("mbHeader.mbDate", "error.validate.mbdate.lessthan.loadate");
}
if (StringUtils.isBlank(request.getParameter("netPayableAccountCode")))
resultBinder.reject("error.netpayable.accountcode.required", "error.netpayable.accountcode.required");
if (StringUtils.isBlank(request.getParameter("netPayableAmount"))
|| Double.valueOf(request.getParameter("netPayableAmount").toString()) <= 0)
resultBinder.reject("error.netpayable.amount.required", "error.netpayable.amount.required");
if (contractorBillRegister.getBilltype().equals(BillTypes.Final_Bill.toString())
&& contractorBillRegister.getWorkOrderEstimate().getWorkCompletionDate() == null)
resultBinder.rejectValue("workOrderEstimate.workCompletionDate", "error.workcompletiondate.required");
final Date currentDate = new Date();
final Date workCompletionDate = contractorBillRegister.getWorkOrderEstimate().getWorkCompletionDate();
if (workCompletionDate != null) {
if (workCompletionDate.after(currentDate))
resultBinder.rejectValue("workOrderEstimate.workCompletionDate", "error.workcompletiondate.futuredate");
if (workCompletionDate
.before(contractorBillRegister.getWorkOrderEstimate().getWorkOrder().getWorkOrderDate()))
resultBinder.rejectValue("workOrderEstimate.workCompletionDate",
"error.workcompletiondate.workorderdate");
if (workCompletionDate.after(contractorBillRegister.getBilldate()))
resultBinder.rejectValue("workOrderEstimate.workCompletionDate", "error.workcompletiondate.billdate");
}
}
private void setDropDownValues(final Model model) {
final List<CChartOfAccounts> contractorPayableAccountList = chartOfAccountsHibernateDAO
.getAccountCodeByPurposeName(WorksConstants.CONTRACTOR_NETPAYABLE_PURPOSE);
final List<CChartOfAccounts> contractorRefundAccountList = chartOfAccountsHibernateDAO
.getAccountCodeByListOfPurposeName(WorksConstants.CONTRACTOR_REFUND_PURPOSE);
model.addAttribute("netPayableAccounCodes", contractorPayableAccountList);
model.addAttribute("refundAccounCodes", contractorRefundAccountList);
model.addAttribute("billTypes", BillTypes.values());
}
private String loadViewData(final Model model, final HttpServletRequest request,
final ContractorBillRegister contractorBillRegister) {
model.addAttribute("stateType", contractorBillRegister.getClass().getSimpleName());
if (contractorBillRegister.getState() != null)
model.addAttribute("currentState", contractorBillRegister.getState().getValue());
prepareWorkflow(model, contractorBillRegister, new WorkflowContainer());
if (contractorBillRegister.getState() != null
&& contractorBillRegister.getState().getValue().equals(WorksConstants.WF_STATE_REJECTED))
model.addAttribute("mode", "edit");
else
model.addAttribute("mode", "view");
model.addAttribute("billDetailsMap", contractorBillRegisterService.getBillDetailsMap(contractorBillRegister, model));
model.addAttribute("workflowHistory", lineEstimateService.getHistory(contractorBillRegister.getState(),
contractorBillRegister.getStateHistory()));
model.addAttribute("approvalDepartmentList", departmentService.getAllDepartments());
model.addAttribute("approvalDesignation", request.getParameter("approvalDesignation"));
model.addAttribute("approvalPosition", request.getParameter("approvalPosition"));
final WorkOrder workOrder = contractorBillRegister.getWorkOrder();
final LineEstimateDetails lineEstimateDetails = lineEstimateService
.findByEstimateNumber(workOrder.getEstimateNumber());
model.addAttribute("lineEstimateDetails", lineEstimateDetails);
model.addAttribute("workOrder", workOrder);
final ContractorBillRegister newcontractorBillRegister = getContractorBillDocuments(contractorBillRegister);
model.addAttribute("contractorBillRegister", newcontractorBillRegister);
final List<MBHeader> mbHeaders = mbHeaderService.getMBHeadersByContractorBill(newcontractorBillRegister);
if (mbHeaders != null && !mbHeaders.isEmpty())
newcontractorBillRegister.setMbHeader(mbHeaders.get(0));
return "contractorBill-update";
}
private ContractorBillRegister getContractorBillDocuments(final ContractorBillRegister contractorBillRegister) {
List<DocumentDetails> documentDetailsList = new ArrayList<DocumentDetails>();
documentDetailsList = worksUtils.findByObjectIdAndObjectType(contractorBillRegister.getId(),
WorksConstants.CONTRACTORBILL);
contractorBillRegister.setDocumentDetails(documentDetailsList);
return contractorBillRegister;
}
@RequestMapping(value = "/view/{contractorBillRegisterId}", method = RequestMethod.GET)
public String viewContractorBillRegister(final Model model, @PathVariable final String contractorBillRegisterId,
final HttpServletRequest request) throws ApplicationException {
final ContractorBillRegister contractorBillRegister = getContractorBillRegister(contractorBillRegisterId);
final String responsePage = loadViewData(model, request, contractorBillRegister);
model.addAttribute("createdbybydesignation",
worksUtils.getUserDesignation(contractorBillRegister.getCreatedBy()));
model.addAttribute("mode", "readOnly");
return responsePage;
}
private ContractorBillRegister addBillDetails(final ContractorBillRegister contractorBillRegister,
final LineEstimateDetails lineEstimateDetails, final BindingResult resultBinder,
final HttpServletRequest request) {
if (contractorBillRegister.getBillDetailes() == null || contractorBillRegister.getBillDetailes().isEmpty())
resultBinder.reject("error.contractorbill.accountdetails.required",
"error.contractorbill.accountdetails.required");
for (final EgBilldetails egBilldetails : contractorBillRegister.getBillDetailes())
if (!contractorBillRegister.getEgBilldetailes().isEmpty() && contractorBillRegister.getEgBilldetailes().size() == 1) {
for (final EgBilldetails refundBill : contractorBillRegister.getRefundBillDetails())
if (refundBill.getGlcodeid() != null)
contractorBillRegister.addEgBilldetailes(
contractorBillRegisterService.getBillDetails(contractorBillRegister, refundBill,
lineEstimateDetails, resultBinder, request));
if (egBilldetails.getGlcodeid() != null)
contractorBillRegister
.addEgBilldetailes(contractorBillRegisterService.getBillDetails(contractorBillRegister, egBilldetails,
lineEstimateDetails, resultBinder, request));
} else if (egBilldetails.getGlcodeid() != null)
contractorBillRegister
.addEgBilldetailes(contractorBillRegisterService.getBillDetails(contractorBillRegister, egBilldetails,
lineEstimateDetails, resultBinder, request));
contractorBillRegisterService.validateZeroCreditAndDebitAmount(contractorBillRegister, resultBinder);
final String netPayableAccountId = request.getParameter("netPayableAccountId");
final String netPayableAccountCodeId = request.getParameter("netPayableAccountCode");
final String netPayableAmount = request.getParameter("netPayableAmount");
if (StringUtils.isNotBlank(netPayableAccountCodeId) && StringUtils.isNotBlank(netPayableAccountCodeId)
&& StringUtils.isNotBlank(netPayableAmount)) {
final EgBilldetails billdetails = new EgBilldetails();
billdetails.setId(new Integer(netPayableAccountId));
billdetails.setGlcodeid(new BigDecimal(netPayableAccountCodeId));
billdetails.setCreditamount(new BigDecimal(netPayableAmount));
contractorBillRegister.addEgBilldetailes(
contractorBillRegisterService.getBillDetails(contractorBillRegister, billdetails, lineEstimateDetails,
resultBinder, request));
}
return contractorBillRegister;
}
}