/*
* 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.collection.web.actions.receipts;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
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.collection.constants.CollectionConstants;
import org.egov.collection.entity.ReceiptHeader;
import org.egov.collection.service.ReceiptHeaderService;
import org.egov.collection.utils.CollectionsUtil;
import org.egov.infra.security.utils.SecurityUtils;
import org.egov.infra.web.struts.actions.BaseFormAction;
import org.egov.infra.web.struts.annotation.ValidationErrorPage;
import org.egov.model.instrument.InstrumentHeader;
import org.egov.pims.commons.Position;
import org.springframework.beans.factory.annotation.Autowired;
/**
* Action class for "Approve Collections"
*/
@ParentPackage("egov")
@Results({ @Result(name = CollectionsWorkflowAction.SUCCESS, location = "collectionsWorkflow-success.jsp"),
@Result(name = CollectionsWorkflowAction.INDEX, location = "collectionsWorkflow-index.jsp"),
@Result(name = CollectionsWorkflowAction.ERROR, location = "collectionsWorkflow-error.jsp"),
@Result(name = CollectionsWorkflowAction.SUBMISSION_REPORT_CASH, type = "redirectAction", location = "cashCollectionReport-submissionReport.action", params = {
"namespace", "/reports", "receiptDate", "${receiptDate}" }),
@Result(name = CollectionsWorkflowAction.SUBMISSION_REPORT_CHEQUE, type = "redirectAction", location = "chequeCollectionReport-submissionReport.action", params = {
"namespace", "/reports", "receiptDate", "${receiptDate}" }),
@Result(name = "cancel", type = "redirectAction", location = "receipt", params = { "namespace", "/receipts",
"method", "cancel" }) })
public class CollectionsWorkflowAction extends BaseFormAction {
private static final long serialVersionUID = 1L;
/**
* List of receipt headers to be submitted/approved
*/
private List<ReceiptHeader> receiptHeaders;
/**
* Array of selected receipt ids that are to be submitted/approved
*/
private Long[] receiptIds;
/**
* Map of instrument type wise amounts for all receipts that are eligible
* for the workflow
*/
private final Map<String, BigDecimal> instrumentWiseAmounts = new HashMap<String, BigDecimal>(4);
/**
* Total amount of all receipts eligible for the workflow action
*/
private BigDecimal totalAmount;
/**
* The counter id for which the receipt list is to be submitted/approved.
*/
private Long counterId = -1l;
/**
* The user name for which the receipt list is to be submitted/approved.
*/
private String userName;
/**
* The service code for which the receipt list is to be submitted/approved.
*/
private String serviceCode;
/**
* Workflow service for changing the state of the receipt
*/
/**
* The collections utility object
*/
private CollectionsUtil collectionsUtil;
/**
* Receipt header service
*/
private ReceiptHeaderService receiptHeaderService;
/**
* Approval/Rejection remarks
*/
private String remarks;
/**
* Workflow action (SUBMIT/APPROVE). Based on this, the JSP can decide to
* display/hide various buttons
*/
private String wfAction;
public void setWfAction(final String wfAction) {
this.wfAction = wfAction;
}
private String receiptDate;
private String approverName;
/**
* Result for cash submission report (redirects to the cash collection
* report)
*/
protected static final String SUBMISSION_REPORT_CASH = "submissionReportCash";
/**
* Result for cheque submission report (redirects to the cheque collection
* report)
*/
protected static final String SUBMISSION_REPORT_CHEQUE = "submissionReportCheque";
@Autowired
private SecurityUtils securityUtils;
private String inboxItemDetails;
public String getInboxItemDetails() {
return inboxItemDetails;
}
/**
* This method is called when user clicks on a collections work flow item in
* the inbox. The inbox item details contains the next work flow action to
* be performed, service code, user id and counter id in the following form:
* <next-workflow-action>-servicecode-username-counterid
*
* @param inboxItemDetails
* the id to set
*/
public void setInboxItemDetails(final String inboxItemDetails) {
final String params[] = inboxItemDetails.split(CollectionConstants.SEPARATOR_HYPHEN, -1);
if (params.length <= 6) {
setWfAction(params[0]);
setServiceCode(params[1]);
setUserName(params[2]);
setCounterId(Long.valueOf(params[4]));
setReceiptDate(params[3]);
}
this.inboxItemDetails = inboxItemDetails;
}
/**
* @param collectionsUtil
* the collectionsUtil to set
*/
public void setCollectionsUtil(final CollectionsUtil collectionsUtil) {
this.collectionsUtil = collectionsUtil;
}
/**
* @param workflow
* the receipt workflow service
*/
public void setReceiptHeaderService(final ReceiptHeaderService receiptHeaderService) {
this.receiptHeaderService = receiptHeaderService;
}
/**
* @return true if the current action is submit_for_approval
*/
public Boolean getIsSubmitAction() {
return wfAction.equals(CollectionConstants.WF_ACTION_SUBMIT);
}
/**
* @return true if partial selection is to be allowed for
* submission/approval, else false
*/
public Boolean getAllowPartialSelection() {
// return wfAction.equals(CollectionConstants.WF_ACTION_SUBMIT);
if (getIsSubmitAction())
return false;
else
return true;
}
/**
* @return true if the current action is approve
*/
public Boolean getIsApproveAction() {
return wfAction.equals(CollectionConstants.WF_ACTION_APPROVE);
}
/**
* @return true if the current action is approve
*/
public Boolean getIsRejectAction() {
return wfAction.equals(CollectionConstants.WF_ACTION_REJECT);
}
/**
* Constructor
*/
public CollectionsWorkflowAction() {
super();
}
@Override
public Object getModel() {
return null;
}
/**
* @return the counter id
*/
public Long getCounterId() {
return counterId;
}
/**
* @param counterId
* the counter id to be set
*/
public void setCounterId(final Long counterId) {
this.counterId = counterId;
}
/**
* @return the user name
*/
public String getUserName() {
return userName;
}
/**
* @param userName
* the user name to set
*/
public void setUserName(final String userName) {
this.userName = userName;
}
/**
* @return the service code
*/
public String getServiceCode() {
return serviceCode;
}
/**
* @param serviceCode
* the Service Code to set
*/
public void setServiceCode(final String serviceCode) {
this.serviceCode = serviceCode;
}
/**
* @return List for receipt headers in status "To be submitted"
*/
public List<ReceiptHeader> getReceiptHeaders() {
return receiptHeaders;
}
/**
* @return The total amount of all receipts eligible for the workflow action
*/
public BigDecimal getTotalAmount() {
return totalAmount;
}
/**
* Returns amount for given instrument type
*
* @param instrumentType
* The instrument type
* @return amount for given instrument type
*/
private BigDecimal getInstrumentTypeAmount(final String instrumentType) {
final BigDecimal amount = instrumentWiseAmounts.get(instrumentType);
return amount == null ? BigDecimal.valueOf(0) : amount;
}
/**
* @return Total amount collected as cash amongst all receipts eligible for
* the workflow action
*/
public BigDecimal getCashAmount() {
return getInstrumentTypeAmount(CollectionConstants.INSTRUMENTTYPE_CASH);
}
/**
* @return Total amount collected as cheque amongst all receipts eligible
* for the workflow action
*/
public BigDecimal getChequeAmount() {
return getInstrumentTypeAmount(CollectionConstants.INSTRUMENTTYPE_CHEQUE);
}
/**
* @return Total amount collected as dd amongst all receipts eligible for
* the workflow action
*/
public BigDecimal getDdAmount() {
return getInstrumentTypeAmount(CollectionConstants.INSTRUMENTTYPE_DD);
}
/**
* @return Total amount collected using card amongst all receipts eligible
* for the workflow action
*/
public BigDecimal getCardAmount() {
return getInstrumentTypeAmount(CollectionConstants.INSTRUMENTTYPE_CARD);
}
/**
* @return Total amount collected using bank amongst all receipts eligible
* for the workflow action
*/
public BigDecimal getBankAmount() {
return getInstrumentTypeAmount(CollectionConstants.INSTRUMENTTYPE_BANK);
}
/**
* @param Array
* of receipt Ids
*/
public void setReceiptIds(final Long[] receiptIds) {
this.receiptIds = receiptIds;
}
/**
* @param Submission
* /Approval/Rejection remarks
*/
public void setRemarks(final String remarks) {
this.remarks = remarks;
}
/**
* Updates the receipt's status by invoking the workflow action
*
* @param wfAction
* Workflow action e.g. submit_for_approval/approve/reject
* @param remarks
* Approval/rejection remarks
* @return SUCCESS/ERROR
*/
private String updateReceiptWorkflowStatus(final String wfAction, final String remarks) {
for (final Long receiptId : receiptIds) {
// Get the next receipt that is to be updated
final ReceiptHeader receiptHeader = receiptHeaderService
.findByNamedQuery(CollectionConstants.QUERY_RECEIPT_BY_ID_AND_STATUSNOTCANCELLED, receiptId);
if (receiptHeader != null) {
receiptHeaderService.performWorkflow(wfAction, receiptHeader, remarks);
approverName = collectionsUtil.getApproverName(receiptHeader.getState().getOwnerPosition());
}
}
// Add the selected receipt ids to sereceiptHeader
// Need to find a better mechanism to achieve this.
getSession().put(CollectionConstants.SESSION_VAR_RECEIPT_IDS, receiptIds);
return SUCCESS;
}
private String updateReceiptWorkflowStatusForAll(final String wfAction, final String remarks) {
final Position position = collectionsUtil.getPositionOfUser(securityUtils.getCurrentUser());
receiptHeaders = receiptHeaderService.findAllByPositionAndInboxItemDetails(position.getId(), inboxItemDetails);
final Position operatorPosition = receiptHeaderService.getOperatorPosition(receiptHeaders.get(0));
final Position approverPosition = receiptHeaderService.getApproverPosition(receiptHeaders.get(0));
receiptIds = new Long[receiptHeaders.size()];
int i = 0;
for (final ReceiptHeader receiptHeader : receiptHeaders) {
if (receiptHeader != null)
receiptIds[i] = receiptHeader.getId();
i++;
}
receiptHeaderService.performWorkflowForAllReceipts(wfAction, receiptHeaders, remarks, operatorPosition,
approverPosition);
approverName = collectionsUtil.getApproverName(approverPosition);
// Add the selected receipt ids to sereceiptHeader
// Need to find a better mechanism to achieve this.
getSession().put(CollectionConstants.SESSION_VAR_RECEIPT_IDS, receiptIds);
return SUCCESS;
}
/**
* Fetches all receipts for set user-counter combination and given status
* code. Also sets the work flow action code to given value, and calculates
* the various amounts using the fetched receipts.
*
* @param statusCode
* Status code for which receipts are to be fetched
* @param workflowAction
* Work flow action code
*/
private void fetchReceipts(final String workflowAction) {// Get
// all
// receipts
// that
// are created by
// currently logged in user from
// his/her current counter and are in SUBMITTED status
final Position position = collectionsUtil.getPositionOfUser(securityUtils.getCurrentUser());
receiptHeaders = receiptHeaderService.findAllByPositionAndInboxItemDetails(position.getId(), inboxItemDetails);
// Populate the selected receipt IDs with all receipt ids
final int receiptCount = receiptHeaders.size();
receiptIds = new Long[receiptCount];
for (int i = 0; i < receiptCount; i++)
receiptIds[i] = receiptHeaders.get(i).getId();
wfAction = workflowAction;
calculateAmounts();
}
/**
* Action that will be called from the workflow inbox. The inbox also passes
* the id of the clicked item which is of the form:
* <next-workflow-action>-servicecode-userid-counterid
*
* @return Next page to be displayed (index)
*/
@Action(value = "/receipts/collectionsWorkflow-listWorkflow")
public String listWorkflow() {
if (wfAction != null && wfAction.equals(CollectionConstants.WF_ACTION_APPROVE))
fetchReceipts(CollectionConstants.WF_ACTION_APPROVE);
else
fetchReceipts(CollectionConstants.WF_ACTION_SUBMIT);
return INDEX;
}
/**
* Action for creating cash submission report
*
* @return submissionReport
*/
@Action(value = "/receipts/collectionsWorkflow-submissionReportCash")
public String submissionReportCash() {
return SUBMISSION_REPORT_CASH;
}
/**
* Action for creating cash submission report
*
* @return submissionReport
*/
@Action(value = "/receipts/collectionsWorkflow-submissionReportCheque")
public String submissionReportCheque() {
return SUBMISSION_REPORT_CHEQUE;
}
/**
* Action method to submit the selected receipt headers
*
* @return SUCCESS/ERROR
*/
@ValidationErrorPage(value = INDEX)
@Action(value = "/receipts/collectionsWorkflow-submitCollections")
public String submitCollections() {
wfAction = CollectionConstants.WF_ACTION_SUBMIT;
return updateReceiptWorkflowStatus(wfAction, remarks);
}
@ValidationErrorPage(value = INDEX)
@Action(value = "/receipts/collectionsWorkflow-submitAllCollections")
public String submitAllCollections() {
setInboxItemDetails(inboxItemDetails);
return updateReceiptWorkflowStatusForAll(wfAction, remarks);
}
/**
* Action method to approve the selected receipt headers
*
* @return SUCCESS/ERROR
*/
@Action(value = "/receipts/collectionsWorkflow-approveCollections")
public String approveCollections() {
wfAction = CollectionConstants.WF_ACTION_APPROVE;
return updateReceiptWorkflowStatus(wfAction, remarks);
}
@Action(value = "/receipts/collectionsWorkflow-approveAllCollections")
public String approveAllCollections() {
setInboxItemDetails(inboxItemDetails);
return updateReceiptWorkflowStatusForAll(wfAction, remarks);
}
/**
* Action method to reject the selected receipt headers
*
* @return SUCCESS/ERROR
*/
@Action(value = "/receipts/collectionsWorkflow-rejectCollections")
public String rejectCollections() {
wfAction = CollectionConstants.WF_ACTION_REJECT;
return updateReceiptWorkflowStatus(wfAction, remarks);
}
/**
* Calculates instrument type wise amounts of all receipts eligible for the
* workflow
*/
private void calculateAmounts() {
totalAmount = BigDecimal.ZERO;
for (final ReceiptHeader receiptHeader : receiptHeaders) {
for (final InstrumentHeader instrumentHeader : receiptHeader.getReceiptInstrument()) {
final String instrumentType = instrumentHeader.getInstrumentType().getType();
// Increment total amount
totalAmount = totalAmount.add(instrumentHeader.getInstrumentAmount()).setScale(2,
BigDecimal.ROUND_HALF_UP);
BigDecimal instrumentAmount = instrumentWiseAmounts.get(instrumentType);
if (instrumentAmount == null)
instrumentAmount = instrumentHeader.getInstrumentAmount();
else
instrumentAmount = instrumentAmount.add(instrumentHeader.getInstrumentAmount());
instrumentWiseAmounts.put(instrumentType, instrumentAmount.setScale(2, BigDecimal.ROUND_HALF_UP));
}
// Add to ReceiptHeader to populate in jsp
receiptHeader.setInstrumentsAsString(receiptHeader.getInstrumentDetailAsString());
}
}
public String getReceiptDate() {
return receiptDate;
}
public void setReceiptDate(final String receiptDate) {
this.receiptDate = receiptDate;
}
public String getApproverName() {
return approverName;
}
public void setApproverName(final String approverName) {
this.approverName = approverName;
}
}