View Javadoc
1   /*
2    * Copyright 2006 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.ole.fp.batch.service.impl;
17  
18  import static org.kuali.ole.fp.document.validation.impl.ProcurementCardDocumentRuleConstants.AUTO_APPROVE_DOCUMENTS_IND;
19  import static org.kuali.ole.fp.document.validation.impl.ProcurementCardDocumentRuleConstants.AUTO_APPROVE_NUMBER_OF_DAYS;
20  import static org.kuali.ole.fp.document.validation.impl.ProcurementCardDocumentRuleConstants.DEFAULT_TRANS_ACCOUNT_PARM_NM;
21  import static org.kuali.ole.fp.document.validation.impl.ProcurementCardDocumentRuleConstants.DEFAULT_TRANS_CHART_CODE_PARM_NM;
22  import static org.kuali.ole.fp.document.validation.impl.ProcurementCardDocumentRuleConstants.DEFAULT_TRANS_OBJECT_CODE_PARM_NM;
23  import static org.kuali.ole.fp.document.validation.impl.ProcurementCardDocumentRuleConstants.ERROR_TRANS_ACCOUNT_PARM_NM;
24  import static org.kuali.ole.fp.document.validation.impl.ProcurementCardDocumentRuleConstants.SINGLE_TRANSACTION_IND_PARM_NM;
25  import static org.kuali.ole.sys.OLEConstants.GL_CREDIT_CODE;
26  import static org.kuali.ole.sys.OLEConstants.FinancialDocumentTypeCodes.PROCUREMENT_CARD;
27  
28  import java.sql.Timestamp;
29  import java.util.ArrayList;
30  import java.util.Collections;
31  import java.util.HashMap;
32  import java.util.Iterator;
33  import java.util.List;
34  import java.util.Map;
35  
36  import org.apache.commons.lang.StringUtils;
37  import org.kuali.ole.coa.businessobject.ProjectCode;
38  import org.kuali.ole.coa.businessobject.SubAccount;
39  import org.kuali.ole.coa.businessobject.SubObjectCode;
40  import org.kuali.ole.coa.service.AccountService;
41  import org.kuali.ole.coa.service.ChartService;
42  import org.kuali.ole.coa.service.ObjectCodeService;
43  import org.kuali.ole.coa.service.ProjectCodeService;
44  import org.kuali.ole.coa.service.SubAccountService;
45  import org.kuali.ole.coa.service.SubObjectCodeService;
46  import org.kuali.ole.fp.batch.ProcurementCardAutoApproveDocumentsStep;
47  import org.kuali.ole.fp.batch.ProcurementCardCreateDocumentsStep;
48  import org.kuali.ole.fp.batch.ProcurementCardLoadStep;
49  import org.kuali.ole.fp.batch.service.ProcurementCardCreateDocumentService;
50  import org.kuali.ole.fp.businessobject.CapitalAssetInformation;
51  import org.kuali.ole.fp.businessobject.ProcurementCardDefault;
52  import org.kuali.ole.fp.businessobject.ProcurementCardHolder;
53  import org.kuali.ole.fp.businessobject.ProcurementCardSourceAccountingLine;
54  import org.kuali.ole.fp.businessobject.ProcurementCardTargetAccountingLine;
55  import org.kuali.ole.fp.businessobject.ProcurementCardTransaction;
56  import org.kuali.ole.fp.businessobject.ProcurementCardTransactionDetail;
57  import org.kuali.ole.fp.businessobject.ProcurementCardVendor;
58  import org.kuali.ole.fp.document.ProcurementCardDocument;
59  import org.kuali.ole.fp.document.validation.impl.ProcurementCardDocumentRuleConstants;
60  import org.kuali.ole.integration.cab.CapitalAssetBuilderModuleService;
61  import org.kuali.ole.sys.OLEConstants;
62  import org.kuali.ole.sys.OLEPropertyConstants;
63  import org.kuali.ole.sys.context.SpringContext;
64  import org.kuali.ole.sys.document.service.AccountingLineRuleHelperService;
65  import org.kuali.ole.sys.document.validation.event.DocumentSystemSaveEvent;
66  import org.kuali.ole.sys.service.UniversityDateService;
67  import org.kuali.ole.sys.util.KfsDateUtils;
68  import org.kuali.rice.core.api.datetime.DateTimeService;
69  import org.kuali.rice.core.api.util.type.KualiDecimal;
70  import org.kuali.rice.coreservice.framework.parameter.ParameterService;
71  import org.kuali.rice.kew.api.KewApiConstants;
72  import org.kuali.rice.kew.api.KewApiServiceLocator;
73  import org.kuali.rice.kew.api.document.DocumentStatus;
74  import org.kuali.rice.kew.api.document.search.DocumentSearchCriteria;
75  import org.kuali.rice.kew.api.document.search.DocumentSearchResult;
76  import org.kuali.rice.kew.api.document.search.DocumentSearchResults;
77  import org.kuali.rice.kew.api.exception.WorkflowException;
78  import org.kuali.rice.kns.service.DataDictionaryService;
79  import org.kuali.rice.krad.bo.DocumentHeader;
80  import org.kuali.rice.krad.service.BusinessObjectService;
81  import org.kuali.rice.krad.service.DocumentService;
82  import org.kuali.rice.krad.util.GlobalVariables;
83  import org.kuali.rice.krad.util.MessageMap;
84  import org.kuali.rice.krad.util.ObjectUtils;
85  import org.kuali.rice.krad.workflow.service.WorkflowDocumentService;
86  import org.springframework.transaction.annotation.Transactional;
87  
88  
89  /**
90   * This is the default implementation of the ProcurementCardCreateDocumentService interface.
91   *
92   * @see org.kuali.ole.fp.batch.service.ProcurementCardCreateDocumentService
93   */
94  public class ProcurementCardCreateDocumentServiceImpl implements ProcurementCardCreateDocumentService {
95      private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(ProcurementCardCreateDocumentServiceImpl.class);
96  
97      protected static final String WORKFLOW_SEARCH_RESULT_KEY = "routeHeaderId";
98  
99      protected ParameterService parameterService;
100     protected BusinessObjectService businessObjectService;
101     protected DocumentService documentService;
102     protected WorkflowDocumentService workflowDocumentService;
103     protected DataDictionaryService dataDictionaryService;
104     protected DateTimeService dateTimeService;
105     protected AccountingLineRuleHelperService accountingLineRuleUtil;
106     protected CapitalAssetBuilderModuleService capitalAssetBuilderModuleService;
107 
108 
109     /**
110      * This method retrieves a collection of credit card transactions and traverses through this list, creating
111      * ProcurementCardDocuments for each card.
112      *
113      * @return True if the procurement card documents were created successfully.  If any problem occur while creating the
114      * documents, a runtime exception will be thrown.
115      *
116      * @see org.kuali.ole.fp.batch.service.ProcurementCardCreateDocumentService#createProcurementCardDocuments()
117      */
118     @Override
119     @SuppressWarnings("rawtypes")
120     @Transactional
121     public boolean createProcurementCardDocuments() {
122         List documents = new ArrayList();
123         List cardTransactions = retrieveTransactions();
124 
125         // iterate through card transaction list and create documents
126         for (Iterator iter = cardTransactions.iterator(); iter.hasNext();) {
127             documents.add(createProcurementCardDocument((List) iter.next()));
128         }
129 
130         // now store all the documents
131         for (Iterator iter = documents.iterator(); iter.hasNext();) {
132             ProcurementCardDocument pcardDocument = (ProcurementCardDocument) iter.next();
133             try {
134                 documentService.saveDocument(pcardDocument, DocumentSystemSaveEvent.class);
135                 if ( LOG.isInfoEnabled() ) {
136                     LOG.info("Saved Procurement Card document: "+pcardDocument.getDocumentNumber());
137                 }
138             }
139             catch (Exception e) {
140                 LOG.error("Error persisting document # " + pcardDocument.getDocumentHeader().getDocumentNumber() + " " + e.getMessage(), e);
141                 throw new RuntimeException("Error persisting document # " + pcardDocument.getDocumentHeader().getDocumentNumber() + " " + e.getMessage(), e);
142             }
143         }
144 
145         return true;
146     }
147 
148     /**
149      * This method retrieves all the procurement card documents with a status of 'I' and routes them to the next step in the
150      * routing path.
151      *
152      * @return True if the routing was performed successfully.  A runtime exception will be thrown if any errors occur while routing.
153      *
154      * @see org.kuali.ole.fp.batch.service.ProcurementCardCreateDocumentService#routeProcurementCardDocuments(java.util.List)
155      */
156     @Override
157     public boolean routeProcurementCardDocuments() {
158 
159         List<String> documentIdList = retrieveProcurementCardDocumentsToRoute(KewApiConstants.ROUTE_HEADER_SAVED_CD);
160 
161         //Collections.reverse(documentIdList);
162         if ( LOG.isInfoEnabled() ) {
163             LOG.info("PCards to Route: "+documentIdList);
164         }
165 
166         for (String pcardDocumentId: documentIdList) {
167             try {
168                 ProcurementCardDocument pcardDocument = (ProcurementCardDocument)documentService.getByDocumentHeaderId(pcardDocumentId);
169                 if ( LOG.isInfoEnabled() ) {
170                     LOG.info("Routing PCDO document # " + pcardDocumentId + ".");
171                 }
172                 documentService.prepareWorkflowDocument(pcardDocument);
173 
174                 //** NOTE
175                 //
176                 //     Calling workflow service to BYPASS business rule checks
177                 //
178                 //** NOTE
179                 workflowDocumentService.route( pcardDocument.getDocumentHeader().getWorkflowDocument(), "", null);
180             }
181             catch (WorkflowException e) {
182                 LOG.error("Error routing document # " + pcardDocumentId + " " + e.getMessage());
183                 throw new RuntimeException(e.getMessage(),e);
184             }
185         }
186 
187         return true;
188     }
189 
190     /**
191      * Returns a list of all initiated but not yet routed procurement card documents, using the KualiWorkflowInfo service.
192      * @return a list of procurement card documents to route
193      */
194     protected List<String> retrieveProcurementCardDocumentsToRoute(String statusCode){
195         List<String> documentIds = new ArrayList<String>();
196 
197         DocumentSearchCriteria.Builder criteria = DocumentSearchCriteria.Builder.create();
198         criteria.setDocumentTypeName(OLEConstants.FinancialDocumentTypeCodes.PROCUREMENT_CARD);
199         criteria.setDocumentStatuses(Collections.singletonList(DocumentStatus.fromCode(statusCode)));
200         DocumentSearchResults results = KewApiServiceLocator.getWorkflowDocumentService().documentSearch(
201                 GlobalVariables.getUserSession().getPrincipalId(), criteria.build());
202 
203         for (DocumentSearchResult resultRow: results.getSearchResults()) {
204             documentIds.add(resultRow.getDocument().getDocumentId());
205     }
206 
207         return documentIds;
208     }
209 
210     /**
211      * This method determines if procurement card documents can be auto approved.  A document can be auto approved if
212      * the grace period for allowing auto approval of a procurement card document has passed.  The grace period is defined
213      * by a parameter in the parameters table.  The create date of the document is then compared against the current date and
214      * if the difference is larger than the grace period defined, then the document is auto approved.
215      *
216      * @return This method always returns true.
217      *
218      * @see org.kuali.ole.fp.batch.service.ProcurementCardCreateDocumentService#autoApproveProcurementCardDocuments()
219      */
220     @Override
221     public boolean autoApproveProcurementCardDocuments() {
222         // check if auto approve is turned on
223         boolean autoApproveOn = parameterService.getParameterValueAsBoolean(ProcurementCardAutoApproveDocumentsStep.class, AUTO_APPROVE_DOCUMENTS_IND);
224 
225         if (!autoApproveOn) { // no auto approve?  then skip out of here...
226             return true;
227         }
228 
229         List<String> documentIdList = retrieveProcurementCardDocumentsToRoute(KewApiConstants.ROUTE_HEADER_ENROUTE_CD);
230 
231         // get number of days and type for auto approve
232         int autoApproveNumberDays = Integer.parseInt(parameterService.getParameterValueAsString(ProcurementCardAutoApproveDocumentsStep.class, AUTO_APPROVE_NUMBER_OF_DAYS));
233 
234         Timestamp currentDate = dateTimeService.getCurrentTimestamp();
235         for (String pcardDocumentId: documentIdList) {
236             try {
237                 ProcurementCardDocument pcardDocument = (ProcurementCardDocument)documentService.getByDocumentHeaderId(pcardDocumentId);
238 
239                 // prevent PCard documents from auto approving if they have capital asset info to collect
240                 if(capitalAssetBuilderModuleService.hasCapitalAssetObjectSubType(pcardDocument)) {
241                     continue;
242                 }
243 
244                 // if number of days in route is passed the allowed number, call doc service for super user approve
245                 Timestamp docCreateDate = new Timestamp( pcardDocument.getDocumentHeader().getWorkflowDocument().getDateCreated().getMillis() );
246                 if (KfsDateUtils.getDifferenceInDays(docCreateDate, currentDate) > autoApproveNumberDays) {
247                     // update document description to reflect the auto approval
248                     pcardDocument.getDocumentHeader().setDocumentDescription("Auto Approved On " + dateTimeService.toDateTimeString(currentDate) + ".");
249 
250                     if ( LOG.isInfoEnabled() ) {
251                         LOG.info("Auto approving document # " + pcardDocument.getDocumentHeader().getDocumentNumber());
252                     }
253                     documentService.superUserApproveDocument(pcardDocument, "");
254                 }
255             } catch (WorkflowException e) {
256                 LOG.error("Error auto approving document # " + pcardDocumentId + " " + e.getMessage(),e);
257                 throw new RuntimeException(e.getMessage(),e);
258             }
259         }
260 
261         return true;
262     }
263 
264 
265     /**
266      * This method retrieves a list of transactions from a temporary table, and groups them into document lists, based on
267      * single transaction indicator or a grouping by card.
268      *
269      * @return List containing transactions for document.
270      */
271     @SuppressWarnings("rawtypes")
272     protected List retrieveTransactions() {
273         List groupedTransactions = new ArrayList();
274 
275         // retrieve records from transaction table order by card number
276         List transactions = (List) businessObjectService.findMatchingOrderBy(ProcurementCardTransaction.class, new HashMap(), OLEPropertyConstants.TRANSACTION_CREDIT_CARD_NUMBER, true);
277 
278         // check apc for single transaction documents or multiple by card
279         boolean singleTransaction = parameterService.getParameterValueAsBoolean(ProcurementCardCreateDocumentsStep.class, SINGLE_TRANSACTION_IND_PARM_NM);
280 
281         List documentTransactions = new ArrayList();
282         if (singleTransaction) {
283             for (Iterator iter = transactions.iterator(); iter.hasNext();) {
284                 documentTransactions.add(iter.next());
285                 groupedTransactions.add(documentTransactions);
286                 documentTransactions = new ArrayList();
287             }
288         }
289         else {
290             Map cardTransactionsMap = new HashMap();
291             for (Iterator iter = transactions.iterator(); iter.hasNext();) {
292                 ProcurementCardTransaction transaction = (ProcurementCardTransaction) iter.next();
293                 if (!cardTransactionsMap.containsKey(transaction.getTransactionCreditCardNumber())) {
294                     cardTransactionsMap.put(transaction.getTransactionCreditCardNumber(), new ArrayList());
295                 }
296                 ((List) cardTransactionsMap.get(transaction.getTransactionCreditCardNumber())).add(transaction);
297             }
298 
299             for (Iterator iter = cardTransactionsMap.values().iterator(); iter.hasNext();) {
300                 groupedTransactions.add(iter.next());
301 
302             }
303         }
304 
305         return groupedTransactions;
306     }
307 
308 
309     /**
310      * Creates a ProcurementCardDocument from the List of transactions given.
311      *
312      * @param transactions List of ProcurementCardTransaction objects to be used for creating the document.
313      * @return A ProcurementCardDocument populated with the transactions provided.
314      */
315     protected ProcurementCardDocument createProcurementCardDocument(List transactions) {
316         ProcurementCardDocument pcardDocument = null;
317 
318         try {
319             // get new document from doc service
320             pcardDocument = (ProcurementCardDocument) SpringContext.getBean(DocumentService.class).getNewDocument(PROCUREMENT_CARD);
321 
322             List<CapitalAssetInformation> capitalAssets = pcardDocument.getCapitalAssetInformation();
323             for (CapitalAssetInformation capitalAsset : capitalAssets) {
324                 if (ObjectUtils.isNotNull(capitalAsset) && ObjectUtils.isNotNull(capitalAsset.getCapitalAssetInformationDetails())) {
325                     capitalAsset.setDocumentNumber(pcardDocument.getDocumentNumber());
326                 }
327             }
328 
329             ProcurementCardTransaction trans = (ProcurementCardTransaction) transactions.get(0);
330             String errors = validateTransaction(trans);
331             createCardHolderRecord(pcardDocument, trans);
332 
333             // for each transaction, create transaction detail object and then acct lines for the detail
334             int transactionLineNumber = 1;
335             KualiDecimal documentTotalAmount = KualiDecimal.ZERO;
336             String errorText = "";
337             for (Iterator iter = transactions.iterator(); iter.hasNext();) {
338                 ProcurementCardTransaction transaction = (ProcurementCardTransaction) iter.next();
339 
340                 // create transaction detail record with accounting lines
341                 errorText += createTransactionDetailRecord(pcardDocument, transaction, transactionLineNumber);
342 
343                 // update document total
344                 documentTotalAmount = documentTotalAmount.add(transaction.getFinancialDocumentTotalAmount());
345 
346                 transactionLineNumber++;
347             }
348 
349             pcardDocument.getFinancialSystemDocumentHeader().setFinancialDocumentTotalAmount(documentTotalAmount);
350             pcardDocument.getDocumentHeader().setDocumentDescription("SYSTEM Generated");
351 
352             // Remove duplicate messages from errorText
353             String messages[] = StringUtils.split(errorText, ".");
354             for (int i = 0; i < messages.length; i++) {
355                 int countMatches = StringUtils.countMatches(errorText, messages[i]) - 1;
356                 errorText = StringUtils.replace(errorText, messages[i] + ".", "", countMatches);
357             }
358             // In case errorText is still too long, truncate it and indicate so.
359             Integer documentExplanationMaxLength = dataDictionaryService.getAttributeMaxLength(DocumentHeader.class.getName(), OLEPropertyConstants.EXPLANATION);
360             if (documentExplanationMaxLength != null && errorText.length() > documentExplanationMaxLength.intValue()) {
361                 String truncatedMessage = " ... TRUNCATED.";
362                 errorText = errorText.substring(0, documentExplanationMaxLength - truncatedMessage.length()) + truncatedMessage;
363             }
364             pcardDocument.getDocumentHeader().setExplanation(errorText);
365         }
366         catch (WorkflowException e) {
367             LOG.error("Error creating pcdo documents: " + e.getMessage(),e);
368             throw new RuntimeException("Error creating pcdo documents: " + e.getMessage(),e);
369         }
370 
371         return pcardDocument;
372     }
373 
374     /**
375      * Creates card holder record and sets that record to the document given.
376      *
377      * @param pcardDocument Procurement card document to place the record in.
378      * @param transaction The transaction to set the card holder record fields from.
379      */
380     protected void createCardHolderRecord(ProcurementCardDocument pcardDocument, ProcurementCardTransaction transaction) {
381         ProcurementCardHolder cardHolder = new ProcurementCardHolder();
382 
383         cardHolder.setDocumentNumber(pcardDocument.getDocumentNumber());
384         cardHolder.setTransactionCreditCardNumber(transaction.getTransactionCreditCardNumber());
385         cardHolder.setChartOfAccountsCode(transaction.getChartOfAccountsCode());
386         cardHolder.setAccountNumber(transaction.getAccountNumber());
387         cardHolder.setSubAccountNumber(transaction.getSubAccountNumber());
388 
389         if (getParameterService().getParameterValueAsBoolean(ProcurementCardCreateDocumentsStep.class, ProcurementCardCreateDocumentsStep.USE_CARD_HOLDER_DEFAULT_PARAMETER_NAME)) {
390             final ProcurementCardDefault procurementCardDefault = retrieveProcurementCardDefault(transaction.getTransactionCreditCardNumber());
391             if (procurementCardDefault != null) {
392                 cardHolder.setCardCycleAmountLimit(procurementCardDefault.getCardCycleAmountLimit());
393                 cardHolder.setCardCycleVolumeLimit(procurementCardDefault.getCardCycleVolumeLimit());
394                 cardHolder.setCardHolderAlternateName(procurementCardDefault.getCardHolderAlternateName());
395                 cardHolder.setCardHolderCityName(procurementCardDefault.getCardHolderCityName());
396                 cardHolder.setCardHolderLine1Address(procurementCardDefault.getCardHolderLine1Address());
397                 cardHolder.setCardHolderLine2Address(procurementCardDefault.getCardHolderLine2Address());
398                 cardHolder.setCardHolderName(procurementCardDefault.getCardHolderName());
399                 cardHolder.setCardHolderStateCode(procurementCardDefault.getCardHolderStateCode());
400                 cardHolder.setCardHolderWorkPhoneNumber(procurementCardDefault.getCardHolderWorkPhoneNumber());
401                 cardHolder.setCardHolderZipCode(procurementCardDefault.getCardHolderZipCode());
402                 cardHolder.setCardLimit(procurementCardDefault.getCardLimit());
403                 cardHolder.setCardNoteText(procurementCardDefault.getCardNoteText());
404                 cardHolder.setCardStatusCode(procurementCardDefault.getCardStatusCode());
405 
406                 if (getParameterService().getParameterValueAsBoolean(ProcurementCardCreateDocumentsStep.class, ProcurementCardCreateDocumentsStep.USE_ACCOUNTING_DEFAULT_PARAMETER_NAME)) {
407                     cardHolder.setChartOfAccountsCode(procurementCardDefault.getChartOfAccountsCode());
408                     cardHolder.setAccountNumber(procurementCardDefault.getAccountNumber());
409                     cardHolder.setSubAccountNumber(procurementCardDefault.getSubAccountNumber());
410                 }
411             }
412         }
413         if (StringUtils.isEmpty(cardHolder.getCardHolderName())) {
414         cardHolder.setCardCycleAmountLimit(transaction.getCardCycleAmountLimit());
415         cardHolder.setCardCycleVolumeLimit(transaction.getCardCycleVolumeLimit());
416         cardHolder.setCardHolderAlternateName(transaction.getCardHolderAlternateName());
417         cardHolder.setCardHolderCityName(transaction.getCardHolderCityName());
418         cardHolder.setCardHolderLine1Address(transaction.getCardHolderLine1Address());
419         cardHolder.setCardHolderLine2Address(transaction.getCardHolderLine2Address());
420         cardHolder.setCardHolderName(transaction.getCardHolderName());
421         cardHolder.setCardHolderStateCode(transaction.getCardHolderStateCode());
422         cardHolder.setCardHolderWorkPhoneNumber(transaction.getCardHolderWorkPhoneNumber());
423         cardHolder.setCardHolderZipCode(transaction.getCardHolderZipCode());
424         cardHolder.setCardLimit(transaction.getCardLimit());
425         cardHolder.setCardNoteText(transaction.getCardNoteText());
426         cardHolder.setCardStatusCode(transaction.getCardStatusCode());
427         }
428 
429         pcardDocument.setProcurementCardHolder(cardHolder);
430     }
431 
432     /**
433      * Creates a transaction detail record and adds that record to the document provided.
434      *
435      * @param pcardDocument Document to place record in.
436      * @param transaction Transaction to set fields from.
437      * @param transactionLineNumber Line number of the new transaction detail record within the procurement card document.
438      * @return The error text that was generated from the creation of the detail records.  If the text is empty, no errors were encountered.
439      */
440     protected String createTransactionDetailRecord(ProcurementCardDocument pcardDocument, ProcurementCardTransaction transaction, Integer transactionLineNumber) {
441         ProcurementCardTransactionDetail transactionDetail = new ProcurementCardTransactionDetail();
442 
443         // set the document transaction detail fields from the loaded transaction record
444         transactionDetail.setDocumentNumber(pcardDocument.getDocumentNumber());
445         transactionDetail.setFinancialDocumentTransactionLineNumber(transactionLineNumber);
446         transactionDetail.setTransactionDate(transaction.getTransactionDate());
447         transactionDetail.setTransactionReferenceNumber(transaction.getTransactionReferenceNumber());
448         transactionDetail.setTransactionBillingCurrencyCode(transaction.getTransactionBillingCurrencyCode());
449         transactionDetail.setTransactionCurrencyExchangeRate(transaction.getTransactionCurrencyExchangeRate());
450         transactionDetail.setTransactionDate(transaction.getTransactionDate());
451         transactionDetail.setTransactionOriginalCurrencyAmount(transaction.getTransactionOriginalCurrencyAmount());
452         transactionDetail.setTransactionOriginalCurrencyCode(transaction.getTransactionOriginalCurrencyCode());
453         transactionDetail.setTransactionPointOfSaleCode(transaction.getTransactionPointOfSaleCode());
454         transactionDetail.setTransactionPostingDate(transaction.getTransactionPostingDate());
455         transactionDetail.setTransactionPurchaseIdentifierDescription(transaction.getTransactionPurchaseIdentifierDescription());
456         transactionDetail.setTransactionPurchaseIdentifierIndicator(transaction.getTransactionPurchaseIdentifierIndicator());
457         transactionDetail.setTransactionSalesTaxAmount(transaction.getTransactionSalesTaxAmount());
458         transactionDetail.setTransactionSettlementAmount(transaction.getTransactionSettlementAmount());
459         transactionDetail.setTransactionTaxExemptIndicator(transaction.getTransactionTaxExemptIndicator());
460         transactionDetail.setTransactionTravelAuthorizationCode(transaction.getTransactionTravelAuthorizationCode());
461         transactionDetail.setTransactionUnitContactName(transaction.getTransactionUnitContactName());
462 
463         if (GL_CREDIT_CODE.equals(transaction.getTransactionDebitCreditCode())) {
464             transactionDetail.setTransactionTotalAmount(transaction.getFinancialDocumentTotalAmount().negated());
465         }
466         else {
467             transactionDetail.setTransactionTotalAmount(transaction.getFinancialDocumentTotalAmount());
468         }
469 
470         // create transaction vendor record
471         createTransactionVendorRecord(pcardDocument, transaction, transactionDetail);
472 
473         // add transaction detail to document
474         pcardDocument.getTransactionEntries().add(transactionDetail);
475 
476         // now create the initial source and target lines for this transaction
477         return createAndValidateAccountingLines(pcardDocument, transaction, transactionDetail);
478     }
479 
480 
481     /**
482      * Creates a transaction vendor detail record and adds it to the transaction detail.
483      *
484      * @param pcardDocument The procurement card document to retrieve values from.
485      * @param transaction Transaction to set fields from.
486      * @param transactionDetail The transaction detail to set the vendor record on.
487      */
488     protected void createTransactionVendorRecord(ProcurementCardDocument pcardDocument, ProcurementCardTransaction transaction, ProcurementCardTransactionDetail transactionDetail) {
489         ProcurementCardVendor transactionVendor = new ProcurementCardVendor();
490 
491         transactionVendor.setDocumentNumber(pcardDocument.getDocumentNumber());
492         transactionVendor.setFinancialDocumentTransactionLineNumber(transactionDetail.getFinancialDocumentTransactionLineNumber());
493         transactionVendor.setTransactionMerchantCategoryCode(transaction.getTransactionMerchantCategoryCode());
494         transactionVendor.setVendorCityName(transaction.getVendorCityName());
495         transactionVendor.setVendorLine1Address(transaction.getVendorLine1Address());
496         transactionVendor.setVendorLine2Address(transaction.getVendorLine2Address());
497         transactionVendor.setVendorName(transaction.getVendorName());
498         transactionVendor.setVendorOrderNumber(transaction.getVendorOrderNumber());
499         transactionVendor.setVendorStateCode(transaction.getVendorStateCode());
500         transactionVendor.setVendorZipCode(transaction.getVendorZipCode());
501         transactionVendor.setVisaVendorIdentifier(transaction.getVisaVendorIdentifier());
502 
503         transactionDetail.setProcurementCardVendor(transactionVendor);
504     }
505 
506     /**
507      * From the transaction accounting attributes, creates source and target accounting lines. Attributes are validated first, and
508      * replaced with default and error values if needed. There will be 1 source and 1 target line generated.
509      *
510      * @param pcardDocument The procurement card document to add the new accounting lines to.
511      * @param transaction The transaction to process into account lines.
512      * @param docTransactionDetail The transaction detail to create source and target accounting lines from.
513      * @return String containing any error messages.
514      */
515     protected String createAndValidateAccountingLines(ProcurementCardDocument pcardDocument, ProcurementCardTransaction transaction, ProcurementCardTransactionDetail docTransactionDetail) {
516         // build source lines
517         ProcurementCardSourceAccountingLine sourceLine = createSourceAccountingLine(transaction, docTransactionDetail);
518         sourceLine.setPostingYear(pcardDocument.getPostingYear());
519 
520         // add line to transaction through document since document contains the next sequence number fields
521         pcardDocument.addSourceAccountingLine(sourceLine);
522 
523         // build target lines
524         ProcurementCardTargetAccountingLine targetLine = createTargetAccountingLine(transaction, docTransactionDetail);
525         targetLine.setPostingYear(pcardDocument.getPostingYear());
526 
527         // add line to transaction through document since document contains the next sequence number fields
528         pcardDocument.addTargetAccountingLine(targetLine);
529 
530         return validateTargetAccountingLine(targetLine);
531     }
532 
533     /**
534      * Creates the to record for the transaction. The chart of account attributes from the transaction are used to create
535      * the accounting line.
536      *
537      * @param transaction The transaction to pull information from to create the accounting line.
538      * @param docTransactionDetail The transaction detail to pull information from to populate the accounting line.
539      * @return The target accounting line fully populated with values from the parameters passed in.
540      */
541     protected ProcurementCardTargetAccountingLine createTargetAccountingLine(ProcurementCardTransaction transaction, ProcurementCardTransactionDetail docTransactionDetail) {
542         ProcurementCardTargetAccountingLine targetLine = new ProcurementCardTargetAccountingLine();
543         targetLine.setDocumentNumber(docTransactionDetail.getDocumentNumber());
544         targetLine.setFinancialDocumentTransactionLineNumber(docTransactionDetail.getFinancialDocumentTransactionLineNumber());
545         targetLine.setChartOfAccountsCode(transaction.getChartOfAccountsCode());
546         targetLine.setAccountNumber(transaction.getAccountNumber());
547         targetLine.setFinancialObjectCode(transaction.getFinancialObjectCode());
548         targetLine.setSubAccountNumber(transaction.getSubAccountNumber());
549         targetLine.setFinancialSubObjectCode(transaction.getFinancialSubObjectCode());
550         targetLine.setProjectCode(transaction.getProjectCode());
551 
552         if (getParameterService().getParameterValueAsBoolean(ProcurementCardCreateDocumentsStep.class, ProcurementCardCreateDocumentsStep.USE_ACCOUNTING_DEFAULT_PARAMETER_NAME)) {
553             final ProcurementCardDefault procurementCardDefault = retrieveProcurementCardDefault(transaction.getTransactionCreditCardNumber());
554             if (procurementCardDefault != null) {
555                     targetLine.setChartOfAccountsCode(procurementCardDefault.getChartOfAccountsCode());
556                     targetLine.setAccountNumber(procurementCardDefault.getAccountNumber());
557                     targetLine.setFinancialObjectCode(procurementCardDefault.getFinancialObjectCode());
558                     targetLine.setSubAccountNumber(procurementCardDefault.getSubAccountNumber());
559                     targetLine.setFinancialSubObjectCode(procurementCardDefault.getFinancialSubObjectCode());
560                     targetLine.setProjectCode(procurementCardDefault.getProjectCode());
561             }
562         }
563 
564         if (GL_CREDIT_CODE.equals(transaction.getTransactionDebitCreditCode())) {
565             targetLine.setAmount(transaction.getFinancialDocumentTotalAmount().negated());
566         }
567         else {
568             targetLine.setAmount(transaction.getFinancialDocumentTotalAmount());
569         }
570 
571         return targetLine;
572     }
573 
574     /**
575      * Creates the from record for the transaction. The clearing chart, account, and object code is used for creating the line.
576      *
577      * @param transaction The transaction to pull information from to create the accounting line.
578      * @param docTransactionDetail The transaction detail to pull information from to populate the accounting line.
579      * @return The source accounting line fully populated with values from the parameters passed in.
580      */
581     protected ProcurementCardSourceAccountingLine createSourceAccountingLine(ProcurementCardTransaction transaction, ProcurementCardTransactionDetail docTransactionDetail) {
582         ProcurementCardSourceAccountingLine sourceLine = new ProcurementCardSourceAccountingLine();
583 
584         sourceLine.setDocumentNumber(docTransactionDetail.getDocumentNumber());
585         sourceLine.setFinancialDocumentTransactionLineNumber(docTransactionDetail.getFinancialDocumentTransactionLineNumber());
586         sourceLine.setChartOfAccountsCode(getDefaultChartCode());
587         sourceLine.setAccountNumber(getDefaultAccountNumber());
588         sourceLine.setFinancialObjectCode(getDefaultObjectCode());
589 
590         if (GL_CREDIT_CODE.equals(transaction.getTransactionDebitCreditCode())) {
591             sourceLine.setAmount(transaction.getFinancialDocumentTotalAmount().negated());
592         }
593         else {
594             sourceLine.setAmount(transaction.getFinancialDocumentTotalAmount());
595         }
596 
597         return sourceLine;
598     }
599 
600     /**
601      * Validates the chart of account attributes for existence and active indicator. Will substitute for defined
602      * default parameters or set fields to empty that if they have errors.
603      *
604      * @param targetLine The target accounting line to be validated.
605      * @return String with error messages discovered during validation.  An empty string indicates no validation errors were found.
606      */
607     protected String validateTargetAccountingLine(ProcurementCardTargetAccountingLine targetLine) {
608         String errorText = "";
609 
610         targetLine.refresh();
611 
612         if (!accountingLineRuleUtil.isValidChart("", targetLine.getChart(), dataDictionaryService.getDataDictionary())) {
613             String tempErrorText = "Chart " + targetLine.getChartOfAccountsCode() + " is invalid; using error Chart Code.";
614             if ( LOG.isInfoEnabled() ) {
615                 LOG.info(tempErrorText);
616             }
617             errorText += " " + tempErrorText;
618 
619             targetLine.setChartOfAccountsCode(getErrorChartCode());
620             targetLine.refresh();
621         }
622 
623         if (!accountingLineRuleUtil.isValidAccount("", targetLine.getAccount(), dataDictionaryService.getDataDictionary()) || targetLine.getAccount().isExpired()) {
624             String tempErrorText = "Chart " + targetLine.getChartOfAccountsCode() + " Account " + targetLine.getAccountNumber() + " is invalid; using error account.";
625             if ( LOG.isInfoEnabled() ) {
626                 LOG.info(tempErrorText);
627             }
628             errorText += " " + tempErrorText;
629 
630             targetLine.setChartOfAccountsCode(getErrorChartCode());
631             targetLine.setAccountNumber(getErrorAccountNumber());
632             targetLine.refresh();
633         }
634 
635         if (!accountingLineRuleUtil.isValidObjectCode("", targetLine.getObjectCode(), dataDictionaryService.getDataDictionary())) {
636             String tempErrorText = "Chart " + targetLine.getChartOfAccountsCode() + " Object Code " + targetLine.getFinancialObjectCode() + " is invalid; using default Object Code.";
637             if ( LOG.isInfoEnabled() ) {
638                 LOG.info(tempErrorText);
639             }
640             errorText += " " + tempErrorText;
641 
642             targetLine.setFinancialObjectCode(getDefaultObjectCode());
643             targetLine.refresh();
644         }
645 
646         if (StringUtils.isNotBlank(targetLine.getSubAccountNumber()) && !accountingLineRuleUtil.isValidSubAccount("", targetLine.getSubAccount(), dataDictionaryService.getDataDictionary())) {
647             String tempErrorText = "Chart " + targetLine.getChartOfAccountsCode() + " Account " + targetLine.getAccountNumber() + " Sub Account " + targetLine.getSubAccountNumber() + " is invalid; Setting Sub Account to blank.";
648             if ( LOG.isInfoEnabled() ) {
649                 LOG.info(tempErrorText);
650             }
651             errorText += " " + tempErrorText;
652 
653             targetLine.setSubAccountNumber("");
654         }
655 
656         if (StringUtils.isNotBlank(targetLine.getFinancialSubObjectCode()) && !accountingLineRuleUtil.isValidSubObjectCode("", targetLine.getSubObjectCode(), dataDictionaryService.getDataDictionary())) {
657             String tempErrorText = "Chart " + targetLine.getChartOfAccountsCode() + " Account " + targetLine.getAccountNumber() + " Object Code " + targetLine.getFinancialObjectCode() + " Sub Object Code " + targetLine.getFinancialSubObjectCode() + " is invalid; setting Sub Object to blank.";
658             if ( LOG.isInfoEnabled() ) {
659                 LOG.info(tempErrorText);
660             }
661             errorText += " " + tempErrorText;
662 
663             targetLine.setFinancialSubObjectCode("");
664         }
665 
666         if (StringUtils.isNotBlank(targetLine.getProjectCode()) && !accountingLineRuleUtil.isValidProjectCode("", targetLine.getProject(), dataDictionaryService.getDataDictionary())) {
667             if ( LOG.isInfoEnabled() ) {
668                 LOG.info("Project Code " + targetLine.getProjectCode() + " is invalid; setting to blank.");
669             }
670             errorText += " Project Code " + targetLine.getProjectCode() + " is invalid; setting to blank.";
671 
672             targetLine.setProjectCode("");
673         }
674 
675         // clear out GlobalVariable message map, since we have taken care of the errors
676         GlobalVariables.setMessageMap(new MessageMap());
677 
678         return errorText;
679     }
680 
681 
682     /**
683      * Validates the chart of account attributes for existence and active indicator. Will substitute for defined
684      * default parameters or set fields to empty that if they have errors.
685      *
686      * @param transaction The transaction to be validated.
687      * @return String with error messages discovered during validation.  An empty string indicates no validation errors were found.
688      */
689     protected String validateTransaction(ProcurementCardTransaction transaction) {
690         String errorText = "";
691 
692         if (getParameterService().getParameterValueAsBoolean(ProcurementCardCreateDocumentsStep.class, ProcurementCardCreateDocumentsStep.USE_ACCOUNTING_DEFAULT_PARAMETER_NAME)) {
693             final ProcurementCardDefault procurementCardDefault = retrieveProcurementCardDefault(transaction.getTransactionCreditCardNumber());
694             if (ObjectUtils.isNull(procurementCardDefault)) {
695                 final String tempErrorText = "Procurement Card Accounting Line Defaults are turned on but no Procurement Card Default record could be retrieved for transaction: "+transaction.getTransactionReferenceNumber() + " by card number.";
696                 if ( LOG.isInfoEnabled() ) {
697                     LOG.info(tempErrorText);
698                 }
699                 errorText += " " + tempErrorText;
700             }
701         }
702         else {
703             transaction.refresh();
704 
705             final ChartService chartService = SpringContext.getBean(ChartService.class);
706             if (transaction.getChartOfAccountsCode() == null || ObjectUtils.isNull(chartService.getByPrimaryId(transaction.getChartOfAccountsCode()))) {
707                 String tempErrorText = "Chart " + transaction.getChartOfAccountsCode() + " is invalid; using error Chart Code.";
708                 if ( LOG.isInfoEnabled() ) {
709                     LOG.info(tempErrorText);
710                 }
711                 errorText += " " + tempErrorText;
712                 transaction.setChartOfAccountsCode(getErrorChartCode());
713                 transaction.refresh();
714             }
715 
716             final AccountService accountService = SpringContext.getBean(AccountService.class);
717             if (transaction.getAccountNumber() == null || ObjectUtils.isNull(accountService.getByPrimaryIdWithCaching(transaction.getChartOfAccountsCode(), transaction.getAccountNumber())) || accountService.getByPrimaryIdWithCaching(transaction.getChartOfAccountsCode(), transaction.getAccountNumber()).isExpired()) {
718                 String tempErrorText = "Chart " + transaction.getChartOfAccountsCode() + " Account " + transaction.getAccountNumber() + " is invalid; using error account.";
719                 if ( LOG.isInfoEnabled() ) {
720                     LOG.info(tempErrorText);
721                 }
722                 errorText += " " + tempErrorText;
723                 transaction.setChartOfAccountsCode(getErrorChartCode());
724                 transaction.setAccountNumber(getErrorAccountNumber());
725                 transaction.refresh();
726             }
727 
728             final UniversityDateService uds = SpringContext.getBean(UniversityDateService.class);
729             final ObjectCodeService ocs = SpringContext.getBean(ObjectCodeService.class);
730             if (transaction.getFinancialObjectCode() == null || ObjectUtils.isNull(ocs.getByPrimaryIdWithCaching(uds.getCurrentFiscalYear(), transaction.getChartOfAccountsCode(), transaction.getFinancialObjectCode()))) {
731                 String tempErrorText = "Chart " + transaction.getChartOfAccountsCode() + " Object Code " + transaction.getFinancialObjectCode() + " is invalid; using default Object Code.";
732                 if ( LOG.isInfoEnabled() ) {
733                     LOG.info(tempErrorText);
734                 }
735                 errorText += " " + tempErrorText;
736 
737                 transaction.setFinancialObjectCode(getDefaultObjectCode());
738                 transaction.refresh();
739             }
740 
741             if (StringUtils.isNotBlank(transaction.getSubAccountNumber())) {
742                 SubAccountService sas = SpringContext.getBean(SubAccountService.class);
743                 SubAccount subAccount = sas.getByPrimaryIdWithCaching(transaction.getChartOfAccountsCode(), transaction.getAccountNumber(), transaction.getSubAccountNumber());
744 
745                 if (ObjectUtils.isNull(subAccount)) {
746                     String tempErrorText = "Chart " + transaction.getChartOfAccountsCode() + " Account " + transaction.getAccountNumber() + " Sub Account " + transaction.getSubAccountNumber() + " is invalid; Setting Sub Account to blank.";
747                     if ( LOG.isInfoEnabled() ) {
748                         LOG.info(tempErrorText);
749                     }
750                     errorText += " " + tempErrorText;
751 
752                     transaction.setSubAccountNumber("");
753                 }
754             }
755 
756             if (StringUtils.isNotBlank(transaction.getFinancialSubObjectCode())) {
757 
758                 SubObjectCodeService socs = SpringContext.getBean(SubObjectCodeService.class);
759                 SubObjectCode soc = socs.getByPrimaryIdForCurrentYear(transaction.getChartOfAccountsCode(), transaction.getAccountNumber(), transaction.getFinancialObjectCode(), transaction.getFinancialSubObjectCode());
760 
761                 if (ObjectUtils.isNull(soc)) {
762                     String tempErrorText = "Chart " + transaction.getChartOfAccountsCode() + " Account " + transaction.getAccountNumber() + " Object Code " + transaction.getFinancialObjectCode() + " Sub Object Code " + transaction.getFinancialSubObjectCode() + " is invalid; setting Sub Object to blank.";
763                     if ( LOG.isInfoEnabled() ) {
764                         LOG.info(tempErrorText);
765                     }
766                     errorText += " " + tempErrorText;
767 
768                     transaction.setFinancialSubObjectCode("");
769                 }
770             }
771 
772             if (StringUtils.isNotBlank(transaction.getProjectCode())) {
773 
774                 ProjectCodeService pcs = SpringContext.getBean(ProjectCodeService.class);
775                 ProjectCode pc = pcs.getByPrimaryId(transaction.getProjectCode());
776 
777                 if (ObjectUtils.isNull(pc)) {
778                     if ( LOG.isInfoEnabled() ) {
779                         LOG.info("Project Code " + transaction.getProjectCode() + " is invalid; setting to blank.");
780                     }
781                     errorText += " Project Code " + transaction.getProjectCode() + " is invalid; setting to blank.";
782 
783                     transaction.setProjectCode("");
784                 }
785             }
786         }
787 
788         // clear out GlobalVariable message map, since we have taken care of the errors
789         GlobalVariables.setMessageMap(new MessageMap());
790 
791         return errorText;
792     }
793 
794     /**
795      * Retrieves the error chart code from the parameter table.
796      * @return The error chart code defined in the parameter table.
797      */
798     protected String getErrorChartCode() {
799         return parameterService.getParameterValueAsString(ProcurementCardCreateDocumentsStep.class, ProcurementCardDocumentRuleConstants.ERROR_TRANS_CHART_CODE_PARM_NM);
800     }
801 
802     /**
803      * Retrieves the error account number from the parameter table.
804      * @return The error account number defined in the parameter table.
805      */
806     protected String getErrorAccountNumber() {
807         return parameterService.getParameterValueAsString(ProcurementCardCreateDocumentsStep.class, ERROR_TRANS_ACCOUNT_PARM_NM);
808     }
809 
810     /**
811      * Gets the default Chart Code, Account from the custom Procurement Cardholder table.
812      *
813      */
814     protected ProcurementCardDefault retrieveProcurementCardDefault(String creditCardNumber) {
815         Map<String, String> pkMap = new HashMap<String, String>();
816         pkMap.put(OLEPropertyConstants.CREDIT_CARD_NUMBER, creditCardNumber);
817         ProcurementCardDefault procurementCardDefault = businessObjectService.findByPrimaryKey(ProcurementCardDefault.class, pkMap);
818 
819         return procurementCardDefault;
820     }
821 
822     /**
823      * Retrieves the default chard code from the parameter table.
824      * @return The default chart code defined in the parameter table.
825      */
826     protected String getDefaultChartCode() {
827         return parameterService.getParameterValueAsString(ProcurementCardLoadStep.class, DEFAULT_TRANS_CHART_CODE_PARM_NM);
828     }
829 
830     /**
831      * Retrieves the default account number from the parameter table.
832      * @return The default account number defined in the parameter table.
833      */
834     protected String getDefaultAccountNumber() {
835         return parameterService.getParameterValueAsString(ProcurementCardLoadStep.class, DEFAULT_TRANS_ACCOUNT_PARM_NM);
836     }
837 
838     /**
839      * Retrieves the default object code from the parameter table.
840      * @return The default object code defined in the parameter table.
841      */
842     protected String getDefaultObjectCode() {
843         return parameterService.getParameterValueAsString(ProcurementCardLoadStep.class, DEFAULT_TRANS_OBJECT_CODE_PARM_NM);
844     }
845 
846     /**
847      * Calls businessObjectService to remove all the procurement card transaction rows from the transaction load table.
848      */
849     protected void cleanTransactionsTable() {
850         businessObjectService.deleteMatching(ProcurementCardTransaction.class, new HashMap());
851     }
852 
853     /**
854      * Loads all the parsed XML transactions into the temp transaction table.
855      *
856      * @param transactions List of ProcurementCardTransactions to load.
857      */
858     protected void loadTransactions(List transactions) {
859         businessObjectService.save(transactions);
860     }
861 
862     /**
863      * @return retrieves the presumably injected implementation of ParameterService to use
864      */
865     public ParameterService getParameterService() {
866         return parameterService;
867     }
868 
869     /**
870      * Sets the parameterService attribute.
871      * @param parameterService
872      */
873     public void setParameterService(ParameterService parameterService) {
874         this.parameterService = parameterService;
875     }
876 
877     /**
878      * Gets the businessObjectService attribute.
879      * @return Returns the businessObjectService.
880      */
881     public BusinessObjectService getBusinessObjectService() {
882         return businessObjectService;
883     }
884 
885     /**
886      * Sets the businessObjectService attribute.
887      * @param businessObjectService The businessObjectService to set.
888      */
889     public void setBusinessObjectService(BusinessObjectService businessObjectService) {
890         this.businessObjectService = businessObjectService;
891     }
892 
893     /**
894      * Gets the documentService attribute.
895      * @return Returns the documentService.
896      */
897     public DocumentService getDocumentService() {
898         return documentService;
899     }
900 
901     /**
902      * Sets the documentService attribute.
903      * @param documentService The documentService to set.
904      */
905     public void setDocumentService(DocumentService documentService) {
906         this.documentService = documentService;
907     }
908 
909     public WorkflowDocumentService getWorkflowDocumentService() {
910         return workflowDocumentService;
911     }
912 
913     public void setWorkflowDocumentService(WorkflowDocumentService workflowDocumentService) {
914         this.workflowDocumentService = workflowDocumentService;
915     }
916 
917     /**
918      * Gets the dataDictionaryService attribute.
919      * @return Returns the dataDictionaryService.
920      */
921     public DataDictionaryService getDataDictionaryService() {
922         return dataDictionaryService;
923     }
924 
925     /**
926      * Sets the dataDictionaryService attribute.
927      * @param dataDictionaryService dataDictionaryService to set.
928      */
929     public void setDataDictionaryService(DataDictionaryService dataDictionaryService) {
930         this.dataDictionaryService = dataDictionaryService;
931     }
932 
933 
934     /**
935      * Gets the dateTimeService attribute.
936      * @return Returns the dateTimeService.
937      */
938     public DateTimeService getDateTimeService() {
939         return dateTimeService;
940     }
941 
942     /**
943      * Sets the dateTimeService attribute.
944      * @param dateTimeService The dateTimeService to set.
945      */
946     public void setDateTimeService(DateTimeService dateTimeService) {
947         this.dateTimeService = dateTimeService;
948     }
949 
950     /**
951      * Sets the accountingLineRuleUtil attribute value.
952      * @param accountingLineRuleUtil The accountingLineRuleUtil to set.
953      */
954     public void setAccountingLineRuleUtil(AccountingLineRuleHelperService accountingLineRuleUtil) {
955         this.accountingLineRuleUtil = accountingLineRuleUtil;
956     }
957 
958     /**
959      * Sets the capitalAssetBuilderModuleService attribute value.
960      * @param capitalAssetBuilderModuleService The capitalAssetBuilderModuleService to set.
961      */
962     public void setCapitalAssetBuilderModuleService(CapitalAssetBuilderModuleService capitalAssetBuilderModuleService) {
963         this.capitalAssetBuilderModuleService = capitalAssetBuilderModuleService;
964     }
965 
966 }