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.module.cam.document.web.struts;
017    
018    import java.io.FileNotFoundException;
019    import java.io.IOException;
020    import java.util.Collection;
021    import java.util.HashMap;
022    import java.util.HashSet;
023    import java.util.List;
024    import java.util.Map;
025    import java.util.Set;
026    
027    import javax.servlet.http.HttpServletRequest;
028    import javax.servlet.http.HttpServletResponse;
029    
030    import org.apache.commons.lang.ArrayUtils;
031    import org.apache.commons.lang.StringUtils;
032    import org.apache.struts.action.ActionForm;
033    import org.apache.struts.action.ActionForward;
034    import org.apache.struts.action.ActionMapping;
035    import org.kuali.kfs.coa.service.AccountService;
036    import org.kuali.kfs.module.cam.CamsConstants;
037    import org.kuali.kfs.module.cam.CamsKeyConstants;
038    import org.kuali.kfs.module.cam.CamsPropertyConstants;
039    import org.kuali.kfs.module.cam.businessobject.Asset;
040    import org.kuali.kfs.module.cam.businessobject.AssetGlobal;
041    import org.kuali.kfs.module.cam.businessobject.AssetPaymentAssetDetail;
042    import org.kuali.kfs.module.cam.businessobject.AssetPaymentDetail;
043    import org.kuali.kfs.module.cam.document.AssetPaymentDocument;
044    import org.kuali.kfs.module.cam.document.service.AssetPaymentService;
045    import org.kuali.kfs.module.cam.document.validation.event.AssetPaymentAddAssetEvent;
046    import org.kuali.kfs.module.cam.document.validation.event.AssetPaymentManuallyAddAccountingLineEvent;
047    import org.kuali.kfs.module.cam.document.validation.event.AssetPaymentPrepareRouteEvent;
048    import org.kuali.kfs.sys.KFSConstants;
049    import org.kuali.kfs.sys.KFSKeyConstants;
050    import org.kuali.kfs.sys.KFSPropertyConstants;
051    import org.kuali.kfs.sys.businessobject.SourceAccountingLine;
052    import org.kuali.kfs.sys.context.SpringContext;
053    import org.kuali.kfs.sys.document.validation.event.AddAccountingLineEvent;
054    import org.kuali.kfs.sys.service.SegmentedLookupResultsService;
055    import org.kuali.kfs.sys.web.struts.KualiAccountingDocumentActionBase;
056    import org.kuali.rice.kew.exception.WorkflowException;
057    import org.kuali.rice.kew.util.KEWConstants;
058    import org.kuali.rice.kns.bo.PersistableBusinessObject;
059    import org.kuali.rice.kns.exception.ValidationException;
060    import org.kuali.rice.kns.question.ConfirmationQuestion;
061    import org.kuali.rice.kns.service.DataDictionaryService;
062    import org.kuali.rice.kns.service.KualiConfigurationService;
063    import org.kuali.rice.kns.service.KualiRuleService;
064    import org.kuali.rice.kns.service.ParameterService;
065    import org.kuali.rice.kns.service.PersistenceService;
066    import org.kuali.rice.kns.util.GlobalVariables;
067    import org.kuali.rice.kns.util.KNSConstants;
068    import org.kuali.rice.kns.util.ObjectUtils;
069    import org.kuali.rice.kns.web.struts.form.KualiDocumentFormBase;
070    
071    public class AssetPaymentAction extends KualiAccountingDocumentActionBase {
072        protected static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(AssetPaymentAction.class);
073    
074    
075        @Override
076        public ActionForward docHandler(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
077            ActionForward actionForward = super.docHandler(mapping, form, request, response);
078            AssetPaymentForm assetPaymentForm = (AssetPaymentForm) form;
079            String command = assetPaymentForm.getCommand();
080    
081            // If a asset was selected from the asset payment lookup page then insert asset into the document.
082            if (KEWConstants.INITIATE_COMMAND.equals(command) && ((assetPaymentForm.getCapitalAssetNumber() != null) && !assetPaymentForm.getCapitalAssetNumber().trim().equals(""))) {
083                List<AssetPaymentAssetDetail> assetPaymentAssetDetails = assetPaymentForm.getAssetPaymentDocument().getAssetPaymentAssetDetail();
084    
085                AssetPaymentAssetDetail assetPaymentAssetDetail = new AssetPaymentAssetDetail();
086                assetPaymentAssetDetail.setDocumentNumber(assetPaymentForm.getAssetPaymentDocument().getDocumentNumber());
087                assetPaymentAssetDetail.setCapitalAssetNumber(new Long(assetPaymentForm.getCapitalAssetNumber()));
088                assetPaymentAssetDetail.refreshReferenceObject(CamsPropertyConstants.AssetPaymentDocument.ASSET);
089                assetPaymentAssetDetail.setPreviousTotalCostAmount(assetPaymentAssetDetail.getAsset().getTotalCostAmount());
090    
091                assetPaymentAssetDetails.add(assetPaymentAssetDetail);
092                assetPaymentForm.getAssetPaymentDocument().setAssetPaymentAssetDetail(assetPaymentAssetDetails);
093                assetPaymentForm.setCapitalAssetNumber("");
094            }
095            return actionForward;
096        }
097    
098        /**
099         * @see org.kuali.kfs.sys.web.struts.KualiAccountingDocumentActionBase#refresh(org.apache.struts.action.ActionMapping,
100         *      org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
101         */
102        @Override
103        public ActionForward refresh(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
104            super.refresh(mapping, form, request, response);
105    
106            AssetPaymentForm assetPaymentForm = (AssetPaymentForm) form;
107    
108            Collection<PersistableBusinessObject> rawValues = null;
109            Map<String, Set<String>> segmentedSelection = new HashMap<String, Set<String>>();
110    
111            // If multiple asset lookup was used to select the assets, then....
112            if (StringUtils.equals(KFSConstants.MULTIPLE_VALUE, assetPaymentForm.getRefreshCaller())) {
113                String lookupResultsSequenceNumber = assetPaymentForm.getLookupResultsSequenceNumber();
114    
115                if (StringUtils.isNotBlank(lookupResultsSequenceNumber)) {
116                    // actually returning from a multiple value lookup
117                    Set<String> selectedIds = SpringContext.getBean(SegmentedLookupResultsService.class).retrieveSetOfSelectedObjectIds(lookupResultsSequenceNumber, GlobalVariables.getUserSession().getPerson().getPrincipalId());
118                    for (String selectedId : selectedIds) {
119                        String selectedObjId = StringUtils.substringBefore(selectedId, ".");
120                        String selectedMonthData = StringUtils.substringAfter(selectedId, ".");
121    
122                        if (!segmentedSelection.containsKey(selectedObjId)) {
123                            segmentedSelection.put(selectedObjId, new HashSet<String>());
124                        }
125                        segmentedSelection.get(selectedObjId).add(selectedMonthData);
126                    }
127                    // Retrieving selected data from table.
128                    LOG.debug("Asking segmentation service for object ids " + segmentedSelection.keySet());
129                    rawValues = SpringContext.getBean(SegmentedLookupResultsService.class).retrieveSelectedResultBOs(lookupResultsSequenceNumber, segmentedSelection.keySet(), Asset.class, GlobalVariables.getUserSession().getPerson().getPrincipalId());
130                }
131    
132                List<AssetPaymentAssetDetail> assetPaymentAssetDetails = assetPaymentForm.getAssetPaymentDocument().getAssetPaymentAssetDetail();
133                if (rawValues != null) {
134                    for (PersistableBusinessObject bo : rawValues) {
135                        Asset asset = (Asset) bo;
136    
137                        boolean addIt = true;
138                        for (AssetPaymentAssetDetail detail : assetPaymentAssetDetails) {
139                            if (detail.getCapitalAssetNumber().compareTo(asset.getCapitalAssetNumber()) == 0) {
140                                addIt = false;
141                                break;
142                            }
143                        }
144    
145                        // If it doesn't already exist in the list add it.
146                        if (addIt) {
147                            AssetPaymentAssetDetail assetPaymentAssetDetail = new AssetPaymentAssetDetail();
148                            assetPaymentAssetDetail.setDocumentNumber(assetPaymentForm.getAssetPaymentDocument().getDocumentNumber());
149                            assetPaymentAssetDetail.setCapitalAssetNumber(asset.getCapitalAssetNumber());
150                            assetPaymentAssetDetail.refreshReferenceObject(CamsPropertyConstants.AssetPaymentDocument.ASSET);
151                            assetPaymentAssetDetail.setPreviousTotalCostAmount(assetPaymentAssetDetail.getAsset().getTotalCostAmount());
152    
153                            assetPaymentAssetDetails.add(assetPaymentAssetDetail);
154                        }
155                    }
156                    assetPaymentForm.getAssetPaymentDocument().setAssetPaymentAssetDetail(assetPaymentAssetDetails);
157                }
158            }
159            return mapping.findForward(KFSConstants.MAPPING_BASIC);
160        }
161    
162        /**
163         * @see org.kuali.kfs.sys.web.struts.KualiAccountingDocumentActionBase#uploadAccountingLines(boolean,
164         *      org.apache.struts.action.ActionForm)
165         */
166        @Override
167        protected void uploadAccountingLines(boolean isSource, ActionForm form) throws FileNotFoundException, IOException {
168            AssetPaymentForm assetPaymentForm = (AssetPaymentForm) form;
169            super.uploadAccountingLines(isSource, assetPaymentForm);
170            List<AssetPaymentDetail> assetPaymentDetails = assetPaymentForm.getAssetPaymentDocument().getSourceAccountingLines();
171            for (AssetPaymentDetail assetPaymentDetail : assetPaymentDetails) {
172                getAssetPaymentService().extractPostedDatePeriod(assetPaymentDetail);
173            }
174        }
175    
176    
177        /**
178         * @see org.kuali.kfs.sys.web.struts.KualiAccountingDocumentActionBase#insertSourceLine(org.apache.struts.action.ActionMapping,
179         *      org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
180         */
181        @Override
182        public ActionForward insertSourceLine(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
183            AssetPaymentForm assetPaymentForm = (AssetPaymentForm) form;
184            SourceAccountingLine line = assetPaymentForm.getNewSourceLine();
185    
186            // populate chartOfAccountsCode from account number if accounts cant cross chart and Javascript is turned off
187            //SpringContext.getBean(AccountService.class).populateAccountingLineChartIfNeeded(line);
188    
189            boolean rulePassed = true;
190            // Check any business rules. We separate general accounting line validation into AssetPaymentManuallyAddAccountingLineEvent,
191            // and trigger it from this action, also document save.
192            rulePassed &= SpringContext.getBean(KualiRuleService.class).applyRules(new AssetPaymentManuallyAddAccountingLineEvent(KFSConstants.NEW_SOURCE_ACCT_LINE_PROPERTY_NAME, assetPaymentForm.getDocument(), line));
193            if (rulePassed) {
194                rulePassed &= SpringContext.getBean(KualiRuleService.class).applyRules(new AddAccountingLineEvent(KFSConstants.NEW_SOURCE_ACCT_LINE_PROPERTY_NAME, assetPaymentForm.getDocument(), line));
195            }
196            if (rulePassed) {
197                // add accountingLine
198                SpringContext.getBean(PersistenceService.class).refreshAllNonUpdatingReferences(line);
199                insertAccountingLine(true, assetPaymentForm, line);
200    
201                // clear the used new source line
202                assetPaymentForm.setNewSourceLine(new AssetPaymentDetail());
203            }
204            
205            return mapping.findForward(KFSConstants.MAPPING_BASIC);
206        }
207    
208    
209        /**
210         * Inserts a new asset into the document
211         * 
212         * @param mapping
213         * @param form
214         * @param request
215         * @param response
216         * @return ActionForward
217         * @throws Exception
218         */
219        public ActionForward insertAssetPaymentAssetDetail(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
220            AssetPaymentForm assetPaymentForm = (AssetPaymentForm) form;
221            AssetPaymentDocument assetPaymentDocument = assetPaymentForm.getAssetPaymentDocument();
222    
223            List<AssetPaymentAssetDetail> assetPaymentDetails = assetPaymentForm.getAssetPaymentDocument().getAssetPaymentAssetDetail();
224    
225            AssetPaymentAssetDetail newAssetPaymentAssetDetail = new AssetPaymentAssetDetail();
226            String sCapitalAssetNumber = assetPaymentForm.getCapitalAssetNumber();
227    
228            String errorPath = CamsPropertyConstants.Asset.CAPITAL_ASSET_NUMBER;
229    
230            // Validating the asset code is numeric
231            Long capitalAssetNumber = null;
232            try {
233                capitalAssetNumber = Long.parseLong(sCapitalAssetNumber);
234            }
235            catch (NumberFormatException e) {
236                // Validating the asset number field is not empty
237                if (ObjectUtils.isNull(sCapitalAssetNumber) || StringUtils.isBlank(sCapitalAssetNumber)) {
238                    String label = SpringContext.getBean(DataDictionaryService.class).getDataDictionary().getBusinessObjectEntry(AssetPaymentAssetDetail.class.getName()).getAttributeDefinition(CamsPropertyConstants.Asset.CAPITAL_ASSET_NUMBER).getLabel();
239                    GlobalVariables.getMessageMap().putError(errorPath, KFSKeyConstants.ERROR_REQUIRED, label);
240                }
241                else {
242                    // it is not empty but has an invalid value.
243                    GlobalVariables.getMessageMap().putError(errorPath, CamsKeyConstants.AssetLocationGlobal.ERROR_INVALID_CAPITAL_ASSET_NUMBER, sCapitalAssetNumber);
244                }
245                return mapping.findForward(KFSConstants.MAPPING_BASIC);
246            }
247    
248            boolean rulePassed = true;
249    
250            newAssetPaymentAssetDetail.setDocumentNumber(assetPaymentDocument.getDocumentNumber());
251            newAssetPaymentAssetDetail.setCapitalAssetNumber(capitalAssetNumber);
252            newAssetPaymentAssetDetail.refreshReferenceObject(CamsPropertyConstants.AssetPaymentDocument.ASSET);
253            // Validating the new asset
254            rulePassed &= SpringContext.getBean(KualiRuleService.class).applyRules(new AssetPaymentAddAssetEvent(errorPath, assetPaymentForm.getDocument(), newAssetPaymentAssetDetail));
255            if (rulePassed) {
256                // Storing the current asset cost.
257                newAssetPaymentAssetDetail.setPreviousTotalCostAmount(newAssetPaymentAssetDetail.getAsset().getTotalCostAmount());
258    
259                assetPaymentForm.getAssetPaymentDocument().addAssetPaymentAssetDetail(newAssetPaymentAssetDetail);
260                assetPaymentForm.setCapitalAssetNumber("");
261            }
262            return mapping.findForward(KFSConstants.MAPPING_BASIC);
263        }
264    
265        /**
266         * Deletes an asset from the document
267         * 
268         * @param mapping
269         * @param form
270         * @param request
271         * @param response
272         * @return ActionForward
273         * @throws Exception
274         */
275        public ActionForward deleteAssetPaymentAssetDetail(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
276            AssetPaymentForm assetPaymentForm = (AssetPaymentForm) form;
277    
278            int deleteIndex = getLineToDelete(request);
279    
280            // Getting the asset number that is going to be deleted from document
281            Long capitalAssetNumber = assetPaymentForm.getAssetPaymentDocument().getAssetPaymentAssetDetail().get(deleteIndex).getCapitalAssetNumber();
282    
283            // Deleting the asset from document
284            assetPaymentForm.getAssetPaymentDocument().getAssetPaymentAssetDetail().remove(deleteIndex);
285    
286            return mapping.findForward(KFSConstants.MAPPING_BASIC);
287        }
288    
289        @Override
290        public ActionForward route(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
291            AssetPaymentDocument assetPaymentDocument = ((AssetPaymentForm) form).getAssetPaymentDocument();
292            String errorPath = KFSConstants.DOCUMENT_PROPERTY_NAME;
293            // run all validation first
294            boolean rulePassed = SpringContext.getBean(KualiRuleService.class).applyRules(new AssetPaymentPrepareRouteEvent(errorPath, assetPaymentDocument));
295            if (rulePassed) {
296                // this super method call could trigger the warning message of object sub type code from payment lines not matching the
297                // one from assets.
298                return super.route(mapping, form, request, response);
299            }
300            else {
301                return mapping.findForward(KFSConstants.MAPPING_BASIC);
302            }
303        }
304    
305        @Override
306        public ActionForward blanketApprove(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
307            AssetPaymentDocument assetPaymentDocument = ((AssetPaymentForm) form).getAssetPaymentDocument();
308            String errorPath = KFSConstants.DOCUMENT_PROPERTY_NAME;
309            // run all validation first
310            boolean rulePassed = SpringContext.getBean(KualiRuleService.class).applyRules(new AssetPaymentPrepareRouteEvent(errorPath, assetPaymentDocument));
311            if (rulePassed) {
312                return super.blanketApprove(mapping, form, request, response);
313            }
314            else {
315                return mapping.findForward(KFSConstants.MAPPING_BASIC);
316            }
317        }
318    
319        protected AssetPaymentService getAssetPaymentService() {
320            return SpringContext.getBean(AssetPaymentService.class);
321        }
322    
323    }