use of org.kuali.kfs.pdp.businessobject.PaymentGroup in project cu-kfs by CU-CommunityApps.
the class AchBundlerFormatServiceImpl method assignDisbursementNumbersAndBundle.
/**
* MOD: This method assigns disbursement numbers and tries to combine payment groups with disbursement type check and ACH if possible.
*
* @param paymentProcess
* @param postFormatProcessSummary
*/
protected boolean assignDisbursementNumbersAndBundle(PaymentProcess paymentProcess, FormatProcessSummary postFormatProcessSummary) {
boolean successful = true;
// keep a map with paymentGroupKey and PaymentInfo (disbursementNumber, noteLines)
Map<String, PaymentInfo> combinedPaymentGroupMap = new HashMap<String, PaymentInfo>();
Iterator<PaymentGroup> paymentGroupIterator = SpringContext.getBean(PaymentGroupService.class).getByProcess(paymentProcess);
int maxNoteLines = getMaxNoteLines();
while (paymentGroupIterator.hasNext()) {
PaymentGroup paymentGroup = paymentGroupIterator.next();
LOG.debug("performFormat() Payment Group ID " + paymentGroup.getId());
// Use the customer's profile's campus code to check for disbursement ranges
String campus = paymentGroup.getBatch().getCustomerProfile().getDefaultPhysicalCampusProcessingCode();
// Where should this come from?
List<DisbursementNumberRange> disbursementRanges = paymentDetailDao.getDisbursementNumberRanges(campus);
DisbursementNumberRange range = getRange(disbursementRanges, paymentGroup.getBank(), paymentGroup.getDisbursementType().getCode());
if (range == null) {
GlobalVariables.getMessageMap().putError(KFSConstants.GLOBAL_ERRORS, PdpKeyConstants.Format.ErrorMessages.ERROR_FORMAT_DISBURSEMENT_MISSING, campus, paymentGroup.getBank().getBankCode(), paymentGroup.getDisbursementType().getCode());
successful = false;
return successful;
}
if (PdpConstants.DisbursementTypeCodes.CHECK.equals(paymentGroup.getDisbursementType().getCode()) || PdpConstants.DisbursementTypeCodes.ACH.equals(paymentGroup.getDisbursementType().getCode())) {
if (paymentGroup.getPymtAttachment().booleanValue() || paymentGroup.getProcessImmediate().booleanValue() || paymentGroup.getPymtSpecialHandling().booleanValue() || (!paymentGroup.getCombineGroups())) {
assignDisbursementNumber(campus, range, paymentGroup, postFormatProcessSummary);
} else {
String paymentGroupKey = paymentGroup.toStringKey();
// check if there was another paymentGroup we can combine with
if (combinedPaymentGroupMap.containsKey(paymentGroupKey)) {
PaymentInfo paymentInfo = combinedPaymentGroupMap.get(paymentGroupKey);
paymentInfo.noteLines = paymentInfo.noteLines.add(new KualiInteger(paymentGroup.getNoteLines()));
// if CHECK and noteLines don't excede the maximum assign the same disbursementNumber
if (PdpConstants.DisbursementTypeCodes.ACH.equals(paymentGroup.getDisbursementType().getCode()) || (PdpConstants.DisbursementTypeCodes.CHECK.equals(paymentGroup.getDisbursementType().getCode()) && paymentInfo.noteLines.intValue() <= maxNoteLines)) {
paymentGroup.setDisbursementNbr(paymentInfo.disbursementNumber);
// update payment info for new noteLines value
combinedPaymentGroupMap.put(paymentGroupKey, paymentInfo);
} else // if noteLines more than maxNoteLines we remove the old entry and get a new disbursement number
if (PdpConstants.DisbursementTypeCodes.CHECK.equals(paymentGroup.getDisbursementType().getCode()) && paymentInfo.noteLines.intValue() > maxNoteLines) {
// remove old entry for this paymentGroupKey
combinedPaymentGroupMap.remove(paymentGroupKey);
// get a new check number and the paymentGroup noteLines
KualiInteger checkNumber = assignDisbursementNumber(campus, range, paymentGroup, postFormatProcessSummary);
int noteLines = paymentGroup.getNoteLines();
// create new payment info with these two
paymentInfo = new PaymentInfo(checkNumber, new KualiInteger(noteLines));
// add new entry in the map for this paymentGroupKey
combinedPaymentGroupMap.put(paymentGroupKey, paymentInfo);
} else {
// if it isn't check or ach, we're in trouble
LOG.error("assignDisbursementNumbersAndBundle() Payment group " + paymentGroup.getId() + " must be CHCK or ACH. It is: " + paymentGroup.getDisbursementType());
throw new IllegalArgumentException("Payment group " + paymentGroup.getId() + " must be Check or ACH");
}
} else // if no entry in the map for this payment group we create a new one
{
// get a new disbursement number and the paymentGroup noteLines
KualiInteger disbursementNumber = assignDisbursementNumber(campus, range, paymentGroup, postFormatProcessSummary);
int noteLines = paymentGroup.getNoteLines();
// create new payment info with these two
PaymentInfo paymentInfo = new PaymentInfo(disbursementNumber, new KualiInteger(noteLines));
// add new entry in the map for this paymentGroupKey
combinedPaymentGroupMap.put(paymentGroupKey, paymentInfo);
}
}
} else {
// if it isn't check or ach, we're in trouble
LOG.error("assignDisbursementNumbers() Payment group " + paymentGroup.getId() + " must be CHCK or ACH. It is: " + paymentGroup.getDisbursementType());
throw new IllegalArgumentException("Payment group " + paymentGroup.getId() + " must be Check or ACH");
}
businessObjectService.save(paymentGroup);
// Generate a GL entry for CHCK & ACH
SpringContext.getBean(PendingTransactionService.class).generatePaymentGeneralLedgerPendingEntry(paymentGroup);
// Update all the ranges
LOG.debug("assignDisbursementNumbers() Save ranges");
for (DisbursementNumberRange element : disbursementRanges) {
businessObjectService.save(element);
}
}
return successful;
}
use of org.kuali.kfs.pdp.businessobject.PaymentGroup in project cu-kfs by CU-CommunityApps.
the class CheckReconciliationImportStep method getTotalNetAmount.
private KualiDecimal getTotalNetAmount(Collection<PaymentGroup> paymentGroups) {
KualiDecimal total = new KualiDecimal(0.0);
for (PaymentGroup paymentGroup : paymentGroups) {
KualiDecimal kd = paymentGroup.getNetPaymentAmount();
total = total.add(kd);
}
return total;
}
use of org.kuali.kfs.pdp.businessobject.PaymentGroup in project cu-kfs by CU-CommunityApps.
the class CheckReconciliationImportStep method updateCheckStatus.
/**
* Get Check Status and update pdp
*
* @param cr Check Reconciliation Object
* @return String
*/
private String updateCheckStatus(CheckReconciliation cr, Collection<Bank> banks, List<CheckReconError> records) throws Exception {
String defaultStatus = CRConstants.EXCP;
String oldStatus = CRConstants.EXCP;
List<String> bankCodes = new ArrayList<String>();
// Generate list of valid bank codes
for (Bank bank : banks) {
if (bank.getBankAccountNumber().equals(cr.getBankAccountNumber())) {
bankCodes.add(bank.getBankCode());
}
}
if (bankCodes.size() == 0) {
throw new Exception("Invalid Bank Account Number : " + cr.getBankAccountNumber());
}
Collection<PaymentGroup> paymentGroups = glTransactionService.getAllPaymentGroupForSearchCriteria(cr.getCheckNumber(), bankCodes);
KualiDecimal totalNetAmount = getTotalNetAmount(paymentGroups);
for (PaymentGroup paymentGroup : paymentGroups) {
/*
* At Cornell Check amount may consist of one or more payment group amounts.
*
if( !cr.getAmount().equals(paymentGroup.getNetPaymentAmount()) ) {
records.add(getCheckReconError(cr, "The check amount does not match payment net amount."));
}
*/
if (!(totalNetAmount.doubleValue() == cr.getAmount().doubleValue())) {
records.add(getCheckReconError(cr, "The check amount does not match payment net amount from the payment groups."));
}
if (statusMap.get(cr.getStatus()) != null) {
defaultStatus = statusMap.get(cr.getStatus());
oldStatus = paymentGroup.getPaymentStatusCode();
// Update PDP status and save
KualiCode code = businessObjectService.findBySinglePrimaryKey(PaymentStatus.class, defaultStatus);
if (paymentGroup.getPaymentStatus() != ((PaymentStatus) code)) {
paymentGroup.setPaymentStatus((PaymentStatus) code);
paymentGroup.setLastUpdatedTimestamp(new Timestamp(cr.getStatusChangeDate().getTime()));
}
if (defaultStatus.equals(CRConstants.CLEARED)) {
if (PaymentStatusCodes.EXTRACTED.equals(oldStatus)) {
businessObjectService.save(paymentGroup);
LOG.info("Check Status in the bank file is cleared. Updated Payment Group : " + paymentGroup.getId() + " Disbursement " + paymentGroup.getDisbursementNbr());
} else {
LOG.warn("Check Status in the bank file is cleared, but Payment Group " + paymentGroup.getId() + " for Disbursement " + paymentGroup.getDisbursementNbr() + " has a current status of " + oldStatus + " and cannot be cleared.");
}
}
} else {
LOG.warn("Update Payment Group Failed ( " + cr.getStatus() + ") ID : " + paymentGroup.getId());
}
}
if (paymentGroups == null) {
LOG.info("No Payments Found : " + cr.getBankAccountNumber() + "-" + cr.getCheckNumber());
} else if (paymentGroups.size() == 0) {
LOG.info("No Payments Found : " + cr.getBankAccountNumber() + "-" + cr.getCheckNumber());
}
return defaultStatus;
}
use of org.kuali.kfs.pdp.businessobject.PaymentGroup in project cu-kfs by CU-CommunityApps.
the class RecurringDisbursementVoucherPaymentMaintenanceServiceImpl method cancelPendingPayment.
@Override
public boolean cancelPendingPayment(Integer paymentGroupId, Integer paymentDetailId, String note, Person user) {
if (LOG.isDebugEnabled()) {
LOG.debug("cancelPendingPayment() Enter method to cancel pending payment with group id = " + paymentGroupId + " and payment detail ID of " + paymentDetailId);
}
PaymentGroup paymentGroup = this.paymentGroupService.get(paymentGroupId);
if (ObjectUtils.isNotNull(paymentGroup)) {
String paymentStatusCode = paymentGroup.getPaymentStatus().getCode();
checkCancelPermissionAndError(user, paymentStatusCode);
if (!(PdpConstants.PaymentStatusCodes.CANCEL_PAYMENT.equals(paymentStatusCode))) {
return cancelPaymentDetail(paymentDetailId, note, user, paymentGroup, paymentStatusCode);
} else {
LOG.debug("cancelPendingPayment() Pending payment group has already been cancelled; exit method.");
return true;
}
} else {
LOG.debug("cancelPendingPayment() Pending payment not found.");
GlobalVariables.getMessageMap().putError(KFSConstants.GLOBAL_ERRORS, PdpKeyConstants.PaymentDetail.ErrorMessages.ERROR_PAYMENT_NOT_FOUND);
return false;
}
}
use of org.kuali.kfs.pdp.businessobject.PaymentGroup in project cu-kfs by CU-CommunityApps.
the class CuExtractPaymentServiceImpl method writeExtractCheckFile.
@Override
protected void writeExtractCheckFile(PaymentStatus extractedStatus, PaymentProcess p, String filename, Integer processId) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date processDate = dateTimeService.getCurrentDate();
BufferedWriter os = null;
BufferedWriter osI = null;
boolean wroteImmediateHeaderRecords = false;
boolean wroteCheckHeaderRecords = false;
String immediateFilename = filename.replace("check", "check_immediate");
String checkFilename = filename;
boolean first = true;
boolean isImmediate = false;
// customer profile, then change the filename to append the RP-Upload prefix.
if (isResearchParticipantExtractFile(processId)) {
String checkFilePrefix = this.kualiConfigurationService.getPropertyValueAsString(PdpKeyConstants.ExtractPayment.CHECK_FILENAME);
checkFilePrefix = MessageFormat.format(checkFilePrefix, new Object[] { null });
checkFilePrefix = PdpConstants.RESEARCH_PARTICIPANT_FILE_PREFIX + KFSConstants.DASH + checkFilePrefix;
filename = getOutputFile(checkFilePrefix, processDate);
}
try {
List<String> notificationEmailAddresses = this.getBankPaymentFileNotificationEmailAddresses();
writeExtractCheckFileMellonBankFastTrack(extractedStatus, p, filename, processId, notificationEmailAddresses);
List<String> bankCodes = paymentGroupService.getDistinctBankCodesForProcessAndType(processId, PdpConstants.DisbursementTypeCodes.CHECK);
for (String bankCode : bankCodes) {
List<Integer> disbNbrs = paymentGroupService.getDisbursementNumbersByDisbursementTypeAndBankCode(processId, PdpConstants.DisbursementTypeCodes.CHECK, bankCode);
for (Iterator<Integer> iter = disbNbrs.iterator(); iter.hasNext(); ) {
Integer disbursementNbr = iter.next();
first = true;
KualiDecimal totalNetAmount = new KualiDecimal(0);
// this seems wasteful, but since the total net amount is needed on the first payment detail...it's needed
Iterator<PaymentDetail> i2 = paymentDetailService.getByDisbursementNumber(disbursementNbr, processId, PdpConstants.DisbursementTypeCodes.CHECK, bankCode);
while (i2.hasNext()) {
PaymentDetail pd = i2.next();
totalNetAmount = totalNetAmount.add(pd.getNetPaymentAmount());
}
List<KualiInteger> paymentGroupIdsSaved = new ArrayList<KualiInteger>();
Iterator<PaymentDetail> paymentDetails = paymentDetailService.getByDisbursementNumber(disbursementNbr, processId, PdpConstants.DisbursementTypeCodes.CHECK, bankCode);
while (paymentDetails.hasNext()) {
PaymentDetail detail = paymentDetails.next();
PaymentGroup group = detail.getPaymentGroup();
if (!testMode) {
if (!paymentGroupIdsSaved.contains(group.getId())) {
group.setDisbursementDate(new java.sql.Date(processDate.getTime()));
group.setPaymentStatus(extractedStatus);
this.businessObjectService.save(group);
paymentGroupIdsSaved.add(group.getId());
}
}
isImmediate = group.getProcessImmediate();
if (first && !isImmediate) {
if (!wroteCheckHeaderRecords) {
os = new BufferedWriter(new FileWriter(checkFilename));
os.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
writeOpenTagAttribute(os, 0, "checks", "processId", processId.toString(), "campusCode", p.getCampusCode());
wroteCheckHeaderRecords = true;
}
writeOpenTagAttribute(os, 2, "check", "disbursementNbr", group.getDisbursementNbr().toString());
// Write check level information
writeBank(os, 4, group.getBank());
writeTag(os, 4, "disbursementDate", sdf.format(processDate));
writeTag(os, 4, "netAmount", totalNetAmount.toString());
writePayee(os, 4, group);
writeTag(os, 4, "campusAddressIndicator", group.getCampusAddress().booleanValue() ? "Y" : "N");
writeTag(os, 4, "attachmentIndicator", group.getPymtAttachment().booleanValue() ? "Y" : "N");
writeTag(os, 4, "specialHandlingIndicator", group.getPymtSpecialHandling().booleanValue() ? "Y" : "N");
writeTag(os, 4, "immediatePaymentIndicator", group.getProcessImmediate().booleanValue() ? "Y" : "N");
writeTag(os, 4, "customerUnivNbr", group.getCustomerInstitutionNumber());
writeTag(os, 4, "paymentDate", sdf.format(group.getPaymentDate()));
// Write customer profile information
CustomerProfile cp = group.getBatch().getCustomerProfile();
writeCustomerProfile(os, 4, cp);
writeOpenTag(os, 4, "payments");
first = false;
}
if (first && isImmediate) {
if (!wroteImmediateHeaderRecords) {
osI = new BufferedWriter(new FileWriter(immediateFilename));
osI.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
writeOpenTagAttribute(osI, 0, "checks", "processId", processId.toString(), "campusCode", p.getCampusCode());
wroteImmediateHeaderRecords = true;
}
writeOpenTagAttribute(osI, 2, "check", "disbursementNbr", group.getDisbursementNbr().toString());
// Write check level information
writeBank(osI, 4, group.getBank());
writeTag(osI, 4, "disbursementDate", sdf.format(processDate));
writeTag(osI, 4, "netAmount", totalNetAmount.toString());
writePayee(osI, 4, group);
writeTag(osI, 4, "campusAddressIndicator", group.getCampusAddress().booleanValue() ? "Y" : "N");
writeTag(osI, 4, "attachmentIndicator", group.getPymtAttachment().booleanValue() ? "Y" : "N");
writeTag(osI, 4, "specialHandlingIndicator", group.getPymtSpecialHandling().booleanValue() ? "Y" : "N");
writeTag(osI, 4, "immediatePaymentIndicator", group.getProcessImmediate().booleanValue() ? "Y" : "N");
writeTag(osI, 4, "customerUnivNbr", group.getCustomerInstitutionNumber());
writeTag(osI, 4, "paymentDate", sdf.format(group.getPaymentDate()));
// Write customer profile information
CustomerProfile cp = group.getBatch().getCustomerProfile();
writeCustomerProfile(osI, 4, cp);
writeOpenTag(osI, 4, "payments");
first = false;
}
if (!isImmediate && wroteCheckHeaderRecords) {
writeOpenTag(os, 6, "payment");
writeTag(os, 8, "purchaseOrderNbr", detail.getPurchaseOrderNbr());
writeTag(os, 8, "invoiceNbr", detail.getInvoiceNbr());
writeTag(os, 8, "requisitionNbr", detail.getRequisitionNbr());
writeTag(os, 8, "custPaymentDocNbr", detail.getCustPaymentDocNbr());
writeTag(os, 8, "invoiceDate", sdf.format(detail.getInvoiceDate()));
writeTag(os, 8, "origInvoiceAmount", detail.getOrigInvoiceAmount().toString());
writeTag(os, 8, "netPaymentAmount", detail.getNetPaymentAmount().toString());
writeTag(os, 8, "invTotDiscountAmount", detail.getInvTotDiscountAmount().toString());
writeTag(os, 8, "invTotShipAmount", detail.getInvTotShipAmount().toString());
writeTag(os, 8, "invTotOtherDebitAmount", detail.getInvTotOtherDebitAmount().toString());
writeTag(os, 8, "invTotOtherCreditAmount", detail.getInvTotOtherCreditAmount().toString());
writeOpenTag(os, 8, "notes");
for (Iterator ix = detail.getNotes().iterator(); ix.hasNext(); ) {
PaymentNoteText note = (PaymentNoteText) ix.next();
writeTag(os, 10, "note", note.getCustomerNoteText());
}
writeCloseTag(os, 8, "notes");
writeCloseTag(os, 6, "payment");
}
if (isImmediate && wroteImmediateHeaderRecords) {
writeOpenTag(osI, 6, "payment");
writeTag(osI, 8, "purchaseOrderNbr", detail.getPurchaseOrderNbr());
writeTag(osI, 8, "invoiceNbr", detail.getInvoiceNbr());
writeTag(osI, 8, "requisitionNbr", detail.getRequisitionNbr());
writeTag(osI, 8, "custPaymentDocNbr", detail.getCustPaymentDocNbr());
writeTag(osI, 8, "invoiceDate", sdf.format(detail.getInvoiceDate()));
writeTag(osI, 8, "origInvoiceAmount", detail.getOrigInvoiceAmount().toString());
writeTag(osI, 8, "netPaymentAmount", detail.getNetPaymentAmount().toString());
writeTag(osI, 8, "invTotDiscountAmount", detail.getInvTotDiscountAmount().toString());
writeTag(osI, 8, "invTotShipAmount", detail.getInvTotShipAmount().toString());
writeTag(osI, 8, "invTotOtherDebitAmount", detail.getInvTotOtherDebitAmount().toString());
writeTag(osI, 8, "invTotOtherCreditAmount", detail.getInvTotOtherCreditAmount().toString());
writeOpenTag(osI, 8, "notes");
for (Iterator ix = detail.getNotes().iterator(); ix.hasNext(); ) {
PaymentNoteText note = (PaymentNoteText) ix.next();
writeTag(osI, 10, "note", note.getCustomerNoteText());
}
writeCloseTag(osI, 8, "notes");
writeCloseTag(osI, 6, "payment");
}
}
if (wroteCheckHeaderRecords && !isImmediate) {
writeCloseTag(os, 4, "payments");
writeCloseTag(os, 2, "check");
}
if (wroteImmediateHeaderRecords && isImmediate) {
writeCloseTag(osI, 4, "payments");
writeCloseTag(osI, 2, "check");
}
}
}
} catch (IOException ie) {
LOG.error("extractChecks() Problem reading file: " + filename, ie);
throw new IllegalArgumentException("Error writing to output file: " + ie.getMessage());
} finally {
// Close file
if (os != null) {
try {
writeCloseTag(os, 0, "checks");
os.close();
// An XML file containing these records are NEVER sent to anyone at this time.
renameFile(checkFilename, checkFilename + ".NOT_USED");
createDoneFile(checkFilename + ".NOT_USED");
} catch (IOException ie) {
// Not much we can do now
}
}
if (osI != null) {
try {
writeCloseTag(osI, 0, "checks");
osI.close();
// An XML file containing these records are ONLY used for local check printing.
renameFile(immediateFilename, immediateFilename + ".READY");
createDoneFile(immediateFilename + ".READY");
} catch (IOException ie) {
// Not much we can do now
LOG.error("IOException encountered in writeExtractCheckFile. Message is: " + ie.getMessage());
}
}
}
}
Aggregations