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.purap.service.impl;
017:
018: import java.sql.Date;
019: import java.sql.Timestamp;
020: import java.util.ArrayList;
021: import java.util.Calendar;
022: import java.util.HashMap;
023: import java.util.List;
024: import java.util.Map;
025:
026: import org.apache.commons.lang.StringUtils;
027: import org.kuali.core.UserSession;
028: import org.kuali.core.exceptions.UserNotFoundException;
029: import org.kuali.core.service.BusinessObjectService;
030: import org.kuali.core.service.DataDictionaryService;
031: import org.kuali.core.service.DateTimeService;
032: import org.kuali.core.service.PersistenceService;
033: import org.kuali.core.util.GlobalVariables;
034: import org.kuali.core.util.KualiDecimal;
035: import org.kuali.core.util.ObjectUtils;
036: import org.kuali.kfs.KFSPropertyConstants;
037: import org.kuali.kfs.context.SpringContext;
038: import org.kuali.kfs.service.ParameterService;
039: import org.kuali.module.financial.service.UniversityDateService;
040: import org.kuali.module.purap.PurapConstants;
041: import org.kuali.module.purap.PurapPropertyConstants;
042: import org.kuali.module.purap.PurapConstants.PurchaseOrderStatuses;
043: import org.kuali.module.purap.bo.AccountsPayableItem;
044: import org.kuali.module.purap.bo.ItemType;
045: import org.kuali.module.purap.bo.OrganizationParameter;
046: import org.kuali.module.purap.bo.PurApItem;
047: import org.kuali.module.purap.document.AccountsPayableDocument;
048: import org.kuali.module.purap.document.AccountsPayableDocumentBase;
049: import org.kuali.module.purap.document.CreditMemoDocument;
050: import org.kuali.module.purap.document.PaymentRequestDocument;
051: import org.kuali.module.purap.document.PurchaseOrderDocument;
052: import org.kuali.module.purap.document.PurchasingAccountsPayableDocument;
053: import org.kuali.module.purap.document.RequisitionDocument;
054: import org.kuali.module.purap.service.LogicContainer;
055: import org.kuali.module.purap.service.PaymentRequestService;
056: import org.kuali.module.purap.service.PurApWorkflowIntegrationService;
057: import org.kuali.module.purap.service.PurapAccountingService;
058: import org.kuali.module.purap.service.PurapGeneralLedgerService;
059: import org.kuali.module.purap.service.PurapService;
060: import org.kuali.module.purap.service.PurchaseOrderService;
061: import org.kuali.module.vendor.service.VendorService;
062:
063: import edu.iu.uis.eden.exception.WorkflowException;
064:
065: public class PurapServiceImpl implements PurapService {
066: private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger
067: .getLogger(PurapServiceImpl.class);
068:
069: private BusinessObjectService businessObjectService;
070: private DateTimeService dateTimeService;
071: private ParameterService parameterService;
072:
073: public void setBusinessObjectService(BusinessObjectService boService) {
074: this .businessObjectService = boService;
075: }
076:
077: public void setDateTimeService(DateTimeService dateTimeService) {
078: this .dateTimeService = dateTimeService;
079: }
080:
081: public void setParameterService(ParameterService parameterService) {
082: this .parameterService = parameterService;
083: }
084:
085: /**
086: * @see org.kuali.module.purap.service.PurapService#updateStatus(org.kuali.module.purap.document.PurchasingAccountsPayableDocument, java.lang.String)
087: */
088: public boolean updateStatus(
089: PurchasingAccountsPayableDocument document, String newStatus) {
090: LOG.debug("updateStatus() started");
091:
092: if (ObjectUtils.isNotNull(document)
093: || ObjectUtils.isNotNull(newStatus)) {
094: String oldStatus = document.getStatusCode();
095: document.setStatusCode(newStatus);
096: LOG.debug("Status of document #"
097: + document.getDocumentNumber()
098: + " has been changed from " + oldStatus + " to "
099: + newStatus);
100: return true;
101: } else {
102: return false;
103: }
104: }
105:
106: /**
107: * @see org.kuali.module.purap.service.PurapService#getRelatedViews(java.lang.Class, java.lang.Integer)
108: */
109: public List getRelatedViews(Class clazz,
110: Integer accountsPayablePurchasingDocumentLinkIdentifier) {
111: LOG.debug("getRelatedViews() started");
112:
113: Map criteria = new HashMap();
114: criteria.put("accountsPayablePurchasingDocumentLinkIdentifier",
115: accountsPayablePurchasingDocumentLinkIdentifier);
116: List boList = (List) businessObjectService.findMatchingOrderBy(
117: clazz, criteria, KFSPropertyConstants.DOCUMENT_NUMBER,
118: true);
119: return boList;
120: }
121:
122: /**
123: * @see org.kuali.module.purap.service.PurapService#addBelowLineItems(org.kuali.module.purap.document.PurchasingAccountsPayableDocument)
124: */
125: public void addBelowLineItems(
126: PurchasingAccountsPayableDocument document) {
127: LOG.debug("addBelowLineItems() started");
128:
129: String[] itemTypes = getBelowTheLineForDocument(document);
130:
131: List<PurApItem> existingItems = document.getItems();
132:
133: List<PurApItem> belowTheLine = new ArrayList<PurApItem>();
134: // needed in case they get out of sync below won't work
135: sortBelowTheLine(itemTypes, existingItems, belowTheLine);
136:
137: List<String> existingItemTypes = new ArrayList();
138: for (PurApItem existingItem : existingItems) {
139: existingItemTypes.add(existingItem.getItemTypeCode());
140: }
141:
142: Class itemClass = document.getItemClass();
143:
144: for (int i = 0; i < itemTypes.length; i++) {
145: int lastFound;
146: if (!existingItemTypes.contains(itemTypes[i])) {
147: try {
148: if (i > 0) {
149: lastFound = existingItemTypes
150: .lastIndexOf(itemTypes[i - 1]) + 1;
151: } else {
152: lastFound = existingItemTypes.size();
153: }
154: PurApItem newItem = (PurApItem) itemClass
155: .newInstance();
156: newItem.setItemTypeCode(itemTypes[i]);
157: existingItems.add(lastFound, newItem);
158: existingItemTypes.add(itemTypes[i]);
159: } catch (Exception e) {
160: // do something
161: }
162: }
163: }
164: }
165:
166: /**
167: * Sorts the below the line elements
168: *
169: * @param itemTypes
170: * @param existingItems
171: * @param belowTheLine
172: */
173: private void sortBelowTheLine(String[] itemTypes,
174: List<PurApItem> existingItems, List<PurApItem> belowTheLine) {
175: LOG.debug("sortBelowTheLine() started");
176:
177: // sort existing below the line if any
178: for (int i = 0; i < existingItems.size(); i++) {
179: PurApItem purApItem = existingItems.get(i);
180: if (!purApItem.getItemType()
181: .isItemTypeAboveTheLineIndicator()) {
182: belowTheLine.add(existingItems.get(i));
183: }
184: }
185: existingItems.removeAll(belowTheLine);
186: for (int i = 0; i < itemTypes.length; i++) {
187: for (PurApItem purApItem : belowTheLine) {
188: if (StringUtils.equalsIgnoreCase(purApItem
189: .getItemTypeCode(), itemTypes[i])) {
190: existingItems.add(purApItem);
191: break;
192: }
193: }
194: }
195: belowTheLine.removeAll(existingItems);
196: if (belowTheLine.size() != 0) {
197: throw new RuntimeException(
198: "below the line item sort didn't work: trying to remove an item without adding it back");
199: }
200: }
201:
202: /**
203: * @see org.kuali.module.purap.service.PurapService#sortBelowTheLine(java.lang.String[], java.util.List, java.util.List)
204: */
205: public void sortBelowTheLine(
206: PurchasingAccountsPayableDocument document) {
207: LOG.debug("sortBelowTheLine() started");
208:
209: String[] itemTypes = getBelowTheLineForDocument(document);
210:
211: List<PurApItem> existingItems = document.getItems();
212:
213: List<PurApItem> belowTheLine = new ArrayList<PurApItem>();
214: // needed in case they get out of sync below won't work
215: sortBelowTheLine(itemTypes, existingItems, belowTheLine);
216: }
217:
218: /**
219: * @see org.kuali.module.purap.service.PurapService#getBelowTheLineForDocument(org.kuali.module.purap.document.PurchasingAccountsPayableDocument)
220: */
221: public String[] getBelowTheLineForDocument(
222: PurchasingAccountsPayableDocument document) {
223: LOG.debug("getBelowTheLineForDocument() started");
224:
225: // Obtain a list of below the line items from system parameter
226: String documentTypeClassName = document.getClass().getName();
227: String[] documentTypeArray = StringUtils.split(
228: documentTypeClassName, ".");
229: String documentType = documentTypeArray[documentTypeArray.length - 1];
230: // If it's a credit memo, we'll have to append the source of the credit memo
231: // whether it's created from a Vendor, a PO or a PREQ.
232: if (documentType.equals("CreditMemoDocument")) {
233:
234: }
235: try {
236: return parameterService
237: .getParameterValues(
238: Class
239: .forName(PurapConstants.PURAP_DETAIL_TYPE_CODE_MAP
240: .get(documentType)),
241: PurapConstants.BELOW_THE_LINES_PARAMETER)
242: .toArray(new String[] {});
243: } catch (ClassNotFoundException e) {
244: throw new RuntimeException(
245: "The getBelowTheLineForDocument method of PurapServiceImpl was unable to resolve the document class for type: "
246: + PurapConstants.PURAP_DETAIL_TYPE_CODE_MAP
247: .get(documentType), e);
248: }
249: }
250:
251: /**
252: * @see org.kuali.module.purap.service.PurapService#getBelowTheLineByType(org.kuali.module.purap.document.PurchasingAccountsPayableDocument,
253: * org.kuali.module.purap.bo.ItemType)
254: */
255: public PurApItem getBelowTheLineByType(
256: PurchasingAccountsPayableDocument document, ItemType iT) {
257: LOG.debug("getBelowTheLineByType() started");
258:
259: String[] itemTypes = getBelowTheLineForDocument(document);
260: boolean foundItemType = false;
261: for (String itemType : itemTypes) {
262: if (StringUtils.equals(iT.getItemTypeCode(), itemType)) {
263: foundItemType = true;
264: break;
265: }
266: }
267: if (!foundItemType) {
268: return null;
269: }
270:
271: PurApItem belowTheLineItem = null;
272: for (PurApItem item : (List<PurApItem>) document.getItems()) {
273: if (!item.getItemType().isItemTypeAboveTheLineIndicator()) {
274: if (StringUtils.equals(iT.getItemTypeCode(), item
275: .getItemType().getItemTypeCode())) {
276: belowTheLineItem = item;
277: break;
278: }
279: }
280: }
281: return belowTheLineItem;
282: }
283:
284: /**
285: * @see org.kuali.module.purap.service.PurapService#isDateInPast(java.sql.Date)
286: */
287: public boolean isDateInPast(Date compareDate) {
288: LOG.debug("isDateInPast() started");
289:
290: Date today = dateTimeService.getCurrentSqlDate();
291: int diffFromToday = dateTimeService.dateDiff(today,
292: compareDate, false);
293: return (diffFromToday < 0);
294: }
295:
296: /**
297: * @see org.kuali.module.purap.service.PurapService#isDateMoreThanANumberOfDaysAway(java.sql.Date, int)
298: */
299: public boolean isDateMoreThanANumberOfDaysAway(Date compareDate,
300: int daysAway) {
301: LOG.debug("isDateMoreThanANumberOfDaysAway() started");
302:
303: Date todayAtMidnight = dateTimeService
304: .getCurrentSqlDateMidnight();
305: Calendar daysAwayCalendar = dateTimeService
306: .getCalendar(todayAtMidnight);
307: daysAwayCalendar.add(Calendar.DATE, daysAway);
308: Timestamp daysAwayTime = new Timestamp(daysAwayCalendar
309: .getTime().getTime());
310: Calendar compareCalendar = dateTimeService
311: .getCalendar(compareDate);
312: compareCalendar.set(Calendar.HOUR, 0);
313: compareCalendar.set(Calendar.MINUTE, 0);
314: compareCalendar.set(Calendar.SECOND, 0);
315: compareCalendar.set(Calendar.MILLISECOND, 0);
316: compareCalendar.set(Calendar.AM_PM, Calendar.AM);
317: Timestamp compareTime = new Timestamp(compareCalendar.getTime()
318: .getTime());
319: return (compareTime.compareTo(daysAwayTime) > 0);
320: }
321:
322: /**
323: * @see org.kuali.module.purap.service.PurapService#isDateAYearAfterToday(java.sql.Date)
324: */
325: public boolean isDateAYearBeforeToday(Date compareDate) {
326: LOG.debug("isDateAYearBeforeToday() started");
327:
328: Calendar calendar = dateTimeService.getCurrentCalendar();
329: calendar.add(Calendar.YEAR, -1);
330: Date yearAgo = new Date(calendar.getTimeInMillis());
331: int diffFromYearAgo = dateTimeService.dateDiff(compareDate,
332: yearAgo, false);
333: return (diffFromYearAgo > 0);
334: }
335:
336: /**
337: * @see org.kuali.module.purap.service.PurapService#getApoLimit(java.lang.Integer, java.lang.String, java.lang.String)
338: */
339: public KualiDecimal getApoLimit(
340: Integer vendorContractGeneratedIdentifier, String chart,
341: String org) {
342: LOG.debug("getApoLimit() started");
343:
344: KualiDecimal purchaseOrderTotalLimit = SpringContext.getBean(
345: VendorService.class).getApoLimitFromContract(
346: vendorContractGeneratedIdentifier, chart, org);
347: if (ObjectUtils.isNull(purchaseOrderTotalLimit)) {
348: // We didn't find the limit on the vendor contract, get it from the org parameter table.
349: if (ObjectUtils.isNull(chart) || ObjectUtils.isNull(org)) {
350: return null;
351: }
352: OrganizationParameter organizationParameter = new OrganizationParameter();
353: organizationParameter.setChartOfAccountsCode(chart);
354: organizationParameter.setOrganizationCode(org);
355: Map orgParamKeys = SpringContext.getBean(
356: PersistenceService.class).getPrimaryKeyFieldValues(
357: organizationParameter);
358: organizationParameter = (OrganizationParameter) businessObjectService
359: .findByPrimaryKey(OrganizationParameter.class,
360: orgParamKeys);
361: purchaseOrderTotalLimit = (organizationParameter == null) ? null
362: : organizationParameter
363: .getOrganizationAutomaticPurchaseOrderLimit();
364: }
365: return purchaseOrderTotalLimit;
366: }
367:
368: /**
369: * @see org.kuali.module.purap.service.PurapService#isFullDocumentEntryCompleted(org.kuali.module.purap.document.PurchasingAccountsPayableDocument)
370: */
371: public boolean isFullDocumentEntryCompleted(
372: PurchasingAccountsPayableDocument purapDocument) {
373: LOG.debug("isFullDocumentEntryCompleted() started");
374:
375: // for now just return true if not in one of the first few states
376: boolean value = false;
377: if (purapDocument instanceof PaymentRequestDocument) {
378: value = PurapConstants.PaymentRequestStatuses.STATUS_ORDER
379: .isFullDocumentEntryCompleted(purapDocument
380: .getStatusCode());
381: } else if (purapDocument instanceof CreditMemoDocument) {
382: value = PurapConstants.CreditMemoStatuses.STATUS_ORDER
383: .isFullDocumentEntryCompleted(purapDocument
384: .getStatusCode());
385: }
386: return value;
387: }
388:
389: /**
390: * @see org.kuali.module.purap.service.PurapService#performLogicForFullEntryCompleted(org.kuali.module.purap.document.PurchasingAccountsPayableDocument)
391: */
392: public void performLogicForFullEntryCompleted(
393: PurchasingAccountsPayableDocument purapDocument) {
394: LOG.debug("performLogicForFullEntryCompleted() started");
395:
396: // below code preferable to run in post processing
397: if (purapDocument instanceof PaymentRequestDocument) {
398: PaymentRequestDocument paymentRequest = (PaymentRequestDocument) purapDocument;
399: // eliminate unentered items
400: deleteUnenteredItems(paymentRequest);
401: // change PREQ accounts from percents to dollars
402: SpringContext.getBean(PurapAccountingService.class)
403: .updateAccountAmounts(paymentRequest);
404: // do GL entries for PREQ creation
405: SpringContext
406: .getBean(PurapGeneralLedgerService.class)
407: .generateEntriesCreatePaymentRequest(paymentRequest);
408:
409: SpringContext.getBean(PaymentRequestService.class)
410: .saveDocumentWithoutValidation(paymentRequest);
411: }
412: // below code preferable to run in post processing
413: else if (purapDocument instanceof CreditMemoDocument) {
414: CreditMemoDocument creditMemo = (CreditMemoDocument) purapDocument;
415: // eliminate unentered items
416: deleteUnenteredItems(creditMemo);
417: // update amounts
418: SpringContext.getBean(PurapAccountingService.class)
419: .updateAccountAmounts(creditMemo);
420: // do GL entries for CM creation
421: SpringContext.getBean(PurapGeneralLedgerService.class)
422: .generateEntriesCreateCreditMemo(creditMemo);
423:
424: // if reopen po indicator set then reopen po
425: if (creditMemo.isReopenPurchaseOrderIndicator()) {
426: performLogicForCloseReopenPO(creditMemo);
427: }
428: } else {
429: throw new RuntimeException(
430: "Attempted to perform full entry logic for unhandled document type '"
431: + purapDocument.getClass().getName() + "'");
432: }
433: }
434:
435: /**
436: * Main hook point for close/Reopen PO.
437: *
438: * @see org.kuali.module.purap.service.PurapService#performLogicForCloseReopenPO(org.kuali.module.purap.document.PurchasingAccountsPayableDocument)
439: */
440: public void performLogicForCloseReopenPO(
441: PurchasingAccountsPayableDocument purapDocument) {
442: LOG.debug("performLogicForCloseReopenPO() started");
443:
444: if (purapDocument instanceof PaymentRequestDocument) {
445: PaymentRequestDocument paymentRequest = (PaymentRequestDocument) purapDocument;
446:
447: if (paymentRequest.isClosePurchaseOrderIndicator()
448: && PurapConstants.PurchaseOrderStatuses.OPEN
449: .equals(paymentRequest
450: .getPurchaseOrderDocument()
451: .getStatusCode())) {
452: // get the po id and get the current po
453: // check the current po: if status is not closed and there is no pending action... route close po as system user
454: processCloseReopenPo(
455: (AccountsPayableDocumentBase) purapDocument,
456: PurapConstants.PurchaseOrderDocTypes.PURCHASE_ORDER_CLOSE_DOCUMENT);
457: }
458:
459: } else if (purapDocument instanceof CreditMemoDocument) {
460: CreditMemoDocument creditMemo = (CreditMemoDocument) purapDocument;
461:
462: if (creditMemo.isReopenPurchaseOrderIndicator()
463: && PurapConstants.PurchaseOrderStatuses.CLOSED
464: .equals(creditMemo
465: .getPurchaseOrderDocument()
466: .getStatusCode())) {
467: // get the po id and get the current PO
468: // route 'Re-Open PO Document' if PO criteria meets requirements from EPIC business rules
469: processCloseReopenPo(
470: (AccountsPayableDocumentBase) purapDocument,
471: PurapConstants.PurchaseOrderDocTypes.PURCHASE_ORDER_REOPEN_DOCUMENT);
472: }
473:
474: } else {
475: throw new RuntimeException(
476: "Attempted to perform full entry logic for unhandled document type '"
477: + purapDocument.getClass().getName() + "'");
478: }
479:
480: }
481:
482: /**
483: * Remove items that have not been "entered" which means no data has been added to them so no more processing needs to continue
484: * on these items.
485: *
486: * @param apDocument AccountsPayableDocument which contains list of items to be reviewed
487: */
488: private void deleteUnenteredItems(AccountsPayableDocument apDocument) {
489: LOG.debug("deleteUnenteredItems() started");
490:
491: List<AccountsPayableItem> deletionList = new ArrayList<AccountsPayableItem>();
492: for (PurApItem item : (List<PurApItem>) apDocument.getItems()) {
493: AccountsPayableItem apItem = (AccountsPayableItem) item;
494: if (!apItem.isConsideredEntered()) {
495: deletionList.add(apItem);
496: }
497: }
498: apDocument.getItems().removeAll(deletionList);
499: }
500:
501: /**
502: * Actual method that will close or reopen a po.
503: *
504: * @param apDocument AccountsPayableDocument
505: * @param docType
506: */
507: public void processCloseReopenPo(
508: AccountsPayableDocumentBase apDocument, String docType) {
509: LOG.debug("processCloseReopenPo() started");
510:
511: String action = null;
512: String newStatus = null;
513: // setup text for note that will be created, will either be closed or reopened
514: if (PurapConstants.PurchaseOrderDocTypes.PURCHASE_ORDER_CLOSE_DOCUMENT
515: .equals(docType)) {
516: action = "closed";
517: newStatus = PurchaseOrderStatuses.PENDING_CLOSE;
518: } else if (PurapConstants.PurchaseOrderDocTypes.PURCHASE_ORDER_REOPEN_DOCUMENT
519: .equals(docType)) {
520: action = "reopened";
521: newStatus = PurchaseOrderStatuses.PENDING_REOPEN;
522: } else {
523: String errorMessage = "Method processCloseReopenPo called using ID + '"
524: + apDocument.getPurapDocumentIdentifier()
525: + "' and invalid doc type '" + docType + "'";
526: LOG.error(errorMessage);
527: throw new RuntimeException(errorMessage);
528: }
529:
530: Integer poId = apDocument.getPurchaseOrderIdentifier();
531: PurchaseOrderDocument purchaseOrderDocument = SpringContext
532: .getBean(PurchaseOrderService.class)
533: .getCurrentPurchaseOrder(poId);
534: if (!StringUtils.equalsIgnoreCase(purchaseOrderDocument
535: .getDocumentHeader().getWorkflowDocument()
536: .getDocumentType(), docType)) {
537: // we are skipping the validation above because it would be too late to correct any errors (i.e. because in
538: // post-processing)
539: SpringContext.getBean(PurchaseOrderService.class)
540: .createAndRoutePotentialChangeDocument(
541: purchaseOrderDocument.getDocumentNumber(),
542: docType,
543: assemblePurchaseOrderNote(apDocument,
544: docType, action), new ArrayList(),
545: newStatus);
546: }
547:
548: /*
549: * if we made it here, route document has not errored out, so set appropriate indicator depending on what is being
550: * requested.
551: */
552: if (PurapConstants.PurchaseOrderDocTypes.PURCHASE_ORDER_CLOSE_DOCUMENT
553: .equals(docType)) {
554: apDocument.setClosePurchaseOrderIndicator(false);
555: } else if (PurapConstants.PurchaseOrderDocTypes.PURCHASE_ORDER_REOPEN_DOCUMENT
556: .equals(docType)) {
557: apDocument.setReopenPurchaseOrderIndicator(false);
558: }
559:
560: }
561:
562: /**
563: * Generate a note for the close/reopen po method.
564: *
565: * @param docType
566: * @param preqId
567: * @return Note to be saved
568: */
569: private String assemblePurchaseOrderNote(
570: AccountsPayableDocumentBase apDocument, String docType,
571: String action) {
572: LOG.debug("assemblePurchaseOrderNote() started");
573:
574: String documentLabel = SpringContext.getBean(
575: DataDictionaryService.class).getDocumentLabelByClass(
576: getClass());
577: StringBuffer closeReopenNote = new StringBuffer("");
578: String userName = GlobalVariables.getUserSession()
579: .getUniversalUser().getPersonName();
580: closeReopenNote.append(SpringContext.getBean(
581: DataDictionaryService.class).getDocumentLabelByClass(
582: PurchaseOrderDocument.class));
583: closeReopenNote.append(" will be manually ");
584: closeReopenNote.append(action);
585: closeReopenNote.append(" by ");
586: closeReopenNote.append(userName);
587: closeReopenNote.append(" when approving ");
588: closeReopenNote.append(documentLabel);
589: closeReopenNote.append(" with ");
590: closeReopenNote.append(SpringContext.getBean(
591: DataDictionaryService.class).getAttributeLabel(
592: getClass(), PurapPropertyConstants.PURAP_DOC_ID));
593: closeReopenNote.append(" ");
594: closeReopenNote.append(apDocument.getPurapDocumentIdentifier());
595:
596: return closeReopenNote.toString();
597: }
598:
599: /**
600: * @see org.kuali.module.purap.service.PurapService#performLogicWithFakedUserSession(java.lang.String, org.kuali.module.purap.service.LogicContainer, java.lang.Object[])
601: */
602: public Object performLogicWithFakedUserSession(
603: String requiredUniversalUserPersonUserId,
604: LogicContainer logicToRun, Object... objects)
605: throws UserNotFoundException, WorkflowException, Exception {
606: LOG.debug("performLogicWithFakedUserSession() started");
607:
608: if (StringUtils.isBlank(requiredUniversalUserPersonUserId)) {
609: throw new RuntimeException(
610: "Attempted to perform logic with a fake user session with a blank user person id: '"
611: + requiredUniversalUserPersonUserId + "'");
612: }
613: if (ObjectUtils.isNull(logicToRun)) {
614: throw new RuntimeException(
615: "Attempted to perform logic with a fake user session with no logic to run");
616: }
617: UserSession actualUserSession = GlobalVariables
618: .getUserSession();
619: try {
620: GlobalVariables.setUserSession(new UserSession(
621: requiredUniversalUserPersonUserId));
622: return logicToRun.runLogic(objects);
623: } finally {
624: GlobalVariables.setUserSession(actualUserSession);
625: }
626: }
627:
628: }
|