001/* 002 * Copyright 2007 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 */ 019package org.kuali.ole.pdp.service.impl; 020 021import java.sql.Timestamp; 022import java.util.Date; 023import java.util.HashMap; 024import java.util.List; 025import java.util.Map; 026 027import org.kuali.ole.pdp.PdpConstants; 028import org.kuali.ole.pdp.PdpKeyConstants; 029import org.kuali.ole.pdp.PdpPropertyConstants; 030import org.kuali.ole.pdp.businessobject.AchAccountNumber; 031import org.kuali.ole.pdp.businessobject.PaymentChangeCode; 032import org.kuali.ole.pdp.businessobject.PaymentDetail; 033import org.kuali.ole.pdp.businessobject.PaymentGroup; 034import org.kuali.ole.pdp.businessobject.PaymentGroupHistory; 035import org.kuali.ole.pdp.businessobject.PaymentNoteText; 036import org.kuali.ole.pdp.businessobject.PaymentStatus; 037import org.kuali.ole.pdp.dataaccess.PaymentDetailDao; 038import org.kuali.ole.pdp.dataaccess.PaymentGroupDao; 039import org.kuali.ole.pdp.service.PaymentGroupService; 040import org.kuali.ole.pdp.service.PaymentMaintenanceService; 041import org.kuali.ole.pdp.service.PdpAuthorizationService; 042import org.kuali.ole.pdp.service.PdpEmailService; 043import org.kuali.ole.pdp.service.PendingTransactionService; 044import org.kuali.ole.sys.OLEConstants; 045import org.kuali.ole.sys.service.BankService; 046import org.kuali.rice.core.api.util.type.KualiInteger; 047import org.kuali.rice.coreservice.framework.parameter.ParameterService; 048import org.kuali.rice.kim.api.identity.Person; 049import org.kuali.rice.krad.bo.KualiCode; 050import org.kuali.rice.krad.service.BusinessObjectService; 051import org.kuali.rice.krad.service.MailService; 052import org.kuali.rice.krad.util.GlobalVariables; 053import org.kuali.rice.krad.util.ObjectUtils; 054import org.springframework.transaction.annotation.Transactional; 055 056/** 057 * @see org.kuali.ole.pdp.service.PaymentMaintenanceService 058 */ 059@Transactional 060public class PaymentMaintenanceServiceImpl implements PaymentMaintenanceService { 061 private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(PaymentMaintenanceServiceImpl.class); 062 063 private PaymentGroupDao paymentGroupDao; 064 private PaymentDetailDao paymentDetailDao; 065 private PendingTransactionService glPendingTransactionService; 066 private MailService mailService; 067 private ParameterService parameterService; 068 private BankService bankService; 069 private BusinessObjectService businessObjectService; 070 private PaymentGroupService paymentGroupService; 071 private PdpEmailService emailService; 072 private PdpAuthorizationService pdpAuthorizationService; 073 074 /** 075 * This method changes status for a payment group. 076 * 077 * @param paymentGroup the payment group 078 * @param newPaymentStatus the new payment status 079 * @param changeStatus the changed payment status 080 * @param note a note for payment status change 081 * @param user the user that changed the status 082 */ 083 protected void changeStatus(PaymentGroup paymentGroup, String newPaymentStatus, String changeStatus, String note, Person user) { 084 if (LOG.isDebugEnabled()) { 085 LOG.debug("changeStatus() enter method with new status of " + newPaymentStatus); 086 } 087 088 PaymentGroupHistory paymentGroupHistory = new PaymentGroupHistory(); 089 KualiCode cd = businessObjectService.findBySinglePrimaryKey(PaymentChangeCode.class, changeStatus); 090 paymentGroupHistory.setPaymentChange((PaymentChangeCode) cd); 091 paymentGroupHistory.setOrigPaymentStatus(paymentGroup.getPaymentStatus()); 092 paymentGroupHistory.setChangeUser(user); 093 paymentGroupHistory.setChangeNoteText(note); 094 paymentGroupHistory.setPaymentGroup(paymentGroup); 095 paymentGroupHistory.setChangeTime(new Timestamp(new Date().getTime())); 096 097 this.businessObjectService.save(paymentGroupHistory); 098 099 KualiCode code = businessObjectService.findBySinglePrimaryKey(PaymentStatus.class, newPaymentStatus); 100 paymentGroup.setPaymentStatus((PaymentStatus) code); 101 this.businessObjectService.save(paymentGroup); 102 LOG.debug("changeStatus() Status has been changed; exit method."); 103 } 104 105 /** 106 * This method changes the state of a paymentGroup. 107 * 108 * @param paymentGroup the payment group to change the state for 109 * @param newPaymentStatus the new payment status 110 * @param changeStatus the status that is changed 111 * @param note the note entered by the user 112 * @param user the user that changed the 113 * @param paymentGroupHistory 114 */ 115 protected void changeStatus(PaymentGroup paymentGroup, String newPaymentStatus, String changeStatus, String note, Person user, PaymentGroupHistory paymentGroupHistory) { 116 if (LOG.isDebugEnabled()) { 117 LOG.debug("changeStatus() enter method with new status of " + newPaymentStatus); 118 } 119 120 KualiCode cd = businessObjectService.findBySinglePrimaryKey(PaymentChangeCode.class, changeStatus); 121 paymentGroupHistory.setPaymentChange((PaymentChangeCode) cd); 122 paymentGroupHistory.setOrigPaymentStatus(paymentGroup.getPaymentStatus()); 123 paymentGroupHistory.setChangeUser(user); 124 paymentGroupHistory.setChangeNoteText(note); 125 paymentGroupHistory.setPaymentGroup(paymentGroup); 126 paymentGroupHistory.setChangeTime(new Timestamp(new Date().getTime())); 127 128 this.businessObjectService.save(paymentGroupHistory); 129 130 KualiCode code = businessObjectService.findBySinglePrimaryKey(PaymentStatus.class, newPaymentStatus); 131 if (paymentGroup.getPaymentStatus() != ((PaymentStatus) code)) { 132 paymentGroup.setPaymentStatus((PaymentStatus) code); 133 } 134 this.businessObjectService.save(paymentGroup); 135 136 LOG.debug("changeStatus() Status has been changed; exit method."); 137 } 138 139 /** 140 * @see org.kuali.ole.pdp.document.service.PaymentMaintenanceService#cancelPendingPayment(java.lang.Integer, java.lang.Integer, 141 * java.lang.String, org.kuali.rice.kim.api.identity.Person) 142 */ 143 @Override 144 public boolean cancelPendingPayment(Integer paymentGroupId, Integer paymentDetailId, String note, Person user) { 145 // All actions must be performed on entire group not individual detail record 146 if (LOG.isDebugEnabled()) { 147 LOG.debug("cancelPendingPayment() Enter method to cancel pending payment with group id = " + paymentGroupId); 148 LOG.debug("cancelPendingPayment() payment detail id being cancelled = " + paymentDetailId); 149 } 150 151 PaymentGroup paymentGroup = this.paymentGroupService.get(paymentGroupId); 152 if (paymentGroup == null) { 153 LOG.debug("cancelPendingPayment() Pending payment not found; throw exception."); 154 GlobalVariables.getMessageMap().putError(OLEConstants.GLOBAL_ERRORS, PdpKeyConstants.PaymentDetail.ErrorMessages.ERROR_PAYMENT_NOT_FOUND); 155 return false; 156 } 157 158 String paymentStatus = paymentGroup.getPaymentStatus().getCode(); 159 160 if (!(PdpConstants.PaymentStatusCodes.CANCEL_PAYMENT.equals(paymentStatus))) { 161 if (LOG.isDebugEnabled()) { 162 LOG.debug("cancelPendingPayment() Payment status is " + paymentStatus + "; continue with cancel."); 163 } 164 165 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))) { 166 if (!pdpAuthorizationService.hasRemovePaymentTaxHoldPermission(user.getPrincipalId())) { 167 LOG.warn("cancelPendingPayment() Payment status is " + paymentStatus + "; user does not have rights to cancel. This should not happen unless user is URL spoofing."); 168 throw new RuntimeException("cancelPendingPayment() Payment status is " + paymentStatus + "; user does not have rights to cancel. This should not happen unless user is URL spoofing."); 169 } 170 171 changeStatus(paymentGroup, PdpConstants.PaymentStatusCodes.CANCEL_PAYMENT, PdpConstants.PaymentChangeCodes.CANCEL_PAYMENT_CHNG_CD, note, user); 172 173 // set primary cancel indicator for EPIC to use 174 Map primaryKeys = new HashMap(); 175 primaryKeys.put(PdpPropertyConstants.PaymentDetail.PAYMENT_ID, paymentDetailId); 176 177 PaymentDetail pd = (PaymentDetail) this.businessObjectService.findByPrimaryKey(PaymentDetail.class, primaryKeys); 178 if (pd != null) { 179 pd.setPrimaryCancelledPayment(Boolean.TRUE); 180 } 181 this.businessObjectService.save(pd); 182 this.emailService.sendCancelEmail(paymentGroup, note, user); 183 184 LOG.debug("cancelPendingPayment() Pending payment cancelled and mail was sent; exit method."); 185 } 186 else if (PdpConstants.PaymentStatusCodes.OPEN.equals(paymentStatus) || PdpConstants.PaymentStatusCodes.HELD_CD.equals(paymentStatus)) { 187 if (!pdpAuthorizationService.hasCancelPaymentPermission(user.getPrincipalId())) { 188 LOG.warn("cancelPendingPayment() Payment status is " + paymentStatus + "; user does not have rights to cancel. This should not happen unless user is URL spoofing."); 189 throw new RuntimeException("cancelPendingPayment() Payment status is " + paymentStatus + "; user does not have rights to cancel. This should not happen unless user is URL spoofing."); 190 } 191 192 changeStatus(paymentGroup, PdpConstants.PaymentStatusCodes.CANCEL_PAYMENT, PdpConstants.PaymentChangeCodes.CANCEL_PAYMENT_CHNG_CD, note, user); 193 194 // set primary cancel indicator for EPIC to use 195 Map primaryKeys = new HashMap(); 196 primaryKeys.put(PdpPropertyConstants.PaymentDetail.PAYMENT_ID, paymentDetailId); 197 198 PaymentDetail pd = (PaymentDetail) this.businessObjectService.findByPrimaryKey(PaymentDetail.class, primaryKeys); 199 if (pd != null) { 200 pd.setPrimaryCancelledPayment(Boolean.TRUE); 201 PaymentNoteText payNoteText = new PaymentNoteText(); 202 payNoteText.setCustomerNoteLineNbr(new KualiInteger(pd.getNotes().size() + 1)); 203 payNoteText.setCustomerNoteText(note); 204 pd.addNote(payNoteText); 205 } 206 207 this.businessObjectService.save(pd); 208 209 LOG.debug("cancelPendingPayment() Pending payment cancelled; exit method."); 210 } 211 else { 212 if (LOG.isDebugEnabled()) { 213 LOG.debug("cancelPendingPayment() Payment status is " + paymentStatus + "; cannot cancel payment in this status"); 214 } 215 216 GlobalVariables.getMessageMap().putError(OLEConstants.GLOBAL_ERRORS, PdpKeyConstants.PaymentDetail.ErrorMessages.ERROR_PAYMENT_INVALID_STATUS_TO_CANCEL); 217 return false; 218 } 219 } 220 else { 221 LOG.debug("cancelPendingPayment() Pending payment group has already been cancelled; exit method."); 222 } 223 return true; 224 } 225 226 /** 227 * @see org.kuali.ole.pdp.document.service.PaymentMaintenanceService#holdPendingPayment(java.lang.Integer, java.lang.String, 228 * org.kuali.rice.kim.api.identity.Person) 229 */ 230 @Override 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(OLEConstants.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(OLEConstants.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.ole.pdp.document.service.PaymentMaintenanceService#removeHoldPendingPayment(java.lang.Integer, 279 * java.lang.String, org.kuali.rice.kim.api.identity.Person) 280 */ 281 @Override 282 public boolean removeHoldPendingPayment(Integer paymentGroupId, String note, Person user) { 283 // All actions must be performed on entire group not individual detail record 284 if (LOG.isDebugEnabled()) { 285 LOG.debug("removeHoldPendingPayment() Enter method to hold pending payment with id = " + paymentGroupId); 286 } 287 PaymentGroup paymentGroup = this.paymentGroupService.get(paymentGroupId); 288 if (paymentGroup == null) { 289 LOG.debug("removeHoldPendingPayment() Payment not found; throw exception."); 290 291 GlobalVariables.getMessageMap().putError(OLEConstants.GLOBAL_ERRORS, PdpKeyConstants.PaymentDetail.ErrorMessages.ERROR_PAYMENT_NOT_FOUND); 292 return false; 293 } 294 295 String paymentStatus = paymentGroup.getPaymentStatus().getCode(); 296 297 if (!(PdpConstants.PaymentStatusCodes.OPEN.equals(paymentStatus))) { 298 if (LOG.isDebugEnabled()) { 299 LOG.debug("removeHoldPendingPayment() Payment status is " + paymentStatus + "; continue with hold removal."); 300 } 301 302 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))) { 303 if (!pdpAuthorizationService.hasRemovePaymentTaxHoldPermission(user.getPrincipalId())) { 304 LOG.warn("removeHoldPendingPayment() User " + user.getPrincipalId() + " does not have rights to remove tax holds. This should not happen unless user is URL spoofing."); 305 throw new RuntimeException("removeHoldPendingPayment() User " + user.getPrincipalId() + " does not have rights to remove tax holds. This should not happen unless user is URL spoofing."); 306 } 307 308 changeStatus(paymentGroup, PdpConstants.PaymentStatusCodes.OPEN, PdpConstants.PaymentChangeCodes.REMOVE_HOLD_CHNG_CD, note, user); 309 LOG.debug("removeHoldPendingPayment() Pending payment was taken off hold; exit method."); 310 } 311 else if (PdpConstants.PaymentStatusCodes.HELD_CD.equals(paymentStatus)) { 312 if (!pdpAuthorizationService.hasHoldPaymentPermission(user.getPrincipalId())) { 313 LOG.warn("removeHoldPendingPayment() User " + user.getPrincipalId() + " does not have rights to hold payments. This should not happen unless user is URL spoofing."); 314 throw new RuntimeException("removeHoldPendingPayment() User " + user.getPrincipalId() + " does not have rights to hold payments. This should not happen unless user is URL spoofing."); 315 } 316 317 changeStatus(paymentGroup, PdpConstants.PaymentStatusCodes.OPEN, PdpConstants.PaymentChangeCodes.REMOVE_HOLD_CHNG_CD, note, user); 318 319 LOG.debug("removeHoldPendingPayment() Pending payment was taken off hold; exit method."); 320 } 321 else { 322 if (LOG.isDebugEnabled()) { 323 LOG.debug("removeHoldPendingPayment() Payment status is " + paymentStatus + "; cannot remove hold on payment in this status"); 324 } 325 326 GlobalVariables.getMessageMap().putError(OLEConstants.GLOBAL_ERRORS, PdpKeyConstants.PaymentDetail.ErrorMessages.ERROR_PAYMENT_INVALID_STATUS_TO_REMOVE_HOLD); 327 return false; 328 } 329 } 330 else { 331 LOG.debug("removeHoldPendingPayment() Pending payment group has already been un-held; exit method."); 332 } 333 return true; 334 } 335 336 /** 337 * @see org.kuali.ole.pdp.document.service.PaymentMaintenanceService#changeImmediateFlag(java.lang.Integer, java.lang.String, 338 * org.kuali.rice.kim.api.identity.Person) 339 */ 340 @Override 341 public void changeImmediateFlag(Integer paymentGroupId, String note, Person user) { 342 // All actions must be performed on entire group not individual detail record 343 if (LOG.isDebugEnabled()) { 344 LOG.debug("changeImmediateFlag() Enter method to hold pending payment with id = " + paymentGroupId); 345 } 346 347 if (!pdpAuthorizationService.hasSetAsImmediatePayPermission(user.getPrincipalId())) { 348 LOG.warn("changeImmediateFlag() User " + user.getPrincipalId() + " does not have rights to set payments as immediate. This should not happen unless user is URL spoofing."); 349 throw new RuntimeException("changeImmediateFlag() User " + user.getPrincipalId() + " does not have rights to payments as immediate. This should not happen unless user is URL spoofing."); 350 } 351 352 PaymentGroupHistory paymentGroupHistory = new PaymentGroupHistory(); 353 PaymentGroup paymentGroup = this.paymentGroupService.get(paymentGroupId); 354 355 paymentGroupHistory.setOrigProcessImmediate(paymentGroup.getProcessImmediate()); 356 357 if (paymentGroup.getProcessImmediate().equals(Boolean.TRUE)) { 358 paymentGroup.setProcessImmediate(Boolean.FALSE); 359 } 360 else { 361 paymentGroup.setProcessImmediate(Boolean.TRUE); 362 } 363 364 changeStatus(paymentGroup, paymentGroup.getPaymentStatus().getCode(), PdpConstants.PaymentChangeCodes.CHANGE_IMMEDIATE_CHNG_CD, note, user, paymentGroupHistory); 365 366 LOG.debug("changeImmediateFlag() exit method."); 367 } 368 369 /** 370 * @see org.kuali.ole.pdp.document.service.PaymentMaintenanceService#cancelDisbursement(java.lang.Integer, java.lang.Integer, 371 * java.lang.String, org.kuali.rice.kim.api.identity.Person) 372 */ 373 @Override 374 public boolean cancelDisbursement(Integer paymentGroupId, Integer paymentDetailId, String note, Person user) { 375 // All actions must be performed on entire group not individual detail record 376 if (LOG.isDebugEnabled()) { 377 LOG.debug("cancelDisbursement() Enter method to cancel disbursement with id = " + paymentGroupId); 378 } 379 380 if (!pdpAuthorizationService.hasCancelPaymentPermission(user.getPrincipalId())) { 381 LOG.warn("cancelDisbursement() User " + user.getPrincipalId() + " does not have rights to cancel payments. This should not happen unless user is URL spoofing."); 382 throw new RuntimeException("cancelDisbursement() User " + user.getPrincipalId() + " does not have rights to cancel payments. This should not happen unless user is URL spoofing."); 383 } 384 385 PaymentGroup paymentGroup = this.paymentGroupService.get(paymentGroupId); 386 387 if (paymentGroup == null) { 388 LOG.debug("cancelDisbursement() Disbursement not found; throw exception."); 389 GlobalVariables.getMessageMap().putError(OLEConstants.GLOBAL_ERRORS, PdpKeyConstants.PaymentDetail.ErrorMessages.ERROR_DISBURSEMENT_NOT_FOUND); 390 return false; 391 } 392 393 // get the target PaymentGroup info 394 PaymentDetail targetPd = getPaymentDetail(paymentDetailId); 395 KualiInteger targetGroupId = targetPd.getPaymentGroupId(); 396 PaymentGroup targetPg = getPaymentGroup(targetGroupId); 397 String targetDvTypeCode = targetPg.getDisbursementTypeCode(); 398 String targetDvBankCode = targetPg.getBankCode(); 399 400 String paymentStatus = paymentGroup.getPaymentStatus().getCode(); 401 402 if (!(PdpConstants.PaymentStatusCodes.CANCEL_DISBURSEMENT.equals(paymentStatus))) { 403 if (((PdpConstants.PaymentStatusCodes.EXTRACTED.equals(paymentStatus)) && (ObjectUtils.isNotNull(paymentGroup.getDisbursementDate()))) || (PdpConstants.PaymentStatusCodes.PENDING_ACH.equals(paymentStatus))) { 404 if (LOG.isDebugEnabled()) { 405 LOG.debug("cancelDisbursement() Payment status is " + paymentStatus + "; continue with cancel."); 406 } 407 408 List<PaymentGroup> allDisbursementPaymentGroups = this.paymentGroupService.getByDisbursementNumber(paymentGroup.getDisbursementNbr().intValue()); 409 410 for (PaymentGroup element : allDisbursementPaymentGroups) { 411 412 // should be the same DV type and the same bank 413 if (!(element.getDisbursementTypeCode().equalsIgnoreCase(targetDvTypeCode) && element.getBankCode().equalsIgnoreCase(targetDvBankCode))) { 414 continue; 415 } 416 417 PaymentGroupHistory pgh = new PaymentGroupHistory(); 418 419 if (!element.getPaymentDetails().get(0).isDisbursementActionAllowed()) { 420 LOG.warn("cancelDisbursement() Payment does not allow disbursement action. This should not happen unless user is URL spoofing."); 421 throw new RuntimeException("cancelDisbursement() Payment does not allow disbursement action. This should not happen unless user is URL spoofing."); 422 } 423 424 if ((ObjectUtils.isNotNull(element.getDisbursementType())) && (element.getDisbursementType().getCode().equals(PdpConstants.DisbursementTypeCodes.CHECK))) { 425 pgh.setPmtCancelExtractStat(Boolean.FALSE); 426 } 427 428 changeStatus(element, PdpConstants.PaymentStatusCodes.CANCEL_DISBURSEMENT, PdpConstants.PaymentChangeCodes.CANCEL_DISBURSEMENT, note, user, pgh); 429 430 glPendingTransactionService.generateCancellationGeneralLedgerPendingEntry(element); 431 432 // set primary cancel indicator for EPIC to use 433 // these payment details will be canceled when running processPdpCancelAndPaidJOb 434 Map<String, KualiInteger> primaryKeys = new HashMap<String, KualiInteger>(); 435 primaryKeys.put(PdpPropertyConstants.PaymentDetail.PAYMENT_DETAIL_PAYMENT_GROUP_ID, element.getId()); 436 437 PaymentDetail pd = this.businessObjectService.findByPrimaryKey(PaymentDetail.class, primaryKeys); 438 if (pd != null) { 439 pd.setPrimaryCancelledPayment(Boolean.TRUE); 440 } 441 442 this.businessObjectService.save(pd); 443 } 444 445 LOG.debug("cancelDisbursement() Disbursement cancelled; exit method."); 446 } 447 else { 448 if (LOG.isDebugEnabled()) { 449 LOG.debug("cancelDisbursement() Payment status is " + paymentStatus + " and disbursement date is " + paymentGroup.getDisbursementDate() + "; cannot cancel payment in this status"); 450 } 451 452 GlobalVariables.getMessageMap().putError(OLEConstants.GLOBAL_ERRORS, PdpKeyConstants.PaymentDetail.ErrorMessages.ERROR_DISBURSEMENT_INVALID_TO_CANCEL); 453 return false; 454 } 455 } 456 else { 457 LOG.debug("cancelDisbursement() Disbursement has already been cancelled; exit method."); 458 } 459 return true; 460 } 461 462 /** 463 * @see org.kuali.ole.pdp.document.service.PaymentMaintenanceService#reissueDisbursement(java.lang.Integer, 464 * java.lang.String, org.kuali.rice.kim.api.identity.Person) 465 */ 466 @Override 467 public boolean reissueDisbursement(Integer paymentGroupId, String note, Person user) { 468 // All actions must be performed on entire group not individual detail record 469 if (LOG.isDebugEnabled()) { 470 LOG.debug("reissueDisbursement() Enter method to reissue disbursement with id = " + paymentGroupId); 471 } 472 473 474 PaymentGroup paymentGroup = this.paymentGroupService.get(paymentGroupId); 475 if (paymentGroup == null) { 476 LOG.debug("reissueDisbursement() Disbursement not found; throw exception."); 477 GlobalVariables.getMessageMap().putError(OLEConstants.GLOBAL_ERRORS, PdpKeyConstants.PaymentDetail.ErrorMessages.ERROR_DISBURSEMENT_NOT_FOUND); 478 return false; 479 } 480 481 String paymentStatus = paymentGroup.getPaymentStatus().getCode(); 482 483 if (!(PdpConstants.PaymentStatusCodes.OPEN.equals(paymentStatus))) { 484 if (((PdpConstants.PaymentStatusCodes.CANCEL_DISBURSEMENT.equals(paymentStatus)) && (ObjectUtils.isNotNull(paymentGroup.getDisbursementDate())))) { 485 if (LOG.isDebugEnabled()) { 486 LOG.debug("reissueDisbursement() Payment status is " + paymentStatus + "; continue with reissue."); 487 } 488 489 List<PaymentGroup> allDisbursementPaymentGroups = this.paymentGroupService.getByDisbursementNumber(paymentGroup.getDisbursementNbr().intValue()); 490 491 for (PaymentGroup pg : allDisbursementPaymentGroups) { 492 PaymentGroupHistory pgh = new PaymentGroupHistory(); 493 494 if (!pg.getPaymentDetails().get(0).isDisbursementActionAllowed()) { 495 LOG.warn("cancelDisbursement() Payment does not allow disbursement action. This should not happen unless user is URL spoofing."); 496 throw new RuntimeException("cancelDisbursement() Payment does not allow disbursement action. This should not happen unless user is URL spoofing."); 497 } 498 499 500 pgh.setOrigProcessImmediate(pg.getProcessImmediate()); 501 pgh.setOrigPmtSpecHandling(pg.getPymtSpecialHandling()); 502 pgh.setBank(pg.getBank()); 503 pgh.setOrigPaymentDate(pg.getPaymentDate()); 504 //put a check for null since disbursement date was not set in testMode / dev 505 if (ObjectUtils.isNotNull(pg.getDisbursementDate())) { 506 pgh.setOrigDisburseDate(new Timestamp(pg.getDisbursementDate().getTime())); 507 } 508 pgh.setOrigAchBankRouteNbr(pg.getAchBankRoutingNbr()); 509 pgh.setOrigDisburseNbr(pg.getDisbursementNbr()); 510 pgh.setOrigAdviceEmail(pg.getAdviceEmailAddress()); 511 pgh.setDisbursementType(pg.getDisbursementType()); 512 pgh.setProcess(pg.getProcess()); 513 514 // glPendingTransactionService.generateReissueGeneralLedgerPendingEntry(pg); 515 516 if (LOG.isDebugEnabled()) { 517 LOG.debug("cancelReissueDisbursement() Status is '" + paymentStatus + "; delete row from AchAccountNumber table."); 518 } 519 520 AchAccountNumber achAccountNumber = pg.getAchAccountNumber(); 521 522 if (ObjectUtils.isNotNull(achAccountNumber)) { 523 this.businessObjectService.delete(achAccountNumber); 524 pg.setAchAccountNumber(null); 525 } 526 527 // if bank functionality is not enabled or the group bank is inactive clear bank code 528 if (!bankService.isBankSpecificationEnabled() || !pg.getBank().isActive()) { 529 pg.setBank(null); 530 } 531 532 pg.setDisbursementDate((java.sql.Date) null); 533 pg.setAchBankRoutingNbr(null); 534 pg.setAchAccountType(null); 535 pg.setPhysCampusProcessCd(null); 536 pg.setDisbursementNbr((KualiInteger) null); 537 pg.setAdviceEmailAddress(null); 538 pg.setDisbursementType(null); 539 pg.setProcess(null); 540 pg.setProcessImmediate(false); 541 changeStatus(pg, PdpConstants.PaymentStatusCodes.OPEN, PdpConstants.PaymentChangeCodes.REISSUE_DISBURSEMENT, note, user, pgh); 542 } 543 544 LOG.debug("reissueDisbursement() Disbursement reissued; exit method."); 545 } 546 else { 547 if (LOG.isDebugEnabled()) { 548 LOG.debug("cancelReissueDisbursement() Payment status is " + paymentStatus + " and disbursement date is " + paymentGroup.getDisbursementDate() + "; cannot cancel payment"); 549 } 550 551 GlobalVariables.getMessageMap().putError(OLEConstants.GLOBAL_ERRORS, PdpKeyConstants.PaymentDetail.ErrorMessages.ERROR_DISBURSEMENT_INVALID_TO_CANCEL_AND_REISSUE); 552 return false; 553 } 554 } 555 else { 556 LOG.debug("cancelReissueDisbursement() Disbursement already cancelled and reissued; exit method."); 557 } 558 return true; 559 } 560 561 /** 562 * @see org.kuali.ole.pdp.document.service.PaymentMaintenanceService#cancelReissueDisbursement(java.lang.Integer, 563 * java.lang.String, org.kuali.rice.kim.api.identity.Person) 564 */ 565 @Override 566 public boolean cancelReissueDisbursement(Integer paymentGroupId, String note, Person user) { 567 // All actions must be performed on entire group not individual detail record 568 if (LOG.isDebugEnabled()) { 569 LOG.debug("cancelReissueDisbursement() Enter method to cancel disbursement with id = " + paymentGroupId); 570 } 571 572 if (!pdpAuthorizationService.hasCancelPaymentPermission(user.getPrincipalId())) { 573 LOG.warn("cancelReissueDisbursement() User " + user.getPrincipalId() + " does not have rights to cancel payments. This should not happen unless user is URL spoofing."); 574 throw new RuntimeException("cancelReissueDisbursement() User " + user.getPrincipalId() + " does not have rights to cancel payments. This should not happen unless user is URL spoofing."); 575 } 576 577 PaymentGroup paymentGroup = this.paymentGroupService.get(paymentGroupId); 578 if (paymentGroup == null) { 579 LOG.debug("cancelReissueDisbursement() Disbursement not found; throw exception."); 580 GlobalVariables.getMessageMap().putError(OLEConstants.GLOBAL_ERRORS, PdpKeyConstants.PaymentDetail.ErrorMessages.ERROR_DISBURSEMENT_NOT_FOUND); 581 return false; 582 } 583 584 String paymentStatus = paymentGroup.getPaymentStatus().getCode(); 585 586 if (!(PdpConstants.PaymentStatusCodes.OPEN.equals(paymentStatus))) { 587 if (((PdpConstants.PaymentStatusCodes.EXTRACTED.equals(paymentStatus)) && (ObjectUtils.isNotNull(paymentGroup.getDisbursementDate()))) || (PdpConstants.PaymentStatusCodes.PENDING_ACH.equals(paymentStatus))) { 588 if (LOG.isDebugEnabled()) { 589 LOG.debug("cancelReissueDisbursement() Payment status is " + paymentStatus + "; continue with cancel."); 590 } 591 592 List<PaymentGroup> allDisbursementPaymentGroups = this.paymentGroupService.getByDisbursementNumber(paymentGroup.getDisbursementNbr().intValue()); 593 594 for (PaymentGroup pg : allDisbursementPaymentGroups) { 595 PaymentGroupHistory pgh = new PaymentGroupHistory(); 596 597 if (!pg.getPaymentDetails().get(0).isDisbursementActionAllowed()) { 598 LOG.warn("cancelDisbursement() Payment does not allow disbursement action. This should not happen unless user is URL spoofing."); 599 throw new RuntimeException("cancelDisbursement() Payment does not allow disbursement action. This should not happen unless user is URL spoofing."); 600 } 601 602 if ((ObjectUtils.isNotNull(pg.getDisbursementType())) && (pg.getDisbursementType().getCode().equals(PdpConstants.DisbursementTypeCodes.CHECK))) { 603 pgh.setPmtCancelExtractStat(Boolean.FALSE); 604 } 605 606 pgh.setOrigProcessImmediate(pg.getProcessImmediate()); 607 pgh.setOrigPmtSpecHandling(pg.getPymtSpecialHandling()); 608 pgh.setBank(pg.getBank()); 609 pgh.setOrigPaymentDate(pg.getPaymentDate()); 610 //put a check for null since disbursement date was not set in testMode / dev 611 if (ObjectUtils.isNotNull(pg.getDisbursementDate())) { 612 pgh.setOrigDisburseDate(new Timestamp(pg.getDisbursementDate().getTime())); 613 } 614 pgh.setOrigAchBankRouteNbr(pg.getAchBankRoutingNbr()); 615 pgh.setOrigDisburseNbr(pg.getDisbursementNbr()); 616 pgh.setOrigAdviceEmail(pg.getAdviceEmailAddress()); 617 pgh.setDisbursementType(pg.getDisbursementType()); 618 pgh.setProcess(pg.getProcess()); 619 620 glPendingTransactionService.generateReissueGeneralLedgerPendingEntry(pg); 621 622 if (LOG.isDebugEnabled()) { 623 LOG.debug("cancelReissueDisbursement() Status is '" + paymentStatus + "; delete row from AchAccountNumber table."); 624 } 625 626 AchAccountNumber achAccountNumber = pg.getAchAccountNumber(); 627 628 if (ObjectUtils.isNotNull(achAccountNumber)) { 629 this.businessObjectService.delete(achAccountNumber); 630 pg.setAchAccountNumber(null); 631 } 632 633 // if bank functionality is not enabled or the group bank is inactive clear bank code 634 if (!bankService.isBankSpecificationEnabled() || !pg.getBank().isActive()) { 635 pg.setBank(null); 636 } 637 638 pg.setDisbursementDate((java.sql.Date) null); 639 pg.setAchBankRoutingNbr(null); 640 pg.setAchAccountType(null); 641 pg.setPhysCampusProcessCd(null); 642 pg.setDisbursementNbr((KualiInteger) null); 643 pg.setAdviceEmailAddress(null); 644 pg.setDisbursementType(null); 645 pg.setProcess(null); 646 pg.setProcessImmediate(false); 647 648 changeStatus(pg, PdpConstants.PaymentStatusCodes.OPEN, PdpConstants.PaymentChangeCodes.CANCEL_REISSUE_DISBURSEMENT, note, user, pgh); 649 } 650 651 LOG.debug("cancelReissueDisbursement() Disbursement cancelled and reissued; exit method."); 652 } 653 else { 654 if (LOG.isDebugEnabled()) { 655 LOG.debug("cancelReissueDisbursement() Payment status is " + paymentStatus + " and disbursement date is " + paymentGroup.getDisbursementDate() + "; cannot cancel payment"); 656 } 657 658 GlobalVariables.getMessageMap().putError(OLEConstants.GLOBAL_ERRORS, PdpKeyConstants.PaymentDetail.ErrorMessages.ERROR_DISBURSEMENT_INVALID_TO_CANCEL_AND_REISSUE); 659 return false; 660 } 661 } 662 else { 663 LOG.debug("cancelReissueDisbursement() Disbursement already cancelled and reissued; exit method."); 664 } 665 return true; 666 } 667 668 /** 669 * Gets DisbursementVoucher by the primary key 670 * 671 * @param paymentDetailId 672 * @return 673 */ 674 protected PaymentDetail getPaymentDetail(Integer paymentDetailId) { 675 Map<String, Integer> primaryKeys = new HashMap<String, Integer>(); 676 primaryKeys.put(PdpPropertyConstants.PaymentDetail.PAYMENT_ID, paymentDetailId); 677 678 return this.businessObjectService.findByPrimaryKey(PaymentDetail.class, primaryKeys); 679 } 680 681 /** 682 * Gets PaymentGroup by the primary key 683 * 684 * @param paymentDetailId 685 * @return 686 */ 687 protected PaymentGroup getPaymentGroup(KualiInteger paymentGroupId) { 688 Map<String, KualiInteger> primaryKeys = new HashMap<String, KualiInteger>(); 689 primaryKeys.put(PdpPropertyConstants.PaymentGroup.PAYMENT_GROUP_ID, paymentGroupId); 690 691 return this.businessObjectService.findByPrimaryKey(PaymentGroup.class, primaryKeys); 692 } 693 694 /** 695 * inject 696 * 697 * @param dao 698 */ 699 public void setPaymentGroupDao(PaymentGroupDao dao) { 700 paymentGroupDao = dao; 701 } 702 703 /** 704 * inject 705 * 706 * @param dao 707 */ 708 public void setPaymentDetailDao(PaymentDetailDao dao) { 709 paymentDetailDao = dao; 710 } 711 712 /** 713 * inject 714 * 715 * @param service 716 */ 717 public void setGlPendingTransactionService(PendingTransactionService service) { 718 glPendingTransactionService = service; 719 } 720 721 /** 722 * inject 723 * 724 * @param service 725 */ 726 public void setMailService(MailService mailService) { 727 this.mailService = mailService; 728 } 729 730 public void setParameterService(ParameterService parameterService) { 731 this.parameterService = parameterService; 732 } 733 734 /** 735 * Sets the bankService attribute value. 736 * 737 * @param bankService The bankService to set. 738 */ 739 public void setBankService(BankService bankService) { 740 this.bankService = bankService; 741 } 742 743 /** 744 * Sets the business object service 745 * 746 * @param businessObjectService 747 */ 748 public void setBusinessObjectService(BusinessObjectService businessObjectService) { 749 this.businessObjectService = businessObjectService; 750 } 751 752 /** 753 * Sets the payment group service 754 * 755 * @param paymentGroupService 756 */ 757 public void setPaymentGroupService(PaymentGroupService paymentGroupService) { 758 this.paymentGroupService = paymentGroupService; 759 } 760 761 public void setEmailService(PdpEmailService emailService) { 762 this.emailService = emailService; 763 } 764 765 public void setPdpAuthorizationService(PdpAuthorizationService pdpAuthorizationService) { 766 this.pdpAuthorizationService = pdpAuthorizationService; 767 } 768}