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.HashMap; 024 import java.util.List; 025 import java.util.Map; 026 027 import org.kuali.kfs.pdp.PdpConstants; 028 import org.kuali.kfs.pdp.PdpKeyConstants; 029 import org.kuali.kfs.pdp.PdpPropertyConstants; 030 import org.kuali.kfs.pdp.businessobject.AchAccountNumber; 031 import org.kuali.kfs.pdp.businessobject.PaymentChangeCode; 032 import org.kuali.kfs.pdp.businessobject.PaymentDetail; 033 import org.kuali.kfs.pdp.businessobject.PaymentGroup; 034 import org.kuali.kfs.pdp.businessobject.PaymentGroupHistory; 035 import org.kuali.kfs.pdp.businessobject.PaymentNoteText; 036 import org.kuali.kfs.pdp.businessobject.PaymentStatus; 037 import org.kuali.kfs.pdp.dataaccess.PaymentDetailDao; 038 import org.kuali.kfs.pdp.dataaccess.PaymentGroupDao; 039 import org.kuali.kfs.pdp.service.EnvironmentService; 040 import org.kuali.kfs.pdp.service.PaymentGroupService; 041 import org.kuali.kfs.pdp.service.PaymentMaintenanceService; 042 import org.kuali.kfs.pdp.service.PdpAuthorizationService; 043 import org.kuali.kfs.pdp.service.PdpEmailService; 044 import org.kuali.kfs.pdp.service.PendingTransactionService; 045 import org.kuali.kfs.sys.KFSConstants; 046 import org.kuali.kfs.sys.service.BankService; 047 import org.kuali.rice.kim.bo.Person; 048 import org.kuali.rice.kns.bo.KualiCode; 049 import org.kuali.rice.kns.service.BusinessObjectService; 050 import org.kuali.rice.kns.service.MailService; 051 import org.kuali.rice.kns.service.ParameterService; 052 import org.kuali.rice.kns.util.GlobalVariables; 053 import org.kuali.rice.kns.util.KualiInteger; 054 import org.kuali.rice.kns.util.ObjectUtils; 055 import org.springframework.transaction.annotation.Transactional; 056 057 /** 058 * @see org.kuali.kfs.pdp.service.PaymentMaintenanceService 059 */ 060 @Transactional 061 public class PaymentMaintenanceServiceImpl implements PaymentMaintenanceService { 062 private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(PaymentMaintenanceServiceImpl.class); 063 064 private PaymentGroupDao paymentGroupDao; 065 private PaymentDetailDao paymentDetailDao; 066 private PendingTransactionService glPendingTransactionService; 067 private EnvironmentService environmentService; 068 private MailService mailService; 069 private ParameterService parameterService; 070 private BankService bankService; 071 private BusinessObjectService businessObjectService; 072 private PaymentGroupService paymentGroupService; 073 private PdpEmailService emailService; 074 private PdpAuthorizationService pdpAuthorizationService; 075 076 /** 077 * This method changes status for a payment group. 078 * 079 * @param paymentGroup the payment group 080 * @param newPaymentStatus the new payment status 081 * @param changeStatus the changed payment status 082 * @param note a note for payment status change 083 * @param user the user that changed the status 084 */ 085 protected void changeStatus(PaymentGroup paymentGroup, String newPaymentStatus, String changeStatus, String note, Person user) { 086 if (LOG.isDebugEnabled()) { 087 LOG.debug("changeStatus() enter method with new status of " + newPaymentStatus); 088 } 089 090 PaymentGroupHistory paymentGroupHistory = new PaymentGroupHistory(); 091 KualiCode cd = businessObjectService.findBySinglePrimaryKey(PaymentChangeCode.class, changeStatus); 092 paymentGroupHistory.setPaymentChange((PaymentChangeCode) cd); 093 paymentGroupHistory.setOrigPaymentStatus(paymentGroup.getPaymentStatus()); 094 paymentGroupHistory.setChangeUser(user); 095 paymentGroupHistory.setChangeNoteText(note); 096 paymentGroupHistory.setPaymentGroup(paymentGroup); 097 paymentGroupHistory.setChangeTime(new Timestamp(new Date().getTime())); 098 099 this.businessObjectService.save(paymentGroupHistory); 100 101 KualiCode code = businessObjectService.findBySinglePrimaryKey(PaymentStatus.class, newPaymentStatus); 102 paymentGroup.setPaymentStatus((PaymentStatus) code); 103 this.businessObjectService.save(paymentGroup); 104 LOG.debug("changeStatus() Status has been changed; exit method."); 105 } 106 107 /** 108 * This method changes the state of a paymentGroup. 109 * 110 * @param paymentGroup the payment group to change the state for 111 * @param newPaymentStatus the new payment status 112 * @param changeStatus the status that is changed 113 * @param note the note entered by the user 114 * @param user the user that changed the 115 * @param paymentGroupHistory 116 */ 117 protected void changeStatus(PaymentGroup paymentGroup, String newPaymentStatus, String changeStatus, String note, Person user, PaymentGroupHistory paymentGroupHistory) { 118 if (LOG.isDebugEnabled()) { 119 LOG.debug("changeStatus() enter method with new status of " + newPaymentStatus); 120 } 121 122 KualiCode cd = businessObjectService.findBySinglePrimaryKey(PaymentChangeCode.class, changeStatus); 123 paymentGroupHistory.setPaymentChange((PaymentChangeCode) cd); 124 paymentGroupHistory.setOrigPaymentStatus(paymentGroup.getPaymentStatus()); 125 paymentGroupHistory.setChangeUser(user); 126 paymentGroupHistory.setChangeNoteText(note); 127 paymentGroupHistory.setPaymentGroup(paymentGroup); 128 paymentGroupHistory.setChangeTime(new Timestamp(new Date().getTime())); 129 130 this.businessObjectService.save(paymentGroupHistory); 131 132 KualiCode code = businessObjectService.findBySinglePrimaryKey(PaymentStatus.class, newPaymentStatus); 133 if (paymentGroup.getPaymentStatus() != ((PaymentStatus) code)) { 134 paymentGroup.setPaymentStatus((PaymentStatus) code); 135 } 136 this.businessObjectService.save(paymentGroup); 137 138 LOG.debug("changeStatus() Status has been changed; exit method."); 139 } 140 141 /** 142 * @see org.kuali.kfs.pdp.document.service.PaymentMaintenanceService#cancelPendingPayment(java.lang.Integer, java.lang.Integer, 143 * java.lang.String, org.kuali.rice.kim.bo.Person) 144 */ 145 public boolean cancelPendingPayment(Integer paymentGroupId, Integer paymentDetailId, String note, Person user) { 146 // All actions must be performed on entire group not individual detail record 147 if (LOG.isDebugEnabled()) { 148 LOG.debug("cancelPendingPayment() Enter method to cancel pending payment with group id = " + paymentGroupId); 149 LOG.debug("cancelPendingPayment() payment detail id being cancelled = " + paymentDetailId); 150 } 151 152 PaymentGroup paymentGroup = this.paymentGroupService.get(paymentGroupId); 153 if (paymentGroup == null) { 154 LOG.debug("cancelPendingPayment() Pending payment not found; throw exception."); 155 GlobalVariables.getMessageMap().putError(KFSConstants.GLOBAL_ERRORS, PdpKeyConstants.PaymentDetail.ErrorMessages.ERROR_PAYMENT_NOT_FOUND); 156 return false; 157 } 158 159 String paymentStatus = paymentGroup.getPaymentStatus().getCode(); 160 161 if (!(PdpConstants.PaymentStatusCodes.CANCEL_PAYMENT.equals(paymentStatus))) { 162 if (LOG.isDebugEnabled()) { 163 LOG.debug("cancelPendingPayment() Payment status is " + paymentStatus + "; continue with cancel."); 164 } 165 166 if ((PdpConstants.PaymentStatusCodes.HELD_TAX_EMPLOYEE_CD.equals(paymentStatus)) || (PdpConstants.PaymentStatusCodes.HELD_TAX_NRA_CD.equals(paymentStatus)) || (PdpConstants.PaymentStatusCodes.HELD_TAX_NRA_EMPL_CD.equals(paymentStatus))) { 167 if (!pdpAuthorizationService.hasRemovePaymentTaxHoldPermission(user.getPrincipalId())) { 168 LOG.warn("cancelPendingPayment() Payment status is " + paymentStatus + "; user does not have rights to cancel. This should not happen unless user is URL spoofing."); 169 throw new RuntimeException("cancelPendingPayment() Payment status is " + paymentStatus + "; user does not have rights to cancel. This should not happen unless user is URL spoofing."); 170 } 171 172 changeStatus(paymentGroup, PdpConstants.PaymentStatusCodes.CANCEL_PAYMENT, PdpConstants.PaymentChangeCodes.CANCEL_PAYMENT_CHNG_CD, note, user); 173 174 // set primary cancel indicator for EPIC to use 175 Map primaryKeys = new HashMap(); 176 primaryKeys.put(PdpPropertyConstants.PaymentDetail.PAYMENT_ID, paymentDetailId); 177 178 PaymentDetail pd = (PaymentDetail) this.businessObjectService.findByPrimaryKey(PaymentDetail.class, primaryKeys); 179 if (pd != null) { 180 pd.setPrimaryCancelledPayment(Boolean.TRUE); 181 } 182 this.businessObjectService.save(pd); 183 this.emailService.sendCancelEmail(paymentGroup, note, user); 184 185 LOG.debug("cancelPendingPayment() Pending payment cancelled and mail was sent; exit method."); 186 } 187 else if (PdpConstants.PaymentStatusCodes.OPEN.equals(paymentStatus) || PdpConstants.PaymentStatusCodes.HELD_CD.equals(paymentStatus)) { 188 if (!pdpAuthorizationService.hasCancelPaymentPermission(user.getPrincipalId())) { 189 LOG.warn("cancelPendingPayment() Payment status is " + paymentStatus + "; user does not have rights to cancel. This should not happen unless user is URL spoofing."); 190 throw new RuntimeException("cancelPendingPayment() Payment status is " + paymentStatus + "; user does not have rights to cancel. This should not happen unless user is URL spoofing."); 191 } 192 193 changeStatus(paymentGroup, PdpConstants.PaymentStatusCodes.CANCEL_PAYMENT, PdpConstants.PaymentChangeCodes.CANCEL_PAYMENT_CHNG_CD, note, user); 194 195 // set primary cancel indicator for EPIC to use 196 Map primaryKeys = new HashMap(); 197 primaryKeys.put(PdpPropertyConstants.PaymentDetail.PAYMENT_ID, paymentDetailId); 198 199 PaymentDetail pd = (PaymentDetail) this.businessObjectService.findByPrimaryKey(PaymentDetail.class, primaryKeys); 200 if (pd != null) { 201 pd.setPrimaryCancelledPayment(Boolean.TRUE); 202 PaymentNoteText payNoteText = new PaymentNoteText(); 203 payNoteText.setCustomerNoteLineNbr(new KualiInteger(pd.getNotes().size() + 1)); 204 payNoteText.setCustomerNoteText(note); 205 pd.addNote(payNoteText); 206 } 207 208 this.businessObjectService.save(pd); 209 210 LOG.debug("cancelPendingPayment() Pending payment cancelled; exit method."); 211 } 212 else { 213 if (LOG.isDebugEnabled()) { 214 LOG.debug("cancelPendingPayment() Payment status is " + paymentStatus + "; cannot cancel payment in this status"); 215 } 216 217 GlobalVariables.getMessageMap().putError(KFSConstants.GLOBAL_ERRORS, PdpKeyConstants.PaymentDetail.ErrorMessages.ERROR_PAYMENT_INVALID_STATUS_TO_CANCEL); 218 return false; 219 } 220 } 221 else { 222 LOG.debug("cancelPendingPayment() Pending payment group has already been cancelled; exit method."); 223 } 224 return true; 225 } 226 227 /** 228 * @see org.kuali.kfs.pdp.document.service.PaymentMaintenanceService#holdPendingPayment(java.lang.Integer, java.lang.String, 229 * org.kuali.rice.kim.bo.Person) 230 */ 231 public boolean holdPendingPayment(Integer paymentGroupId, String note, Person user) { 232 // All actions must be performed on entire group not individual detail record 233 if (LOG.isDebugEnabled()) { 234 LOG.debug("holdPendingPayment() Enter method to hold pending payment with id = " + paymentGroupId); 235 } 236 237 if (!pdpAuthorizationService.hasHoldPaymentPermission(user.getPrincipalId())) { 238 LOG.warn("holdPendingPayment() User " + user.getPrincipalId() + " does not have rights to hold payments. This should not happen unless user is URL spoofing."); 239 throw new RuntimeException("holdPendingPayment() User " + user.getPrincipalId() + " does not have rights to hold payments. This should not happen unless user is URL spoofing."); 240 } 241 242 PaymentGroup paymentGroup = this.paymentGroupService.get(paymentGroupId); 243 if (paymentGroup == null) { 244 LOG.debug("holdPendingPayment() Pending payment not found; throw exception."); 245 GlobalVariables.getMessageMap().putError(KFSConstants.GLOBAL_ERRORS, PdpKeyConstants.PaymentDetail.ErrorMessages.ERROR_PAYMENT_NOT_FOUND); 246 return false; 247 } 248 249 String paymentStatus = paymentGroup.getPaymentStatus().getCode(); 250 251 if (!(PdpConstants.PaymentStatusCodes.HELD_CD.equals(paymentStatus))) { 252 if (PdpConstants.PaymentStatusCodes.OPEN.equals(paymentStatus)) { 253 if (LOG.isDebugEnabled()) { 254 LOG.debug("holdPendingPayment() Payment status is " + paymentStatus + "; continue with hold."); 255 } 256 257 changeStatus(paymentGroup, PdpConstants.PaymentStatusCodes.HELD_CD, PdpConstants.PaymentChangeCodes.HOLD_CHNG_CD, note, user); 258 259 LOG.debug("holdPendingPayment() Pending payment was put on hold; exit method."); 260 } 261 else { 262 if (LOG.isDebugEnabled()) { 263 LOG.debug("holdPendingPayment() Payment status is " + paymentStatus + "; cannot hold payment in this status"); 264 } 265 266 GlobalVariables.getMessageMap().putError(KFSConstants.GLOBAL_ERRORS, PdpKeyConstants.PaymentDetail.ErrorMessages.ERROR_PAYMENT_INVALID_STATUS_TO_HOLD); 267 return false; 268 } 269 } 270 else { 271 LOG.debug("holdPendingPayment() Pending payment group has already been held; exit method."); 272 } 273 return true; 274 275 } 276 277 /** 278 * @see org.kuali.kfs.pdp.document.service.PaymentMaintenanceService#removeHoldPendingPayment(java.lang.Integer, 279 * java.lang.String, org.kuali.rice.kim.bo.Person) 280 */ 281 public boolean removeHoldPendingPayment(Integer paymentGroupId, String note, Person user) { 282 // All actions must be performed on entire group not individual detail record 283 if (LOG.isDebugEnabled()) { 284 LOG.debug("removeHoldPendingPayment() Enter method to hold pending payment with id = " + paymentGroupId); 285 } 286 PaymentGroup paymentGroup = this.paymentGroupService.get(paymentGroupId); 287 if (paymentGroup == null) { 288 LOG.debug("removeHoldPendingPayment() Payment not found; throw exception."); 289 290 GlobalVariables.getMessageMap().putError(KFSConstants.GLOBAL_ERRORS, PdpKeyConstants.PaymentDetail.ErrorMessages.ERROR_PAYMENT_NOT_FOUND); 291 return false; 292 } 293 294 String paymentStatus = paymentGroup.getPaymentStatus().getCode(); 295 296 if (!(PdpConstants.PaymentStatusCodes.OPEN.equals(paymentStatus))) { 297 if (LOG.isDebugEnabled()) { 298 LOG.debug("removeHoldPendingPayment() Payment status is " + paymentStatus + "; continue with hold removal."); 299 } 300 301 if ((PdpConstants.PaymentStatusCodes.HELD_TAX_EMPLOYEE_CD.equals(paymentStatus)) || (PdpConstants.PaymentStatusCodes.HELD_TAX_NRA_CD.equals(paymentStatus)) || (PdpConstants.PaymentStatusCodes.HELD_TAX_NRA_EMPL_CD.equals(paymentStatus))) { 302 if (!pdpAuthorizationService.hasRemovePaymentTaxHoldPermission(user.getPrincipalId())) { 303 LOG.warn("removeHoldPendingPayment() User " + user.getPrincipalId() + " does not have rights to remove tax holds. This should not happen unless user is URL spoofing."); 304 throw new RuntimeException("removeHoldPendingPayment() User " + user.getPrincipalId() + " does not have rights to remove tax holds. This should not happen unless user is URL spoofing."); 305 } 306 307 changeStatus(paymentGroup, PdpConstants.PaymentStatusCodes.OPEN, PdpConstants.PaymentChangeCodes.REMOVE_HOLD_CHNG_CD, note, user); 308 LOG.debug("removeHoldPendingPayment() Pending payment was taken off hold; exit method."); 309 } 310 else if (PdpConstants.PaymentStatusCodes.HELD_CD.equals(paymentStatus)) { 311 if (!pdpAuthorizationService.hasHoldPaymentPermission(user.getPrincipalId())) { 312 LOG.warn("removeHoldPendingPayment() User " + user.getPrincipalId() + " does not have rights to hold payments. This should not happen unless user is URL spoofing."); 313 throw new RuntimeException("removeHoldPendingPayment() User " + user.getPrincipalId() + " does not have rights to hold payments. This should not happen unless user is URL spoofing."); 314 } 315 316 changeStatus(paymentGroup, PdpConstants.PaymentStatusCodes.OPEN, PdpConstants.PaymentChangeCodes.REMOVE_HOLD_CHNG_CD, note, user); 317 318 LOG.debug("removeHoldPendingPayment() Pending payment was taken off hold; exit method."); 319 } 320 else { 321 if (LOG.isDebugEnabled()) { 322 LOG.debug("removeHoldPendingPayment() Payment status is " + paymentStatus + "; cannot remove hold on payment in this status"); 323 } 324 325 GlobalVariables.getMessageMap().putError(KFSConstants.GLOBAL_ERRORS, PdpKeyConstants.PaymentDetail.ErrorMessages.ERROR_PAYMENT_INVALID_STATUS_TO_REMOVE_HOLD); 326 return false; 327 } 328 } 329 else { 330 LOG.debug("removeHoldPendingPayment() Pending payment group has already been un-held; exit method."); 331 } 332 return true; 333 } 334 335 /** 336 * @see org.kuali.kfs.pdp.document.service.PaymentMaintenanceService#changeImmediateFlag(java.lang.Integer, java.lang.String, 337 * org.kuali.rice.kim.bo.Person) 338 */ 339 public void changeImmediateFlag(Integer paymentGroupId, String note, Person user) { 340 // All actions must be performed on entire group not individual detail record 341 if (LOG.isDebugEnabled()) { 342 LOG.debug("changeImmediateFlag() Enter method to hold pending payment with id = " + paymentGroupId); 343 } 344 345 if (!pdpAuthorizationService.hasSetAsImmediatePayPermission(user.getPrincipalId())) { 346 LOG.warn("changeImmediateFlag() User " + user.getPrincipalId() + " does not have rights to set payments as immediate. This should not happen unless user is URL spoofing."); 347 throw new RuntimeException("changeImmediateFlag() User " + user.getPrincipalId() + " does not have rights to payments as immediate. This should not happen unless user is URL spoofing."); 348 } 349 350 PaymentGroupHistory paymentGroupHistory = new PaymentGroupHistory(); 351 PaymentGroup paymentGroup = this.paymentGroupService.get(paymentGroupId); 352 353 paymentGroupHistory.setOrigProcessImmediate(paymentGroup.getProcessImmediate()); 354 355 if (paymentGroup.getProcessImmediate().equals(Boolean.TRUE)) { 356 paymentGroup.setProcessImmediate(Boolean.FALSE); 357 } 358 else { 359 paymentGroup.setProcessImmediate(Boolean.TRUE); 360 } 361 362 changeStatus(paymentGroup, paymentGroup.getPaymentStatus().getCode(), PdpConstants.PaymentChangeCodes.CHANGE_IMMEDIATE_CHNG_CD, note, user, paymentGroupHistory); 363 364 LOG.debug("changeImmediateFlag() exit method."); 365 } 366 367 /** 368 * @see org.kuali.kfs.pdp.document.service.PaymentMaintenanceService#cancelDisbursement(java.lang.Integer, java.lang.Integer, 369 * java.lang.String, org.kuali.rice.kim.bo.Person) 370 */ 371 public boolean cancelDisbursement(Integer paymentGroupId, Integer paymentDetailId, String note, Person user) { 372 // All actions must be performed on entire group not individual detail record 373 if (LOG.isDebugEnabled()) { 374 LOG.debug("cancelDisbursement() Enter method to cancel disbursement with id = " + paymentGroupId); 375 } 376 377 if (!pdpAuthorizationService.hasCancelPaymentPermission(user.getPrincipalId())) { 378 LOG.warn("cancelDisbursement() User " + user.getPrincipalId() + " does not have rights to cancel payments. This should not happen unless user is URL spoofing."); 379 throw new RuntimeException("cancelDisbursement() User " + user.getPrincipalId() + " does not have rights to cancel payments. This should not happen unless user is URL spoofing."); 380 } 381 382 PaymentGroup paymentGroup = this.paymentGroupService.get(paymentGroupId); 383 384 if (paymentGroup == null) { 385 LOG.debug("cancelDisbursement() Disbursement not found; throw exception."); 386 GlobalVariables.getMessageMap().putError(KFSConstants.GLOBAL_ERRORS, PdpKeyConstants.PaymentDetail.ErrorMessages.ERROR_DISBURSEMENT_NOT_FOUND); 387 return false; 388 } 389 390 String paymentStatus = paymentGroup.getPaymentStatus().getCode(); 391 392 if (!(PdpConstants.PaymentStatusCodes.CANCEL_DISBURSEMENT.equals(paymentStatus))) { 393 if (((PdpConstants.PaymentStatusCodes.EXTRACTED.equals(paymentStatus)) && (ObjectUtils.isNotNull(paymentGroup.getDisbursementDate()))) || (PdpConstants.PaymentStatusCodes.PENDING_ACH.equals(paymentStatus))) { 394 if (LOG.isDebugEnabled()) { 395 LOG.debug("cancelDisbursement() Payment status is " + paymentStatus + "; continue with cancel."); 396 } 397 398 List<PaymentGroup> allDisbursementPaymentGroups = this.paymentGroupService.getByDisbursementNumber(paymentGroup.getDisbursementNbr().intValue()); 399 400 for (PaymentGroup element : allDisbursementPaymentGroups) { 401 PaymentGroupHistory pgh = new PaymentGroupHistory(); 402 403 if (!element.getPaymentDetails().get(0).isDisbursementActionAllowed()) { 404 LOG.warn("cancelDisbursement() Payment does not allow disbursement action. This should not happen unless user is URL spoofing."); 405 throw new RuntimeException("cancelDisbursement() Payment does not allow disbursement action. This should not happen unless user is URL spoofing."); 406 } 407 408 if ((ObjectUtils.isNotNull(element.getDisbursementType())) && (element.getDisbursementType().getCode().equals(PdpConstants.DisbursementTypeCodes.CHECK))) { 409 pgh.setPmtCancelExtractStat(Boolean.FALSE); 410 } 411 412 changeStatus(element, PdpConstants.PaymentStatusCodes.CANCEL_DISBURSEMENT, PdpConstants.PaymentChangeCodes.CANCEL_DISBURSEMENT, note, user, pgh); 413 414 glPendingTransactionService.generateCancellationGeneralLedgerPendingEntry(element); 415 } 416 417 // set primary cancel indicator for EPIC to use 418 Map primaryKeys = new HashMap(); 419 primaryKeys.put(PdpPropertyConstants.PaymentDetail.PAYMENT_ID, paymentDetailId); 420 421 PaymentDetail pd = (PaymentDetail) this.businessObjectService.findByPrimaryKey(PaymentDetail.class, primaryKeys); 422 if (pd != null) { 423 pd.setPrimaryCancelledPayment(Boolean.TRUE); 424 } 425 426 this.businessObjectService.save(pd); 427 428 LOG.debug("cancelDisbursement() Disbursement cancelled; exit method."); 429 } 430 else { 431 if (LOG.isDebugEnabled()) { 432 LOG.debug("cancelDisbursement() Payment status is " + paymentStatus + " and disbursement date is " + paymentGroup.getDisbursementDate() + "; cannot cancel payment in this status"); 433 } 434 435 GlobalVariables.getMessageMap().putError(KFSConstants.GLOBAL_ERRORS, PdpKeyConstants.PaymentDetail.ErrorMessages.ERROR_DISBURSEMENT_INVALID_TO_CANCEL); 436 return false; 437 } 438 } 439 else { 440 LOG.debug("cancelDisbursement() Disbursement has already been cancelled; exit method."); 441 } 442 return true; 443 } 444 445 /** 446 * @see org.kuali.kfs.pdp.document.service.PaymentMaintenanceService#cancelReissueDisbursement(java.lang.Integer, 447 * java.lang.String, org.kuali.rice.kim.bo.Person) 448 */ 449 public boolean cancelReissueDisbursement(Integer paymentGroupId, String note, Person user) { 450 // All actions must be performed on entire group not individual detail record 451 if (LOG.isDebugEnabled()) { 452 LOG.debug("cancelReissueDisbursement() Enter method to cancel disbursement with id = " + paymentGroupId); 453 } 454 455 if (!pdpAuthorizationService.hasCancelPaymentPermission(user.getPrincipalId())) { 456 LOG.warn("cancelReissueDisbursement() User " + user.getPrincipalId() + " does not have rights to cancel payments. This should not happen unless user is URL spoofing."); 457 throw new RuntimeException("cancelReissueDisbursement() User " + user.getPrincipalId() + " does not have rights to cancel payments. This should not happen unless user is URL spoofing."); 458 } 459 460 PaymentGroup paymentGroup = this.paymentGroupService.get(paymentGroupId); 461 if (paymentGroup == null) { 462 LOG.debug("cancelReissueDisbursement() Disbursement not found; throw exception."); 463 GlobalVariables.getMessageMap().putError(KFSConstants.GLOBAL_ERRORS, PdpKeyConstants.PaymentDetail.ErrorMessages.ERROR_DISBURSEMENT_NOT_FOUND); 464 return false; 465 } 466 467 String paymentStatus = paymentGroup.getPaymentStatus().getCode(); 468 469 if (!(PdpConstants.PaymentStatusCodes.OPEN.equals(paymentStatus))) { 470 if (((PdpConstants.PaymentStatusCodes.EXTRACTED.equals(paymentStatus)) && (ObjectUtils.isNotNull(paymentGroup.getDisbursementDate()))) || (PdpConstants.PaymentStatusCodes.PENDING_ACH.equals(paymentStatus))) { 471 if (LOG.isDebugEnabled()) { 472 LOG.debug("cancelReissueDisbursement() Payment status is " + paymentStatus + "; continue with cancel."); 473 } 474 475 List<PaymentGroup> allDisbursementPaymentGroups = this.paymentGroupService.getByDisbursementNumber(paymentGroup.getDisbursementNbr().intValue()); 476 477 for (PaymentGroup pg : allDisbursementPaymentGroups) { 478 PaymentGroupHistory pgh = new PaymentGroupHistory(); 479 480 if (!pg.getPaymentDetails().get(0).isDisbursementActionAllowed()) { 481 LOG.warn("cancelDisbursement() Payment does not allow disbursement action. This should not happen unless user is URL spoofing."); 482 throw new RuntimeException("cancelDisbursement() Payment does not allow disbursement action. This should not happen unless user is URL spoofing."); 483 } 484 485 if ((ObjectUtils.isNotNull(pg.getDisbursementType())) && (pg.getDisbursementType().getCode().equals(PdpConstants.DisbursementTypeCodes.CHECK))) { 486 pgh.setPmtCancelExtractStat(Boolean.FALSE); 487 } 488 489 pgh.setOrigProcessImmediate(pg.getProcessImmediate()); 490 pgh.setOrigPmtSpecHandling(pg.getPymtSpecialHandling()); 491 pgh.setBank(pg.getBank()); 492 pgh.setOrigPaymentDate(pg.getPaymentDate()); 493 //put a check for null since disbursement date was not set in testMode / dev 494 if (ObjectUtils.isNotNull(pg.getDisbursementDate())) { 495 pgh.setOrigDisburseDate(new Timestamp(pg.getDisbursementDate().getTime())); 496 } 497 pgh.setOrigAchBankRouteNbr(pg.getAchBankRoutingNbr()); 498 pgh.setOrigDisburseNbr(pg.getDisbursementNbr()); 499 pgh.setOrigAdviceEmail(pg.getAdviceEmailAddress()); 500 pgh.setDisbursementType(pg.getDisbursementType()); 501 pgh.setProcess(pg.getProcess()); 502 503 glPendingTransactionService.generateReissueGeneralLedgerPendingEntry(pg); 504 505 if (LOG.isDebugEnabled()) { 506 LOG.debug("cancelReissueDisbursement() Status is '" + paymentStatus + "; delete row from AchAccountNumber table."); 507 } 508 509 AchAccountNumber achAccountNumber = pg.getAchAccountNumber(); 510 511 if (ObjectUtils.isNotNull(achAccountNumber)) { 512 this.businessObjectService.delete(achAccountNumber); 513 pg.setAchAccountNumber(null); 514 } 515 516 // if bank functionality is not enabled or the group bank is inactive clear bank code 517 if (!bankService.isBankSpecificationEnabled() || !pg.getBank().isActive()) { 518 pg.setBank(null); 519 } 520 521 pg.setDisbursementDate((java.sql.Date) null); 522 pg.setAchBankRoutingNbr(null); 523 pg.setAchAccountType(null); 524 pg.setPhysCampusProcessCd(null); 525 pg.setDisbursementNbr((KualiInteger) null); 526 pg.setAdviceEmailAddress(null); 527 pg.setDisbursementType(null); 528 pg.setProcess(null); 529 pg.setProcessImmediate(false); 530 531 changeStatus(pg, PdpConstants.PaymentStatusCodes.OPEN, PdpConstants.PaymentChangeCodes.CANCEL_REISSUE_DISBURSEMENT, note, user, pgh); 532 } 533 534 LOG.debug("cancelReissueDisbursement() Disbursement cancelled and reissued; exit method."); 535 } 536 else { 537 if (LOG.isDebugEnabled()) { 538 LOG.debug("cancelReissueDisbursement() Payment status is " + paymentStatus + " and disbursement date is " + paymentGroup.getDisbursementDate() + "; cannot cancel payment"); 539 } 540 541 GlobalVariables.getMessageMap().putError(KFSConstants.GLOBAL_ERRORS, PdpKeyConstants.PaymentDetail.ErrorMessages.ERROR_DISBURSEMENT_INVALID_TO_CANCEL_AND_REISSUE); 542 return false; 543 } 544 } 545 else { 546 LOG.debug("cancelReissueDisbursement() Disbursement already cancelled and reissued; exit method."); 547 } 548 return true; 549 } 550 551 /** 552 * inject 553 * 554 * @param dao 555 */ 556 public void setPaymentGroupDao(PaymentGroupDao dao) { 557 paymentGroupDao = dao; 558 } 559 560 /** 561 * inject 562 * 563 * @param dao 564 */ 565 public void setPaymentDetailDao(PaymentDetailDao dao) { 566 paymentDetailDao = dao; 567 } 568 569 /** 570 * inject 571 * 572 * @param service 573 */ 574 public void setGlPendingTransactionService(PendingTransactionService service) { 575 glPendingTransactionService = service; 576 } 577 578 /** 579 * inject 580 * 581 * @param service 582 */ 583 public void setEnvironmentService(EnvironmentService environmentService) { 584 this.environmentService = environmentService; 585 } 586 587 /** 588 * inject 589 * 590 * @param service 591 */ 592 public void setMailService(MailService mailService) { 593 this.mailService = mailService; 594 } 595 596 public void setParameterService(ParameterService parameterService) { 597 this.parameterService = parameterService; 598 } 599 600 /** 601 * Sets the bankService attribute value. 602 * 603 * @param bankService The bankService to set. 604 */ 605 public void setBankService(BankService bankService) { 606 this.bankService = bankService; 607 } 608 609 /** 610 * Sets the business object service 611 * 612 * @param businessObjectService 613 */ 614 public void setBusinessObjectService(BusinessObjectService businessObjectService) { 615 this.businessObjectService = businessObjectService; 616 } 617 618 /** 619 * Sets the payment group service 620 * 621 * @param paymentGroupService 622 */ 623 public void setPaymentGroupService(PaymentGroupService paymentGroupService) { 624 this.paymentGroupService = paymentGroupService; 625 } 626 627 public void setEmailService(PdpEmailService emailService) { 628 this.emailService = emailService; 629 } 630 631 public void setPdpAuthorizationService(PdpAuthorizationService pdpAuthorizationService) { 632 this.pdpAuthorizationService = pdpAuthorizationService; 633 } 634 }