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 }