001    /*
002     * Copyright 2011 The Kuali Foundation.
003     * 
004     * Licensed under the Educational Community License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     * 
008     * http://www.opensource.org/licenses/ecl2.php
009     * 
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package org.kuali.kfs.fp.document.web.struts;
017    
018    import javax.servlet.http.HttpServletRequest;
019    import javax.servlet.http.HttpServletResponse;
020    
021    import org.apache.commons.lang.StringUtils;
022    import org.apache.struts.action.ActionForm;
023    import org.apache.struts.action.ActionForward;
024    import org.apache.struts.action.ActionMapping;
025    import org.kuali.kfs.coa.service.AccountService;
026    import org.kuali.kfs.fp.businessobject.ProcurementCardTargetAccountingLine;
027    import org.kuali.kfs.fp.businessobject.ProcurementCardTransactionDetail;
028    import org.kuali.kfs.fp.document.ProcurementCardDocument;
029    import org.kuali.kfs.sys.KFSConstants;
030    import org.kuali.kfs.sys.KFSKeyConstants;
031    import org.kuali.kfs.sys.businessobject.AccountingLine;
032    import org.kuali.kfs.sys.businessobject.TargetAccountingLine;
033    import org.kuali.kfs.sys.context.SpringContext;
034    import org.kuali.kfs.sys.document.AccountingDocument;
035    import org.kuali.kfs.sys.document.validation.event.AddAccountingLineEvent;
036    import org.kuali.kfs.sys.document.validation.event.DeleteAccountingLineEvent;
037    import org.kuali.kfs.sys.web.struts.KualiAccountingDocumentActionBase;
038    import org.kuali.kfs.sys.web.struts.KualiAccountingDocumentFormBase;
039    import org.kuali.rice.kns.service.KualiRuleService;
040    import org.kuali.rice.kns.service.PersistenceService;
041    import org.kuali.rice.kns.util.GlobalVariables;
042    import org.kuali.rice.kns.util.KNSConstants;
043    import org.kuali.rice.kns.util.TypedArrayList;
044    
045    /**
046     * This class handles specific Actions requests for the ProcurementCard.
047     */
048    public class ProcurementCardAction extends KualiAccountingDocumentActionBase {
049        private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(ProcurementCardAction.class);
050    
051        /**
052         * Override to accomodate multiple target lines.
053         * 
054         * @param transForm
055         */
056        @Override
057        protected void processAccountingLineOverrides(KualiAccountingDocumentFormBase transForm) {
058            ProcurementCardForm procurementCardForm = (ProcurementCardForm) transForm;
059    
060            processAccountingLineOverrides(procurementCardForm.getNewSourceLine());
061            processAccountingLineOverrides(procurementCardForm.getNewTargetLines());
062            if (procurementCardForm.hasDocumentId()) {
063                AccountingDocument financialDocument = (AccountingDocument) procurementCardForm.getDocument();
064    
065                processAccountingLineOverrides(financialDocument.getSourceAccountingLines());
066                processAccountingLineOverrides(financialDocument.getTargetAccountingLines());
067            }
068        }
069    
070        /**
071         * Override to add the new accounting line to the correct transaction
072         * 
073         * @see org.kuali.module.financial.web.struts.action.KualiFinancialDocumentActionBase#insertTargetLine(org.apache.struts.action.ActionMapping,
074         *      org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
075         */
076        @Override
077        public ActionForward insertTargetLine(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
078            ProcurementCardForm procurementCardForm = (ProcurementCardForm) form;
079            ProcurementCardDocument procurementCardDocument = (ProcurementCardDocument) procurementCardForm.getDocument();
080    
081            // get index of new target line
082            int newTargetIndex = super.getSelectedLine(request);
083            ProcurementCardTargetAccountingLine line = (ProcurementCardTargetAccountingLine) procurementCardForm.getNewTargetLines().get(newTargetIndex);
084            
085            // populate chartOfAccountsCode from account number if accounts cant cross chart and Javascript is turned off
086            //SpringContext.getBean(AccountService.class).populateAccountingLineChartIfNeeded(line);
087    
088            ProcurementCardTransactionDetail transactionDetail = (ProcurementCardTransactionDetail) procurementCardDocument.getTransactionEntries().get(newTargetIndex);
089            line.setFinancialDocumentTransactionLineNumber(transactionDetail.getFinancialDocumentTransactionLineNumber());
090    
091            // check any business rules
092            boolean rulePassed = SpringContext.getBean(KualiRuleService.class).applyRules(new AddAccountingLineEvent(KFSConstants.NEW_TARGET_ACCT_LINES_PROPERTY_NAME + "[" + Integer.toString(newTargetIndex) + "]", procurementCardForm.getDocument(), (AccountingLine) line));
093    
094            if (rulePassed) {
095                // add accountingLine
096                SpringContext.getBean(PersistenceService.class).retrieveNonKeyFields(line);
097                insertAccountingLine(false, procurementCardForm, line);
098    
099                // clear the used newTargetIndex
100                procurementCardForm.getNewTargetLines().set(newTargetIndex, new ProcurementCardTargetAccountingLine());
101            }
102    
103            return mapping.findForward(KFSConstants.MAPPING_BASIC);
104        }
105    
106        /**
107         * @see org.kuali.kfs.sys.web.struts.KualiAccountingDocumentActionBase#performBalanceInquiryForTargetLine(org.apache.struts.action.ActionMapping,
108         *      org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
109         */
110        @Override
111        public ActionForward performBalanceInquiryForTargetLine(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
112            ProcurementCardForm procurementCardForm = (ProcurementCardForm) form;
113            ProcurementCardDocument procurementCardDocument = (ProcurementCardDocument) procurementCardForm.getDocument();
114    
115            int targetContainerIndex = this.getSelectedContainer(request);
116            ProcurementCardTransactionDetail ProcurementCardTransactionDetail = (ProcurementCardTransactionDetail) procurementCardDocument.getTransactionEntries().get(targetContainerIndex);
117    
118            int targetIndex = super.getSelectedLine(request);
119            TargetAccountingLine targetLine = (ProcurementCardTargetAccountingLine) ProcurementCardTransactionDetail.getTargetAccountingLines().get(targetIndex);
120    
121            return performBalanceInquiryForAccountingLine(mapping, form, request, targetLine);
122        }
123    
124        /**
125         * Override to resync base accounting lines. New lines on the PCDO document can be inserted anywhere in the list, not necessary
126         * at the end.
127         * 
128         * @see org.kuali.module.financial.web.struts.action.KualiFinancialDocumentActionBase#insertAccountingLine(boolean,
129         *      org.kuali.module.financial.web.struts.form.KualiFinancialDocumentFormBase, org.kuali.rice.kns.bo.AccountingLine)
130         */
131        @Override
132        protected void insertAccountingLine(boolean isSource, KualiAccountingDocumentFormBase financialDocumentForm, AccountingLine line) {
133            AccountingDocument tdoc = financialDocumentForm.getFinancialDocument();
134    
135            // add it to the document
136            tdoc.addTargetAccountingLine((TargetAccountingLine) line);
137        }
138    
139        /**
140         * Override to get the correct container of the transaction and then delete the correct accounting line
141         * 
142         * @see org.kuali.module.financial.web.struts.action.KualiFinancialDocumentActionBase#deleteTargetLine(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response
143         */
144        @Override
145        public ActionForward deleteTargetLine(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
146            int targetContainerIndex = this.getSelectedContainer(request);
147            int targetIndex = this.getSelectedLine(request);
148            
149            KualiAccountingDocumentFormBase financialDocumentForm = (KualiAccountingDocumentFormBase) form;
150    
151            String errorPath = KFSConstants.DOCUMENT_PROPERTY_NAME + "." + KFSConstants.EXISTING_TARGET_ACCT_LINE_PROPERTY_NAME + "[" + targetIndex + "]";
152            boolean rulePassed = SpringContext.getBean(KualiRuleService.class).applyRules(new DeleteAccountingLineEvent(errorPath, financialDocumentForm.getDocument(), ((AccountingDocument) financialDocumentForm.getDocument()).getTargetAccountingLine(targetIndex), false));
153    
154            // if the rule evaluation passed, let's delete it
155            if (rulePassed) {
156                deleteAccountingLineFromTransactionContainer(financialDocumentForm, targetContainerIndex, targetIndex);
157            }
158            else {
159                String[] errorParams = new String[] { "target", Integer.toString(targetIndex + 1) };
160                GlobalVariables.getMessageMap().putError(errorPath, KFSKeyConstants.ERROR_ACCOUNTINGLINE_DELETERULE_INVALIDACCOUNT, errorParams);
161            }
162    
163            return mapping.findForward(KFSConstants.MAPPING_BASIC);
164        }
165        
166        /**
167         * Override to remove the accounting line from the correct transaction
168         * 
169         * @see org.kuali.module.financial.web.struts.action.KualiFinancialDocumentActionBase#deleteAccountingLine(boolean,
170         *      org.kuali.module.financial.web.struts.form.KualiFinancialDocumentFormBase, int)
171         */
172        @Override
173        protected void deleteAccountingLine(boolean isSource, KualiAccountingDocumentFormBase financialDocumentForm, int deleteIndex) {
174            ProcurementCardDocument procurementCardDocument = (ProcurementCardDocument) financialDocumentForm.getDocument();
175            procurementCardDocument.removeTargetAccountingLine(deleteIndex);
176        }
177    
178        /**
179         * Ensures that ProcurementCardForm.newTargetLines is cleared. Otherwise works like super.reload.
180         * 
181         * @see org.kuali.rice.kns.web.struts.action.KualiDocumentActionBase#reload(org.apache.struts.action.ActionMapping,
182         *      org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
183         */
184        @Override
185        public ActionForward reload(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
186            ProcurementCardForm procurementCardForm = (ProcurementCardForm) form;
187            procurementCardForm.setNewTargetLines(new TypedArrayList(ProcurementCardTargetAccountingLine.class));
188    
189            return super.reload(mapping, procurementCardForm, request, response);
190        }
191    
192        // get the index of selected transaction entry
193        protected int getSelectedContainer(HttpServletRequest request) {
194            int selectedContainer = -1;
195            String parameterName = (String) request.getAttribute(KNSConstants.METHOD_TO_CALL_ATTRIBUTE);
196            if (StringUtils.isNotBlank(parameterName)) {
197                String lineNumber = StringUtils.substringBetween(parameterName, ".transactionEntries[", "].");
198                selectedContainer = Integer.parseInt(lineNumber);
199            }
200    
201            return selectedContainer;
202        }
203        
204        /**
205         * Removes the target accounting line at the given index from the transaction container transaction entries.
206         * 
207         * @param financialDocumentForm, targetContainerIndex, targetIndex
208         */
209        protected void deleteAccountingLineFromTransactionContainer(KualiAccountingDocumentFormBase financialDocumentForm, int targetContainerIndex, int targetIndex) {
210            ProcurementCardDocument procurementCardDocument = (ProcurementCardDocument) financialDocumentForm.getDocument(); 
211            ProcurementCardTransactionDetail procurementCardTransactionDetail = (ProcurementCardTransactionDetail) procurementCardDocument.getTransactionEntries().get(targetContainerIndex);
212            procurementCardTransactionDetail.getTargetAccountingLines().remove(targetIndex);
213        }
214    }