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.authorization; 017 018 import java.util.Set; 019 020 import org.apache.commons.lang.StringUtils; 021 import org.kuali.kfs.fp.businessobject.CashDrawer; 022 import org.kuali.kfs.fp.document.CashManagementDocument; 023 import org.kuali.kfs.fp.document.service.CashManagementService; 024 import org.kuali.kfs.fp.service.CashDrawerService; 025 import org.kuali.kfs.sys.KFSConstants; 026 import org.kuali.kfs.sys.KfsAuthorizationConstants; 027 import org.kuali.kfs.sys.KFSConstants.CashDrawerConstants; 028 import org.kuali.kfs.sys.context.SpringContext; 029 import org.kuali.kfs.sys.document.authorization.LedgerPostingDocumentPresentationControllerBase; 030 import org.kuali.rice.kew.dto.ValidActionsDTO; 031 import org.kuali.rice.kew.util.KEWConstants; 032 import org.kuali.rice.kns.datadictionary.MaintenanceDocumentEntry; 033 import org.kuali.rice.kns.document.Document; 034 import org.kuali.rice.kns.maintenance.Maintainable; 035 import org.kuali.rice.kns.service.DataDictionaryService; 036 import org.kuali.rice.kns.service.MaintenanceDocumentService; 037 import org.kuali.rice.kns.workflow.service.KualiWorkflowDocument; 038 039 public class CashManagementDocumentPresentationControllerBase extends LedgerPostingDocumentPresentationControllerBase implements CashManagementDocumentPresentationController { 040 041 /** 042 * @see org.kuali.kfs.sys.document.authorization.FinancialSystemTransactionalDocumentPresentationControllerBase#getEditModes(org.kuali.rice.kns.document.Document) 043 */ 044 @Override 045 public Set<String> getEditModes(Document document) { 046 Set<String> editModes = super.getEditModes(document); 047 048 KualiWorkflowDocument workflowDocument = document.getDocumentHeader().getWorkflowDocument(); 049 if (workflowDocument.stateIsSaved()) { 050 editModes.add(KfsAuthorizationConstants.CashManagementEditMode.ALLOW_CANCEL_DEPOSITS); 051 052 CashManagementDocument cashManagementDocument = (CashManagementDocument) document; 053 if (!cashManagementDocument.hasFinalDeposit()) { 054 editModes.add(KfsAuthorizationConstants.CashManagementEditMode.ALLOW_ADDITIONAL_DEPOSITS); 055 } 056 } 057 058 return editModes; 059 } 060 061 /** 062 * @see org.kuali.rice.kns.document.authorization.DocumentPresentationControllerBase#canApprove(org.kuali.rice.kns.document.Document) 063 */ 064 @Override 065 protected boolean canApprove(Document document) { 066 KualiWorkflowDocument workflowDocument = document.getDocumentHeader().getWorkflowDocument(); 067 if (workflowDocument.stateIsEnroute()) { 068 ValidActionsDTO validActions = workflowDocument.getRouteHeader().getValidActions(); 069 return validActions.contains(KEWConstants.ACTION_TAKEN_APPROVED_CD); 070 } 071 072 return super.canApprove(document); 073 } 074 075 /** 076 * @see org.kuali.rice.kns.document.authorization.DocumentPresentationControllerBase#canBlanketApprove(org.kuali.rice.kns.document.Document) 077 */ 078 @Override 079 protected boolean canBlanketApprove(Document document) { 080 KualiWorkflowDocument workflowDocument = document.getDocumentHeader().getWorkflowDocument(); 081 if (workflowDocument.stateIsInitiated() || workflowDocument.stateIsSaved()) { 082 CashManagementDocument cmDoc = (CashManagementDocument) document; 083 if (!cmDoc.hasFinalDeposit() || !SpringContext.getBean(CashManagementService.class).allVerifiedCashReceiptsAreDeposited(cmDoc)) { 084 return false; 085 } 086 087 // CM document can only be routed if it contains a Final Deposit 088 ValidActionsDTO validActions = workflowDocument.getRouteHeader().getValidActions(); 089 return validActions.contains(KEWConstants.ACTION_TAKEN_BLANKET_APPROVE_CD); 090 } 091 092 return super.canBlanketApprove(document); 093 } 094 095 /** 096 * @see org.kuali.rice.kns.document.authorization.DocumentPresentationControllerBase#canCancel(org.kuali.rice.kns.document.Document) 097 */ 098 @Override 099 protected boolean canCancel(Document document) { 100 KualiWorkflowDocument workflowDocument = document.getDocumentHeader().getWorkflowDocument(); 101 if (workflowDocument.stateIsInitiated() || workflowDocument.stateIsSaved()) { 102 CashManagementDocument cmDoc = (CashManagementDocument) document; 103 if (!SpringContext.getBean(CashManagementService.class).allowDocumentCancellation(cmDoc)) { 104 return false; 105 } 106 107 // CM document can only be routed if it contains a Final Deposit 108 ValidActionsDTO validActions = workflowDocument.getRouteHeader().getValidActions(); 109 return validActions.contains(KEWConstants.ACTION_TAKEN_CANCELED_CD); 110 } 111 112 return super.canCancel(document); 113 } 114 115 /** 116 * @see org.kuali.rice.kns.document.authorization.DocumentPresentationControllerBase#canDisapprove(org.kuali.rice.kns.document.Document) 117 */ 118 @Override 119 protected boolean canDisapprove(Document document) { 120 KualiWorkflowDocument workflowDocument = document.getDocumentHeader().getWorkflowDocument(); 121 if (workflowDocument.stateIsEnroute()) { 122 ValidActionsDTO validActions = workflowDocument.getRouteHeader().getValidActions(); 123 return validActions.contains(KEWConstants.ACTION_TAKEN_DENIED_CD); 124 } 125 126 return super.canDisapprove(document); 127 } 128 129 /** 130 * @see org.kuali.rice.kns.document.authorization.DocumentPresentationControllerBase#canRoute(org.kuali.rice.kns.document.Document) 131 */ 132 @Override 133 protected boolean canRoute(Document document) { 134 KualiWorkflowDocument workflowDocument = document.getDocumentHeader().getWorkflowDocument(); 135 if (workflowDocument.stateIsInitiated() || workflowDocument.stateIsSaved()) { 136 CashManagementDocument cmDoc = (CashManagementDocument) document; 137 if (!cmDoc.hasFinalDeposit() || !SpringContext.getBean(CashManagementService.class).allVerifiedCashReceiptsAreDeposited(cmDoc)) { 138 return false; 139 } 140 141 // CM document can only be routed if it contains a Final Deposit 142 ValidActionsDTO validActions = workflowDocument.getRouteHeader().getValidActions(); 143 return validActions.contains(KEWConstants.ACTION_TAKEN_ROUTED_CD); 144 } 145 146 return super.canRoute(document); 147 } 148 149 /** 150 * @see org.kuali.rice.kns.document.authorization.DocumentPresentationControllerBase#canSave(org.kuali.rice.kns.document.Document) 151 */ 152 @Override 153 protected boolean canSave(Document document) { 154 KualiWorkflowDocument workflowDocument = document.getDocumentHeader().getWorkflowDocument(); 155 if (workflowDocument.stateIsInitiated() || workflowDocument.stateIsSaved()) { 156 CashManagementDocument cmDoc = (CashManagementDocument) document; 157 if (cmDoc.getCashDrawerStatus() == null || cmDoc.getCashDrawerStatus().equals(CashDrawerConstants.STATUS_CLOSED)) { 158 return false; 159 } 160 161 // CM document can only be saved (via the save button) if the CashDrawer is not closed 162 ValidActionsDTO validActions = workflowDocument.getRouteHeader().getValidActions(); 163 return validActions.contains(KEWConstants.ACTION_TAKEN_SAVED_CD); 164 } 165 166 return super.canRoute(document); 167 } 168 169 /** 170 * @see org.kuali.rice.kns.document.authorization.DocumentPresentationControllerBase#canAdHocRoute(org.kuali.rice.kns.document.Document) 171 */ 172 @Override 173 protected boolean canAddAdhocRequests(Document document) { 174 KualiWorkflowDocument workflowDocument = document.getDocumentHeader().getWorkflowDocument(); 175 if (workflowDocument.stateIsEnroute()) { 176 ValidActionsDTO validActions = workflowDocument.getRouteHeader().getValidActions(); 177 return validActions.contains(KEWConstants.ACTION_TAKEN_FYI_CD); 178 } 179 180 return super.canAddAdhocRequests(document); 181 } 182 183 /** 184 * Determines if the cash drawer can be opened by testing two things: 185 * <ol> 186 * <li>That the cash drawer is currently closed.</li> 187 * <li>That no cash drawer maintenance documents have a lock on the cash drawer.</li> 188 * </ol> 189 * @param document the document that wishes to open the cash drawer 190 * @return true if the cash drawer can be opened, false otherwise 191 */ 192 public boolean canOpenCashDrawer(Document document) { 193 final CashDrawer cashDrawer = retrieveCashDrawer(document); 194 return cashDrawer.isClosed() && noExistCashDrawerMaintLocks(cashDrawer, document.getDocumentNumber()); 195 } 196 197 /** 198 * Retrieves the cash drawer associated with the given cash management document 199 * @param document a CashManagementDocument with an associated cash drawer 200 * @return the associated cash drawer 201 */ 202 protected CashDrawer retrieveCashDrawer(Document document) { 203 final CashManagementDocument cmDoc = (CashManagementDocument)document; 204 final CashDrawer cashDrawer = SpringContext.getBean(CashDrawerService.class).getByCampusCode(cmDoc.getCampusCode()); 205 return cashDrawer; 206 } 207 208 /** 209 * Determines that no maintenance documents have locks on the given cash drawer 210 * @param cashDrawer the cash drawer that may have locks on it 211 * @return true if there are no maintenance documents with locks on the cash drawer, false otherwise 212 */ 213 protected boolean noExistCashDrawerMaintLocks(CashDrawer cashDrawer, String documentNumber) { 214 final MaintenanceDocumentEntry cashDrawerMaintDocEntry = SpringContext.getBean(DataDictionaryService.class).getDataDictionary().getMaintenanceDocumentEntryForBusinessObjectClass(cashDrawer.getClass()); 215 Maintainable cashDrawerMaintainable = createCashDrawerMaintainable(cashDrawerMaintDocEntry); 216 cashDrawerMaintainable.setBoClass(cashDrawer.getClass()); 217 cashDrawerMaintainable.setBusinessObject(cashDrawer); 218 cashDrawerMaintainable.setDocumentNumber(documentNumber); 219 220 final String lockingDocument = SpringContext.getBean(MaintenanceDocumentService.class).getLockingDocumentId(cashDrawerMaintainable, documentNumber); 221 return StringUtils.isBlank(lockingDocument); 222 } 223 224 /** 225 * Builds an instance of the appropriate Maintainable implementation for the Cash Drawer Maintainable 226 * @param cashDrawerMaintenanceDocumentEntry the data dictionary entry from the Cash Drawer's maintenance document 227 * @return an appropriate Maintainable 228 */ 229 protected Maintainable createCashDrawerMaintainable(MaintenanceDocumentEntry cashDrawerMaintenanceDocumentEntry) { 230 Maintainable cashDrawerMaintainable; 231 try { 232 cashDrawerMaintainable = cashDrawerMaintenanceDocumentEntry.getMaintainableClass().newInstance(); 233 } 234 catch (InstantiationException ie) { 235 throw new RuntimeException("Cannot instantiate instance of maintainable implementation "+cashDrawerMaintenanceDocumentEntry.getMaintainableClass().getName(), ie); 236 } 237 catch (IllegalAccessException iae) { 238 throw new RuntimeException("Illegal access occurred while instantiating instance of maintainable implementation "+cashDrawerMaintenanceDocumentEntry.getMaintainableClass().getName(), iae); 239 } 240 return cashDrawerMaintainable; 241 } 242 }