/*
* 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.sys.service.impl;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.kuali.kfs.fp.document.AdvanceDepositDocument;
import org.kuali.kfs.integration.ar.AccountsReceivableModuleService;
import org.kuali.kfs.sys.KFSConstants;
import org.kuali.kfs.sys.businessobject.AccountingLine;
import org.kuali.kfs.sys.businessobject.ElectronicPaymentClaim;
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.core.api.datetime.DateTimeService;
import org.kuali.rice.core.api.parameter.ParameterEvaluatorService;
import org.kuali.rice.coreservice.framework.parameter.ParameterService;
import org.kuali.rice.kim.api.KimConstants;
import org.kuali.rice.kim.api.identity.Person;
import org.kuali.rice.kim.api.services.IdentityManagementService;
import org.kuali.rice.krad.document.Document;
import org.kuali.rice.krad.service.BusinessObjectService;
import org.kuali.rice.krad.service.DocumentService;
import org.kuali.rice.krad.util.ObjectUtils;
public class ElectronicPaymentClaimingServiceImpl implements ElectronicPaymentClaimingService {
private org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(ElectronicPaymentClaimingServiceImpl.class);
private DocumentService documentService;
private BusinessObjectService businessObjectService;
private ParameterService parameterService;
private DateTimeService dateTimeService;
protected static final String ELECTRONIC_FUNDS_CLAIMANT_GROUP_PARAMETER = "ELECTRONIC_FUNDS_CLAIMANT_GROUP";
protected final static String ELECTRONIC_PAYMENT_ADMINISTRATOR_GROUP_PARAM_NAME = "ELECTRONIC_FUNDS_ADMINISTRATOR_GROUP";
protected static final String ELECTRONIC_FUNDS_CLAIM_SUMMARIES_PER_NOTE_PARAMETER = "ELECTRONIC_FUNDS_CLAIM_SUMMARIES_PER_NOTE";
protected static final String CLAIMING_NOTE_PRELUDE = "Claiming CR Items: ";
protected static final String DI_CLAIMING_DOC_HELPER_BEAN_NAME = "distributionOfIncomeAndExpenseElectronicPaymentClaimingDocumentHelper";
protected static final String YEDI_CLAIMING_DOC_HELPER_BEAN_NAME = "yearEndDistributionOfIncomeAndExpenseElectronicPaymentClaimingDocumentHelper";
protected static final String CLAIMING_DOC_HELPER_BEAN_NAME = "expenseElectronicPaymentClaimingDocumentHelper";
protected static final String ELECTRONIC_PAYMENT_CLAIM_ACCOUNTS_PARAMETER = "ELECTRONIC_FUNDS_ACCOUNTS";
/**
* @see org.kuali.kfs.sys.service.ElectronicPaymentClaimingService#constructNotesForClaims(java.util.List)
*/
public List<String> constructNoteTextsForClaims(List<ElectronicPaymentClaim> claims) {
int summariesPerNote;
List<String> noteTexts = new ArrayList<String>();
try {
summariesPerNote = Integer.parseInt(parameterService.getParameterValueAsString(ElectronicPaymentClaim.class, ELECTRONIC_FUNDS_CLAIM_SUMMARIES_PER_NOTE_PARAMETER));
int i = 0;
while (i < claims.size()) {
String noteText = constructNoteText(claims, i, summariesPerNote);
noteTexts.add(noteText);
i += summariesPerNote;
}
}
catch (NumberFormatException nfe) {
throw new RuntimeException("The KFS-SYS / ElectronicPaymentClaim / " + ELECTRONIC_FUNDS_CLAIM_SUMMARIES_PER_NOTE_PARAMETER + " should have a value that can be parsed into an integer.", nfe);
}
return noteTexts;
}
/**
* This creates a note for the given point in the list of summaries.
*
* @param claims a List of ElectronicPaymentClaim records that are being claimed
* @param startPoint the point in the list the note is starting at
* @param maxSummariesPerNote the number of ElectronicPaymentClaim summaries we can have on a note
* @return a newly constructed note, that needs to have a user added
*/
protected String constructNoteText(List<ElectronicPaymentClaim> claims, int startPoint, int maxSummariesPerNote) {
StringBuilder sb = new StringBuilder();
sb.append(CLAIMING_NOTE_PRELUDE);
for (int i = startPoint; i < (startPoint + maxSummariesPerNote) && i < claims.size(); i++) {
ElectronicPaymentClaim claim = claims.get(i);
sb.append(createSummaryLineForClaim(claim));
}
// substring out the final " ; "
String noteText = sb.substring(0, sb.length() - 3);
return noteText;
}
/**
* Creates a summary line for a note from a claim
*
* @param claim the electronic payment claim to summarize
* @return a String with the summary of the claim.
*/
protected String createSummaryLineForClaim(ElectronicPaymentClaim claim) {
StringBuilder summary = new StringBuilder();
summary.append(claim.getDocumentNumber());
summary.append('-');
summary.append(claim.getFinancialDocumentLineNumber().toString());
summary.append(' ');
final Date advanceDepositDate = claim.getGeneratingAdvanceDepositDetail().getFinancialDocumentAdvanceDepositDate();
if (!ObjectUtils.isNull(advanceDepositDate)) {
summary.append(dateTimeService.toDateString(advanceDepositDate));
summary.append(' ');
}
summary.append('$');
summary.append(claim.getGeneratingAccountingLine().getAmount());
summary.append(' ');
summary.append(';');
summary.append(' ');
return summary.toString();
}
/**
* @see org.kuali.kfs.sys.service.ElectronicPaymentClaimingService#createPaymentClaimingDocument(java.util.List,
* org.kuali.kfs.sys.service.ElectronicPaymentClaimingDocumentGenerationStrategy)
*/
public String createPaymentClaimingDocument(List<ElectronicPaymentClaim> claims, ElectronicPaymentClaimingDocumentGenerationStrategy documentCreationHelper, Person user) {
return documentCreationHelper.createDocumentFromElectronicPayments(claims, user);
}
/**
* @see org.kuali.kfs.sys.service.ElectronicPaymentClaimingService#getClaimingDocumentChoices(org.kuali.rice.kim.api.identity.Person)
*/
public List<ElectronicPaymentClaimingDocumentGenerationStrategy> getClaimingDocumentChoices(Person user) {
List<ElectronicPaymentClaimingDocumentGenerationStrategy> documentChoices = new ArrayList<ElectronicPaymentClaimingDocumentGenerationStrategy>();
Map<String, ElectronicPaymentClaimingDocumentGenerationStrategy> claimingDocHelpers = SpringContext.getBeansOfType(ElectronicPaymentClaimingDocumentGenerationStrategy.class);
ElectronicPaymentClaimingDocumentGenerationStrategy claimingDocHelper;
// try the helper for no document case
claimingDocHelper = claimingDocHelpers.get(CLAIMING_DOC_HELPER_BEAN_NAME);
if (claimingDocHelper.userMayUseToClaim(user)) {
documentChoices.add(claimingDocHelper);
}
// try the DI
claimingDocHelper = claimingDocHelpers.get(DI_CLAIMING_DOC_HELPER_BEAN_NAME);
if (claimingDocHelper.userMayUseToClaim(user)) {
documentChoices.add(claimingDocHelper);
}
// try the YEDI
claimingDocHelper = claimingDocHelpers.get(YEDI_CLAIMING_DOC_HELPER_BEAN_NAME);
if (claimingDocHelper.userMayUseToClaim(user)) {
documentChoices.add(claimingDocHelper);
}
// try the AR Cash Control
claimingDocHelper = SpringContext.getBean(AccountsReceivableModuleService.class).getAccountsReceivablePaymentClaimingStrategy();
if (claimingDocHelper.userMayUseToClaim(user)) {
documentChoices.add(claimingDocHelper);
}
return documentChoices;
}
/**
* Sets the referenceFinancialDocumentNumber on each of the payments passed in with the given document number and then saves
* them.
*
* @param payments a list of payments to claim
* @param docmentNumber the document number of the claiming document
*/
public void claimElectronicPayments(List<ElectronicPaymentClaim> payments, String documentNumber) {
for (ElectronicPaymentClaim payment : payments) {
payment.setReferenceFinancialDocumentNumber(documentNumber);
payment.setPaymentClaimStatusCode(ElectronicPaymentClaim.ClaimStatusCodes.CLAIMED);
businessObjectService.save(payment);
}
}
/**
* @see org.kuali.kfs.sys.service.ElectronicPaymentClaimingService#declaimElectronicPaymentClaimsForDocument(org.kuali.rice.krad.document.Document)
*/
public void declaimElectronicPaymentClaimsForDocument(Document document) {
Map<String, String> searchKeys = new HashMap<String, String>();
searchKeys.put("referenceFinancialDocumentNumber", document.getDocumentNumber());
Collection<ElectronicPaymentClaim> claimsAsObjects = businessObjectService.findMatching(ElectronicPaymentClaim.class, searchKeys);
for (Object claimAsObject : claimsAsObjects) {
ElectronicPaymentClaim claim = (ElectronicPaymentClaim) claimAsObject;
claim.setReferenceFinancialDocumentNumber(null);
claim.setPaymentClaimStatusCode(ElectronicPaymentClaim.ClaimStatusCodes.UNCLAIMED);
businessObjectService.save(claim);
}
}
/**
* @see org.kuali.kfs.sys.service.ElectronicPaymentClaimingService#isAuthorizedForClaimingElectronicPayment(org.kuali.rice.kim.api.identity.Person,
* java.lang.String, java.lang.String)
*/
public boolean isAuthorizedForClaimingElectronicPayment(Person user, String workflowDocumentTypeName) {
String principalId = user.getPrincipalId();
String namespaceCode = KFSConstants.ParameterNamespaces.KFS;
String permissionTemplateName = KFSConstants.PermissionTemplate.CLAIM_ELECTRONIC_PAYMENT.name;
Map<String,String> permissionDetails = new HashMap<String,String>();
permissionDetails.put(KimConstants.AttributeConstants.DOCUMENT_TYPE_NAME, workflowDocumentTypeName);
IdentityManagementService identityManagementService = SpringContext.getBean(IdentityManagementService.class);
boolean isAuthorized = identityManagementService.hasPermissionByTemplateName(principalId, namespaceCode, permissionTemplateName, permissionDetails);
return isAuthorized;
}
/**
* @see org.kuali.kfs.sys.service.ElectronicPaymentClaimingService#generateElectronicPaymentClaimRecords(org.kuali.kfs.fp.document.AdvanceDepositDocument)
*/
public List<ElectronicPaymentClaim> generateElectronicPaymentClaimRecords(AdvanceDepositDocument doc) {
List<ElectronicPaymentClaim> claimRecords = new ArrayList<ElectronicPaymentClaim>();
for (Object accountingLineAsObj : doc.getSourceAccountingLines()) {
final AccountingLine accountingLine = (AccountingLine) accountingLineAsObj;
if (this.representsElectronicFundAccount(accountingLine)) {
ElectronicPaymentClaim electronicPayment = createElectronicPayment(doc, accountingLine);
businessObjectService.save(electronicPayment);
claimRecords.add(electronicPayment);
}
}
return claimRecords;
}
/**
* Determines if the given accounting line represents an electronic payment
* @param accountingLine the accounting line to check
* @return true if the accounting line does represent an electronic payment, false otherwise
*/
public boolean representsElectronicFundAccount(AccountingLine accountingLine) {
return /*REFACTORME*/SpringContext.getBean(ParameterEvaluatorService.class).getParameterEvaluator(AdvanceDepositDocument.class, ELECTRONIC_PAYMENT_CLAIM_ACCOUNTS_PARAMETER, accountingLine.getChartOfAccountsCode(), accountingLine.getAccountNumber()).evaluationSucceeds();
}
/**
* Creates an electronic payment claim record to match the given accounting line on the document
*
* @param accountingLine an accounting line that an electronic payment claim record should be created for
* @return the created ElectronicPaymentClaim business object
*/
protected ElectronicPaymentClaim createElectronicPayment(AdvanceDepositDocument document, AccountingLine accountingLine) {
ElectronicPaymentClaim electronicPayment = new ElectronicPaymentClaim();
electronicPayment.setDocumentNumber(document.getDocumentNumber());
electronicPayment.setFinancialDocumentLineNumber(accountingLine.getSequenceNumber());
electronicPayment.setFinancialDocumentPostingPeriodCode(document.getPostingPeriodCode());
electronicPayment.setFinancialDocumentPostingYear(document.getPostingYear());
electronicPayment.setPaymentClaimStatusCode(ElectronicPaymentClaim.ClaimStatusCodes.UNCLAIMED);
return electronicPayment;
}
/**
* Sets the businessObjectService attribute value.
*
* @param businessObjectService The businessObjectService to set.
*/
public void setBusinessObjectService(BusinessObjectService businessObjectService) {
this.businessObjectService = businessObjectService;
}
/**
* Sets the documentService attribute value.
*
* @param documentService The documentService to set.
*/
public void setDocumentService(DocumentService documentService) {
this.documentService = documentService;
}
/**
* Sets the parameterService attribute value.
*
* @param parameterService The parameterService to set.
*/
public void setParameterService(ParameterService parameterService) {
this.parameterService = parameterService;
}
/**
* Sets the dateTimeService attribute value.
*
* @param dateTimeService The dateTimeService to set.
*/
public void setDateTimeService(DateTimeService dateTimeService) {
this.dateTimeService = dateTimeService;
}
}