org.kuali.kfs.fp.document.web.struts.ProcurementCardAction.java Source code

Java tutorial

Introduction

Here is the source code for org.kuali.kfs.fp.document.web.struts.ProcurementCardAction.java

Source

/*
 * The Kuali Financial System, a comprehensive financial management system for higher education.
 * 
 * Copyright 2005-2014 The Kuali Foundation
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) 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 Affero General Public License for more details.
 * 
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.kuali.kfs.fp.document.web.struts;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.upload.FormFile;
import org.kuali.kfs.fp.businessobject.ProcurementCardTargetAccountingLine;
import org.kuali.kfs.fp.businessobject.ProcurementCardTransactionDetail;
import org.kuali.kfs.fp.document.ProcurementCardDocument;
import org.kuali.kfs.sys.KFSConstants;
import org.kuali.kfs.sys.KFSKeyConstants;
import org.kuali.kfs.sys.businessobject.AccountingLine;
import org.kuali.kfs.sys.businessobject.AccountingLineParser;
import org.kuali.kfs.sys.businessobject.TargetAccountingLine;
import org.kuali.kfs.sys.context.SpringContext;
import org.kuali.kfs.sys.document.AccountingDocument;
import org.kuali.kfs.sys.document.validation.event.AddAccountingLineEvent;
import org.kuali.kfs.sys.document.validation.event.DeleteAccountingLineEvent;
import org.kuali.kfs.sys.exception.AccountingLineParserException;
import org.kuali.kfs.sys.web.struts.KualiAccountingDocumentFormBase;
import org.kuali.rice.kew.api.exception.WorkflowException;
import org.kuali.rice.kns.web.struts.form.KualiDocumentFormBase;
import org.kuali.rice.krad.service.KualiRuleService;
import org.kuali.rice.krad.service.PersistenceService;
import org.kuali.rice.krad.util.GlobalVariables;
import org.kuali.rice.krad.util.KRADConstants;

/**
 * This class handles specific Actions requests for the ProcurementCard.
 */
public class ProcurementCardAction extends CapitalAccountingLinesActionBase {
    private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(ProcurementCardAction.class);

    @Override
    protected void loadDocument(KualiDocumentFormBase kualiDocumentFormBase) throws WorkflowException {
        super.loadDocument(kualiDocumentFormBase);
        ProcurementCardDocument procureCardDocument = (ProcurementCardDocument) kualiDocumentFormBase.getDocument();
        int transactionsCount = procureCardDocument.getTransactionEntries().size();
        ProcurementCardForm procurementCardForm = (ProcurementCardForm) kualiDocumentFormBase;
        procurementCardForm.buildNewTargetAccountingLines(transactionsCount);
    }

    /**
     * Override to accomodate multiple target lines.
     *
     * @param transForm
     */
    @Override
    protected void processAccountingLineOverrides(KualiAccountingDocumentFormBase transForm) {
        ProcurementCardForm procurementCardForm = (ProcurementCardForm) transForm;

        processAccountingLineOverrides(procurementCardForm.getNewSourceLine());
        processAccountingLineOverrides(procurementCardForm.getNewTargetLines());
        if (procurementCardForm.hasDocumentId()) {
            AccountingDocument financialDocument = (AccountingDocument) procurementCardForm.getDocument();

            processAccountingLineOverrides(financialDocument.getSourceAccountingLines());
            processAccountingLineOverrides(financialDocument.getTargetAccountingLines());
        }
    }

    /**
     * Override to add the new accounting line to the correct transaction
     *
     * @see org.kuali.module.financial.web.struts.action.KualiFinancialDocumentActionBase#insertTargetLine(org.apache.struts.action.ActionMapping,
     *      org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
     */
    @Override
    public ActionForward insertTargetLine(ActionMapping mapping, ActionForm form, HttpServletRequest request,
            HttpServletResponse response) throws Exception {
        ProcurementCardForm procurementCardForm = (ProcurementCardForm) form;
        ProcurementCardDocument procurementCardDocument = (ProcurementCardDocument) procurementCardForm
                .getDocument();

        int targetContainerIndex = this.getSelectedContainer(request);
        ProcurementCardTargetAccountingLine line = (ProcurementCardTargetAccountingLine) procurementCardForm
                .getNewTargetLines().get(targetContainerIndex);

        ProcurementCardTransactionDetail transactionDetail = (ProcurementCardTransactionDetail) procurementCardDocument
                .getTransactionEntries().get(targetContainerIndex);
        line.setFinancialDocumentTransactionLineNumber(
                transactionDetail.getFinancialDocumentTransactionLineNumber());

        // check any business rules
        boolean rulePassed = SpringContext.getBean(KualiRuleService.class)
                .applyRules(new AddAccountingLineEvent(
                        KFSConstants.NEW_TARGET_ACCT_LINES_PROPERTY_NAME + "["
                                + Integer.toString(targetContainerIndex) + "]",
                        procurementCardForm.getDocument(), line));

        if (rulePassed) {
            // add accountingLine
            SpringContext.getBean(PersistenceService.class).retrieveNonKeyFields(line);
            insertAccountingLine(false, procurementCardForm, line);

            ProcurementCardTargetAccountingLine newLine = new ProcurementCardTargetAccountingLine();
            newLine.setTransactionContainerIndex(targetContainerIndex);

            procurementCardForm.getNewTargetLines().set(targetContainerIndex, newLine);
        }

        return mapping.findForward(KFSConstants.MAPPING_BASIC);
    }

    /**
     * @see org.kuali.kfs.sys.web.struts.KualiAccountingDocumentActionBase#performBalanceInquiryForTargetLine(org.apache.struts.action.ActionMapping,
     *      org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
     */
    @Override
    public ActionForward performBalanceInquiryForTargetLine(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response) throws Exception {
        ProcurementCardForm procurementCardForm = (ProcurementCardForm) form;
        ProcurementCardDocument procurementCardDocument = (ProcurementCardDocument) procurementCardForm
                .getDocument();

        int targetContainerIndex = this.getSelectedContainer(request);
        ProcurementCardTransactionDetail ProcurementCardTransactionDetail = (ProcurementCardTransactionDetail) procurementCardDocument
                .getTransactionEntries().get(targetContainerIndex);

        int targetIndex = super.getSelectedLine(request);
        TargetAccountingLine targetLine = (ProcurementCardTargetAccountingLine) ProcurementCardTransactionDetail
                .getTargetAccountingLines().get(targetIndex);

        return performBalanceInquiryForAccountingLine(mapping, form, request, targetLine);
    }

    /**
     * Override to resync base accounting lines. New lines on the PCDO document can be inserted anywhere in the list, not necessary
     * at the end.
     *
     * @see org.kuali.module.financial.web.struts.action.KualiFinancialDocumentActionBase#insertAccountingLine(boolean,
     *      org.kuali.module.financial.web.struts.form.KualiFinancialDocumentFormBase, org.kuali.rice.krad.bo.AccountingLine)
     */
    @Override
    protected void insertAccountingLine(boolean isSource, KualiAccountingDocumentFormBase financialDocumentForm,
            AccountingLine line) {
        AccountingDocument tdoc = financialDocumentForm.getFinancialDocument();

        // add it to the document
        tdoc.addTargetAccountingLine((TargetAccountingLine) line);
    }

    /**
     * Override to get the correct container of the transaction and then delete the correct accounting line
     *
     * @see org.kuali.module.financial.web.struts.action.KualiFinancialDocumentActionBase#deleteTargetLine(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response
     */
    @Override
    public ActionForward deleteTargetLine(ActionMapping mapping, ActionForm form, HttpServletRequest request,
            HttpServletResponse response) throws Exception {
        int targetContainerIndex = this.getSelectedContainer(request);
        int targetIndex = this.getSelectedLine(request);

        KualiAccountingDocumentFormBase financialDocumentForm = (KualiAccountingDocumentFormBase) form;

        String errorPath = KFSConstants.DOCUMENT_PROPERTY_NAME + "."
                + KFSConstants.EXISTING_TARGET_ACCT_LINE_PROPERTY_NAME + "[" + targetIndex + "]";
        boolean rulePassed = SpringContext.getBean(KualiRuleService.class).applyRules(new DeleteAccountingLineEvent(
                errorPath, financialDocumentForm.getDocument(),
                ((AccountingDocument) financialDocumentForm.getDocument()).getTargetAccountingLine(targetIndex),
                false));

        // if the rule evaluation passed, let's delete it
        if (rulePassed) {
            deleteAccountingLineFromTransactionContainer(financialDocumentForm, targetContainerIndex, targetIndex);
        } else {
            String[] errorParams = new String[] { "target", Integer.toString(targetIndex + 1) };
            GlobalVariables.getMessageMap().putError(errorPath,
                    KFSKeyConstants.ERROR_ACCOUNTINGLINE_DELETERULE_INVALIDACCOUNT, errorParams);
        }

        return mapping.findForward(KFSConstants.MAPPING_BASIC);
    }

    /**
     * Override to remove the accounting line from the correct transaction
     *
     * @see org.kuali.module.financial.web.struts.action.KualiFinancialDocumentActionBase#deleteAccountingLine(boolean,
     *      org.kuali.module.financial.web.struts.form.KualiFinancialDocumentFormBase, int)
     */
    @Override
    protected void deleteAccountingLine(boolean isSource, KualiAccountingDocumentFormBase financialDocumentForm,
            int deleteIndex) {
        ProcurementCardDocument procurementCardDocument = (ProcurementCardDocument) financialDocumentForm
                .getDocument();
        procurementCardDocument.removeTargetAccountingLine(deleteIndex);
    }

    /**
     * Ensures that ProcurementCardForm.newTargetLines is cleared. Otherwise works like super.reload.
     *
     * @see org.kuali.rice.kns.web.struts.action.KualiDocumentActionBase#reload(org.apache.struts.action.ActionMapping,
     *      org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
     */
    @Override
    public ActionForward reload(ActionMapping mapping, ActionForm form, HttpServletRequest request,
            HttpServletResponse response) throws Exception {
        ProcurementCardForm procurementCardForm = (ProcurementCardForm) form;
        procurementCardForm.setNewTargetLines(new ArrayList<ProcurementCardTargetAccountingLine>());

        return super.reload(mapping, procurementCardForm, request, response);
    }

    // get the index of selected transaction entry
    protected int getSelectedContainer(HttpServletRequest request) {
        int selectedContainer = -1;
        String parameterName = (String) request.getAttribute(KRADConstants.METHOD_TO_CALL_ATTRIBUTE);
        if (StringUtils.isNotBlank(parameterName)) {
            String lineNumber = StringUtils.substringBetween(parameterName, ".transactionEntries[", "].");
            selectedContainer = Integer.parseInt(lineNumber);
        }

        return selectedContainer;
    }

    /**
     * Removes the target accounting line at the given index from the transaction container transaction entries.
     *
     * @param financialDocumentForm, targetContainerIndex, targetIndex
     */
    protected void deleteAccountingLineFromTransactionContainer(
            KualiAccountingDocumentFormBase financialDocumentForm, int targetContainerIndex, int targetIndex) {
        ProcurementCardDocument procurementCardDocument = (ProcurementCardDocument) financialDocumentForm
                .getDocument();
        ProcurementCardTransactionDetail procurementCardTransactionDetail = (ProcurementCardTransactionDetail) procurementCardDocument
                .getTransactionEntries().get(targetContainerIndex);
        procurementCardTransactionDetail.getTargetAccountingLines().remove(targetIndex);
    }

    /**
     *
     * @see org.kuali.kfs.sys.web.struts.KualiAccountingDocumentActionBase#uploadTargetLines(org.apache.struts.action.ActionMapping,
     *      org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
     */
    @Override
    public ActionForward uploadTargetLines(ActionMapping mapping, ActionForm form, HttpServletRequest request,
            HttpServletResponse response) throws Exception {
        ProcurementCardForm procurementCardForm = (ProcurementCardForm) form;
        ProcurementCardDocument procurementCardDocument = (ProcurementCardDocument) procurementCardForm
                .getDocument();

        // get index of transaction line
        int tranasactionIndex = getTransactionLineIndex(request);

        uploadTargetAccountingLines(form, tranasactionIndex);

        return mapping.findForward(KFSConstants.MAPPING_BASIC);
    }

    /**
     * This method handles retrieving the actual upload file as an input stream into the document.
     *
     * @param isSource
     * @param form
     * @throws FileNotFoundException
     * @throws IOException
     */
    protected void uploadTargetAccountingLines(ActionForm form, int tranasactionIndex)
            throws FileNotFoundException, IOException {
        ProcurementCardForm pcardForm = (ProcurementCardForm) form;

        List importedLines = null;

        ProcurementCardDocument procurementCardDocument = (ProcurementCardDocument) pcardForm
                .getFinancialDocument();
        ProcurementCardTransactionDetail transactionDetail = (ProcurementCardTransactionDetail) procurementCardDocument
                .getTransactionEntries().get(tranasactionIndex);

        AccountingLineParser accountingLineParser = procurementCardDocument.getAccountingLineParser();

        // import the lines
        String errorPathPrefix = null;
        try {
            errorPathPrefix = KFSConstants.DOCUMENT_PROPERTY_NAME + "."
                    + KFSConstants.TARGET_ACCOUNTING_LINE_ERRORS;
            // get the import file
            FormFile targetFile = ((ProcurementCardTransactionDetail) (procurementCardDocument
                    .getTransactionEntries().get(tranasactionIndex))).getTargetFile();
            checkUploadFile(targetFile);
            importedLines = accountingLineParser.importTargetAccountingLines(targetFile.getFileName(),
                    targetFile.getInputStream(), procurementCardDocument);
        } catch (AccountingLineParserException e) {
            GlobalVariables.getMessageMap().putError(errorPathPrefix, e.getErrorKey(), e.getErrorParameters());
        }

        // add line to list for those lines which were successfully imported
        if (importedLines != null) {
            for (Iterator i = importedLines.iterator(); i.hasNext();) {
                ProcurementCardTargetAccountingLine importedLine = (ProcurementCardTargetAccountingLine) i.next();
                importedLine.setFinancialDocumentTransactionLineNumber(
                        transactionDetail.getFinancialDocumentTransactionLineNumber());
                super.insertAccountingLine(false, pcardForm, importedLine);
            }
        }
    }

    /**
     * Parses the method to call attribute to pick off the transaction line number which should have an action performed
     * on it.
     *
     * @param request
     * @return
     */
    protected int getTransactionLineIndex(HttpServletRequest request) {
        int selectedLine = -1;
        String parameterName = (String) request.getAttribute(KFSConstants.METHOD_TO_CALL_ATTRIBUTE);
        if (StringUtils.isNotBlank(parameterName)) {
            String lineNumber = StringUtils.substringBetween(parameterName, "document.transactionEntries[", "]");
            selectedLine = Integer.parseInt(lineNumber);
        }

        return selectedLine;
    }
}