/*
* 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/>.
*/
/*
* Created on Aug 12, 2004
*/
package org.kuali.kfs.pdp.service.impl;
import java.sql.Timestamp;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.kuali.kfs.pdp.PdpConstants;
import org.kuali.kfs.pdp.PdpKeyConstants;
import org.kuali.kfs.pdp.PdpPropertyConstants;
import org.kuali.kfs.pdp.businessobject.PaymentChangeCode;
import org.kuali.kfs.pdp.businessobject.PaymentGroup;
import org.kuali.kfs.pdp.businessobject.PaymentGroupHistory;
import org.kuali.kfs.pdp.businessobject.PaymentStatus;
import org.kuali.kfs.pdp.dataaccess.BatchMaintenanceDao;
import org.kuali.kfs.pdp.service.BatchMaintenanceService;
import org.kuali.kfs.pdp.service.PaymentGroupService;
import org.kuali.rice.kim.api.identity.Person;
import org.kuali.rice.krad.service.BusinessObjectService;
import org.kuali.rice.krad.util.GlobalVariables;
import org.kuali.rice.krad.util.KRADConstants;
import org.springframework.transaction.annotation.Transactional;
/**
* This class provides methods for Batch maintenance.
*/
@Transactional
public class BatchMaintenanceServiceImpl implements BatchMaintenanceService {
private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(BatchMaintenanceServiceImpl.class);
private BatchMaintenanceDao batchMaintenanceDao;
private BusinessObjectService businessObjectService;
private PaymentGroupService paymentGroupService;
/**
* This method changes the status for PaymentGroup and PaymentGroupHistory.
*
* @param paymentGroup the PaymentGroup to change the status
* @param newPaymentStatus the new payment status
* @param changeStatus the payment change status code
* @param note a note from the user
*/
public void changeStatus(PaymentGroup paymentGroup, String newPaymentStatus, String changeStatus, String note, Person user) {
if (LOG.isDebugEnabled()) {
LOG.debug("changeStatus() enter method with new status of " + newPaymentStatus);
}
PaymentGroupHistory paymentGroupHistory = new PaymentGroupHistory();
PaymentChangeCode paymentChange = (PaymentChangeCode) businessObjectService.findBySinglePrimaryKey(PaymentChangeCode.class, changeStatus);
paymentGroupHistory.setPaymentChange(paymentChange);
paymentGroupHistory.setOrigPaymentStatus(paymentGroup.getPaymentStatus());
paymentGroupHistory.setChangeUser(user);
paymentGroupHistory.setChangeNoteText(note);
paymentGroupHistory.setPaymentGroup(paymentGroup);
paymentGroupHistory.setChangeTime(new Timestamp(new Date().getTime()));
this.businessObjectService.save(paymentGroupHistory);
PaymentStatus paymentStatus = (PaymentStatus) businessObjectService.findBySinglePrimaryKey(PaymentStatus.class, newPaymentStatus);
paymentGroup.setPaymentStatus(paymentStatus);
this.businessObjectService.save(paymentGroup);
LOG.debug("changeStatus() Status has been changed; exit method.");
}
/**
* cancelPendingBatch() This method cancels a pending batch by canceling each payment in the batch if the following rules apply.
* - All payments must have a status of 'OPEN'.
*
* @param paymentBatchId (Integer) Primary key of the Pending Batch to be canceled.
* @param note (String) Change note text entered by user.
* @param user (User) Actor making change.
*/
public boolean cancelPendingBatch(Integer paymentBatchId, String note, Person user) {
if (LOG.isDebugEnabled()) {
LOG.debug("cancelPendingBatch() Enter method to cancel batch with id = " + paymentBatchId);
}
if (doBatchPaymentsHaveOpenOrHeldStatus(paymentBatchId)) {
List<PaymentGroup> paymentGroupList = this.paymentGroupService.getByBatchId(paymentBatchId);
if (paymentGroupList == null || paymentGroupList.isEmpty()) {
LOG.debug("cancelPendingBatch() Pending payment groups not found for batchId; throw exception.");
GlobalVariables.getMessageMap().putError(KRADConstants.GLOBAL_ERRORS, PdpKeyConstants.BatchConstants.ErrorMessages.ERROR_PENDING_PAYMNET_GROUP_NOT_FOUND);
return false;
}
// cancel each payment
// All actions must be performed on entire group not individual detail record
for (PaymentGroup paymentGroup : paymentGroupList) {
changeStatus(paymentGroup, PdpConstants.PaymentStatusCodes.CANCEL_PAYMENT, PdpConstants.PaymentChangeCodes.CANCEL_BATCH_CHNG_CD, note, user);
}
LOG.debug("cancelPendingBatch() All payment groups in batch have been canceled; exit method.");
}
else {
LOG.debug("cancelPendingBatch() Not all payment groups are open; cannot cancel batch.");
GlobalVariables.getMessageMap().putError(KRADConstants.GLOBAL_ERRORS, PdpKeyConstants.BatchConstants.ErrorMessages.ERROR_NOT_ALL_PAYMENT_GROUPS_OPEN_CANNOT_CANCEL);
return false;
}
return true;
}
/**
* holdPendingBatch() This method holds a pending batch by holding each payment in the batch if the following rules apply. - All
* payments must have a status of 'OPEN'.
*
* @param paymentBatchId (Integer) Primary key of the Pending Batch to be held.
* @param note (String) Change note text entered by user.
* @param user (User) Actor making change.
*/
public boolean holdPendingBatch(Integer paymentBatchId, String note, Person user) {
if (LOG.isDebugEnabled()) {
LOG.debug("holdPendingBatch() Enter method to hold batch with id = " + paymentBatchId);
}
if (doBatchPaymentsHaveOpenStatus(paymentBatchId)) {
List<PaymentGroup> paymentGroupList = this.paymentGroupService.getByBatchId(paymentBatchId);
if (paymentGroupList == null || paymentGroupList.isEmpty()) {
LOG.debug("holdPendingBatch() Pending payment groups not found for batchId; throw exception.");
GlobalVariables.getMessageMap().putError(KRADConstants.GLOBAL_ERRORS, PdpKeyConstants.BatchConstants.ErrorMessages.ERROR_PENDING_PAYMNET_GROUP_NOT_FOUND);
return false;
}
// hold each payment
// All actions must be performed on entire group not individual detail record
for (PaymentGroup paymentGroup : paymentGroupList) {
changeStatus(paymentGroup, PdpConstants.PaymentStatusCodes.HELD_CD, PdpConstants.PaymentChangeCodes.HOLD_BATCH_CHNG_CD, note, user);
}
LOG.debug("holdPendingBatch() All payment groups in batch have been held; exit method.");
}
else {
LOG.debug("holdPendingBatch() Not all payment groups are open; cannot hold batch.");
GlobalVariables.getMessageMap().putError(KRADConstants.GLOBAL_ERRORS, PdpKeyConstants.BatchConstants.ErrorMessages.ERROR_NOT_ALL_PAYMENT_GROUPS_OPEN_CANNOT_HOLD);
return false;
}
return true;
}
/**
* removeBatchHold() This method removes holds on batches of payments if the following rules apply. - All Payments' statuses in
* batch must be: "held".
*
* @param paymentBatchId (Integer) Primary key of the Pending Batch to be released from hold.
* @param note (String) Change note text entered by user.
* @param user (User) Actor making change.
*/
public boolean removeBatchHold(Integer paymentBatchId, String note, Person user) {
if (LOG.isDebugEnabled()) {
LOG.debug("removeBatchHold() Enter method to remove hold batch with id = " + paymentBatchId);
}
if (doBatchPaymentsHaveHeldStatus(paymentBatchId)) {
List<PaymentGroup> paymentGroupList = this.paymentGroupService.getByBatchId(paymentBatchId);
if (paymentGroupList == null || paymentGroupList.isEmpty()) {
LOG.debug("removeBatchHold() Pending payment groups not found for batchId; throw exception.");
GlobalVariables.getMessageMap().putError(KRADConstants.GLOBAL_ERRORS, PdpKeyConstants.BatchConstants.ErrorMessages.ERROR_PENDING_PAYMNET_GROUP_NOT_FOUND);
return false;
}
// hold each payment
// All actions must be performed on entire group not individual detail record
for (PaymentGroup paymentGroup : paymentGroupList) {
changeStatus(paymentGroup, PdpConstants.PaymentStatusCodes.OPEN, PdpConstants.PaymentChangeCodes.REMOVE_HOLD_BATCH_CHNG_CD, note, user);
}
LOG.debug("removeBatchHold() All payment groups in batch have been held; exit method.");
}
else {
LOG.debug("removeBatchHold() Not all payment groups are open; cannot remove hold on batch.");
GlobalVariables.getMessageMap().putError(KRADConstants.GLOBAL_ERRORS, PdpKeyConstants.BatchConstants.ErrorMessages.ERROR_NOT_ALL_PAYMENT_GROUPS_OPEN_CANNOT_REMOVE_HOLD);
return false;
}
return true;
}
/**
* @see org.kuali.kfs.pdp.document.service.BatchMaintenanceService#doBatchPaymentsHaveOpenStatus(java.lang.Integer)
*/
public boolean doBatchPaymentsHaveOpenStatus(Integer batchId) {
// check if batch has any payments
Map<String, String> fieldValues = new HashMap<String, String>();
fieldValues.put(PdpPropertyConstants.PaymentGroup.PAYMENT_GROUP_BATCH_ID, String.valueOf(batchId));
List batchPayments = (List) businessObjectService.findMatching(PaymentGroup.class, fieldValues);
List statusList = (List) this.businessObjectService.findAll(PaymentStatus.class);
return batchMaintenanceDao.doBatchPaymentsHaveOpenStatus(batchId, batchPayments, statusList);
}
/**
* @see org.kuali.kfs.pdp.document.service.BatchMaintenanceService#doBatchPaymentsHaveHeldStatus(java.lang.Integer)
*/
public boolean doBatchPaymentsHaveHeldStatus(Integer batchId) {
// check if batch has any payments
Map<String, String> fieldValues = new HashMap<String, String>();
fieldValues.put(PdpPropertyConstants.PaymentGroup.PAYMENT_GROUP_BATCH_ID, String.valueOf(batchId));
List batchPayments = (List) businessObjectService.findMatching(PaymentGroup.class, fieldValues);
List statusList = (List) this.businessObjectService.findAll(PaymentStatus.class);
return batchMaintenanceDao.doBatchPaymentsHaveHeldStatus(batchId, batchPayments, statusList);
}
/**
* @see org.kuali.kfs.pdp.document.service.BatchMaintenanceService#doBatchPaymentsHaveOpenOrHeldStatus(java.lang.Integer)
*/
public boolean doBatchPaymentsHaveOpenOrHeldStatus(Integer batchId) {
LOG.debug("doBatchPaymentsHaveOpenOrHeldStatus() enter method.");
if ((doBatchPaymentsHaveOpenStatus(batchId)) || (doBatchPaymentsHaveHeldStatus(batchId))) {
LOG.debug("doBatchPaymentsHaveOpenOrHeldStatus() All payment groups have status 'HELD' or all payments have status 'OPEN'.");
return true;
}
else {
LOG.debug("doBatchPaymentsHaveOpenOrHeldStatus() Not all payment groups have status 'HELD' or not all payments have status 'OPEN'.");
return false;
}
}
/**
* This method sets the batchMaintenanceDao
*
* @param batchMaintenanceDao BatchMaintenanceDao
*/
public void setBatchMaintenanceDao(BatchMaintenanceDao batchMaintenanceDao) {
this.batchMaintenanceDao = batchMaintenanceDao;
}
/**
* Sets the business object service
*
* @param businessObjectService
*/
public void setBusinessObjectService(BusinessObjectService businessObjectService) {
this.businessObjectService = businessObjectService;
}
public void setPaymentGroupService(PaymentGroupService paymentGroupService) {
this.paymentGroupService = paymentGroupService;
}
}