/* * The Kuali Financial System, a comprehensive financial management system for higher education. * * Copyright 2005-2014 The Kuali Foundation * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.kuali.kfs.fp.batch.service.impl; import static org.kuali.kfs.fp.document.validation.impl.ProcurementCardDocumentRuleConstants.AUTO_APPROVE_DOCUMENTS_IND; import static org.kuali.kfs.fp.document.validation.impl.ProcurementCardDocumentRuleConstants.AUTO_APPROVE_NUMBER_OF_DAYS; import static org.kuali.kfs.fp.document.validation.impl.ProcurementCardDocumentRuleConstants.DEFAULT_TRANS_ACCOUNT_PARM_NM; import static org.kuali.kfs.fp.document.validation.impl.ProcurementCardDocumentRuleConstants.DEFAULT_TRANS_CHART_CODE_PARM_NM; import static org.kuali.kfs.fp.document.validation.impl.ProcurementCardDocumentRuleConstants.DEFAULT_TRANS_OBJECT_CODE_PARM_NM; import static org.kuali.kfs.fp.document.validation.impl.ProcurementCardDocumentRuleConstants.ERROR_TRANS_ACCOUNT_PARM_NM; import static org.kuali.kfs.fp.document.validation.impl.ProcurementCardDocumentRuleConstants.SINGLE_TRANSACTION_IND_PARM_NM; import static org.kuali.kfs.sys.KFSConstants.GL_CREDIT_CODE; import static org.kuali.kfs.sys.KFSConstants.FinancialDocumentTypeCodes.PROCUREMENT_CARD; import java.sql.Date; import java.sql.Timestamp; import java.text.DateFormat; import java.text.MessageFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.apache.commons.lang.StringUtils; import org.kuali.kfs.coa.businessobject.ProjectCode; import org.kuali.kfs.coa.businessobject.SubAccount; import org.kuali.kfs.coa.businessobject.SubObjectCode; import org.kuali.kfs.coa.service.AccountService; import org.kuali.kfs.coa.service.ChartService; import org.kuali.kfs.coa.service.ObjectCodeService; import org.kuali.kfs.coa.service.ProjectCodeService; import org.kuali.kfs.coa.service.SubAccountService; import org.kuali.kfs.coa.service.SubObjectCodeService; import org.kuali.kfs.fp.batch.ProcurementCardAutoApproveDocumentsStep; import org.kuali.kfs.fp.batch.ProcurementCardCreateDocumentsStep; import org.kuali.kfs.fp.batch.ProcurementCardLoadStep; import org.kuali.kfs.fp.batch.ProcurementCardReportType; import org.kuali.kfs.fp.batch.service.ProcurementCardCreateDocumentService; import org.kuali.kfs.fp.businessobject.CapitalAssetInformation; import org.kuali.kfs.fp.businessobject.ProcurementCardDefault; import org.kuali.kfs.fp.businessobject.ProcurementCardHolder; import org.kuali.kfs.fp.businessobject.ProcurementCardSourceAccountingLine; import org.kuali.kfs.fp.businessobject.ProcurementCardTargetAccountingLine; import org.kuali.kfs.fp.businessobject.ProcurementCardTransaction; import org.kuali.kfs.fp.businessobject.ProcurementCardTransactionDetail; import org.kuali.kfs.fp.businessobject.ProcurementCardVendor; import org.kuali.kfs.fp.document.ProcurementCardDocument; import org.kuali.kfs.fp.document.validation.impl.ProcurementCardDocumentRuleConstants; import org.kuali.kfs.integration.cab.CapitalAssetBuilderModuleService; import org.kuali.kfs.sys.KFSConstants; import org.kuali.kfs.sys.KFSPropertyConstants; import org.kuali.kfs.sys.context.SpringContext; import org.kuali.kfs.sys.document.service.AccountingLineRuleHelperService; import org.kuali.kfs.sys.document.service.FinancialSystemDocumentService; import org.kuali.kfs.sys.document.validation.event.DocumentSystemSaveEvent; import org.kuali.kfs.sys.service.UniversityDateService; import org.kuali.kfs.sys.service.VelocityEmailService; import org.kuali.kfs.sys.util.KfsDateUtils; import org.kuali.rice.core.api.datetime.DateTimeService; import org.kuali.rice.core.api.util.type.KualiDecimal; import org.kuali.rice.core.web.format.CurrencyFormatter; import org.kuali.rice.core.web.format.Formatter; import org.kuali.rice.coreservice.framework.parameter.ParameterService; import org.kuali.rice.kew.api.KewApiConstants; import org.kuali.rice.kew.api.document.DocumentStatus; import org.kuali.rice.kew.api.exception.WorkflowException; import org.kuali.rice.krad.bo.DocumentHeader; import org.kuali.rice.krad.service.BusinessObjectService; import org.kuali.rice.krad.service.DataDictionaryService; import org.kuali.rice.krad.service.DocumentService; import org.kuali.rice.krad.util.GlobalVariables; import org.kuali.rice.krad.util.MessageMap; import org.kuali.rice.krad.util.ObjectUtils; import org.kuali.rice.krad.workflow.service.WorkflowDocumentService; import org.springframework.transaction.annotation.Transactional; /** * This is the default implementation of the ProcurementCardCreateDocumentService interface. * * @see org.kuali.kfs.fp.batch.service.ProcurementCardCreateDocumentService */ public class ProcurementCardCreateDocumentServiceImpl implements ProcurementCardCreateDocumentService { private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(ProcurementCardCreateDocumentServiceImpl.class); protected static final String WORKFLOW_SEARCH_RESULT_KEY = "routeHeaderId"; protected ParameterService parameterService; protected BusinessObjectService businessObjectService; protected DocumentService documentService; protected WorkflowDocumentService workflowDocumentService; protected DataDictionaryService dataDictionaryService; protected DateTimeService dateTimeService; protected AccountingLineRuleHelperService accountingLineRuleUtil; protected CapitalAssetBuilderModuleService capitalAssetBuilderModuleService; protected FinancialSystemDocumentService financialSystemDocumentService; private VelocityEmailService procurementCardCreateEmailService; public static final String DOCUMENT_DESCRIPTION_PATTERN = "{0}-{1}-{2}-{3}"; /** * This method retrieves a collection of credit card transactions and traverses through this list, creating * ProcurementCardDocuments for each card. * * @return True if the procurement card documents were created successfully. If any problem occur while creating the * documents, a runtime exception will be thrown. * * @see org.kuali.kfs.fp.batch.service.ProcurementCardCreateDocumentService#createProcurementCardDocuments() */ @Override @SuppressWarnings("rawtypes") @Transactional public boolean createProcurementCardDocuments() { List documents = new ArrayList(); List cardTransactions = retrieveTransactions(); // iterate through card transaction list and create documents for (Iterator iter = cardTransactions.iterator(); iter.hasNext();) { documents.add(createProcurementCardDocument((List) iter.next())); } // now store all the documents for (Iterator iter = documents.iterator(); iter.hasNext();) { ProcurementCardDocument pcardDocument = (ProcurementCardDocument) iter.next(); try { documentService.saveDocument(pcardDocument, DocumentSystemSaveEvent.class); if ( LOG.isInfoEnabled() ) { LOG.info("Saved Procurement Card document: "+pcardDocument.getDocumentNumber()); } } catch (Exception e) { LOG.error("Error persisting document # " + pcardDocument.getDocumentHeader().getDocumentNumber() + " " + e.getMessage(), e); throw new RuntimeException("Error persisting document # " + pcardDocument.getDocumentHeader().getDocumentNumber() + " " + e.getMessage(), e); } } // send email notification sendEmailNotification(documents); return true; } /** * Sending email notification with initializing template variable details in report. * * @param documents */ protected void sendEmailNotification(List<ProcurementCardDocument> documents) { List<ProcurementCardReportType> summaryList = getSortedReportSummaryList(documents); int totalBatchTransactions = getBatchTotalTransactionCnt(summaryList); DateFormat dateFormat = getDateFormat(KFSConstants.CoreModuleNamespaces.FINANCIAL, KFSConstants.ProcurementCardParameters.PCARD_BATCH_CREATE_DOC_STEP, KFSConstants.ProcurementCardParameters.BATCH_SUMMARY_RUNNING_TIMESTAMP_FORMAT, KFSConstants.ProcurementCardEmailTimeFormat); // Create formatter for payment amounts and batch run time String batchRunTime = dateFormat.format(dateTimeService.getCurrentDate()); final Map<String, Object> templateVariables = new HashMap<String, Object>(); templateVariables.put(KFSConstants.ProcurementCardEmailVariableTemplate.DOC_CREATE_DATE, batchRunTime); templateVariables.put(KFSConstants.ProcurementCardEmailVariableTemplate.TRANSACTION_COUNTER, totalBatchTransactions); templateVariables.put(KFSConstants.ProcurementCardEmailVariableTemplate.TRANSACTION_SUMMARY_LIST, summaryList); // Handle for email sending exception procurementCardCreateEmailService.sendEmailNotification(templateVariables); } /** * Retrieve date formatter used to format batch running timestamp in report. System parameter has precedence over system default String. * * @return */ protected DateFormat getDateFormat(String namespaceCode, String componentCode, String parameterName, String defaultValue) { DateFormat dateFormat = new SimpleDateFormat(defaultValue); if (getParameterService().parameterExists(namespaceCode, componentCode, parameterName)) { String formatParmVal = getParameterService().getParameterValueAsString(namespaceCode, componentCode, parameterName, defaultValue); if (StringUtils.isNotBlank(formatParmVal)) { try { dateFormat = new SimpleDateFormat(formatParmVal); } catch (IllegalArgumentException e) { LOG.error("Parameter PCARD_BATCH_SUMMARY_RUNNING_TIMESTAMP_FORMAT used by ProcurementCardCreateDocumentsStep does not set up properly. Use system default timestamp format instead for generating report."); dateFormat = new SimpleDateFormat(defaultValue); } } } dateFormat.setLenient(false); return dateFormat; } /** * Get the total number of transactions processed by this batch run * * @param summaryList * @return */ protected int getBatchTotalTransactionCnt(List<ProcurementCardReportType> summaryList) { int totalBatchTransactionCnt = 0; for (ProcurementCardReportType procurementCardReportType : summaryList) { totalBatchTransactionCnt += procurementCardReportType.getTotalTranNumber(); } return totalBatchTransactionCnt; } /** * Build the sorted batch report summary list * * @param documents * @return */ protected List<ProcurementCardReportType> getSortedReportSummaryList(List<ProcurementCardDocument> documents) { KualiDecimal totalAmount; int totalTransactionCounter; HashMap<String, String> totalDocMap; Map<Date, HashMap<String, String>> docMapByPstDt = new HashMap<Date, HashMap<String, String>>(); Map<Date, Integer> transctionMapByPstDt = new HashMap<Date, Integer>(); Map<Date, KualiDecimal> totalAmountMapByPstDt = new HashMap<Date, KualiDecimal>(); Iterator iter = null; Date keyDate = null; // walk through each doc and calculate the total amount per bank transaction posting date. for (ProcurementCardDocument pDoc : documents) { iter = pDoc.getTransactionEntries().iterator(); while (iter.hasNext()) { ProcurementCardTransactionDetail pCardDetail = (ProcurementCardTransactionDetail) iter.next(); keyDate = pCardDetail.getTransactionPostingDate(); if (docMapByPstDt.containsKey(keyDate)) { totalDocMap = docMapByPstDt.get(keyDate); totalTransactionCounter = transctionMapByPstDt.get(keyDate).intValue(); totalAmount = totalAmountMapByPstDt.get(keyDate); } else { totalDocMap = new HashMap<String, String>(); totalTransactionCounter = 0; totalAmount = KualiDecimal.ZERO; } // update number of transactions totalTransactionCounter++; // update number of eDocs if (!totalDocMap.containsKey(pDoc.getDocumentNumber())) { totalDocMap.put(pDoc.getDocumentNumber(), pDoc.getDocumentNumber()); } // update transaction total totalAmount = totalAmount.add(pCardDetail.getTransactionTotalAmount()); docMapByPstDt.put(keyDate, totalDocMap); transctionMapByPstDt.put(keyDate, totalTransactionCounter); totalAmountMapByPstDt.put(keyDate, totalAmount); } } List<ProcurementCardReportType> summaryList = buildBatchReportSummary(docMapByPstDt, transctionMapByPstDt, totalAmountMapByPstDt); sortingSummaryList(summaryList); return summaryList; } /** * Build Procurement Card report object. * * @param docMapByPstDt * @param transctionMapByPstDt * @param totalAmountMapByPstDt * @return */ protected List<ProcurementCardReportType> buildBatchReportSummary(Map<Date, HashMap<String, String>> docMapByPstDt, Map<Date, Integer> transctionMapByPstDt, Map<Date, KualiDecimal> totalAmountMapByPstDt) { List<ProcurementCardReportType> summaryList = new ArrayList<ProcurementCardReportType>(); ProcurementCardReportType reportEntry; Formatter currencyFormatter = new CurrencyFormatter(); DateFormat dateFormatter = getDateFormat(KFSConstants.CoreModuleNamespaces.FINANCIAL, KFSConstants.ProcurementCardParameters.PCARD_BATCH_CREATE_DOC_STEP, KFSConstants.ProcurementCardParameters.BATCH_SUMMARY_POSTING_DATE_FORMAT,KFSConstants.ProcurementCardTransactionTimeFormat); for (Date keyDate : docMapByPstDt.keySet()) { reportEntry = new ProcurementCardReportType(); reportEntry.setTransactionPostingDate(keyDate); reportEntry.setFormattedPostingDate(dateFormatter.format(keyDate)); reportEntry.setTotalDocNumber(docMapByPstDt.get(keyDate).keySet().isEmpty() ? 0 : docMapByPstDt.get(keyDate).keySet().size()); reportEntry.setTotalTranNumber(transctionMapByPstDt.get(keyDate)); reportEntry.setTotalAmount(currencyFormatter.formatForPresentation(totalAmountMapByPstDt.get(keyDate)).toString()); summaryList.add(reportEntry); } return summaryList; } /** * Sorting the report summary list by transaction posting date * * @param summaryList */ protected void sortingSummaryList(List<ProcurementCardReportType> summaryList) { Comparator<ProcurementCardReportType> comparator = new Comparator<ProcurementCardReportType>() { @Override public int compare(ProcurementCardReportType o1, ProcurementCardReportType o2) { if (o1 == null && o1 == null) { return 0; } if (o1 == null || o2 == null) { return o1 == null ? -1 : 1; } return o1.getTransactionPostingDate().compareTo(o2.getTransactionPostingDate()); } }; // sort by posting date Collections.sort(summaryList, comparator); } /** * This method retrieves all the procurement card documents with a status of 'I' and routes them to the next step in the * routing path. * * @return True if the routing was performed successfully. A runtime exception will be thrown if any errors occur while routing. * * @see org.kuali.kfs.fp.batch.service.ProcurementCardCreateDocumentService#routeProcurementCardDocuments(java.util.List) */ @Override public boolean routeProcurementCardDocuments() { Collection<ProcurementCardDocument> procurementCardDocumentList = retrieveProcurementCardDocumentsToRoute(KewApiConstants.ROUTE_HEADER_SAVED_CD); //Collections.reverse(documentIdList); if ( LOG.isInfoEnabled() ) { LOG.info("Number of PCards to Route: "+procurementCardDocumentList.size()); } for (ProcurementCardDocument pcardDocument: procurementCardDocumentList) { try { if ( LOG.isInfoEnabled() ) { LOG.info("Routing PCDO document # " + pcardDocument.getDocumentNumber() + "."); } documentService.prepareWorkflowDocument(pcardDocument); //** NOTE // // Calling workflow service to BYPASS business rule checks // //** NOTE workflowDocumentService.route( pcardDocument.getDocumentHeader().getWorkflowDocument(), "", null); } catch (WorkflowException e) { LOG.error("Error routing document # " + pcardDocument.getDocumentNumber() + " " + e.getMessage()); throw new RuntimeException(e.getMessage(),e); } } return true; } /** * Returns a list of all initiated but not yet routed procurement card documents, using the KualiWorkflowInfo service. * @return a list of procurement card documents to route */ protected Collection<ProcurementCardDocument> retrieveProcurementCardDocumentsToRoute(String statusCode){ try { return this.getFinancialSystemDocumentService().findByWorkflowStatusCode(ProcurementCardDocument.class, DocumentStatus.fromCode(statusCode)); } catch (WorkflowException e) { LOG.error("Error searching for enroute procurement card documents " + e.getMessage()); throw new RuntimeException(e.getMessage(),e); } } /** * This method determines if procurement card documents can be auto approved. A document can be auto approved if * the grace period for allowing auto approval of a procurement card document has passed. The grace period is defined * by a parameter in the parameters table. The create date of the document is then compared against the current date and * if the difference is larger than the grace period defined, then the document is auto approved. * * @return This method always returns true. * * @see org.kuali.kfs.fp.batch.service.ProcurementCardCreateDocumentService#autoApproveProcurementCardDocuments() */ @Override public boolean autoApproveProcurementCardDocuments() { // check if auto approve is turned on boolean autoApproveOn = parameterService.getParameterValueAsBoolean(ProcurementCardAutoApproveDocumentsStep.class, AUTO_APPROVE_DOCUMENTS_IND); if (!autoApproveOn) { // no auto approve? then skip out of here... return true; } Collection<ProcurementCardDocument> pcardDocumentList = retrieveProcurementCardDocumentsToRoute(KewApiConstants.ROUTE_HEADER_ENROUTE_CD); // get number of days and type for auto approve int autoApproveNumberDays = Integer.parseInt(parameterService.getParameterValueAsString(ProcurementCardAutoApproveDocumentsStep.class, AUTO_APPROVE_NUMBER_OF_DAYS)); Timestamp currentDate = dateTimeService.getCurrentTimestamp(); for (ProcurementCardDocument pcardDocument: pcardDocumentList) { try { // prevent PCard documents from auto approving if they have capital asset info to collect if(capitalAssetBuilderModuleService.hasCapitalAssetObjectSubType(pcardDocument)) { continue; } // if number of days in route is passed the allowed number, call doc service for super user approve Timestamp docCreateDate = new Timestamp( pcardDocument.getDocumentHeader().getWorkflowDocument().getDateCreated().getMillis() ); if (KfsDateUtils.getDifferenceInDays(docCreateDate, currentDate) > autoApproveNumberDays) { // update document description to reflect the auto approval pcardDocument.getDocumentHeader().setDocumentDescription("Auto Approved On " + dateTimeService.toDateTimeString(currentDate) + "."); if ( LOG.isInfoEnabled() ) { LOG.info("Auto approving document # " + pcardDocument.getDocumentHeader().getDocumentNumber()); } pcardDocument.setAutoApprovedIndicator(true); documentService.superUserApproveDocument(pcardDocument, ""); } } catch (WorkflowException e) { LOG.error("Error auto approving document # " + pcardDocument.getDocumentNumber() + " " + e.getMessage(),e); throw new RuntimeException(e.getMessage(),e); } } return true; } /** * This method retrieves a list of transactions from a temporary table, and groups them into document lists, based on * single transaction indicator or a grouping by card. * * @return List containing transactions for document. */ @SuppressWarnings("rawtypes") protected List retrieveTransactions() { List groupedTransactions = new ArrayList(); // retrieve records from transaction table order by card number List transactions = (List) businessObjectService.findMatchingOrderBy(ProcurementCardTransaction.class, new HashMap(), KFSPropertyConstants.TRANSACTION_CREDIT_CARD_NUMBER, true); // check apc for single transaction documents or multiple by card boolean singleTransaction = parameterService.getParameterValueAsBoolean(ProcurementCardCreateDocumentsStep.class, SINGLE_TRANSACTION_IND_PARM_NM); List documentTransactions = new ArrayList(); if (singleTransaction) { for (Iterator iter = transactions.iterator(); iter.hasNext();) { documentTransactions.add(iter.next()); groupedTransactions.add(documentTransactions); documentTransactions = new ArrayList(); } } else { Map cardTransactionsMap = new HashMap(); for (Iterator iter = transactions.iterator(); iter.hasNext();) { ProcurementCardTransaction transaction = (ProcurementCardTransaction) iter.next(); if (!cardTransactionsMap.containsKey(transaction.getTransactionCreditCardNumber())) { cardTransactionsMap.put(transaction.getTransactionCreditCardNumber(), new ArrayList()); } ((List) cardTransactionsMap.get(transaction.getTransactionCreditCardNumber())).add(transaction); } for (Iterator iter = cardTransactionsMap.values().iterator(); iter.hasNext();) { groupedTransactions.add(iter.next()); } } return groupedTransactions; } /** * Creates a ProcurementCardDocument from the List of transactions given. * * @param transactions List of ProcurementCardTransaction objects to be used for creating the document. * @return A ProcurementCardDocument populated with the transactions provided. */ protected ProcurementCardDocument createProcurementCardDocument(List transactions) { ProcurementCardDocument pcardDocument = null; try { // get new document from doc service pcardDocument = (ProcurementCardDocument) SpringContext.getBean(DocumentService.class).getNewDocument(PROCUREMENT_CARD); List<CapitalAssetInformation> capitalAssets = pcardDocument.getCapitalAssetInformation(); for (CapitalAssetInformation capitalAsset : capitalAssets) { if (ObjectUtils.isNotNull(capitalAsset) && ObjectUtils.isNotNull(capitalAsset.getCapitalAssetInformationDetails())) { capitalAsset.setDocumentNumber(pcardDocument.getDocumentNumber()); } } ProcurementCardTransaction trans = (ProcurementCardTransaction) transactions.get(0); String errors = validateTransaction(trans); createCardHolderRecord(pcardDocument, trans); // for each transaction, create transaction detail object and then acct lines for the detail int transactionLineNumber = 1; KualiDecimal documentTotalAmount = KualiDecimal.ZERO; String errorText = ""; for (Iterator iter = transactions.iterator(); iter.hasNext();) { ProcurementCardTransaction transaction = (ProcurementCardTransaction) iter.next(); // create transaction detail record with accounting lines errorText += createTransactionDetailRecord(pcardDocument, transaction, transactionLineNumber); // update document total documentTotalAmount = documentTotalAmount.add(transaction.getFinancialDocumentTotalAmount()); transactionLineNumber++; } pcardDocument.getFinancialSystemDocumentHeader().setFinancialDocumentTotalAmount(documentTotalAmount); // PCDO Default Description //pcardDocument.getDocumentHeader().setDocumentDescription("SYSTEM Generated"); setupDocumentDescription(pcardDocument); // Remove duplicate messages from errorText String messages[] = StringUtils.split(errorText, "."); for (int i = 0; i < messages.length; i++) { int countMatches = StringUtils.countMatches(errorText, messages[i]) - 1; errorText = StringUtils.replace(errorText, messages[i] + ".", "", countMatches); } // In case errorText is still too long, truncate it and indicate so. Integer documentExplanationMaxLength = dataDictionaryService.getAttributeMaxLength(DocumentHeader.class.getName(), KFSPropertyConstants.EXPLANATION); if (documentExplanationMaxLength != null && errorText.length() > documentExplanationMaxLength.intValue()) { String truncatedMessage = " ... TRUNCATED."; errorText = errorText.substring(0, documentExplanationMaxLength - truncatedMessage.length()) + truncatedMessage; } pcardDocument.getDocumentHeader().setExplanation(errorText); } catch (WorkflowException e) { LOG.error("Error creating pcdo documents: " + e.getMessage(),e); throw new RuntimeException("Error creating pcdo documents: " + e.getMessage(),e); } return pcardDocument; } /** * Set up PCDO document description as "cardholder name-card number (which is 4 digits)-chartOfAccountsCode-default account" * * @param pcardDocument */ protected void setupDocumentDescription(ProcurementCardDocument pcardDocument) { ProcurementCardHolder cardHolder = pcardDocument.getProcurementCardHolder(); if (ObjectUtils.isNotNull(cardHolder)) { String cardHolderName = StringUtils.left(cardHolder.getCardHolderName(), 23); String lastFourDigits = StringUtils.right(cardHolder.getTransactionCreditCardNumber(), 4); String chartOfAccountsCode = cardHolder.getChartOfAccountsCode(); String accountNumber = cardHolder.getAccountNumber(); String description = MessageFormat.format(DOCUMENT_DESCRIPTION_PATTERN, cardHolderName, lastFourDigits, chartOfAccountsCode, accountNumber); pcardDocument.getDocumentHeader().setDocumentDescription(description); } } /** * Creates card holder record and sets that record to the document given. * * @param pcardDocument Procurement card document to place the record in. * @param transaction The transaction to set the card holder record fields from. */ protected void createCardHolderRecord(ProcurementCardDocument pcardDocument, ProcurementCardTransaction transaction) { ProcurementCardHolder cardHolder = new ProcurementCardHolder(); cardHolder.setDocumentNumber(pcardDocument.getDocumentNumber()); cardHolder.setTransactionCreditCardNumber(transaction.getTransactionCreditCardNumber()); final ProcurementCardDefault procurementCardDefault = retrieveProcurementCardDefault(transaction.getTransactionCreditCardNumber()); if (procurementCardDefault != null) { if (getParameterService().getParameterValueAsBoolean(ProcurementCardCreateDocumentsStep.class, ProcurementCardCreateDocumentsStep.USE_CARD_HOLDER_DEFAULT_PARAMETER_NAME)) { cardHolder.setCardCycleAmountLimit(procurementCardDefault.getCardCycleAmountLimit()); cardHolder.setCardCycleVolumeLimit(procurementCardDefault.getCardCycleVolumeLimit()); cardHolder.setCardHolderAlternateName(procurementCardDefault.getCardHolderAlternateName()); cardHolder.setCardHolderCityName(procurementCardDefault.getCardHolderCityName()); cardHolder.setCardHolderLine1Address(procurementCardDefault.getCardHolderLine1Address()); cardHolder.setCardHolderLine2Address(procurementCardDefault.getCardHolderLine2Address()); cardHolder.setCardHolderName(procurementCardDefault.getCardHolderName()); cardHolder.setCardHolderStateCode(procurementCardDefault.getCardHolderStateCode()); cardHolder.setCardHolderWorkPhoneNumber(procurementCardDefault.getCardHolderWorkPhoneNumber()); cardHolder.setCardHolderZipCode(procurementCardDefault.getCardHolderZipCode()); cardHolder.setCardLimit(procurementCardDefault.getCardLimit()); cardHolder.setCardNoteText(procurementCardDefault.getCardNoteText()); cardHolder.setCardStatusCode(procurementCardDefault.getCardStatusCode()); } if (getParameterService().getParameterValueAsBoolean(ProcurementCardCreateDocumentsStep.class, ProcurementCardCreateDocumentsStep.USE_ACCOUNTING_DEFAULT_PARAMETER_NAME)) { cardHolder.setChartOfAccountsCode(procurementCardDefault.getChartOfAccountsCode()); cardHolder.setAccountNumber(procurementCardDefault.getAccountNumber()); cardHolder.setSubAccountNumber(procurementCardDefault.getSubAccountNumber()); } } if (StringUtils.isEmpty(cardHolder.getAccountNumber())) { cardHolder.setChartOfAccountsCode(transaction.getChartOfAccountsCode()); cardHolder.setAccountNumber(transaction.getAccountNumber()); cardHolder.setSubAccountNumber(transaction.getSubAccountNumber()); } if (StringUtils.isEmpty(cardHolder.getCardHolderName())) { cardHolder.setCardCycleAmountLimit(transaction.getCardCycleAmountLimit()); cardHolder.setCardCycleVolumeLimit(transaction.getCardCycleVolumeLimit()); cardHolder.setCardHolderAlternateName(transaction.getCardHolderAlternateName()); cardHolder.setCardHolderCityName(transaction.getCardHolderCityName()); cardHolder.setCardHolderLine1Address(transaction.getCardHolderLine1Address()); cardHolder.setCardHolderLine2Address(transaction.getCardHolderLine2Address()); cardHolder.setCardHolderName(transaction.getCardHolderName()); cardHolder.setCardHolderStateCode(transaction.getCardHolderStateCode()); cardHolder.setCardHolderWorkPhoneNumber(transaction.getCardHolderWorkPhoneNumber()); cardHolder.setCardHolderZipCode(transaction.getCardHolderZipCode()); cardHolder.setCardLimit(transaction.getCardLimit()); cardHolder.setCardNoteText(transaction.getCardNoteText()); cardHolder.setCardStatusCode(transaction.getCardStatusCode()); } pcardDocument.setProcurementCardHolder(cardHolder); } /** * Creates a transaction detail record and adds that record to the document provided. * * @param pcardDocument Document to place record in. * @param transaction Transaction to set fields from. * @param transactionLineNumber Line number of the new transaction detail record within the procurement card document. * @return The error text that was generated from the creation of the detail records. If the text is empty, no errors were encountered. */ protected String createTransactionDetailRecord(ProcurementCardDocument pcardDocument, ProcurementCardTransaction transaction, Integer transactionLineNumber) { ProcurementCardTransactionDetail transactionDetail = new ProcurementCardTransactionDetail(); // set the document transaction detail fields from the loaded transaction record transactionDetail.setDocumentNumber(pcardDocument.getDocumentNumber()); transactionDetail.setFinancialDocumentTransactionLineNumber(transactionLineNumber); transactionDetail.setTransactionDate(transaction.getTransactionDate()); transactionDetail.setTransactionReferenceNumber(transaction.getTransactionReferenceNumber()); transactionDetail.setTransactionBillingCurrencyCode(transaction.getTransactionBillingCurrencyCode()); transactionDetail.setTransactionCurrencyExchangeRate(transaction.getTransactionCurrencyExchangeRate()); transactionDetail.setTransactionDate(transaction.getTransactionDate()); transactionDetail.setTransactionOriginalCurrencyAmount(transaction.getTransactionOriginalCurrencyAmount()); transactionDetail.setTransactionOriginalCurrencyCode(transaction.getTransactionOriginalCurrencyCode()); transactionDetail.setTransactionPointOfSaleCode(transaction.getTransactionPointOfSaleCode()); transactionDetail.setTransactionPostingDate(transaction.getTransactionPostingDate()); transactionDetail.setTransactionPurchaseIdentifierDescription(transaction.getTransactionPurchaseIdentifierDescription()); transactionDetail.setTransactionPurchaseIdentifierIndicator(transaction.getTransactionPurchaseIdentifierIndicator()); transactionDetail.setTransactionSalesTaxAmount(transaction.getTransactionSalesTaxAmount()); transactionDetail.setTransactionSettlementAmount(transaction.getTransactionSettlementAmount()); transactionDetail.setTransactionTaxExemptIndicator(transaction.getTransactionTaxExemptIndicator()); transactionDetail.setTransactionTravelAuthorizationCode(transaction.getTransactionTravelAuthorizationCode()); transactionDetail.setTransactionUnitContactName(transaction.getTransactionUnitContactName()); if (GL_CREDIT_CODE.equals(transaction.getTransactionDebitCreditCode())) { transactionDetail.setTransactionTotalAmount(transaction.getFinancialDocumentTotalAmount().negated()); } else { transactionDetail.setTransactionTotalAmount(transaction.getFinancialDocumentTotalAmount()); } // create transaction vendor record createTransactionVendorRecord(pcardDocument, transaction, transactionDetail); // add transaction detail to document pcardDocument.getTransactionEntries().add(transactionDetail); // now create the initial source and target lines for this transaction return createAndValidateAccountingLines(pcardDocument, transaction, transactionDetail); } /** * Creates a transaction vendor detail record and adds it to the transaction detail. * * @param pcardDocument The procurement card document to retrieve values from. * @param transaction Transaction to set fields from. * @param transactionDetail The transaction detail to set the vendor record on. */ protected void createTransactionVendorRecord(ProcurementCardDocument pcardDocument, ProcurementCardTransaction transaction, ProcurementCardTransactionDetail transactionDetail) { ProcurementCardVendor transactionVendor = new ProcurementCardVendor(); transactionVendor.setDocumentNumber(pcardDocument.getDocumentNumber()); transactionVendor.setFinancialDocumentTransactionLineNumber(transactionDetail.getFinancialDocumentTransactionLineNumber()); transactionVendor.setTransactionMerchantCategoryCode(transaction.getTransactionMerchantCategoryCode()); transactionVendor.setVendorCityName(transaction.getVendorCityName()); transactionVendor.setVendorLine1Address(transaction.getVendorLine1Address()); transactionVendor.setVendorLine2Address(transaction.getVendorLine2Address()); transactionVendor.setVendorName(transaction.getVendorName()); transactionVendor.setVendorOrderNumber(transaction.getVendorOrderNumber()); transactionVendor.setVendorStateCode(transaction.getVendorStateCode()); transactionVendor.setVendorZipCode(transaction.getVendorZipCode()); transactionVendor.setVisaVendorIdentifier(transaction.getVisaVendorIdentifier()); transactionDetail.setProcurementCardVendor(transactionVendor); } /** * From the transaction accounting attributes, creates source and target accounting lines. Attributes are validated first, and * replaced with default and error values if needed. There will be 1 source and 1 target line generated. * * @param pcardDocument The procurement card document to add the new accounting lines to. * @param transaction The transaction to process into account lines. * @param docTransactionDetail The transaction detail to create source and target accounting lines from. * @return String containing any error messages. */ protected String createAndValidateAccountingLines(ProcurementCardDocument pcardDocument, ProcurementCardTransaction transaction, ProcurementCardTransactionDetail docTransactionDetail) { // build source lines ProcurementCardSourceAccountingLine sourceLine = createSourceAccountingLine(transaction, docTransactionDetail); sourceLine.setPostingYear(pcardDocument.getPostingYear()); // add line to transaction through document since document contains the next sequence number fields pcardDocument.addSourceAccountingLine(sourceLine); // build target lines ProcurementCardTargetAccountingLine targetLine = createTargetAccountingLine(transaction, docTransactionDetail); targetLine.setPostingYear(pcardDocument.getPostingYear()); // add line to transaction through document since document contains the next sequence number fields pcardDocument.addTargetAccountingLine(targetLine); return validateTargetAccountingLine(targetLine); } /** * Creates the to record for the transaction. The chart of account attributes from the transaction are used to create * the accounting line. * * @param transaction The transaction to pull information from to create the accounting line. * @param docTransactionDetail The transaction detail to pull information from to populate the accounting line. * @return The target accounting line fully populated with values from the parameters passed in. */ protected ProcurementCardTargetAccountingLine createTargetAccountingLine(ProcurementCardTransaction transaction, ProcurementCardTransactionDetail docTransactionDetail) { ProcurementCardTargetAccountingLine targetLine = new ProcurementCardTargetAccountingLine(); targetLine.setDocumentNumber(docTransactionDetail.getDocumentNumber()); targetLine.setFinancialDocumentTransactionLineNumber(docTransactionDetail.getFinancialDocumentTransactionLineNumber()); targetLine.setChartOfAccountsCode(transaction.getChartOfAccountsCode()); targetLine.setAccountNumber(transaction.getAccountNumber()); targetLine.setFinancialObjectCode(transaction.getFinancialObjectCode()); targetLine.setSubAccountNumber(transaction.getSubAccountNumber()); targetLine.setFinancialSubObjectCode(transaction.getFinancialSubObjectCode()); targetLine.setProjectCode(transaction.getProjectCode()); if (getParameterService().getParameterValueAsBoolean(ProcurementCardCreateDocumentsStep.class, ProcurementCardCreateDocumentsStep.USE_ACCOUNTING_DEFAULT_PARAMETER_NAME)) { final ProcurementCardDefault procurementCardDefault = retrieveProcurementCardDefault(transaction.getTransactionCreditCardNumber()); if (procurementCardDefault != null) { targetLine.setChartOfAccountsCode(procurementCardDefault.getChartOfAccountsCode()); targetLine.setAccountNumber(procurementCardDefault.getAccountNumber()); targetLine.setFinancialObjectCode(procurementCardDefault.getFinancialObjectCode()); targetLine.setSubAccountNumber(procurementCardDefault.getSubAccountNumber()); targetLine.setFinancialSubObjectCode(procurementCardDefault.getFinancialSubObjectCode()); targetLine.setProjectCode(procurementCardDefault.getProjectCode()); } } if (GL_CREDIT_CODE.equals(transaction.getTransactionDebitCreditCode())) { targetLine.setAmount(transaction.getFinancialDocumentTotalAmount().negated()); } else { targetLine.setAmount(transaction.getFinancialDocumentTotalAmount()); } return targetLine; } /** * Creates the from record for the transaction. The clearing chart, account, and object code is used for creating the line. * * @param transaction The transaction to pull information from to create the accounting line. * @param docTransactionDetail The transaction detail to pull information from to populate the accounting line. * @return The source accounting line fully populated with values from the parameters passed in. */ protected ProcurementCardSourceAccountingLine createSourceAccountingLine(ProcurementCardTransaction transaction, ProcurementCardTransactionDetail docTransactionDetail) { ProcurementCardSourceAccountingLine sourceLine = new ProcurementCardSourceAccountingLine(); sourceLine.setDocumentNumber(docTransactionDetail.getDocumentNumber()); sourceLine.setFinancialDocumentTransactionLineNumber(docTransactionDetail.getFinancialDocumentTransactionLineNumber()); sourceLine.setChartOfAccountsCode(getDefaultChartCode()); sourceLine.setAccountNumber(getDefaultAccountNumber()); sourceLine.setFinancialObjectCode(getDefaultObjectCode()); if (GL_CREDIT_CODE.equals(transaction.getTransactionDebitCreditCode())) { sourceLine.setAmount(transaction.getFinancialDocumentTotalAmount().negated()); } else { sourceLine.setAmount(transaction.getFinancialDocumentTotalAmount()); } return sourceLine; } /** * Validates the chart of account attributes for existence and active indicator. Will substitute for defined * default parameters or set fields to empty that if they have errors. * * @param targetLine The target accounting line to be validated. * @return String with error messages discovered during validation. An empty string indicates no validation errors were found. */ protected String validateTargetAccountingLine(ProcurementCardTargetAccountingLine targetLine) { String errorText = ""; targetLine.refresh(); final String lineNumber = targetLine.getSequenceNumber() == null ? "new" : targetLine.getSequenceNumber().toString(); if (!accountingLineRuleUtil.isValidChart("", targetLine.getChart(), dataDictionaryService.getDataDictionary())) { String tempErrorText = "Target Accounting Line "+lineNumber+" Chart " + targetLine.getChartOfAccountsCode() + " is invalid; using error Chart Code."; if ( LOG.isInfoEnabled() ) { LOG.info(tempErrorText); } errorText += " " + tempErrorText; targetLine.setChartOfAccountsCode(getErrorChartCode()); targetLine.refresh(); } if (!accountingLineRuleUtil.isValidAccount("", targetLine.getAccount(), dataDictionaryService.getDataDictionary()) || targetLine.getAccount().isExpired()) { String tempErrorText = "Target Accounting Line "+lineNumber+" Chart " + targetLine.getChartOfAccountsCode() + " Account " + targetLine.getAccountNumber() + " is invalid; using error account."; if ( LOG.isInfoEnabled() ) { LOG.info(tempErrorText); } errorText += " " + tempErrorText; targetLine.setChartOfAccountsCode(getErrorChartCode()); targetLine.setAccountNumber(getErrorAccountNumber()); targetLine.refresh(); } if (!accountingLineRuleUtil.isValidObjectCode("", targetLine.getObjectCode(), dataDictionaryService.getDataDictionary())) { String tempErrorText = "Target Accounting Line "+lineNumber+" Chart " + targetLine.getChartOfAccountsCode() + " Object Code " + targetLine.getFinancialObjectCode() + " is invalid; using default Object Code."; if ( LOG.isInfoEnabled() ) { LOG.info(tempErrorText); } errorText += " " + tempErrorText; targetLine.setFinancialObjectCode(getDefaultObjectCode()); targetLine.refresh(); } if (StringUtils.isNotBlank(targetLine.getSubAccountNumber()) && !accountingLineRuleUtil.isValidSubAccount("", targetLine.getSubAccount(), dataDictionaryService.getDataDictionary())) { String tempErrorText = "Target Accounting Line "+lineNumber+" Chart " + targetLine.getChartOfAccountsCode() + " Account " + targetLine.getAccountNumber() + " Sub Account " + targetLine.getSubAccountNumber() + " is invalid; Setting Sub Account to blank."; if ( LOG.isInfoEnabled() ) { LOG.info(tempErrorText); } errorText += " " + tempErrorText; targetLine.setSubAccountNumber(""); } if (StringUtils.isNotBlank(targetLine.getFinancialSubObjectCode()) && !accountingLineRuleUtil.isValidSubObjectCode("", targetLine.getSubObjectCode(), dataDictionaryService.getDataDictionary())) { String tempErrorText = "Target Accounting Line "+lineNumber+" Chart " + targetLine.getChartOfAccountsCode() + " Account " + targetLine.getAccountNumber() + " Object Code " + targetLine.getFinancialObjectCode() + " Sub Object Code " + targetLine.getFinancialSubObjectCode() + " is invalid; setting Sub Object to blank."; if ( LOG.isInfoEnabled() ) { LOG.info(tempErrorText); } errorText += " " + tempErrorText; targetLine.setFinancialSubObjectCode(""); } if (StringUtils.isNotBlank(targetLine.getProjectCode()) && !accountingLineRuleUtil.isValidProjectCode("", targetLine.getProject(), dataDictionaryService.getDataDictionary())) { if ( LOG.isInfoEnabled() ) { LOG.info("Target Accounting Line "+lineNumber+" Project Code " + targetLine.getProjectCode() + " is invalid; setting to blank."); } errorText += " Target Accounting Line "+lineNumber+" Project Code " + targetLine.getProjectCode() + " is invalid; setting to blank."; targetLine.setProjectCode(""); } // clear out GlobalVariable message map, since we have taken care of the errors GlobalVariables.setMessageMap(new MessageMap()); return errorText; } /** * Validates the chart of account attributes for existence and active indicator. Will substitute for defined * default parameters or set fields to empty that if they have errors. * * @param transaction The transaction to be validated. * @return String with error messages discovered during validation. An empty string indicates no validation errors were found. */ protected String validateTransaction(ProcurementCardTransaction transaction) { String errorText = ""; final String lineNumber = transaction.getTransactionSequenceRowNumber() == null ? "new" : transaction.getTransactionSequenceRowNumber().toString(); if (getParameterService().getParameterValueAsBoolean(ProcurementCardCreateDocumentsStep.class, ProcurementCardCreateDocumentsStep.USE_ACCOUNTING_DEFAULT_PARAMETER_NAME)) { final ProcurementCardDefault procurementCardDefault = retrieveProcurementCardDefault(transaction.getTransactionCreditCardNumber()); if (ObjectUtils.isNull(procurementCardDefault)) { 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."; if ( LOG.isInfoEnabled() ) { LOG.info(tempErrorText); } errorText += " " + tempErrorText; } } else { transaction.refresh(); final ChartService chartService = SpringContext.getBean(ChartService.class); if (transaction.getChartOfAccountsCode() == null || ObjectUtils.isNull(chartService.getByPrimaryId(transaction.getChartOfAccountsCode()))) { String tempErrorText = "Transaction "+lineNumber+" Chart " + transaction.getChartOfAccountsCode() + " is invalid; using error Chart Code."; if ( LOG.isInfoEnabled() ) { LOG.info(tempErrorText); } errorText += " " + tempErrorText; transaction.setChartOfAccountsCode(getErrorChartCode()); transaction.refresh(); } final AccountService accountService = SpringContext.getBean(AccountService.class); if (transaction.getAccountNumber() == null || ObjectUtils.isNull(accountService.getByPrimaryIdWithCaching(transaction.getChartOfAccountsCode(), transaction.getAccountNumber())) || accountService.getByPrimaryIdWithCaching(transaction.getChartOfAccountsCode(), transaction.getAccountNumber()).isExpired()) { String tempErrorText = "Transaction "+lineNumber+" Chart " + transaction.getChartOfAccountsCode() + " Account " + transaction.getAccountNumber() + " is invalid; using error account."; if ( LOG.isInfoEnabled() ) { LOG.info(tempErrorText); } errorText += " " + tempErrorText; transaction.setChartOfAccountsCode(getErrorChartCode()); transaction.setAccountNumber(getErrorAccountNumber()); transaction.refresh(); } final UniversityDateService uds = SpringContext.getBean(UniversityDateService.class); final ObjectCodeService ocs = SpringContext.getBean(ObjectCodeService.class); if (transaction.getFinancialObjectCode() == null || ObjectUtils.isNull(ocs.getByPrimaryIdWithCaching(uds.getCurrentFiscalYear(), transaction.getChartOfAccountsCode(), transaction.getFinancialObjectCode()))) { String tempErrorText = "Transaction "+lineNumber+" Chart " + transaction.getChartOfAccountsCode() + " Object Code " + transaction.getFinancialObjectCode() + " is invalid; using default Object Code."; if ( LOG.isInfoEnabled() ) { LOG.info(tempErrorText); } errorText += " " + tempErrorText; transaction.setFinancialObjectCode(getDefaultObjectCode()); transaction.refresh(); } if (StringUtils.isNotBlank(transaction.getSubAccountNumber())) { SubAccountService sas = SpringContext.getBean(SubAccountService.class); SubAccount subAccount = sas.getByPrimaryIdWithCaching(transaction.getChartOfAccountsCode(), transaction.getAccountNumber(), transaction.getSubAccountNumber()); if (ObjectUtils.isNull(subAccount)) { String tempErrorText = "Transaction "+lineNumber+" Chart " + transaction.getChartOfAccountsCode() + " Account " + transaction.getAccountNumber() + " Sub Account " + transaction.getSubAccountNumber() + " is invalid; Setting Sub Account to blank."; if ( LOG.isInfoEnabled() ) { LOG.info(tempErrorText); } errorText += " " + tempErrorText; transaction.setSubAccountNumber(""); } } if (StringUtils.isNotBlank(transaction.getFinancialSubObjectCode())) { SubObjectCodeService socs = SpringContext.getBean(SubObjectCodeService.class); SubObjectCode soc = socs.getByPrimaryIdForCurrentYear(transaction.getChartOfAccountsCode(), transaction.getAccountNumber(), transaction.getFinancialObjectCode(), transaction.getFinancialSubObjectCode()); if (ObjectUtils.isNull(soc)) { String tempErrorText = "Transaction "+lineNumber+" Chart " + transaction.getChartOfAccountsCode() + " Account " + transaction.getAccountNumber() + " Object Code " + transaction.getFinancialObjectCode() + " Sub Object Code " + transaction.getFinancialSubObjectCode() + " is invalid; setting Sub Object to blank."; if ( LOG.isInfoEnabled() ) { LOG.info(tempErrorText); } errorText += " " + tempErrorText; transaction.setFinancialSubObjectCode(""); } } if (StringUtils.isNotBlank(transaction.getProjectCode())) { ProjectCodeService pcs = SpringContext.getBean(ProjectCodeService.class); ProjectCode pc = pcs.getByPrimaryId(transaction.getProjectCode()); if (ObjectUtils.isNull(pc)) { if ( LOG.isInfoEnabled() ) { LOG.info("Transaction "+lineNumber+" Project Code " + transaction.getProjectCode() + " is invalid; setting to blank."); } errorText += " Transaction "+lineNumber+" Project Code " + transaction.getProjectCode() + " is invalid; setting to blank."; transaction.setProjectCode(""); } } } // clear out GlobalVariable message map, since we have taken care of the errors GlobalVariables.setMessageMap(new MessageMap()); return errorText; } /** * Retrieves the error chart code from the parameter table. * @return The error chart code defined in the parameter table. */ protected String getErrorChartCode() { return parameterService.getParameterValueAsString(ProcurementCardCreateDocumentsStep.class, ProcurementCardDocumentRuleConstants.ERROR_TRANS_CHART_CODE_PARM_NM); } /** * Retrieves the error account number from the parameter table. * @return The error account number defined in the parameter table. */ protected String getErrorAccountNumber() { return parameterService.getParameterValueAsString(ProcurementCardCreateDocumentsStep.class, ERROR_TRANS_ACCOUNT_PARM_NM); } /** * Gets the default Chart Code, Account from the custom Procurement Cardholder table. * */ protected ProcurementCardDefault retrieveProcurementCardDefault(String creditCardNumber) { Map<String, String> fieldValues = new HashMap<String, String>(); fieldValues.put(KFSPropertyConstants.CREDIT_CARD_NUMBER, creditCardNumber); List<ProcurementCardDefault> matchingPcardDefaults = (List<ProcurementCardDefault>)businessObjectService.findMatching(ProcurementCardDefault.class, fieldValues); ProcurementCardDefault procurementCardDefault = null; if ( !matchingPcardDefaults.isEmpty() ) { procurementCardDefault = matchingPcardDefaults.get(0); } return procurementCardDefault; } /** * Retrieves the default chard code from the parameter table. * @return The default chart code defined in the parameter table. */ protected String getDefaultChartCode() { return parameterService.getParameterValueAsString(ProcurementCardLoadStep.class, DEFAULT_TRANS_CHART_CODE_PARM_NM); } /** * Retrieves the default account number from the parameter table. * @return The default account number defined in the parameter table. */ protected String getDefaultAccountNumber() { return parameterService.getParameterValueAsString(ProcurementCardLoadStep.class, DEFAULT_TRANS_ACCOUNT_PARM_NM); } /** * Retrieves the default object code from the parameter table. * @return The default object code defined in the parameter table. */ protected String getDefaultObjectCode() { return parameterService.getParameterValueAsString(ProcurementCardLoadStep.class, DEFAULT_TRANS_OBJECT_CODE_PARM_NM); } /** * Calls businessObjectService to remove all the procurement card transaction rows from the transaction load table. */ protected void cleanTransactionsTable() { businessObjectService.deleteMatching(ProcurementCardTransaction.class, new HashMap()); } /** * Loads all the parsed XML transactions into the temp transaction table. * * @param transactions List of ProcurementCardTransactions to load. */ protected void loadTransactions(List transactions) { businessObjectService.save(transactions); } /** * @return retrieves the presumably injected implementation of ParameterService to use */ public ParameterService getParameterService() { return parameterService; } /** * Sets the parameterService attribute. * @param parameterService */ public void setParameterService(ParameterService parameterService) { this.parameterService = parameterService; } /** * Gets the businessObjectService attribute. * @return Returns the businessObjectService. */ public BusinessObjectService getBusinessObjectService() { return businessObjectService; } /** * Sets the businessObjectService attribute. * @param businessObjectService The businessObjectService to set. */ public void setBusinessObjectService(BusinessObjectService businessObjectService) { this.businessObjectService = businessObjectService; } /** * Gets the documentService attribute. * @return Returns the documentService. */ public DocumentService getDocumentService() { return documentService; } /** * Sets the documentService attribute. * @param documentService The documentService to set. */ public void setDocumentService(DocumentService documentService) { this.documentService = documentService; } public WorkflowDocumentService getWorkflowDocumentService() { return workflowDocumentService; } public void setWorkflowDocumentService(WorkflowDocumentService workflowDocumentService) { this.workflowDocumentService = workflowDocumentService; } /** * Gets the dataDictionaryService attribute. * @return Returns the dataDictionaryService. */ public DataDictionaryService getDataDictionaryService() { return dataDictionaryService; } /** * Sets the dataDictionaryService attribute. * @param dataDictionaryService dataDictionaryService to set. */ public void setDataDictionaryService(DataDictionaryService dataDictionaryService) { this.dataDictionaryService = dataDictionaryService; } /** * Gets the dateTimeService attribute. * @return Returns the dateTimeService. */ public DateTimeService getDateTimeService() { return dateTimeService; } /** * Sets the dateTimeService attribute. * @param dateTimeService The dateTimeService to set. */ public void setDateTimeService(DateTimeService dateTimeService) { this.dateTimeService = dateTimeService; } /** * Sets the accountingLineRuleUtil attribute value. * @param accountingLineRuleUtil The accountingLineRuleUtil to set. */ public void setAccountingLineRuleUtil(AccountingLineRuleHelperService accountingLineRuleUtil) { this.accountingLineRuleUtil = accountingLineRuleUtil; } /** * Sets the capitalAssetBuilderModuleService attribute value. * @param capitalAssetBuilderModuleService The capitalAssetBuilderModuleService to set. */ public void setCapitalAssetBuilderModuleService(CapitalAssetBuilderModuleService capitalAssetBuilderModuleService) { this.capitalAssetBuilderModuleService = capitalAssetBuilderModuleService; } /** * Sets the procurementCardCreateEmailService attribute. * * @param procurementCardCreateEmailService The procurementCardCreateEmailService to set. */ public void setProcurementCardCreateEmailService(VelocityEmailService procurementCardCreateEmailService) { this.procurementCardCreateEmailService = procurementCardCreateEmailService; } /** * Gets the financialSystemDocumentHeaderSerivce attribute * * @return */ public FinancialSystemDocumentService getFinancialSystemDocumentService() { return financialSystemDocumentService; } /** * Spring hook to inject financialSystemDocumentHeaderService * * @param financialSystemDocumentService */ public void setFinancialSystemDocumentService(FinancialSystemDocumentService financialSystemDocumentService) { this.financialSystemDocumentService = financialSystemDocumentService; } }