/* * 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.document.service.impl; import java.sql.Date; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.lang.StringUtils; import org.kuali.kfs.fp.batch.DvToPdpExtractStep; import org.kuali.kfs.fp.businessobject.DisbursementVoucherNonEmployeeExpense; import org.kuali.kfs.fp.businessobject.DisbursementVoucherNonEmployeeTravel; import org.kuali.kfs.fp.businessobject.DisbursementVoucherPayeeDetail; import org.kuali.kfs.fp.businessobject.DisbursementVoucherPreConferenceDetail; import org.kuali.kfs.fp.businessobject.DisbursementVoucherPreConferenceRegistrant; import org.kuali.kfs.fp.dataaccess.DisbursementVoucherDao; import org.kuali.kfs.fp.document.DisbursementVoucherConstants; import org.kuali.kfs.fp.document.DisbursementVoucherDocument; import org.kuali.kfs.pdp.PdpConstants; import org.kuali.kfs.pdp.PdpParameterConstants; import org.kuali.kfs.pdp.businessobject.PaymentAccountDetail; import org.kuali.kfs.pdp.businessobject.PaymentDetail; import org.kuali.kfs.pdp.businessobject.PaymentGroup; import org.kuali.kfs.pdp.businessobject.PaymentNoteText; import org.kuali.kfs.sys.KFSConstants; import org.kuali.kfs.sys.KFSParameterKeyConstants; import org.kuali.kfs.sys.KFSPropertyConstants; import org.kuali.kfs.sys.batch.service.PaymentSourceToExtractService; import org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntry; import org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySequenceHelper; import org.kuali.kfs.sys.businessobject.SourceAccountingLine; import org.kuali.kfs.sys.document.service.PaymentSourceHelperService; import org.kuali.kfs.sys.document.validation.event.AccountingDocumentSaveWithNoLedgerEntryGenerationEvent; import org.kuali.kfs.sys.service.GeneralLedgerPendingEntryService; import org.kuali.kfs.sys.service.impl.KfsParameterConstants; import org.kuali.kfs.vnd.businessobject.VendorDetail; import org.kuali.kfs.vnd.document.service.VendorService; import org.kuali.rice.core.api.parameter.ParameterEvaluator; import org.kuali.rice.core.api.parameter.ParameterEvaluatorService; import org.kuali.rice.core.api.util.type.KualiDecimal; import org.kuali.rice.core.api.util.type.KualiInteger; import org.kuali.rice.coreservice.framework.parameter.ParameterService; import org.kuali.rice.kew.api.exception.WorkflowException; import org.kuali.rice.krad.service.BusinessObjectService; import org.kuali.rice.krad.service.DocumentService; import org.springframework.transaction.annotation.Transactional; @Transactional public class DisbursementVoucherExtractionHelperServiceImpl implements PaymentSourceToExtractService<DisbursementVoucherDocument> { static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(DisbursementVoucherExtractionHelperServiceImpl.class); protected BusinessObjectService businessObjectService; protected DocumentService documentService; protected GeneralLedgerPendingEntryService generalLedgerPendingEntryService; protected ParameterService parameterService; protected ParameterEvaluatorService parameterEvaluatorService; protected VendorService vendorService; protected DisbursementVoucherDao disbursementVoucherDao; protected PaymentSourceHelperService paymentSourceHelperService; /** * Rolls the disbursement voucher back to a cancelled state * @see org.kuali.kfs.sys.batch.service.PaymentSourceToExtractService#cancelPayment(org.kuali.kfs.sys.document.PaymentSource, java.sql.Date) */ @Override public void cancelPayment(DisbursementVoucherDocument dv, Date cancelDate) { if (dv.getCancelDate() == null) { try { // set the canceled date dv.setCancelDate(cancelDate); dv.refreshReferenceObject("generalLedgerPendingEntries"); getPaymentSourceHelperService().handleEntryCancellation(dv, this); // set the financial document status to canceled dv.getFinancialSystemDocumentHeader().setFinancialDocumentStatusCode(KFSConstants.DocumentStatusCodes.CANCELLED); // save the document getDocumentService().saveDocument(dv, AccountingDocumentSaveWithNoLedgerEntryGenerationEvent.class); } catch (WorkflowException we) { LOG.error("encountered workflow exception while attempting to save Disbursement Voucher: " + dv.getDocumentNumber() + " " + we); throw new RuntimeException(we); } } } /** * Always returns true - on the DV, we roll back everything * @see org.kuali.kfs.sys.batch.service.PaymentSourceToExtractService#shouldRollBackPendingEntry(org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntry) */ @Override public boolean shouldRollBackPendingEntry(GeneralLedgerPendingEntry entry) { return true; } /** * Updates the given general ledger pending entry so that it will have the opposite effect of what it was created to do; this, * in effect, undoes the entries that were already posted for this document * * @param glpe the general ledger pending entry to undo */ protected void oppositifyEntry(GeneralLedgerPendingEntry glpe, BusinessObjectService boService, GeneralLedgerPendingEntrySequenceHelper glpeSeqHelper) { if (glpe.getTransactionDebitCreditCode().equals(KFSConstants.GL_CREDIT_CODE)) { glpe.setTransactionDebitCreditCode(KFSConstants.GL_DEBIT_CODE); } else if (glpe.getTransactionDebitCreditCode().equals(KFSConstants.GL_DEBIT_CODE)) { glpe.setTransactionDebitCreditCode(KFSConstants.GL_CREDIT_CODE); } glpe.setTransactionLedgerEntrySequenceNumber(glpeSeqHelper.getSequenceCounter()); glpeSeqHelper.increment(); glpe.setFinancialDocumentApprovedCode(KFSConstants.PENDING_ENTRY_APPROVED_STATUS_CODE.APPROVED); boService.save(glpe); } /** * Retrieve disbursement vouchers for extraction * @see org.kuali.kfs.sys.batch.service.PaymentSourceToExtractService#retrievePaymentSourcesByCampus(boolean) */ @Override public Map<String, List<DisbursementVoucherDocument>> retrievePaymentSourcesByCampus(boolean immediatesOnly) { if (LOG.isDebugEnabled()) { LOG.debug("retrievePaymentSourcesByCampus() started"); } if (immediatesOnly) { throw new UnsupportedOperationException("DisbursementVoucher PDP does immediates extraction through normal document processing; immediates for DisbursementVoucher should not be run through batch."); } Map<String, List<DisbursementVoucherDocument>> documentsByCampus = new HashMap<String, List<DisbursementVoucherDocument>>(); Collection<DisbursementVoucherDocument> docs = disbursementVoucherDao.getDocumentsByHeaderStatus(KFSConstants.DocumentStatusCodes.APPROVED, false); for (DisbursementVoucherDocument element : docs) { String dvdCampusCode = element.getCampusCode(); if (StringUtils.isNotBlank(dvdCampusCode)) { if (documentsByCampus.containsKey(dvdCampusCode)) { List<DisbursementVoucherDocument> documents = documentsByCampus.get(dvdCampusCode); documents.add(element); } else { List<DisbursementVoucherDocument> documents = new ArrayList<DisbursementVoucherDocument>(); documents.add(element); documentsByCampus.put(dvdCampusCode, documents); } } } return documentsByCampus; } /** * Creates a PaymentGroup to pay the passed in DisbursementVoucher * @see org.kuali.kfs.fp.document.service.DisbursementVoucherPaymentService#createPaymentGroup(org.kuali.kfs.fp.document.DisbursementVoucherDocument, java.sql.Date) */ @Override public PaymentGroup createPaymentGroup(DisbursementVoucherDocument document, Date processRunDate) { if (LOG.isDebugEnabled()) { LOG.debug("createPaymentGroupForDisbursementVoucher() started"); } PaymentGroup pg = new PaymentGroup(); pg.setCombineGroups(Boolean.TRUE); pg.setCampusAddress(Boolean.FALSE); document.refreshReferenceObject(KFSPropertyConstants.DV_PAYEE_DETAIL); DisbursementVoucherPayeeDetail pd = document.getDvPayeeDetail(); String rc = pd.getDisbVchrPaymentReasonCode(); if (KFSConstants.PaymentPayeeTypes.CUSTOMER.equals(document.getDvPayeeDetail().getDisbursementVoucherPayeeTypeCode())) { pg.setPayeeIdTypeCd(PdpConstants.PayeeIdTypeCodes.CUSTOMER); pg.setTaxablePayment(Boolean.FALSE); } // If the payee is an employee, set these flags accordingly else if (!document.getDvPayeeDetail().isVendor()) { pg.setEmployeeIndicator(Boolean.TRUE); pg.setPayeeIdTypeCd(PdpConstants.PayeeIdTypeCodes.EMPLOYEE); pg.setTaxablePayment( !/*REFACTORME*/getParameterEvaluatorService().getParameterEvaluator(DisbursementVoucherDocument.class, DisbursementVoucherConstants.RESEARCH_PAYMENT_REASONS_PARM_NM, rc).evaluationSucceeds() && !getParameterService().getParameterValueAsString(DisbursementVoucherDocument.class, DisbursementVoucherConstants.PAYMENT_REASON_CODE_RENTAL_PAYMENT_PARM_NM).equals(rc) && !getParameterService().getParameterValueAsString(DisbursementVoucherDocument.class, DisbursementVoucherConstants.PAYMENT_REASON_CODE_ROYALTIES_PARM_NM).equals(rc)); } // Payee is not an employee else { // These are taxable VendorDetail vendDetail = getVendorService().getVendorDetail(pd.getDisbVchrVendorHeaderIdNumberAsInteger(), pd.getDisbVchrVendorDetailAssignedIdNumberAsInteger()); String vendorOwnerCode = vendDetail.getVendorHeader().getVendorOwnershipCode(); String vendorOwnerCategoryCode = vendDetail.getVendorHeader().getVendorOwnershipCategoryCode(); String payReasonCode = pd.getDisbVchrPaymentReasonCode(); pg.setPayeeIdTypeCd(PdpConstants.PayeeIdTypeCodes.VENDOR_ID); // Assume it is not taxable until proven otherwise pg.setTaxablePayment(Boolean.FALSE); pg.setPayeeOwnerCd(vendorOwnerCode); ParameterEvaluator parameterEvaluator1 = /*REFACTORME*/getParameterEvaluatorService().getParameterEvaluator(DvToPdpExtractStep.class, PdpParameterConstants.TAXABLE_PAYMENT_REASON_CODES_BY_OWNERSHIP_CODES_PARAMETER_NAME, PdpParameterConstants.NON_TAXABLE_PAYMENT_REASON_CODES_BY_OWNERSHIP_CODES_PARAMETER_NAME, vendorOwnerCode, payReasonCode); ParameterEvaluator parameterEvaluator2 = /*REFACTORME*/getParameterEvaluatorService().getParameterEvaluator(DvToPdpExtractStep.class, PdpParameterConstants.TAXABLE_PAYMENT_REASON_CODES_BY_CORPORATION_OWNERSHIP_TYPE_CATEGORY_PARAMETER_NAME, PdpParameterConstants.NON_TAXABLE_PAYMENT_REASON_CODES_BY_CORPORATION_OWNERSHIP_TYPE_CATEGORY_PARAMETER_NAME, vendorOwnerCategoryCode, payReasonCode); if ( parameterEvaluator1.evaluationSucceeds() ) { pg.setTaxablePayment(Boolean.TRUE); } else if (getParameterService().getParameterValueAsString(DvToPdpExtractStep.class, PdpParameterConstants.CORPORATION_OWNERSHIP_TYPE_PARAMETER_NAME).equals("CP") && StringUtils.isEmpty(vendorOwnerCategoryCode) && /*REFACTORME*/getParameterEvaluatorService().getParameterEvaluator(DvToPdpExtractStep.class, PdpParameterConstants.TAXABLE_PAYMENT_REASON_CODES_FOR_BLANK_CORPORATION_OWNERSHIP_TYPE_CATEGORIES_PARAMETER_NAME, payReasonCode).evaluationSucceeds()) { pg.setTaxablePayment(Boolean.TRUE); } else if (getParameterService().getParameterValueAsString(DvToPdpExtractStep.class, PdpParameterConstants.CORPORATION_OWNERSHIP_TYPE_PARAMETER_NAME).equals("CP") && !StringUtils.isEmpty(vendorOwnerCategoryCode) && parameterEvaluator2.evaluationSucceeds() ) { pg.setTaxablePayment(Boolean.TRUE); } } pg.setCity(pd.getDisbVchrPayeeCityName()); pg.setCountry(pd.getDisbVchrPayeeCountryCode()); pg.setLine1Address(pd.getDisbVchrPayeeLine1Addr()); pg.setLine2Address(pd.getDisbVchrPayeeLine2Addr()); pg.setPayeeName(pd.getDisbVchrPayeePersonName()); pg.setPayeeId(pd.getDisbVchrPayeeIdNumber()); pg.setState(pd.getDisbVchrPayeeStateCode()); pg.setZipCd(pd.getDisbVchrPayeeZipCode()); pg.setPaymentDate(document.getDisbursementVoucherDueDate()); pg.setProcessImmediate(document.isImmediatePaymentIndicator()); pg.setPymtAttachment(document.isDisbVchrAttachmentCode()); pg.setPymtSpecialHandling(document.isDisbVchrSpecialHandlingCode()); pg.setNraPayment(pd.isDisbVchrAlienPaymentCode()); pg.setBankCode(document.getDisbVchrBankCode()); pg.setPaymentStatusCode(PdpConstants.PaymentStatusCodes.OPEN); // now add the payment detail final PaymentDetail paymentDetail = buildPaymentDetail(document, processRunDate); pg.addPaymentDetails(paymentDetail); paymentDetail.setPaymentGroup(pg); return pg; } /** * This method builds a payment detail object from the disbursement voucher document provided and links that detail file to the * batch and process run date given. * * @param document The disbursement voucher document to retrieve payment information from to populate the PaymentDetail. * @param batch The batch file associated with the payment. * @param processRunDate The date of the payment detail invoice. * @return A fully populated PaymentDetail instance. */ protected PaymentDetail buildPaymentDetail(DisbursementVoucherDocument document, Date processRunDate) { if (LOG.isDebugEnabled()) { LOG.debug("buildPaymentDetail() started"); } final String maxNoteLinesParam = getParameterService().getParameterValueAsString(KfsParameterConstants.PRE_DISBURSEMENT_ALL.class, PdpParameterConstants.MAX_NOTE_LINES); int maxNoteLines; try { maxNoteLines = Integer.parseInt(maxNoteLinesParam); } catch (NumberFormatException nfe) { throw new IllegalArgumentException("Invalid Max Notes Lines parameter, value: "+maxNoteLinesParam+" cannot be converted to an integer"); } PaymentDetail pd = new PaymentDetail(); if (StringUtils.isNotEmpty(document.getDocumentHeader().getOrganizationDocumentNumber())) { pd.setOrganizationDocNbr(document.getDocumentHeader().getOrganizationDocumentNumber()); } pd.setCustPaymentDocNbr(document.getDocumentNumber()); pd.setInvoiceDate(new java.sql.Date(processRunDate.getTime())); pd.setOrigInvoiceAmount(document.getDisbVchrCheckTotalAmount()); pd.setInvTotDiscountAmount(KualiDecimal.ZERO); pd.setInvTotOtherCreditAmount(KualiDecimal.ZERO); pd.setInvTotOtherDebitAmount(KualiDecimal.ZERO); pd.setInvTotShipAmount(KualiDecimal.ZERO); pd.setNetPaymentAmount(document.getDisbVchrCheckTotalAmount()); pd.setPrimaryCancelledPayment(Boolean.FALSE); pd.setFinancialDocumentTypeCode(DisbursementVoucherConstants.DOCUMENT_TYPE_CHECKACH); pd.setFinancialSystemOriginCode(KFSConstants.ORIGIN_CODE_KUALI); // Handle accounts for (SourceAccountingLine sal : (List<? extends SourceAccountingLine>)document.getSourceAccountingLines()) { PaymentAccountDetail pad = new PaymentAccountDetail(); pad.setFinChartCode(sal.getChartOfAccountsCode()); pad.setAccountNbr(sal.getAccountNumber()); if (StringUtils.isNotEmpty(sal.getSubAccountNumber())) { pad.setSubAccountNbr(sal.getSubAccountNumber()); } else { pad.setSubAccountNbr(KFSConstants.getDashSubAccountNumber()); } pad.setFinObjectCode(sal.getFinancialObjectCode()); if (StringUtils.isNotEmpty(sal.getFinancialSubObjectCode())) { pad.setFinSubObjectCode(sal.getFinancialSubObjectCode()); } else { pad.setFinSubObjectCode(KFSConstants.getDashFinancialSubObjectCode()); } if (StringUtils.isNotEmpty(sal.getOrganizationReferenceId())) { pad.setOrgReferenceId(sal.getOrganizationReferenceId()); } if (StringUtils.isNotEmpty(sal.getProjectCode())) { pad.setProjectCode(sal.getProjectCode()); } else { pad.setProjectCode(KFSConstants.getDashProjectCode()); } pad.setAccountNetAmount(sal.getAmount()); pd.addAccountDetail(pad); } // Handle notes DisbursementVoucherPayeeDetail dvpd = document.getDvPayeeDetail(); int line = 0; PaymentNoteText pnt = new PaymentNoteText(); pnt.setCustomerNoteLineNbr(new KualiInteger(line++)); pnt.setCustomerNoteText("Info: " + document.getDisbVchrContactPersonName() + " " + document.getDisbVchrContactPhoneNumber()); pd.addNote(pnt); String dvSpecialHandlingPersonName = null; String dvSpecialHandlingLine1Address = null; String dvSpecialHandlingLine2Address = null; String dvSpecialHandlingCity = null; String dvSpecialHandlingState = null; String dvSpecialHandlingZip = null; dvSpecialHandlingPersonName = dvpd.getDisbVchrSpecialHandlingPersonName(); dvSpecialHandlingLine1Address = dvpd.getDisbVchrSpecialHandlingLine1Addr(); dvSpecialHandlingLine2Address = dvpd.getDisbVchrSpecialHandlingLine2Addr(); dvSpecialHandlingCity = dvpd.getDisbVchrSpecialHandlingCityName(); dvSpecialHandlingState = dvpd.getDisbVchrSpecialHandlingStateCode(); dvSpecialHandlingZip = dvpd.getDisbVchrSpecialHandlingZipCode(); if (StringUtils.isNotEmpty(dvSpecialHandlingPersonName)) { pnt = new PaymentNoteText(); pnt.setCustomerNoteLineNbr(new KualiInteger(line++)); pnt.setCustomerNoteText("Send Check To: " + dvSpecialHandlingPersonName); if (LOG.isDebugEnabled()) { LOG.debug("Creating special handling person name note: "+pnt.getCustomerNoteText()); } pd.addNote(pnt); } if (StringUtils.isNotEmpty(dvSpecialHandlingLine1Address)) { pnt = new PaymentNoteText(); pnt.setCustomerNoteLineNbr(new KualiInteger(line++)); pnt.setCustomerNoteText(dvSpecialHandlingLine1Address); if (LOG.isDebugEnabled()) { LOG.debug("Creating special handling address 1 note: "+pnt.getCustomerNoteText()); } pd.addNote(pnt); } if (StringUtils.isNotEmpty(dvSpecialHandlingLine2Address)) { pnt = new PaymentNoteText(); pnt.setCustomerNoteLineNbr(new KualiInteger(line++)); pnt.setCustomerNoteText(dvSpecialHandlingLine2Address); if (LOG.isDebugEnabled()) { LOG.debug("Creating special handling address 2 note: "+pnt.getCustomerNoteText()); } pd.addNote(pnt); } if (StringUtils.isNotEmpty(dvSpecialHandlingCity)) { pnt = new PaymentNoteText(); pnt.setCustomerNoteLineNbr(new KualiInteger(line++)); pnt.setCustomerNoteText(dvSpecialHandlingCity + ", " + dvSpecialHandlingState + " " + dvSpecialHandlingZip); if (LOG.isDebugEnabled()) { LOG.debug("Creating special handling city note: "+pnt.getCustomerNoteText()); } pd.addNote(pnt); } if (document.isDisbVchrAttachmentCode()) { pnt = new PaymentNoteText(); pnt.setCustomerNoteLineNbr(new KualiInteger(line++)); pnt.setCustomerNoteText("Attachment Included"); if (LOG.isDebugEnabled()) { LOG.debug("create attachment note: "+pnt.getCustomerNoteText()); } pd.addNote(pnt); } String paymentReasonCode = dvpd.getDisbVchrPaymentReasonCode(); if (/*REFACTORME*/getParameterEvaluatorService().getParameterEvaluator(DisbursementVoucherDocument.class, DisbursementVoucherConstants.NONEMPLOYEE_TRAVEL_PAY_REASONS_PARM_NM, paymentReasonCode).evaluationSucceeds()) { DisbursementVoucherNonEmployeeTravel dvnet = document.getDvNonEmployeeTravel(); pnt = new PaymentNoteText(); pnt.setCustomerNoteLineNbr(new KualiInteger(line++)); pnt.setCustomerNoteText("Reimbursement associated with " + dvnet.getDisbVchrServicePerformedDesc()); if (LOG.isDebugEnabled()) { LOG.debug("Creating non employee travel notes: "+pnt.getCustomerNoteText()); } pd.addNote(pnt); pnt = new PaymentNoteText(); pnt.setCustomerNoteLineNbr(new KualiInteger(line++)); pnt.setCustomerNoteText("The total per diem amount for your daily expenses is " + dvnet.getDisbVchrPerdiemCalculatedAmt()); if (LOG.isDebugEnabled()) { LOG.debug("Creating non employee travel notes: "+pnt.getCustomerNoteText()); } pd.addNote(pnt); if (dvnet.getDisbVchrPersonalCarAmount() != null && dvnet.getDisbVchrPersonalCarAmount().compareTo(KualiDecimal.ZERO) != 0) { pnt = new PaymentNoteText(); pnt.setCustomerNoteLineNbr(new KualiInteger(line++)); pnt.setCustomerNoteText("The total dollar amount for your vehicle mileage is " + dvnet.getDisbVchrPersonalCarAmount()); if (LOG.isDebugEnabled()) { LOG.debug("Creating non employee travel vehicle note: "+pnt.getCustomerNoteText()); } pd.addNote(pnt); for (DisbursementVoucherNonEmployeeExpense exp : (List<DisbursementVoucherNonEmployeeExpense>)dvnet.getDvNonEmployeeExpenses()) { if (line < (maxNoteLines - 8)) { pnt = new PaymentNoteText(); pnt.setCustomerNoteLineNbr(new KualiInteger(line++)); pnt.setCustomerNoteText(exp.getDisbVchrExpenseCompanyName() + " " + exp.getDisbVchrExpenseAmount()); if (LOG.isDebugEnabled()) { LOG.debug("Creating non employee travel expense note: "+pnt.getCustomerNoteText()); } pd.addNote(pnt); } } } } else if (/*REFACTORME*/getParameterEvaluatorService().getParameterEvaluator(DisbursementVoucherDocument.class, DisbursementVoucherConstants.PREPAID_TRAVEL_PAYMENT_REASONS_PARM_NM, paymentReasonCode).evaluationSucceeds()) { pnt = new PaymentNoteText(); pnt.setCustomerNoteLineNbr(new KualiInteger(line++)); pnt.setCustomerNoteText("Payment is for the following individuals/charges:"); pd.addNote(pnt); if (LOG.isDebugEnabled()) { LOG.info("Creating prepaid travel note note: "+pnt.getCustomerNoteText()); } DisbursementVoucherPreConferenceDetail dvpcd = document.getDvPreConferenceDetail(); for (DisbursementVoucherPreConferenceRegistrant dvpcr : (List<DisbursementVoucherPreConferenceRegistrant>)dvpcd.getDvPreConferenceRegistrants()) { if (line < (maxNoteLines - 8)) { pnt = new PaymentNoteText(); pnt.setCustomerNoteLineNbr(new KualiInteger(line++)); pnt.setCustomerNoteText(dvpcr.getDvConferenceRegistrantName() + " " + dvpcr.getDisbVchrExpenseAmount()); if (LOG.isDebugEnabled()) { LOG.debug("Creating pre-paid conference registrants note: "+pnt.getCustomerNoteText()); } pd.addNote(pnt); } } } // Get the original, raw form, note text from the DV document. final String text = document.getDisbVchrCheckStubText(); if (!StringUtils.isBlank(text)) { pnt = this.getPaymentSourceHelperService().buildNoteForCheckStubText(text, line); // Logging... if (LOG.isDebugEnabled()) { LOG.debug("Creating check stub text note: " + pnt.getCustomerNoteText()); } pd.addNote(pnt); } return pd; } /** * Uses the value in the KFS-FP / DisbursementVoucher / PRE_DISBURSEMENT_EXTRACT_ORGANIZATION parameter * @see org.kuali.kfs.sys.document.PaymentSource#getPreDisbursementCustomerProfileUnit() */ @Override public String getPreDisbursementCustomerProfileUnit() { final String unit = getParameterService().getParameterValueAsString(DisbursementVoucherDocument.class, KFSParameterKeyConstants.PdpExtractBatchParameters.PDP_ORG_CODE); return unit; } /** * Uses the value in the KFS-FP / DisbursementVoucher / PRE_DISBURSEMENT_EXTRACT_SUB_UNIT * @see org.kuali.kfs.sys.document.PaymentSource#getPreDisbursementCustomerProfileSubUnit() */ @Override public String getPreDisbursementCustomerProfileSubUnit() { final String subUnit = getParameterService().getParameterValueAsString(DisbursementVoucherDocument.class, KFSParameterKeyConstants.PdpExtractBatchParameters.PDP_SBUNT_CODE); return subUnit; } /** * * @see org.kuali.kfs.sys.batch.service.PaymentSourceToExtractService#markAsExtracted(org.kuali.rice.krad.document.Document, java.sql.Date) */ @Override public void markAsExtracted(DisbursementVoucherDocument document, Date sqlProcessRunDate, KualiInteger paymentGroupId) { try { document.getFinancialSystemDocumentHeader().setFinancialDocumentStatusCode(KFSConstants.DocumentStatusCodes.Payments.EXTRACTED); document.setExtractDate(sqlProcessRunDate); getDocumentService().saveDocument(document, AccountingDocumentSaveWithNoLedgerEntryGenerationEvent.class); } catch (WorkflowException we) { LOG.error("Could not save disbursement voucher document #" + document.getDocumentNumber() + ": " + we); throw new RuntimeException(we); } } /** * The amount check total amount from the given DV * @see org.kuali.kfs.sys.batch.service.PaymentSourceToExtractService#getPaymentAmount(org.kuali.rice.krad.document.Document) */ @Override public KualiDecimal getPaymentAmount(DisbursementVoucherDocument document) { return document.getDisbVchrCheckTotalAmount(); } /** * Calls setPaidDate to set when this DisbursementVoucher was paid * @see org.kuali.kfs.sys.batch.service.PaymentSourceToExtractService#markAsPaid(org.kuali.kfs.sys.document.PaymentSource, java.sql.Date) */ @Override public void markAsPaid(DisbursementVoucherDocument paymentSource, Date processDate) { try { paymentSource.setPaidDate(processDate); getDocumentService().saveDocument(paymentSource, AccountingDocumentSaveWithNoLedgerEntryGenerationEvent.class); } catch (WorkflowException we) { LOG.error("encountered workflow exception while attempting to save Disbursement Voucher: " + paymentSource.getDocumentNumber() + " " + we); throw new RuntimeException(we); } } /** * Resets the DisbursementVoucher so that it it no longer marked as extracted; to do that, it sets its financial system document status back to approved, * and sets the paid date and extract date to null * @see org.kuali.kfs.sys.batch.service.PaymentSourceToExtractService#resetFromExtraction(org.kuali.kfs.sys.document.PaymentSource) */ @Override public void resetFromExtraction(DisbursementVoucherDocument paymentSource) { try { paymentSource.setExtractDate(null); // reset the status to APPROVED so DV will be extracted to PDP again paymentSource.setPaidDate(null); paymentSource.getFinancialSystemDocumentHeader().setFinancialDocumentStatusCode(KFSConstants.DocumentStatusCodes.APPROVED); getDocumentService().saveDocument(paymentSource, AccountingDocumentSaveWithNoLedgerEntryGenerationEvent.class); } catch (WorkflowException we) { LOG.error("encountered workflow exception while attempting to save Disbursement Voucher: " + paymentSource.getDocumentNumber() + " " + we); throw new RuntimeException(we); } } /** * Returns DVCA * @see org.kuali.kfs.sys.document.PaymentSource#getAchCheckDocumentType() */ @Override public String getAchCheckDocumentType(DisbursementVoucherDocument document) { return DisbursementVoucherConstants.DOCUMENT_TYPE_CHECKACH; } /** * Returns true if the doc type is "DVCA" * @see org.kuali.kfs.sys.batch.service.PaymentSourceToExtractService#handlesAchCheckDocumentType(java.lang.String) */ @Override public boolean handlesAchCheckDocumentType(String achCheckDocumentType) { return StringUtils.equals(achCheckDocumentType, DisbursementVoucherConstants.DOCUMENT_TYPE_CHECKACH); } /** * Returns the value of the KFS-FP / Disbursement Voucher / IMMEDIATE_EXTRACT_NOTIFICATION_FROM_EMAIL_ADDRESS parameter * @see org.kuali.kfs.sys.document.PaymentSource#getImmediateExtractEMailFromAddress() */ @Override public String getImmediateExtractEMailFromAddress() { return getParameterService().getParameterValueAsString(DisbursementVoucherDocument.class, KFSParameterKeyConstants.PdpExtractBatchParameters.IMMEDIATE_EXTRACT_FROM_ADDRESS_PARM_NM); } /** * Returns the value of the KFS-FP / Disbursement Voucher / IMMEDIATE_EXTRACT_NOTIFICATION_TO_EMAIL_ADDRESSES parameter * @see org.kuali.kfs.sys.document.PaymentSource#getImmediateExtractEmailToAddresses() */ @Override public List<String> getImmediateExtractEmailToAddresses() { List<String> toAddresses = new ArrayList<String>(); toAddresses.addAll(getParameterService().getParameterValuesAsString(DisbursementVoucherDocument.class, KFSParameterKeyConstants.PdpExtractBatchParameters.IMMEDIATE_EXTRACT_TO_ADDRESSES_PARM_NM)); return toAddresses; } /** * Determines if the payment would be 0 - if it's greater than that, it should be extracted * @see org.kuali.kfs.sys.batch.service.PaymentSourceToExtractService#shouldExtractPayment(org.kuali.kfs.sys.document.PaymentSource) */ @Override public boolean shouldExtractPayment(DisbursementVoucherDocument paymentSource) { return KualiDecimal.ZERO.isLessThan(getPaymentAmount(paymentSource)); } /** * @return the injected implementation of the BusinessObjectService */ public BusinessObjectService getBusinessObjectService() { return businessObjectService; } /** * Injects an implementation of the BusinessObjectService * @param businessObjectService the implementation of the BusinessObjectService to inject */ public void setBusinessObjectService(BusinessObjectService businessObjectService) { this.businessObjectService = businessObjectService; } /** * @return the injected implementation of the GeneralLedgerPendingEntryService */ public GeneralLedgerPendingEntryService getGeneralLedgerPendingEntryService() { return generalLedgerPendingEntryService; } /** * Injects an implementation of the GeneralLedgerPendingEntryService * @param generalLedgerPendingEntryService the implementation of GeneralLedgerPendingEntryService to inject and use */ public void setGeneralLedgerPendingEntryService(GeneralLedgerPendingEntryService generalLedgerPendingEntryService) { this.generalLedgerPendingEntryService = generalLedgerPendingEntryService; } /** * This method sets the disbursementVoucherDao instance. * * @param disbursementVoucherDao The DisbursementVoucherDao to be set. */ public void setDisbursementVoucherDao(DisbursementVoucherDao disbursementVoucherDao) { this.disbursementVoucherDao = disbursementVoucherDao; } /** * @return an implementation of the ParameterService */ public ParameterService getParameterService() { return parameterService; } /** * Sets the implementation of the ParameterService for this service to use * @param parameterService an implementation of ParameterService */ public void setParameterService(ParameterService parameterService) { this.parameterService = parameterService; } /** * @return an implementation of the ParameterEvaluatorService */ public ParameterEvaluatorService getParameterEvaluatorService() { return parameterEvaluatorService; } /** * Sets the implementation of the ParameterEvaluatorService for this service to use * @param parameterService an implementation of ParameterEvaluatorService */ public void setParameterEvaluatorService(ParameterEvaluatorService parameterEvaluatorService) { this.parameterEvaluatorService = parameterEvaluatorService; } /** * @return an implementation of the VendorService */ public VendorService getVendorService() { return vendorService; } /** * Sets the implementation of the VendorService for this service to use * @param parameterService an implementation of VendorService */ public void setVendorService(VendorService vendorService) { this.vendorService = vendorService; } /** * @return an implementation of the DocumentService */ public DocumentService getDocumentService() { return documentService; } /** * Sets the implementation of the DocumentService for this service to use * @param parameterService an implementation of DocumentService */ public void setDocumentService(DocumentService documentService) { this.documentService = documentService; } /** * @return an implementation of the PaymentSourceHelperService */ public PaymentSourceHelperService getPaymentSourceHelperService() { return paymentSourceHelperService; } /** * Sets the implementation of the PaymentSourceHelperService for this service to use * @param paymentSourceHelperService an implementation of PaymentSourceHelperService */ public void setPaymentSourceHelperService(PaymentSourceHelperService paymentSourceHelperService) { this.paymentSourceHelperService = paymentSourceHelperService; } }