001    /*
002     * Copyright 2011 The Kuali Foundation.
003     * 
004     * Licensed under the Educational Community License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     * 
008     * http://www.opensource.org/licenses/ecl2.php
009     * 
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    /*
017     * Created on Aug 12, 2004
018     */
019    package org.kuali.kfs.pdp.service.impl;
020    
021    import java.sql.Timestamp;
022    import java.util.Date;
023    import java.util.List;
024    
025    import org.kuali.kfs.pdp.PdpConstants;
026    import org.kuali.kfs.pdp.PdpKeyConstants;
027    import org.kuali.kfs.pdp.businessobject.PaymentChangeCode;
028    import org.kuali.kfs.pdp.businessobject.PaymentGroup;
029    import org.kuali.kfs.pdp.businessobject.PaymentGroupHistory;
030    import org.kuali.kfs.pdp.businessobject.PaymentStatus;
031    import org.kuali.kfs.pdp.dataaccess.BatchMaintenanceDao;
032    import org.kuali.kfs.pdp.service.BatchMaintenanceService;
033    import org.kuali.kfs.pdp.service.PaymentGroupService;
034    import org.kuali.rice.kim.bo.Person;
035    import org.kuali.rice.kns.service.BusinessObjectService;
036    import org.kuali.rice.kns.util.GlobalVariables;
037    import org.kuali.rice.kns.util.KNSConstants;
038    import org.springframework.transaction.annotation.Transactional;
039    
040    /**
041     * This class provides methods for Batch maintenance.
042     */
043    @Transactional
044    public class BatchMaintenanceServiceImpl implements BatchMaintenanceService {
045        private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(BatchMaintenanceServiceImpl.class);
046    
047        private BatchMaintenanceDao batchMaintenanceDao;
048        private BusinessObjectService businessObjectService;
049        private PaymentGroupService paymentGroupService;
050        
051        /**
052         * This method changes the status for PaymentGroup and PaymentGroupHistory.
053         * 
054         * @param paymentGroup the PaymentGroup to change the status
055         * @param newPaymentStatus the new payment status
056         * @param changeStatus the payment change status code
057         * @param note a note from the user
058         */
059        public void changeStatus(PaymentGroup paymentGroup, String newPaymentStatus, String changeStatus, String note, Person user) {
060            LOG.debug("changeStatus() enter method with new status of " + newPaymentStatus);
061    
062            PaymentGroupHistory paymentGroupHistory = new PaymentGroupHistory();
063            PaymentChangeCode paymentChange = (PaymentChangeCode) businessObjectService.findBySinglePrimaryKey(PaymentChangeCode.class, changeStatus);
064            
065            paymentGroupHistory.setPaymentChange(paymentChange);
066            paymentGroupHistory.setOrigPaymentStatus(paymentGroup.getPaymentStatus());
067            paymentGroupHistory.setChangeUser(user);
068            paymentGroupHistory.setChangeNoteText(note);
069            paymentGroupHistory.setPaymentGroup(paymentGroup);
070            paymentGroupHistory.setChangeTime(new Timestamp(new Date().getTime()));
071            
072            this.businessObjectService.save(paymentGroupHistory);
073    
074            PaymentStatus paymentStatus = (PaymentStatus) businessObjectService.findBySinglePrimaryKey(PaymentStatus.class, newPaymentStatus);
075    
076            paymentGroup.setPaymentStatus(paymentStatus);
077    
078            this.businessObjectService.save(paymentGroup);
079    
080            LOG.debug("changeStatus() Status has been changed; exit method.");
081        }
082    
083        /**
084         * cancelPendingBatch() This method cancels a pending batch by canceling each payment in the batch if the following rules apply. -
085         * All payments must have a status of 'OPEN'.
086         * 
087         * @param paymentBatchId (Integer) Primary key of the Pending Batch to be canceled.
088         * @param note (String) Change note text entered by user.
089         * @param user (User) Actor making change.
090         */
091        public boolean cancelPendingBatch(Integer paymentBatchId, String note, Person user) {
092            LOG.debug("cancelPendingBatch() Enter method to cancel batch with id = " + paymentBatchId);
093    
094            if (doBatchPaymentsHaveOpenOrHeldStatus(paymentBatchId)) {
095                List<PaymentGroup> paymentGroupList = this.paymentGroupService.getByBatchId(paymentBatchId);
096    
097                if (paymentGroupList == null || paymentGroupList.isEmpty()) {
098                    LOG.debug("cancelPendingBatch() Pending payment groups not found for batchId; throw exception.");
099                    
100                    GlobalVariables.getMessageMap().putError(KNSConstants.GLOBAL_ERRORS, PdpKeyConstants.BatchConstants.ErrorMessages.ERROR_PENDING_PAYMNET_GROUP_NOT_FOUND);
101                    
102                    return false;
103                }
104    
105                // cancel each payment
106                // All actions must be performed on entire group not individual detail record
107                for (PaymentGroup paymentGroup : paymentGroupList) {
108                    changeStatus(paymentGroup, PdpConstants.PaymentStatusCodes.CANCEL_PAYMENT, PdpConstants.PaymentChangeCodes.CANCEL_BATCH_CHNG_CD, note, user);
109                }
110    
111                LOG.debug("cancelPendingBatch() All payment groups in batch have been canceled; exit method.");
112            }
113            else {
114                LOG.debug("cancelPendingBatch() Not all payment groups are open; cannot cancel batch.");
115    
116                GlobalVariables.getMessageMap().putError(KNSConstants.GLOBAL_ERRORS, PdpKeyConstants.BatchConstants.ErrorMessages.ERROR_NOT_ALL_PAYMENT_GROUPS_OPEN_CANNOT_CANCEL);
117                
118                return false;
119            }
120            return true;
121        }
122    
123        /**
124         * holdPendingBatch() This method holds a pending batch by holding each payment in the batch if the following rules apply. - All
125         * payments must have a status of 'OPEN'.
126         * 
127         * @param paymentBatchId (Integer) Primary key of the Pending Batch to be held.
128         * @param note (String) Change note text entered by user.
129         * @param user (User) Actor making change.
130         */
131        public boolean holdPendingBatch(Integer paymentBatchId, String note, Person user) {
132            LOG.debug("holdPendingBatch() Enter method to hold batch with id = " + paymentBatchId);
133    
134            if (doBatchPaymentsHaveOpenStatus(paymentBatchId)) {
135                List<PaymentGroup> paymentGroupList = this.paymentGroupService.getByBatchId(paymentBatchId);
136    
137                if (paymentGroupList == null || paymentGroupList.isEmpty()) {
138                    LOG.debug("holdPendingBatch() Pending payment groups not found for batchId; throw exception.");
139                    
140                    GlobalVariables.getMessageMap().putError(KNSConstants.GLOBAL_ERRORS, PdpKeyConstants.BatchConstants.ErrorMessages.ERROR_PENDING_PAYMNET_GROUP_NOT_FOUND);
141                    
142                    return false;
143                }
144    
145                // hold each payment
146                // All actions must be performed on entire group not individual detail record
147                for (PaymentGroup paymentGroup : paymentGroupList) {
148                    changeStatus(paymentGroup, PdpConstants.PaymentStatusCodes.HELD_CD, PdpConstants.PaymentChangeCodes.HOLD_BATCH_CHNG_CD, note, user);
149                }
150    
151                LOG.debug("holdPendingBatch() All payment groups in batch have been held; exit method.");
152            }
153            else {
154                LOG.debug("holdPendingBatch() Not all payment groups are open; cannot hold batch.");
155                
156                GlobalVariables.getMessageMap().putError(KNSConstants.GLOBAL_ERRORS, PdpKeyConstants.BatchConstants.ErrorMessages.ERROR_NOT_ALL_PAYMENT_GROUPS_OPEN_CANNOT_HOLD);
157                
158                return false;
159            }
160            return true;
161        }
162    
163        /**
164         * removeBatchHold() This method removes holds on batches of payments if the following rules apply. - All Payments' statuses in
165         * batch must be: "held".
166         * 
167         * @param paymentBatchId (Integer) Primary key of the Pending Batch to be released from hold.
168         * @param note (String) Change note text entered by user.
169         * @param user (User) Actor making change.
170         */
171        public boolean removeBatchHold(Integer paymentBatchId, String note, Person user) {
172            LOG.debug("removeBatchHold() Enter method to remove hold batch with id = " + paymentBatchId);
173    
174            if (doBatchPaymentsHaveHeldStatus(paymentBatchId)) {
175                List<PaymentGroup> paymentGroupList = this.paymentGroupService.getByBatchId(paymentBatchId);
176    
177                if (paymentGroupList == null || paymentGroupList.isEmpty()) {
178                    LOG.debug("removeBatchHold() Pending payment groups not found for batchId; throw exception.");
179                    
180                    GlobalVariables.getMessageMap().putError(KNSConstants.GLOBAL_ERRORS, PdpKeyConstants.BatchConstants.ErrorMessages.ERROR_PENDING_PAYMNET_GROUP_NOT_FOUND);
181                    
182                    return false;
183                }
184    
185                // hold each payment
186                // All actions must be performed on entire group not individual detail record
187                for (PaymentGroup paymentGroup : paymentGroupList) {
188                    changeStatus(paymentGroup, PdpConstants.PaymentStatusCodes.OPEN, PdpConstants.PaymentChangeCodes.REMOVE_HOLD_BATCH_CHNG_CD, note, user);
189                }
190    
191                LOG.debug("removeBatchHold() All payment groups in batch have been held; exit method.");
192            }
193            else {
194                LOG.debug("removeBatchHold() Not all payment groups are open; cannot remove hold on batch.");
195                
196                GlobalVariables.getMessageMap().putError(KNSConstants.GLOBAL_ERRORS, PdpKeyConstants.BatchConstants.ErrorMessages.ERROR_NOT_ALL_PAYMENT_GROUPS_OPEN_CANNOT_REMOVE_HOLD);
197                
198                return false;
199            }
200            return true;
201    
202        }
203    
204        /**
205         * @see org.kuali.kfs.pdp.document.service.BatchMaintenanceService#doBatchPaymentsHaveOpenStatus(java.lang.Integer)
206         */
207        public boolean doBatchPaymentsHaveOpenStatus(Integer batchId) {
208            return batchMaintenanceDao.doBatchPaymentsHaveOpenStatus(batchId);
209        }
210    
211        /**
212         * @see org.kuali.kfs.pdp.document.service.BatchMaintenanceService#doBatchPaymentsHaveHeldStatus(java.lang.Integer)
213         */
214        public boolean doBatchPaymentsHaveHeldStatus(Integer batchId) {
215            return batchMaintenanceDao.doBatchPaymentsHaveHeldStatus(batchId);
216        }
217    
218        /**
219         * @see org.kuali.kfs.pdp.document.service.BatchMaintenanceService#doBatchPaymentsHaveOpenOrHeldStatus(java.lang.Integer)
220         */
221        public boolean doBatchPaymentsHaveOpenOrHeldStatus(Integer batchId) {
222            LOG.debug("doBatchPaymentsHaveOpenOrHeldStatus() enter method.");
223    
224            if ((doBatchPaymentsHaveOpenStatus(batchId)) || (doBatchPaymentsHaveHeldStatus(batchId))) {
225                LOG.debug("doBatchPaymentsHaveOpenOrHeldStatus() All payment groups have status 'HELD' or all payments have status 'OPEN'.");
226    
227                return true;
228            }
229            else {
230                LOG.debug("doBatchPaymentsHaveOpenOrHeldStatus() Not all payment groups have status 'HELD' or not all payments have status 'OPEN'.");
231    
232                return false;
233            }
234        }
235    
236        /**
237         * This method sets the batchMaintenanceDao
238         * 
239         * @param batchMaintenanceDao BatchMaintenanceDao
240         */
241        public void setBatchMaintenanceDao(BatchMaintenanceDao batchMaintenanceDao) {
242            this.batchMaintenanceDao = batchMaintenanceDao;
243        }
244    
245        /**
246         * Sets the business object service
247         * 
248         * @param businessObjectService
249         */
250        public void setBusinessObjectService(BusinessObjectService businessObjectService) {
251            this.businessObjectService = businessObjectService;
252        }
253    
254        public void setPaymentGroupService(PaymentGroupService paymentGroupService) {
255            this.paymentGroupService = paymentGroupService;
256        }
257    
258    }
259