/* * 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.egf.web.actions.budget; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.Map; 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.apache.struts2.interceptor.validation.SkipValidation; import org.egov.commons.CFinancialYear; import org.egov.commons.CFunction; import org.egov.commons.Functionary; import org.egov.commons.Fund; import org.egov.commons.Scheme; import org.egov.commons.SubScheme; import org.egov.commons.dao.EgwStatusHibernateDAO; import org.egov.dao.budget.BudgetDetailsDAO; import org.egov.egf.model.BudgetReAppropriationView; import org.egov.eis.service.EisCommonService; import org.egov.infra.admin.master.entity.Boundary; import org.egov.infra.admin.master.entity.Department; import org.egov.infra.admin.master.service.AppConfigValueService; import org.egov.infra.config.core.ApplicationThreadLocals; import org.egov.infra.validation.exception.ValidationError; import org.egov.infra.validation.exception.ValidationException; import org.egov.infra.web.struts.actions.BaseFormAction; import org.egov.infra.web.struts.annotation.ValidationErrorPage; import org.egov.infra.workflow.service.WorkflowService; import org.egov.infstr.utils.EgovMasterDataCaching; import org.egov.model.budget.Budget; import org.egov.model.budget.BudgetDetail; import org.egov.model.budget.BudgetGroup; import org.egov.model.budget.BudgetReAppropriation; import org.egov.model.budget.BudgetReAppropriationMisc; import org.egov.pims.commons.Position; import org.egov.services.budget.BudgetDetailService; import org.egov.services.budget.BudgetReAppropriationService; import org.egov.services.budget.BudgetService; import org.egov.utils.BudgetDetailConfig; import org.egov.utils.BudgetDetailHelper; import org.egov.utils.Constants; import org.hibernate.Query; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.util.ValueStack; @ParentPackage("egov") @Results({ @Result(name = "new", location = "budgetReAppropriation-new.jsp"), @Result(name = "search", location = "budgetReAppropriation-search.jsp"), @Result(name = "beRe", location = "budgetReAppropriation-beRe.jsp") }) public class BudgetReAppropriationAction extends BaseFormAction { private static final long serialVersionUID = 1L; private static final String BERE = "beRe"; private static final Logger LOGGER = Logger.getLogger(BudgetReAppropriationAction.class); private List<BudgetReAppropriationView> budgetReAppropriationList = new ArrayList<BudgetReAppropriationView>(); private List<BudgetReAppropriationView> newBudgetReAppropriationList = new ArrayList<BudgetReAppropriationView>(); @Autowired protected BudgetDetailConfig budgetDetailConfig; private BudgetDetail budgetDetail; protected Budget budget; protected List<String> headerFields = new ArrayList<String>(); protected List<String> gridFields = new ArrayList<String>(); protected List<String> mandatoryFields = new ArrayList<String>(); @Autowired private BudgetDetailHelper budgetDetailHelper; @Autowired private EisCommonService eisCommonService; @Autowired @Qualifier("budgetService") private BudgetService budgetService; @Autowired @Qualifier("budgetDetailService") private BudgetDetailService budgetDetailService; @Autowired @Qualifier("budgetReAppropriationService") private BudgetReAppropriationService budgetReAppropriationService; @Autowired @Qualifier("workflowService") private WorkflowService<BudgetReAppropriation> budgetReAppropriationWorkflowService; @Autowired private BudgetDetailsDAO budgetDetailsDAO; private CFinancialYear financialYear; private String beRe = Constants.BE; private String sequenceNumber; private BudgetReAppropriationMisc appropriationMisc = new BudgetReAppropriationMisc(); private List<BudgetReAppropriation> reAppropriationList = null; private String type = ""; private String finalStatus = ""; private static final String ACTIONNAME = "actionName"; @Autowired private AppConfigValueService appConfigValuesService; @Autowired private EgovMasterDataCaching masterDataCache; @Autowired private EgwStatusHibernateDAO egwStatusDAO; private String message = ""; public BudgetReAppropriationMisc getAppropriationMisc() { return appropriationMisc; } public void setAppropriationMisc(final BudgetReAppropriationMisc appropriationMisc) { this.appropriationMisc = appropriationMisc; } public String getBeRe() { return beRe; } public void setBudgetReAppropriationService( final BudgetReAppropriationService budgetReAppropriationService) { this.budgetReAppropriationService = budgetReAppropriationService; } public void setBeRe(final String beRe) { this.beRe = beRe; } public void setBudgetService(final BudgetService budgetService) { this.budgetService = budgetService; } public void setBudgetDetailHelper(final BudgetDetailHelper budgetDetailHelper) { this.budgetDetailHelper = budgetDetailHelper; } public List<BudgetReAppropriationView> getNewBudgetReAppropriationList() { return newBudgetReAppropriationList; } public void setFinancialYear(final CFinancialYear financialYear) { this.financialYear = financialYear; } public BudgetDetail getBudgetDetail() { return budgetDetail; } public void setBudgetDetail(final BudgetDetail budgetDetail) { this.budgetDetail = budgetDetail; } public void setEisCommonService(final EisCommonService eisCommonService) { this.eisCommonService = eisCommonService; } public CFinancialYear getFinancialYear() { return financialYear; } public List<BudgetReAppropriationView> getBudgetReAppropriationList() { return budgetReAppropriationList; } public Budget getBudget() { return budget; } public List<String> getHeaderFields() { return headerFields; } public List<String> getGridFields() { return gridFields; } public List<String> getMandatoryFields() { return mandatoryFields; } public BudgetReAppropriationAction() { } protected void setupDropdownsInHeader() { setupDropdownDataExcluding(Constants.SUB_SCHEME); finalStatus = getFinalStatus(); dropdownData.put("financialYearList", getFinancialYearDropDown()); if (financialYear != null && financialYear.getId() != 0L) dropdownData.put("budgetList", getApprovedBudgetsForFY(financialYear.getId(), finalStatus)); else dropdownData.put("budgetList", Collections.EMPTY_LIST); dropdownData.put("budgetGroupList", persistenceService.findAllBy("from BudgetGroup where isActive=true order by name")); if (shouldShowField(Constants.SUB_SCHEME)) dropdownData.put("subSchemeList", Collections.EMPTY_LIST); if (shouldShowField(Constants.FUNCTIONARY)) dropdownData.put("functionaryList", masterDataCache.get("egi-functionary")); if (shouldShowField(Constants.FUNCTION)) dropdownData.put("functionList", masterDataCache.get("egi-function")); if (shouldShowField(Constants.SCHEME)) dropdownData.put("schemeList", persistenceService.findAllBy("from Scheme where isActive=true order by name")); if (shouldShowField(Constants.EXECUTING_DEPARTMENT)) dropdownData.put("executingDepartmentList", masterDataCache.get("egi-department")); if (shouldShowField(Constants.FUND)) dropdownData .put("fundList", persistenceService.findAllBy("from Fund where isNotLeaf=false and isActive=true order by name")); if (shouldShowField(Constants.BOUNDARY)) dropdownData.put("boundaryList", persistenceService.findAllBy("from Boundary order by name")); dropdownData.put("finYearList", getPersistenceService().findAllBy("from CFinancialYear where isActive=true order by finYearRange desc ")); } public final boolean shouldShowField(final String fieldName) { if (headerFields.isEmpty() && gridFields.isEmpty()) return true; return budgetDetailConfig.shouldShowField(headerFields, fieldName) || budgetDetailConfig.shouldShowField(gridFields, fieldName); } public boolean shouldShowHeaderField(final String fieldName) { return budgetDetailConfig.shouldShowField(headerFields, fieldName); } public boolean shouldShowGridField(final String fieldName) { return budgetDetailConfig.shouldShowField(gridFields, fieldName); } @Override public String execute() throws Exception { return NEW; } @Override public void prepare() { super.prepare(); headerFields = budgetDetailConfig.getHeaderFields(); gridFields = budgetDetailConfig.getGridFields(); mandatoryFields = budgetDetailConfig.getMandatoryFields(); addRelatedEntity("budgetGroup", BudgetGroup.class); addRelatedEntity("budget", Budget.class); if (shouldShowField(Constants.FUNCTIONARY)) addRelatedEntity(Constants.FUNCTIONARY, Functionary.class); if (shouldShowField(Constants.FUNCTION)) addRelatedEntity(Constants.FUNCTION, CFunction.class); if (shouldShowField(Constants.SCHEME)) addRelatedEntity(Constants.SCHEME, Scheme.class); if (shouldShowField(Constants.SUB_SCHEME)) addRelatedEntity(Constants.SUB_SCHEME, SubScheme.class); if (shouldShowField(Constants.FUND)) addRelatedEntity(Constants.FUND, Fund.class); if (shouldShowField(Constants.EXECUTING_DEPARTMENT)) addRelatedEntity(Constants.EXECUTING_DEPARTMENT, Department.class); if (shouldShowField(Constants.BOUNDARY)) addRelatedEntity(Constants.BOUNDARY, Boundary.class); appropriationMisc.setReAppropriationDate(new Date()); if (financialYear != null && financialYear.getId() != 0L && budgetService.hasApprovedReForYear(financialYear.getId())) beRe = Constants.RE; setupDropdownsInHeader(); dropdownData.put("departmentList", masterDataCache.get("egi-department")); dropdownData.put("designationList", Collections.EMPTY_LIST); dropdownData.put("userList", Collections.EMPTY_LIST); } @Override public Object getModel() { return budgetDetail; } @Action(value = "/budget/budgetReAppropriation-create") public String create() { save(ApplicationThreadLocals.getUserId().intValue()); return NEW; } @Action(value = "/budget/budgetReAppropriation-createAndForward") public String createAndForward() { final BudgetReAppropriationMisc misc = save(getUserId()); addActionMessage(getText("budget.reapp.approved.end")); /* * final Position owner = misc.getState().getOwnerPosition(); if * ("END".equalsIgnoreCase(misc.getCurrentState().getValue())) addActionMessage(getText("budget.reapp.approved.end")); * else addActionMessage(getText("budget.reapp.approved") + * budgetService.getEmployeeNameAndDesignationForPosition(owner)); */ clearFields(); return NEW; } private void clearFields() { budgetDetail = new BudgetDetail(); budgetReAppropriationList = new ArrayList<BudgetReAppropriationView>(); newBudgetReAppropriationList = new ArrayList<BudgetReAppropriationView>(); } private BudgetReAppropriationMisc save(final Integer userId) { boolean reAppropriationCreated = false; boolean reAppForNewBudgetCreated = false; BudgetReAppropriationMisc misc = null; if (financialYear != null && financialYear.getId() != 0) financialYear = (CFinancialYear) persistenceService.find("from CFinancialYear where id=?", financialYear.getId()); try { misc = budgetReAppropriationService.createBudgetReAppropriationMisc(parameters.get(ACTIONNAME)[0] + "|" + userId, beRe, financialYear, appropriationMisc, getPosition()); removeEmptyReAppropriation(budgetReAppropriationList); reAppropriationCreated = budgetReAppropriationService.createReAppropriation(parameters.get(ACTIONNAME)[0] + "|" + userId, budgetReAppropriationList, getPosition(), financialYear, beRe, misc, parameters.get("appropriationMisc.reAppropriationDate")[0]); removeEmptyReAppropriation(newBudgetReAppropriationList); reAppForNewBudgetCreated = budgetReAppropriationService.createReAppropriationForNewBudgetDetail( parameters.get(ACTIONNAME)[0] + "|" + userId, newBudgetReAppropriationList, getPosition(), misc); if (!reAppropriationCreated && !reAppForNewBudgetCreated) throw new ValidationException(Arrays.asList(new ValidationError("budgetDetail.budgetGroup.mandatory", "budgetDetail.budgetGroup.mandatory"))); newBudgetReAppropriationList.clear(); budgetReAppropriationList.clear(); } catch (final ValidationException e) { throw new ValidationException(Arrays.asList(new ValidationError(e.getErrors().get(0).getMessage(), e.getErrors().get(0).getMessage()))); } catch (final Exception e) { throw new ValidationException(Arrays.asList(new ValidationError(e.getMessage(), e.getMessage()))); } if (reAppropriationCreated) addActionMessage(getText("budget.reappropriation.existing.saved") + misc.getSequenceNumber()); if (reAppForNewBudgetCreated) addActionMessage(getText("budget.reappropriation.new.saved") + misc.getSequenceNumber()); clearFields(); return misc; } private Integer getUserId() { Integer userId = null; if (null != parameters.get("approverUserId") && Integer.valueOf(parameters.get("approverUserId")[0]) != -1) userId = Integer.valueOf(parameters.get("approverUserId")[0]); else userId = ApplicationThreadLocals.getUserId().intValue(); return userId; } protected BudgetReAppropriationMisc createBudgetReAppropriationMisc(final String actionName) { final Budget budget = new Budget(); budget.setIsbere(beRe); budget.setFinancialYear(financialYear); final BudgetDetail budgetDetail = new BudgetDetail(); budgetDetail.setBudget(budget); return budgetReAppropriationService.createReAppropriationMisc(actionName, appropriationMisc, budgetDetail, getPosition()); } public void setBudgetDetailService(final BudgetDetailService budgetDetailService) { this.budgetDetailService = budgetDetailService; } protected Position getPosition() { try { return eisCommonService.getPositionByUserId(ApplicationThreadLocals.getUserId()); } catch (final ValidationException e) { throw new ValidationException(Arrays.asList(new ValidationError(e.getErrors().get(0).getMessage(), e.getErrors().get(0).getMessage()))); } catch (final Exception e) { throw new ValidationException(Arrays.asList(new ValidationError("Do transaction with proper user", "Do transaction with proper user"))); } } public void removeEmptyReAppropriation(final List<BudgetReAppropriationView> reAppropriationList) { for (final Iterator<BudgetReAppropriationView> detail = reAppropriationList.iterator(); detail.hasNext();) if (detail.next() == null) detail.remove(); } protected String getFinalStatus() { return appConfigValuesService.getConfigValuesByModuleAndKey(Constants.EGF, "budget_final_approval_status").get(0) .getValue(); } @ValidationErrorPage(value = NEW) @Action(value = "/budget/budgetReAppropriation-loadActuals") public String loadActuals() { removeEmptyReAppropriation(budgetReAppropriationList); removeEmptyReAppropriation(newBudgetReAppropriationList); if (budgetReAppropriationService.rowsToAddForExistingDetails(budgetReAppropriationList)) loadData(budgetReAppropriationList); if (budgetReAppropriationService.rowsToAddExists(newBudgetReAppropriationList)) loadData(newBudgetReAppropriationList); return NEW; } private void loadData(final List<BudgetReAppropriationView> reAppList) { budgetReAppropriationService.validateMandatoryFields(reAppList); for (final BudgetReAppropriationView entry : reAppList) { entry.setBudgetDetail(budgetReAppropriationService.setRelatedValues(entry.getBudgetDetail())); final List<BudgetDetail> detailList = budgetDetailService.searchByCriteriaWithTypeAndFY(financialYear.getId(), beRe, entry.getBudgetDetail()); if (detailList.size() == 1) { final BudgetDetail budgetDetail = detailList.get(0); final Map<String, Object> paramMap = budgetDetailHelper.constructParamMap(getValueStack(), budgetDetail); paramMap.put(Constants.ASONDATE, appropriationMisc.getReAppropriationDate()); entry.setActuals(budgetDetailHelper.getTotalActualsFor(paramMap, appropriationMisc.getReAppropriationDate())); entry.setApprovedAmount(budgetDetail.getApprovedAmount()); // this is total of reappropriated amount entry.setAppropriatedAmount(budgetDetail.getApprovedReAppropriationsTotal()); entry.setAvailableAmount(entry.getApprovedAmount().add(entry.getAppropriatedAmount()) .subtract(entry.getActuals())); if (budgetDetail.getPlanningPercent() == null) // TODO change the planningPercentage to planningPercent entry.setPlanningPercent(BigDecimal.ZERO); else entry.setPlanningPercent(budgetDetail.getPlanningPercent()); if (budgetDetail.getPlanningPercent() == BigDecimal.ZERO) entry.setPlanningBudgetApproved(entry.getApprovedAmount().add(entry.getAppropriatedAmount())); else // TODO put the division after the multiplication entry.setPlanningBudgetApproved(entry.getApprovedAmount().add(entry.getAppropriatedAmount()) .multiply(entry.getPlanningPercent()).divide(new BigDecimal(String.valueOf(100)))); entry.setPlanningBudgetUsage(budgetDetailsDAO.getPlanningBudgetUsage(budgetDetail)); entry.setPlanningBudgetAvailable(entry.getPlanningBudgetApproved().subtract(entry.getPlanningBudgetUsage())); // entry.setActuals(entry.getActuals().add(budgetDetailHelper.getBillAmountForBudgetCheck(paramMap))); } } } @Action(value = "/budget/budgetReAppropriation-ajaxLoadBeRe") public String ajaxLoadBeRe() { if (parameters.get("id") != null) { final Long id = Long.valueOf(parameters.get("id")[0]); if (id != 0L && budgetService.hasApprovedReForYear(id)) beRe = Constants.RE; else beRe = Constants.BE; dropdownData.put("budgetList", getApprovedBudgetsForFY(id, finalStatus)); } return BERE; } protected ValueStack getValueStack() { return ActionContext.getContext().getValueStack(); } List getFinancialYearDropDown() { List<Long> ids = new ArrayList<Long>(); ids = (List<Long>) persistenceService .findAllBy( "select distinct financialYear.id from Budget where isActiveBudget=true and isPrimaryBudget=true and status.code='Approved'"); Query query; if (!ids.isEmpty()) { query = persistenceService.getSession() .createQuery("from CFinancialYear where id in (:ids) order by finYearRange desc") .setParameterList("ids", ids); return query.list(); } return new ArrayList(); } protected List getApprovedBudgetsForFY(final Long id, final String finalStatus) { if (id != null && id != 0L) return budgetService .findAllBy( "from Budget where id not in (select parent from Budget where parent is not null) and isactivebudget = true and status.moduletype='BUDGET' and status.code='" + finalStatus + "' and financialYear.id=? and isbere=? order by name", id, beRe); return new ArrayList(); } public boolean isFieldMandatory(final String field) { return mandatoryFields.contains(field); } @Action(value = "/budget/budgetReAppropriation-beforeSearch") public String beforeSearch() { return "search"; } @SkipValidation @Action(value = "/budget/budgetReAppropriation-search") public String search() { String sql = " ba.budgetDetail.budget.financialYear=" + financialYear.getId() + " and ba.budgetDetail.budget.isbere='" + budgetDetail.getBudget().getIsbere() + "' "; if (budgetDetail.getFund().getId() != null && budgetDetail.getFund().getId() != 0) sql = sql + " and ba.budgetDetail.fund=" + budgetDetail.getFund().getId(); if (budgetDetail.getExecutingDepartment() != null && budgetDetail.getExecutingDepartment().getId() != 0) sql = sql + " and ba.budgetDetail.executingDepartment=" + budgetDetail.getExecutingDepartment().getId(); if (budgetDetail.getFunction() != null && budgetDetail.getFunction().getId() != 0) sql = sql + " and ba.budgetDetail.function=" + budgetDetail.getFunction().getId(); if (budgetDetail.getFunctionary() != null && budgetDetail.getFunctionary().getId() != 0) sql = sql + " and ba.budgetDetail.functionary=" + budgetDetail.getFunctionary().getId(); if (budgetDetail.getScheme() != null && budgetDetail.getScheme().getId() != 0) sql = sql + " and ba.budgetDetail.scheme=" + budgetDetail.getScheme().getId(); if (budgetDetail.getSubScheme() != null && budgetDetail.getSubScheme().getId() != 0) sql = sql + " and ba.budgetDetail.subScheme=" + budgetDetail.getSubScheme().getId(); if (budgetDetail.getBoundary() != null && budgetDetail.getBoundary().getId() != 0) sql = sql + " and ba.budgetDetail.boundary=" + budgetDetail.getBoundary().getId(); if (budgetDetail.getBudgetGroup().getId() != null && budgetDetail.getBudgetGroup().getId() != 0) sql = sql + " and ba.budgetDetail.budgetGroup=" + budgetDetail.getBudgetGroup().getId(); if (type.equals("A")) sql = sql + " and ba.additionAmount is not null and ba.additionAmount!=0 "; else if (type.equals("R")) sql = sql + " and ba.deductionAmount is not null and ba.deductionAmount!=0 "; if (LOGGER.isInfoEnabled()) LOGGER.info("search query==" + sql); reAppropriationList = getPersistenceService() .findAllBy( " from BudgetReAppropriation ba where ba.status.code='Approved' and " + sql + " order by ba.budgetDetail.fund,ba.budgetDetail.executingDepartment,ba.budgetDetail.function,ba.reAppropriationMisc.sequenceNumber"); return "search"; } public void transition(final String actionName, final BudgetReAppropriation detail, final String comment) { budgetReAppropriationWorkflowService.transition(actionName, detail, comment); } public List<BudgetReAppropriation> getReAppropriationList() { return reAppropriationList; } public String getType() { return type; } public void setType(final String type) { this.type = type; } public void setReAppropriationList(final List<BudgetReAppropriation> reAppropriationList) { this.reAppropriationList = reAppropriationList; } public void setMessage(final String message) { this.message = message; } public String getMessage() { return message; } public void setBudgetReAppropriationWorkflowService( final WorkflowService<BudgetReAppropriation> budgetReAppropriationWorkflowService) { this.budgetReAppropriationWorkflowService = budgetReAppropriationWorkflowService; } public BudgetDetailsDAO getBudgetDetailsDAO() { return budgetDetailsDAO; } public void setBudgetDetailsDAO(final BudgetDetailsDAO budgetDetailsDAO) { this.budgetDetailsDAO = budgetDetailsDAO; } }