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.ar.document.authorization;
017    
018    import java.util.HashMap;
019    import java.util.Map;
020    import java.util.Set;
021    
022    import org.apache.commons.lang.StringUtils;
023    import org.kuali.kfs.module.ar.ArAuthorizationConstants;
024    import org.kuali.kfs.module.ar.ArConstants;
025    import org.kuali.kfs.module.ar.businessobject.CashControlDetail;
026    import org.kuali.kfs.module.ar.document.CashControlDocument;
027    import org.kuali.kfs.module.ar.document.PaymentApplicationDocument;
028    import org.kuali.kfs.sys.context.SpringContext;
029    import org.kuali.kfs.sys.document.FinancialSystemTransactionalDocument;
030    import org.kuali.kfs.sys.document.authorization.FinancialSystemTransactionalDocumentPresentationControllerBase;
031    import org.kuali.kfs.sys.service.BankService;
032    import org.kuali.rice.kns.document.Document;
033    import org.kuali.rice.kns.workflow.service.KualiWorkflowDocument;
034    import org.kuali.kfs.gl.service.EntryService;
035    import org.kuali.kfs.sys.KFSConstants;
036    
037    public class CashControlDocumentPresentationController extends FinancialSystemTransactionalDocumentPresentationControllerBase {
038    
039        @Override
040        public Set<String> getEditModes(Document document) {
041            Set<String> editModes = super.getEditModes(document);
042    
043            CashControlDocument cashControlDocument = (CashControlDocument) document;
044            KualiWorkflowDocument workflowDocument = document.getDocumentHeader().getWorkflowDocument();
045    
046            if ((workflowDocument.stateIsInitiated() || workflowDocument.stateIsSaved()) && !(cashControlDocument.getElectronicPaymentClaims().size() > 0)) {
047                editModes.add(ArAuthorizationConstants.CashControlDocumentEditMode.EDIT_PAYMENT_MEDIUM);
048                editModes.add(ArAuthorizationConstants.CashControlDocumentEditMode.EDIT_DETAILS);
049                editModes.add(ArAuthorizationConstants.CashControlDocumentEditMode.EDIT_REF_DOC_NBR);
050                editModes.add(ArAuthorizationConstants.CashControlDocumentEditMode.EDIT_BANK_CODE);
051                if (SpringContext.getBean(BankService.class).isBankSpecificationEnabled()) {
052                    editModes.add(ArAuthorizationConstants.CashControlDocumentEditMode.SHOW_BANK_CODE);
053                }
054            }
055            else {
056                if (StringUtils.isNotBlank(cashControlDocument.getBankCode())) {
057                    editModes.add(ArAuthorizationConstants.CashControlDocumentEditMode.SHOW_BANK_CODE);
058                }
059            }
060    
061            // if the document is in routing, then we have some special rules
062            if (workflowDocument.stateIsEnroute()) {
063    
064                // if doc is cash-type then payment app link always shows, once its in routing
065                if (ArConstants.PaymentMediumCode.CASH.equalsIgnoreCase(cashControlDocument.getCustomerPaymentMediumCode())) {
066                    editModes.add(ArAuthorizationConstants.CashControlDocumentEditMode.EDIT_PAYMENT_APP_DOC);
067                }
068                // if not cash, then payapp link only shows once the GLPE's have been generated
069                else if (!cashControlDocument.getGeneralLedgerPendingEntries().isEmpty()) {
070                    editModes.add(ArAuthorizationConstants.CashControlDocumentEditMode.EDIT_PAYMENT_APP_DOC);
071                }
072    
073                // the person who has the approval request in their Action List
074                // should be able to modify the document
075                if (workflowDocument.isApprovalRequested() && !ArConstants.PaymentMediumCode.CASH.equalsIgnoreCase(cashControlDocument.getCustomerPaymentMediumCode())) {
076                    // if glpes have not been generated yet the user can change payment medium and generate glpes
077                    if (cashControlDocument.getGeneralLedgerPendingEntries().isEmpty()) {
078                        editModes.add(ArAuthorizationConstants.CashControlDocumentEditMode.EDIT_PAYMENT_MEDIUM);
079                        editModes.add(ArAuthorizationConstants.CashControlDocumentEditMode.SHOW_GENERATE_BUTTON);
080                    }
081                    Integer totalGLRecordsCreated = cashControlDocument.getGeneralLedgerEntriesPostedCount();
082                    
083                    if (totalGLRecordsCreated.intValue() > 0) {
084                        editModes.remove(ArAuthorizationConstants.CashControlDocumentEditMode.SHOW_GENERATE_BUTTON);
085                        editModes.remove(ArAuthorizationConstants.CashControlDocumentEditMode.EDIT_PAYMENT_MEDIUM);                    
086                    }
087                }
088                if (workflowDocument.isApprovalRequested() && ArConstants.PaymentMediumCode.CASH.equalsIgnoreCase(cashControlDocument.getCustomerPaymentMediumCode())) {
089                    // if payment medium cash then the ref doc number can be changed
090                    editModes.add(ArAuthorizationConstants.CashControlDocumentEditMode.EDIT_PAYMENT_MEDIUM);
091                    editModes.add(ArAuthorizationConstants.CashControlDocumentEditMode.EDIT_REF_DOC_NBR);
092                }
093    
094            }
095    
096            return editModes;
097        }
098    
099        @Override
100        public boolean canBlanketApprove(Document document) {
101            return false;
102        }
103    
104        @Override
105        public boolean canDisapprove(Document document) {
106            return !hasAtLeastOneAppDocApproved((CashControlDocument) document);
107        }
108    
109        @Override
110        public boolean canApprove(Document document) {
111            return hasAllAppDocsApproved((CashControlDocument) document);
112        }
113    
114        @Override
115        public boolean canErrorCorrect(FinancialSystemTransactionalDocument document) {
116            return false;
117        }
118    
119        @Override
120        public boolean canCancel(Document document) {
121            return !hasAtLeastOneAppDocApproved((CashControlDocument) document);
122        }
123    
124        protected boolean containsGLPEs(CashControlDocument document) {
125            return !document.getGeneralLedgerPendingEntries().isEmpty();
126        }
127    
128        /**
129         * This method checks if the CashControlDocument has at least one application document that has been approved
130         * 
131         * @param ccDoc the CashControlDocument
132         * @return true if it has at least one application document approved, false otherwise
133         */
134        protected boolean hasAtLeastOneAppDocApproved(CashControlDocument cashControlDocument) {
135            boolean result = false;
136            // check if there is at least one Application Document approved
137            for (CashControlDetail cashControlDetail : cashControlDocument.getCashControlDetails()) {
138                PaymentApplicationDocument applicationDocument = cashControlDetail.getReferenceFinancialDocument();
139                KualiWorkflowDocument workflowDocument = applicationDocument.getDocumentHeader().getWorkflowDocument();
140    
141                if (workflowDocument != null && workflowDocument.stateIsApproved()) {
142                    result = true;
143                    break;
144                }
145            }
146            return result;
147        }
148    
149        /**
150         * This method chech if all application document have been approved
151         * 
152         * @param cashControlDocument the CashControlDocument
153         * @return true if all application documents have been approved, false otherwise
154         */
155        protected boolean hasAllAppDocsApproved(CashControlDocument cashControlDocument) {
156            boolean result = true;
157            for (CashControlDetail cashControlDetail : cashControlDocument.getCashControlDetails()) {
158    
159                PaymentApplicationDocument applicationDocument = cashControlDetail.getReferenceFinancialDocument();
160                KualiWorkflowDocument workflowDocument = applicationDocument.getDocumentHeader().getWorkflowDocument();
161    
162                if (!(workflowDocument.stateIsApproved() || workflowDocument.stateIsFinal())) {
163                    result = false;
164                    break;
165                }
166    
167            }
168            return result;
169        }
170    
171    }