001: /*
002: * Copyright 2006-2007 The Kuali Foundation.
003: *
004: * Licensed under the Educational Community License, Version 1.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/ecl1.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.module.financial.service.impl;
017:
018: import java.util.ArrayList;
019: import java.util.Arrays;
020: import java.util.HashMap;
021: import java.util.Iterator;
022: import java.util.List;
023: import java.util.Map;
024:
025: import org.apache.commons.lang.StringUtils;
026: import org.kuali.core.bo.Campus;
027: import org.kuali.core.bo.DocumentHeader;
028: import org.kuali.core.bo.user.KualiGroup;
029: import org.kuali.core.bo.user.UniversalUser;
030: import org.kuali.core.exceptions.GroupNotFoundException;
031: import org.kuali.core.exceptions.InfrastructureException;
032: import org.kuali.core.service.BusinessObjectService;
033: import org.kuali.core.service.KualiGroupService;
034: import org.kuali.core.util.GlobalVariables;
035: import org.kuali.core.workflow.service.KualiWorkflowDocument;
036: import org.kuali.core.workflow.service.WorkflowDocumentService;
037: import org.kuali.kfs.KFSConstants;
038: import org.kuali.kfs.KFSPropertyConstants;
039: import org.kuali.kfs.context.SpringContext;
040: import org.kuali.kfs.service.ParameterService;
041: import org.kuali.module.financial.bo.CashDrawer;
042: import org.kuali.module.financial.bo.CashieringTransaction;
043: import org.kuali.module.financial.bo.CoinDetail;
044: import org.kuali.module.financial.bo.CurrencyDetail;
045: import org.kuali.module.financial.dao.CashManagementDao;
046: import org.kuali.module.financial.document.CashReceiptDocument;
047: import org.kuali.module.financial.service.CashDrawerService;
048: import org.kuali.module.financial.service.CashReceiptService;
049: import org.springframework.transaction.annotation.Transactional;
050:
051: import edu.iu.uis.eden.exception.WorkflowException;
052:
053: /**
054: *
055: * This is the default implementation of the CashReceiptService interface.
056: */
057: @Transactional
058: public class CashReceiptServiceImpl implements CashReceiptService {
059:
060: private BusinessObjectService businessObjectService;
061: private WorkflowDocumentService workflowDocumentService;
062: private CashManagementDao cashManagementDao;
063: private CashDrawerService cashDrawerService;
064: private ParameterService parameterService;
065: private KualiGroupService kualiGroupService;
066:
067: /**
068: * This method uses the campus code provided to determine the cash receipt verification unit. The verification unit
069: * is equivalent to the campus code with a prefix retrieved from the parameter service using the ParameterService
070: * using the key "VERIFICATION_UNIT_GROUP_PREFIX".
071: *
072: * @param campusCode The campus code used to determine the verification unit.
073: * @return The cash receipt verification unit based on the campus code provided.
074: *
075: * @see org.kuali.module.financial.service.CashReceiptService#getCashReceiptVerificationUnitWorkgroupNameByCampusCode(java.lang.String)
076: */
077: public String getCashReceiptVerificationUnitForCampusCode(
078: String campusCode) {
079: String vunit = null;
080:
081: if (StringUtils.isBlank(campusCode)) {
082: throw new IllegalArgumentException(
083: "invalid (blank) campusCode");
084: }
085:
086: vunit = parameterService.getParameterValue(
087: CashReceiptDocument.class,
088: "VERIFICATION_UNIT_GROUP_PREFIX")
089: + campusCode;
090:
091: KualiGroup group = null;
092: try {
093: group = kualiGroupService.getByGroupName(vunit);
094: } catch (GroupNotFoundException e) {
095: throw new IllegalArgumentException(vunit
096: + " does not have a corresponding workgroup");
097: }
098:
099: return vunit;
100: }
101:
102: /**
103: * This method uses the unit name provided to determine the associated campus code. The campus code is a substring of the
104: * unit name and can be retrieved by removing the verification unit prefix from the unit name. The prefix to be removed
105: * can be retrieved from the ParameterService using the key "VERIFICATION_UNIT_GROUP_PREFIX".
106: *
107: * @param unitName The unit name to be used to determine the campus code.
108: * @return The campus code retrieved from the unit name provided.
109: *
110: * @see org.kuali.module.financial.service.CashReceiptService#getCampusCodeForCashReceiptVerificationUnit(java.lang.String)
111: */
112: public String getCampusCodeForCashReceiptVerificationUnit(
113: String unitName) {
114: String campusCode = null;
115:
116: if (StringUtils.isBlank(unitName)) {
117: throw new IllegalArgumentException(
118: "invalid (blank) unitName");
119: }
120:
121: // pretend that a lookup is actually happening
122: campusCode = unitName.replace(
123: parameterService.getParameterValue(
124: CashReceiptDocument.class,
125: "VERIFICATION_UNIT_GROUP_PREFIX"), "")
126: .toUpperCase();
127:
128: if (!verifyCampus(campusCode)) {
129: throw new IllegalArgumentException("The campus "
130: + campusCode + " does not exist");
131: }
132:
133: return campusCode;
134: }
135:
136: /**
137: * This method verifies the campus code provided exists. This is done by retrieving all the available campuses from
138: * the BusinessObjectService and then looking for a matching campus code within the result set.
139: *
140: * @param campusCode The campus code to be verified.
141: * @return True if the campus code provided is valid and exists, false otherwise.
142: */
143: private boolean verifyCampus(String campusCode) {
144: Iterator campiiIter = businessObjectService.findAll(
145: Campus.class).iterator();
146: boolean foundCampus = false;
147: while (campiiIter.hasNext() && !foundCampus) {
148: Campus campus = (Campus) campiiIter.next();
149: if (campus.getCampusCode().equals(campusCode)) {
150: foundCampus = true;
151: }
152: }
153: return foundCampus;
154:
155: }
156:
157: /**
158: * This method retrieves the cash receipt verification unit based on the user provided. This is done by retrieving the campus
159: * code associated with the user provided and then performing the lookup using this campus code.
160: *
161: * @param user The user to be used to retrieve the verification unit.
162: * @return The cash receipt verification unit associated with the user provided.
163: *
164: * @see org.kuali.module.financial.service.CashReceiptService#getCashReceiptVerificationUnit(org.kuali.core.bo.user.KualiUser)
165: */
166: public String getCashReceiptVerificationUnitForUser(
167: UniversalUser user) {
168: String unitName = null;
169:
170: if (user == null) {
171: throw new IllegalArgumentException("invalid (null) user");
172: }
173:
174: return getCashReceiptVerificationUnitForCampusCode(user
175: .getCampusCode());
176: }
177:
178: /**
179: * This method retrieves a collection of cash receipts using the verification unit and the status provided to
180: * retrieve the cash receipts.
181: *
182: * @param verificationUnit The verification unit used to retrieve a collection of associated cash receipts.
183: * @param statusCode The status code of the cash receipts to be retrieved.
184: * @return A collection of cash receipt documents which match the search criteria provided.
185: *
186: * @see org.kuali.module.financial.service.CashReceiptService#getCashReceipts(java.lang.String, java.lang.String)
187: */
188: public List getCashReceipts(String verificationUnit,
189: String statusCode) {
190: if (StringUtils.isBlank(statusCode)) {
191: throw new IllegalArgumentException(
192: "invalid (blank) statusCode");
193: }
194:
195: String[] statii = new String[] { statusCode };
196: return getCashReceipts(verificationUnit, statii);
197: }
198:
199: /**
200: * This method retrieves a collection of cash receipts using the verification unit and the statuses provided to
201: * retrieve the cash receipts.
202: *
203: * @param verificationUnit The verification unit used to retrieve a collection of associated cash receipts.
204: * @param statii A collection of possible statuses that will be used in the lookup of cash receipts.
205: * @return A collection of cash receipt documents which match the search criteria provided.
206: *
207: * @see org.kuali.module.financial.service.CashReceiptService#getCashReceipts(java.lang.String, java.lang.String[])
208: */
209: public List getCashReceipts(String verificationUnit, String[] statii) {
210: if (StringUtils.isBlank(verificationUnit)) {
211: throw new IllegalArgumentException(
212: "invalid (blank) verificationUnit");
213: }
214: if (statii == null) {
215: throw new IllegalArgumentException("invalid (null) statii");
216: } else {
217: if (statii.length == 0) {
218: throw new IllegalArgumentException(
219: "invalid (empty) statii");
220: } else {
221: for (int i = 0; i < statii.length; ++i) {
222: if (StringUtils.isBlank(statii[i])) {
223: throw new IllegalArgumentException(
224: "invalid (blank) status code " + i);
225: }
226: }
227: }
228: }
229:
230: return getPopulatedCashReceipts(verificationUnit, statii);
231: }
232:
233: /**
234: * This method retrieves a populated collection of cash receipts using the lookup parameters provided. A populated
235: * cash receipt document is a cash receipt document with fully populated workflow fields.
236: *
237: * @param verificationUnit The verification unit used to retrieve a collection of associated cash receipts.
238: * @param statii A collection of possible statuses that will be used in the lookup of the cash receipts.
239: * @return List of CashReceiptDocument instances with their associated workflowDocuments populated.
240: */
241: public List getPopulatedCashReceipts(String verificationUnit,
242: String[] statii) {
243: Map queryCriteria = buildCashReceiptCriteriaMap(
244: verificationUnit, statii);
245:
246: List documents = new ArrayList(getBusinessObjectService()
247: .findMatchingOrderBy(CashReceiptDocument.class,
248: queryCriteria,
249: KFSPropertyConstants.DOCUMENT_NUMBER, true));
250:
251: populateWorkflowFields(documents);
252:
253: return documents;
254: }
255:
256: /**
257: * This method builds out a map of search criteria for performing cash receipt lookups using the values provided.
258: *
259: * @param workgroupName The workgroup name to use as search criteria for looking up cash receipts.
260: * @param statii A collection of possible statuses to use as search criteria for looking up cash receipts.
261: * @return The search criteria provided in a map with CashReceiptConstants used as keys to the parameters given.
262: */
263: private Map buildCashReceiptCriteriaMap(String workgroupName,
264: String[] statii) {
265: Map queryCriteria = new HashMap();
266:
267: if (statii.length == 1) {
268: queryCriteria
269: .put(
270: KFSConstants.CashReceiptConstants.CASH_RECEIPT_DOC_HEADER_STATUS_CODE_PROPERTY_NAME,
271: statii[0]);
272: } else if (statii.length > 0) {
273: List<String> statusList = Arrays.asList(statii);
274: queryCriteria
275: .put(
276: KFSConstants.CashReceiptConstants.CASH_RECEIPT_DOC_HEADER_STATUS_CODE_PROPERTY_NAME,
277: statusList);
278: }
279:
280: String campusLocationCode = getCampusCodeForCashReceiptVerificationUnit(workgroupName);
281: queryCriteria
282: .put(
283: KFSConstants.CashReceiptConstants.CASH_RECEIPT_CAMPUS_LOCATION_CODE_PROPERTY_NAME,
284: campusLocationCode);
285:
286: return queryCriteria;
287: }
288:
289: /**
290: * This method populates the workflowDocument field of each CashReceiptDocument in the given List
291: *
292: * @param documents A collection of CashReceiptDocuments to be populated with workflow document data.
293: */
294: private void populateWorkflowFields(List documents) {
295: for (Iterator i = documents.iterator(); i.hasNext();) {
296: CashReceiptDocument cr = (CashReceiptDocument) i.next();
297:
298: KualiWorkflowDocument workflowDocument = null;
299: DocumentHeader docHeader = cr.getDocumentHeader();
300: try {
301: Long documentHeaderId = Long.valueOf(docHeader
302: .getDocumentNumber());
303: UniversalUser user = GlobalVariables.getUserSession()
304: .getUniversalUser();
305:
306: workflowDocument = getWorkflowDocumentService()
307: .createWorkflowDocument(documentHeaderId, user);
308: } catch (WorkflowException e) {
309: throw new InfrastructureException(
310: "unable to retrieve workflow document for documentHeaderId '"
311: + docHeader.getDocumentNumber() + "'",
312: e);
313: }
314:
315: docHeader.setWorkflowDocument(workflowDocument);
316: }
317: }
318:
319: /**
320: * This method retrieves the cash details from the cash receipt document provided and adds those details to the
321: * associated cash drawer. After the details are added to the drawer, the drawer is persisted to the database.
322: *
323: * @param crDoc The cash receipt document the cash details will be retrieved from.
324: *
325: * @see org.kuali.module.financial.service.CashReceiptService#addCashDetailsToCashDrawer(org.kuali.module.financial.document.CashReceiptDocument)
326: */
327: public void addCashDetailsToCashDrawer(CashReceiptDocument crDoc) {
328: CashDrawer drawer = retrieveCashDrawer(crDoc);
329: // we need to to add the currency and coin to the cash management doc's cumulative CR as well
330: if (crDoc.getCurrencyDetail() != null
331: && !crDoc.getCurrencyDetail().isEmpty()) {
332: CurrencyDetail cumulativeCurrencyDetail = cashManagementDao
333: .findCurrencyDetailByCashieringRecordSource(
334: drawer
335: .getReferenceFinancialDocumentNumber(),
336: CashieringTransaction.DETAIL_DOCUMENT_TYPE,
337: KFSConstants.CurrencyCoinSources.CASH_RECEIPTS);
338: cumulativeCurrencyDetail.add(crDoc.getCurrencyDetail());
339: businessObjectService.save(cumulativeCurrencyDetail);
340:
341: drawer.addCurrency(crDoc.getCurrencyDetail());
342: }
343: if (crDoc.getCoinDetail() != null
344: && !crDoc.getCoinDetail().isEmpty()) {
345: CoinDetail cumulativeCoinDetail = cashManagementDao
346: .findCoinDetailByCashieringRecordSource(
347: drawer
348: .getReferenceFinancialDocumentNumber(),
349: CashieringTransaction.DETAIL_DOCUMENT_TYPE,
350: KFSConstants.CurrencyCoinSources.CASH_RECEIPTS);
351: cumulativeCoinDetail.add(crDoc.getCoinDetail());
352: businessObjectService.save(cumulativeCoinDetail);
353:
354: drawer.addCoin(crDoc.getCoinDetail());
355: }
356: SpringContext.getBean(BusinessObjectService.class).save(drawer);
357: }
358:
359: /**
360: * This method finds the appropriate cash drawer for this cash receipt document to add cash to.
361: *
362: * @param crDoc The document the cash drawer will be retrieved from.
363: * @return An instance of a cash drawer associated with the cash receipt document provided.
364: */
365: private CashDrawer retrieveCashDrawer(CashReceiptDocument crDoc) {
366: String workgroupName = getCashReceiptVerificationUnitForCampusCode(crDoc
367: .getCampusLocationCode());
368: if (workgroupName == null) {
369: throw new RuntimeException(
370: "Cannot find workgroup name for Cash Receipt document: "
371: + crDoc.getDocumentNumber());
372: }
373:
374: CashDrawer drawer = cashDrawerService.getByWorkgroupName(
375: workgroupName, false);
376: if (drawer == null) {
377: throw new RuntimeException(
378: "There is no Cash Drawer for Workgroup "
379: + workgroupName);
380: }
381: return drawer;
382: }
383:
384: // injection-molding
385: /**
386: * Gets the businessObjectService attribute.
387: * @return current value of businessObjectService.
388: */
389: public BusinessObjectService getBusinessObjectService() {
390: return businessObjectService;
391: }
392:
393: /**
394: * Sets the businessObjectService attribute value.
395: * @param businessObjectService The businessObjectService to set.
396: */
397: public void setBusinessObjectService(
398: BusinessObjectService businessObjectService) {
399: this .businessObjectService = businessObjectService;
400: }
401:
402: /**
403: * Gets the workflowDocumentService attribute.
404: * @return current value of workflowDocumentService.
405: */
406: public WorkflowDocumentService getWorkflowDocumentService() {
407: return workflowDocumentService;
408: }
409:
410: /**
411: * Sets the workflowDocumentService attribute value.
412: * @param workflowDocumentService The workflowDocumentService to set.
413: */
414: public void setWorkflowDocumentService(
415: WorkflowDocumentService workflowDocumentService) {
416: this .workflowDocumentService = workflowDocumentService;
417: }
418:
419: /**
420: * Gets the cashManagementDao attribute.
421: *
422: * @return Returns the cashManagementDao.
423: */
424: public CashManagementDao getCashManagementDao() {
425: return cashManagementDao;
426: }
427:
428: /**
429: * Sets the cashManagementDao attribute value.
430: *
431: * @param cashManagementDao The cashManagementDao to set.
432: */
433: public void setCashManagementDao(CashManagementDao cashManagementDao) {
434: this .cashManagementDao = cashManagementDao;
435: }
436:
437: /**
438: * Gets the cashDrawerService attribute.
439: *
440: * @return Returns the cashDrawerService.
441: */
442: public CashDrawerService getCashDrawerService() {
443: return cashDrawerService;
444: }
445:
446: /**
447: * Sets the cashDrawerService attribute value.
448: *
449: * @param cashDrawerService The cashDrawerService to set.
450: */
451: public void setCashDrawerService(CashDrawerService cashDrawerService) {
452: this .cashDrawerService = cashDrawerService;
453: }
454:
455: /**
456: * Gets the kualiGroupService attribute.
457: *
458: * @return Returns the kualiGroupService.
459: */
460: public KualiGroupService getKualiGroupService() {
461: return kualiGroupService;
462: }
463:
464: /**
465: * Sets the kualiGroupService attribute value.
466: *
467: * @param kualiGroupService The kualiGroupService to set.
468: */
469: public void setKualiGroupService(KualiGroupService kualiGroupService) {
470: this .kualiGroupService = kualiGroupService;
471: }
472:
473: /**
474: * Gets the parameterService attribute.
475: *
476: * @return Returns the parameterService.
477: */
478: public ParameterService getParameterService() {
479: return parameterService;
480: }
481:
482: /**
483: * Sets the parameterService attribute value.
484: *
485: * @param parameterService The parameterService to set.
486: */
487: public void setParameterService(ParameterService parameterService) {
488: this.parameterService = parameterService;
489: }
490:
491: }
|