/* * 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 java.util.List; import org.apache.log4j.Logger; import org.kuali.kfs.fp.document.DistributionOfIncomeAndExpenseDocument; import org.kuali.kfs.sys.KFSConstants; import org.kuali.kfs.sys.businessobject.ElectronicPaymentClaim; import org.kuali.kfs.sys.businessobject.SourceAccountingLine; import org.kuali.kfs.sys.context.SpringContext; import org.kuali.kfs.sys.service.ElectronicPaymentClaimingDocumentGenerationStrategy; import org.kuali.kfs.sys.service.ElectronicPaymentClaimingService; import org.kuali.rice.coreservice.framework.parameter.ParameterService; import org.kuali.rice.kew.api.KewApiConstants; import org.kuali.rice.kew.api.doctype.DocumentTypeService; import org.kuali.rice.kew.api.exception.WorkflowException; import org.kuali.rice.kim.api.identity.Person; import org.kuali.rice.krad.bo.Note; import org.kuali.rice.krad.service.DocumentService; public class DistributionOfIncomeAndExpenseElectronicPaymentClaimingHelperStrategyImpl implements ElectronicPaymentClaimingDocumentGenerationStrategy { private static final Logger LOG = Logger.getLogger(DistributionOfIncomeAndExpenseElectronicPaymentClaimingHelperStrategyImpl.class); protected DocumentService documentService; protected ElectronicPaymentClaimingService electronicPaymentClaimingService; protected ParameterService parameterService; /** * The name of the parameter to get the description for this document; without a description, we can't save the document, and if * we don't save the document, there's a chance that electronic payment claims will go to limbo */ protected final static String DOCUMENT_DESCRIPTION_PARAM_NAME = "ELECTRONIC_FUNDS_DOCUMENT_DESCRIPTION"; protected final static String URL_PREFIX = "financial"; protected final static String URL_MIDDLE = ".do?methodToCall=docHandler&command="; protected final static String URL_SUFFIX = "&docId="; protected final static String URL_DOC_TYPE = "DistributionOfIncomeAndExpense"; /** * @see org.kuali.kfs.sys.service.ElectronicPaymentClaimingDocumentGenerationStrategy#createDocumentFromElectronicPayments(java.util.List) */ public String createDocumentFromElectronicPayments(List<ElectronicPaymentClaim> electronicPayments, Person user) { DistributionOfIncomeAndExpenseDocument document = null; try { document = (DistributionOfIncomeAndExpenseDocument) documentService.getNewDocument(getClaimingDocumentWorkflowDocumentType()); addAccountingLinesToDocument(document, electronicPayments); addDescriptionToDocument(document); addNotesToDocument(document, electronicPayments, user); documentService.saveDocument(document); electronicPaymentClaimingService.claimElectronicPayments(electronicPayments, document.getDocumentNumber()); } catch (WorkflowException we) { throw new RuntimeException("WorkflowException while creating a DistributionOfIncomeAndExpenseDocument to claim ElectronicPaymentClaim records.", we); } return getURLForDocument(document); } /** * Builds the URL that can be used to redirect to the correct document * * @param doc the document to build the URL for * @return the relative URL to redirect to */ protected String getURLForDocument(DistributionOfIncomeAndExpenseDocument doc) { StringBuilder url = new StringBuilder(); url.append(URL_PREFIX); url.append(getUrlDocType()); url.append(URL_MIDDLE); url.append(KewApiConstants.ACTIONLIST_COMMAND); url.append(URL_SUFFIX); url.append(doc.getDocumentNumber()); return url.toString(); } /** * Creates notes for the claims (using the ElectronicPaymentClaimingService) and then adds them to the document * * @param claimingDoc the claiming document * @param claims the electronic payments being claimed * @param user the user doing the claiming */ protected void addNotesToDocument(DistributionOfIncomeAndExpenseDocument claimingDoc, List<ElectronicPaymentClaim> claims, Person user) { for (String noteText : electronicPaymentClaimingService.constructNoteTextsForClaims(claims)) { try { Note note = documentService.createNoteFromDocument(claimingDoc, noteText); claimingDoc.addNote(note); } catch (Exception e) { LOG.error("Exception while attempting to create or add note: ", e); } } } /** * Adds an accounting line to the document for each ElectronicPaymentClaim record that is being added * * @param document the claiming Distribution of Income and Expense document * @param electronicPayments the list of ElectronicPaymentClaim records that are being claimed */ protected void addAccountingLinesToDocument(DistributionOfIncomeAndExpenseDocument document, List<ElectronicPaymentClaim> electronicPayments) { for (ElectronicPaymentClaim payment : electronicPayments) { SourceAccountingLine claimingAccountingLine = copyAccountingLineToNew(payment.getGeneratingAccountingLine(), createNewAccountingLineForDocument(document)); document.addSourceAccountingLine(claimingAccountingLine); } } /** * Adds the parameterized description to the document, so the doc can be saved * * @param document the document to add a description to */ protected void addDescriptionToDocument(DistributionOfIncomeAndExpenseDocument document) { String description = parameterService.getParameterValueAsString(DistributionOfIncomeAndExpenseDocument.class, DistributionOfIncomeAndExpenseElectronicPaymentClaimingHelperStrategyImpl.DOCUMENT_DESCRIPTION_PARAM_NAME); if (description != null) { document.getDocumentHeader().setDocumentDescription(description); } else { throw new RuntimeException("There is evidently no value for Parameter KFS-FP / Distribution of Income and Expense / " + DistributionOfIncomeAndExpenseElectronicPaymentClaimingHelperStrategyImpl.DOCUMENT_DESCRIPTION_PARAM_NAME + "; please set a value before claiming Electronic Payments"); } } /** * Creates a new accounting line, based on what the source accounting line class for the document is * * @param document the document that is claiming these payments * @return a new, ready-to-be-filled in accounting line of the class that the given document uses for Source Accounting Lines */ protected SourceAccountingLine createNewAccountingLineForDocument(DistributionOfIncomeAndExpenseDocument document) { try { Class<? extends SourceAccountingLine> accountingLineClass = document.getSourceAccountingLineClass(); return accountingLineClass.newInstance(); } catch (Exception ex) { throw new RuntimeException( "Unable to create source accounting line for document: " + document, ex); } } /** * Copies an original accounting line to a new accounting line * * @param line the original accounting line * @return an accounting line that copies that accounting line */ protected SourceAccountingLine copyAccountingLineToNew(SourceAccountingLine line, SourceAccountingLine newLine) { newLine.setChartOfAccountsCode(line.getChartOfAccountsCode()); newLine.setAccountNumber(line.getAccountNumber()); newLine.setSubAccountNumber(line.getSubAccountNumber()); newLine.setFinancialObjectCode(line.getFinancialObjectCode()); newLine.setFinancialSubObjectCode(line.getFinancialSubObjectCode()); newLine.setProjectCode(line.getProjectCode()); newLine.setOrganizationReferenceId(line.getOrganizationReferenceId()); newLine.setAmount(line.getAmount()); return newLine; } /** * @see org.kuali.kfs.sys.service.ElectronicPaymentClaimingDocumentGenerationStrategy#getClaimingDocumentWorkflowDocumentType() * @return the name DistributionOfIncomeAndExpenseDocument workflow document type */ public String getClaimingDocumentWorkflowDocumentType() { return KFSConstants.FinancialDocumentTypeCodes.DISTRIBUTION_OF_INCOME_AND_EXPENSE; } /** * @return the class of the document which claims these electronic payments */ protected String getUrlDocType() { return DistributionOfIncomeAndExpenseElectronicPaymentClaimingHelperStrategyImpl.URL_DOC_TYPE; } /** * Uses the data dictionary to find the label for this document * * @see org.kuali.kfs.sys.service.ElectronicPaymentClaimingDocumentGenerationStrategy#getDocumentLabel() */ public String getDocumentLabel() { try { return SpringContext.getBean(DocumentTypeService.class).getDocumentTypeByName(getClaimingDocumentWorkflowDocumentType()).getLabel(); } catch (Exception e) { LOG.error("Caught Exception trying to get Workflow Document Type" + e); } return "DI"; } /** * This always returns true if the given user in the claiming workgroup. * * @see org.kuali.kfs.sys.service.ElectronicPaymentClaimingDocumentGenerationStrategy#userMayUseToClaim(org.kuali.rice.kim.api.identity.Person) */ public boolean userMayUseToClaim(Person claimingUser) { final String documentTypeName = getClaimingDocumentWorkflowDocumentType(); final boolean canClaim = electronicPaymentClaimingService.isAuthorizedForClaimingElectronicPayment(claimingUser, documentTypeName) || electronicPaymentClaimingService.isAuthorizedForClaimingElectronicPayment(claimingUser, null); return canClaim; } /** * @see org.kuali.kfs.sys.service.ElectronicPaymentClaimingDocumentGenerationStrategy#isDocumentReferenceValid(java.lang.String) */ public boolean isDocumentReferenceValid(String referenceDocumentNumber) { boolean valid = false; try { long docNumberAsLong = Long.parseLong(referenceDocumentNumber); if (docNumberAsLong > 0L) { valid = documentService.documentExists(referenceDocumentNumber); } } catch (NumberFormatException nfe) { // the doc # can't be parsed into a Long? Then it ain't no valid! LOG.warn( "Unable to parse referenceDocumentNumber (" + referenceDocumentNumber + ") into a number: " + nfe.getMessage() ); } return valid; } /** * Sets the documentService attribute value. * * @param documentService The documentService to set. */ public void setDocumentService(DocumentService documentService) { this.documentService = documentService; } /** * Sets the electronicPaymentClaimingService attribute value. * * @param electronicPaymentClaimingService The electronicPaymentClaimingService to set. */ public void setElectronicPaymentClaimingService(ElectronicPaymentClaimingService electronicPaymentClaimingService) { this.electronicPaymentClaimingService = electronicPaymentClaimingService; } /** * Sets the parameterService attribute value. * * @param parameterService The parameterService to set. */ public void setParameterService(ParameterService parameterService) { this.parameterService = parameterService; } }