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 package org.kuali.kfs.pdp.service.impl; 017 018 import java.text.MessageFormat; 019 import java.util.Arrays; 020 import java.util.Collections; 021 import java.util.Date; 022 import java.util.HashSet; 023 import java.util.List; 024 import java.util.Map; 025 026 import org.apache.commons.lang.StringUtils; 027 import org.kuali.kfs.pdp.PdpKeyConstants; 028 import org.kuali.kfs.pdp.PdpParameterConstants; 029 import org.kuali.kfs.pdp.PdpPropertyConstants; 030 import org.kuali.kfs.pdp.batch.ExtractAchPaymentsStep; 031 import org.kuali.kfs.pdp.batch.LoadPaymentsStep; 032 import org.kuali.kfs.pdp.businessobject.ACHBank; 033 import org.kuali.kfs.pdp.businessobject.Batch; 034 import org.kuali.kfs.pdp.businessobject.CustomerProfile; 035 import org.kuali.kfs.pdp.businessobject.PaymentDetail; 036 import org.kuali.kfs.pdp.businessobject.PaymentFileLoad; 037 import org.kuali.kfs.pdp.businessobject.PaymentGroup; 038 import org.kuali.kfs.pdp.businessobject.PaymentNoteText; 039 import org.kuali.kfs.pdp.service.AchBankService; 040 import org.kuali.kfs.pdp.service.CustomerProfileService; 041 import org.kuali.kfs.pdp.service.PdpEmailService; 042 import org.kuali.kfs.sys.KFSConstants; 043 import org.kuali.kfs.sys.KFSPropertyConstants; 044 import org.kuali.kfs.sys.service.impl.KfsParameterConstants; 045 import org.kuali.rice.kim.bo.Person; 046 import org.kuali.rice.kns.mail.InvalidAddressException; 047 import org.kuali.rice.kns.mail.MailMessage; 048 import org.kuali.rice.kns.service.DataDictionaryService; 049 import org.kuali.rice.kns.service.KualiConfigurationService; 050 import org.kuali.rice.kns.service.MailService; 051 import org.kuali.rice.kns.service.ParameterService; 052 import org.kuali.rice.kns.util.ErrorMessage; 053 import org.kuali.rice.kns.util.KualiDecimal; 054 import org.kuali.rice.kns.util.MessageMap; 055 import org.kuali.rice.kns.web.format.CurrencyFormatter; 056 import org.kuali.rice.kns.web.format.Formatter; 057 058 /** 059 * @see org.kuali.kfs.pdp.service.PdpEmailService 060 */ 061 public class PdpEmailServiceImpl implements PdpEmailService { 062 private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(PdpEmailServiceImpl.class); 063 064 private CustomerProfileService customerProfileService; 065 private KualiConfigurationService kualiConfigurationService; 066 protected MailService mailService; 067 protected ParameterService parameterService; 068 private DataDictionaryService dataDictionaryService; 069 private AchBankService achBankService; 070 071 /** 072 * @see org.kuali.kfs.pdp.service.PdpEmailService#sendErrorEmail(org.kuali.kfs.pdp.businessobject.PaymentFileLoad, 073 * org.kuali.rice.kns.util.ErrorMap) 074 */ 075 public void sendErrorEmail(PaymentFileLoad paymentFile, MessageMap errors) { 076 LOG.debug("sendErrorEmail() starting"); 077 078 // check email configuration 079 if (!isPaymentEmailEnabled()) { 080 return; 081 } 082 083 MailMessage message = new MailMessage(); 084 085 message.setFromAddress(mailService.getBatchMailingList()); 086 message.setSubject(getEmailSubject(PdpParameterConstants.PAYMENT_LOAD_FAILURE_EMAIL_SUBJECT_PARAMETER_NAME)); 087 088 StringBuffer body = new StringBuffer(); 089 List<String> ccAddresses = parameterService.getParameterValues(LoadPaymentsStep.class, PdpParameterConstants.HARD_EDIT_CC); 090 091 if (paymentFile == null) { 092 if (ccAddresses.isEmpty()) { 093 LOG.error("sendErrorEmail() No HARD_EDIT_CC addresses. No email sent"); 094 return; 095 } 096 097 message.getToAddresses().addAll(ccAddresses); 098 099 body.append(getMessage(PdpKeyConstants.MESSAGE_PAYMENT_EMAIL_BAD_FILE_PARSE) + "\n\n"); 100 } 101 else { 102 CustomerProfile customer = customerProfileService.get(paymentFile.getChart(), paymentFile.getUnit(), paymentFile.getSubUnit()); 103 if (customer == null) { 104 LOG.error("sendErrorEmail() Invalid Customer. Sending email to CC addresses"); 105 106 if (ccAddresses.isEmpty()) { 107 LOG.error("sendErrorEmail() No HARD_EDIT_CC addresses. No email sent"); 108 return; 109 } 110 111 message.getToAddresses().addAll(ccAddresses); 112 113 body.append(getMessage(PdpKeyConstants.MESSAGE_PAYMENT_EMAIL_INVALID_CUSTOMER) + "\n\n"); 114 } 115 else { 116 String toAddresses = StringUtils.deleteWhitespace(customer.getProcessingEmailAddr()); 117 List<String> toAddressList = Arrays.asList(toAddresses.split(",")); 118 119 message.getToAddresses().addAll(toAddressList); 120 message.getCcAddresses().addAll(ccAddresses); 121 //TODO: for some reason the mail service does not work unless the bcc list has addresss. This is a temporary workaround 122 message.getBccAddresses().addAll(ccAddresses); 123 } 124 } 125 126 if (paymentFile != null) { 127 body.append(getMessage(PdpKeyConstants.MESSAGE_PAYMENT_EMAIL_FILE_NOT_LOADED) + "\n\n"); 128 addPaymentFieldsToBody(body, null, paymentFile.getChart(), paymentFile.getUnit(), paymentFile.getSubUnit(), paymentFile.getCreationDate(), paymentFile.getPaymentCount(), paymentFile.getPaymentTotalAmount()); 129 } 130 131 body.append("\n" + getMessage(PdpKeyConstants.MESSAGE_PAYMENT_EMAIL_ERROR_MESSAGES) + "\n"); 132 List<ErrorMessage> errorMessages = errors.getMessages(KFSConstants.GLOBAL_ERRORS); 133 for (ErrorMessage errorMessage : errorMessages) { 134 body.append(getMessage(errorMessage.getErrorKey(), (Object[]) errorMessage.getMessageParameters()) + "\n\n"); 135 } 136 137 message.setMessage(body.toString()); 138 139 // KFSMI-6475 - if not a production instance, replace the recipients with the testers list 140 alterMessageWhenNonProductionInstance(message, null); 141 142 try { 143 mailService.sendMessage(message); 144 } catch (InvalidAddressException e) { 145 LOG.error("sendErrorEmail() Invalid email address. Message not sent", e); 146 } 147 } 148 149 /** 150 * KFSMI-6475 - Alter the subject and switch all recipients 151 * 152 * @param message 153 * @param environmentCode 154 */ 155 @SuppressWarnings("rawtypes") 156 public void alterMessageWhenNonProductionInstance( MailMessage message, String environmentCode ) { 157 if ( !kualiConfigurationService.isProductionEnvironment() ) { 158 if ( environmentCode == null ) { 159 environmentCode = kualiConfigurationService.getPropertyString(KFSConstants.ENVIRONMENT_KEY); 160 } 161 // Add the environment code to the subject 162 message.setSubject(environmentCode + ": " + message.getSubject()); 163 // insert the original recipients into the beginning of the message 164 StringBuffer recipients = new StringBuffer(); 165 recipients.append("To : ").append(message.getToAddresses().toString()).append('\n'); 166 recipients.append("Cc : ").append(message.getCcAddresses().toString()).append('\n'); 167 recipients.append("Bcc: ").append(message.getBccAddresses().toString()).append('\n'); 168 recipients.append('\n'); 169 message.setMessage( recipients.toString() + message.getMessage() ); 170 // Clear out the recipients 171 message.setToAddresses(new HashSet()); 172 message.setCcAddresses(Collections.emptySet()); 173 message.setBccAddresses(Collections.emptySet()); 174 // Set all to the batch mailing list 175 message.addToAddress(mailService.getBatchMailingList()); 176 } 177 } 178 179 /** 180 * @see org.kuali.kfs.pdp.service.PdpEmailService#sendLoadEmail(org.kuali.kfs.pdp.businessobject.PaymentFileLoad, 181 * java.util.List) 182 */ 183 public void sendLoadEmail(PaymentFileLoad paymentFile, List<String> warnings) { 184 LOG.debug("sendLoadEmail() starting"); 185 186 // check email configuration 187 if (!isPaymentEmailEnabled()) { 188 return; 189 } 190 191 MailMessage message = new MailMessage(); 192 193 message.setFromAddress(mailService.getBatchMailingList()); 194 message.setSubject(getEmailSubject(PdpParameterConstants.PAYMENT_LOAD_SUCCESS_EMAIL_SUBJECT_PARAMETER_NAME)); 195 196 List<String> ccAddresses = parameterService.getParameterValues(LoadPaymentsStep.class, PdpParameterConstants.HARD_EDIT_CC); 197 message.getCcAddresses().addAll(ccAddresses); 198 message.getBccAddresses().addAll(ccAddresses); 199 200 CustomerProfile customer = customerProfileService.get(paymentFile.getChart(), paymentFile.getUnit(), paymentFile.getSubUnit()); 201 String toAddresses = StringUtils.deleteWhitespace(customer.getProcessingEmailAddr()); 202 List<String> toAddressList = Arrays.asList(toAddresses.split(",")); 203 204 message.getToAddresses().addAll(toAddressList); 205 206 StringBuffer body = new StringBuffer(); 207 body.append(getMessage(PdpKeyConstants.MESSAGE_PAYMENT_EMAIL_FILE_LOADED) + "\n\n"); 208 addPaymentFieldsToBody(body, paymentFile.getBatchId().intValue(), paymentFile.getChart(), paymentFile.getUnit(), paymentFile.getSubUnit(), paymentFile.getCreationDate(), paymentFile.getPaymentCount(), paymentFile.getPaymentTotalAmount()); 209 210 body.append("\n" + getMessage(PdpKeyConstants.MESSAGE_PAYMENT_EMAIL_WARNING_MESSAGES) + "\n"); 211 for (String warning : warnings) { 212 body.append(warning + "\n\n"); 213 } 214 215 message.setMessage(body.toString()); 216 217 // KFSMI-6475 - if not a production instance, replace the recipients with the testers list 218 alterMessageWhenNonProductionInstance(message, null); 219 220 try { 221 mailService.sendMessage(message); 222 } 223 catch (InvalidAddressException e) { 224 LOG.error("sendErrorEmail() Invalid email address. Message not sent", e); 225 } 226 227 if (paymentFile.isFileThreshold()) { 228 sendThresholdEmail(true, paymentFile, customer); 229 } 230 231 if (paymentFile.isDetailThreshold()) { 232 sendThresholdEmail(false, paymentFile, customer); 233 } 234 } 235 236 /** 237 * Sends email for a payment that was over the customer file threshold or the detail threshold 238 * 239 * @param fileThreshold indicates whether the file threshold (true) was violated or the detail threshold (false) 240 * @param paymentFile parsed payment file object 241 * @param customer payment customer 242 */ 243 protected void sendThresholdEmail(boolean fileThreshold, PaymentFileLoad paymentFile, CustomerProfile customer) { 244 MailMessage message = new MailMessage(); 245 246 message.setFromAddress(mailService.getBatchMailingList()); 247 message.setSubject(getEmailSubject(PdpParameterConstants.PAYMENT_LOAD_THRESHOLD_EMAIL_SUBJECT_PARAMETER_NAME)); 248 249 StringBuffer body = new StringBuffer(); 250 251 body.append(getMessage(PdpKeyConstants.MESSAGE_PAYMENT_EMAIL_FILE_LOADED) + "\n\n"); 252 addPaymentFieldsToBody(body, paymentFile.getBatchId().intValue(), paymentFile.getChart(), paymentFile.getUnit(), paymentFile.getSubUnit(), paymentFile.getCreationDate(), paymentFile.getPaymentCount(), paymentFile.getPaymentTotalAmount()); 253 254 if (fileThreshold) { 255 String toAddresses = StringUtils.deleteWhitespace(customer.getFileThresholdEmailAddress()); 256 List<String> toAddressList = Arrays.asList(toAddresses.split(",")); 257 258 message.getToAddresses().addAll(toAddressList); 259 body.append("\n" + getMessage(PdpKeyConstants.MESSAGE_PAYMENT_EMAIL_FILE_THRESHOLD, paymentFile.getPaymentTotalAmount(), customer.getFileThresholdAmount())); 260 } 261 else { 262 String toAddresses = StringUtils.deleteWhitespace(customer.getPaymentThresholdEmailAddress()); 263 List<String> toAddressList = Arrays.asList(toAddresses.split(",")); 264 265 message.getToAddresses().addAll(toAddressList); 266 267 body.append("\n" + getMessage(PdpKeyConstants.MESSAGE_PAYMENT_EMAIL_DETAIL_THRESHOLD, customer.getPaymentThresholdAmount()) + "\n\n"); 268 for (PaymentDetail paymentDetail : paymentFile.getThresholdPaymentDetails()) { 269 paymentDetail.refresh(); 270 body.append(getMessage(PdpKeyConstants.MESSAGE_PAYMENT_EMAIL_FILE_THRESHOLD, paymentDetail.getPaymentGroup().getPayeeName(), paymentDetail.getNetPaymentAmount()) + "\n"); 271 } 272 } 273 274 List<String> ccAddresses = parameterService.getParameterValues(LoadPaymentsStep.class, PdpParameterConstants.HARD_EDIT_CC); 275 message.getCcAddresses().addAll(ccAddresses); 276 message.getBccAddresses().addAll(ccAddresses); 277 278 message.setMessage(body.toString()); 279 280 // KFSMI-6475 - if not a production instance, replace the recipients with the testers list 281 alterMessageWhenNonProductionInstance(message, null); 282 283 try { 284 mailService.sendMessage(message); 285 } 286 catch (InvalidAddressException e) { 287 LOG.error("sendErrorEmail() Invalid email address. Message not sent", e); 288 } 289 } 290 291 /** 292 * @see org.kuali.kfs.pdp.service.PdpEmailService#sendTaxEmail(org.kuali.kfs.pdp.businessobject.PaymentFileLoad) 293 */ 294 public void sendTaxEmail(PaymentFileLoad paymentFile) { 295 LOG.debug("sendTaxEmail() starting"); 296 297 MailMessage message = new MailMessage(); 298 299 message.setFromAddress(mailService.getBatchMailingList()); 300 message.setSubject(getEmailSubject(PdpParameterConstants.PAYMENT_LOAD_TAX_EMAIL_SUBJECT_PARAMETER_NAME)); 301 302 StringBuffer body = new StringBuffer(); 303 304 String taxEmail = parameterService.getParameterValue(KfsParameterConstants.PRE_DISBURSEMENT_ALL.class, PdpParameterConstants.TAX_GROUP_EMAIL_ADDRESS); 305 if (StringUtils.isBlank(taxEmail)) { 306 LOG.error("No Tax E-mail Application Setting found to send notification e-mail"); 307 return; 308 } 309 else { 310 message.addToAddress(taxEmail); 311 } 312 List<String> ccAddresses = parameterService.getParameterValues(LoadPaymentsStep.class, PdpParameterConstants.HARD_EDIT_CC); 313 message.getCcAddresses().addAll(ccAddresses); 314 message.getBccAddresses().addAll(ccAddresses); 315 316 body.append(getMessage(PdpKeyConstants.MESSAGE_PAYMENT_EMAIL_FILE_TAX_LOADED) + "\n\n"); 317 addPaymentFieldsToBody(body, paymentFile.getBatchId().intValue(), paymentFile.getChart(), paymentFile.getUnit(), paymentFile.getSubUnit(), paymentFile.getCreationDate(), paymentFile.getPaymentCount(), paymentFile.getPaymentTotalAmount()); 318 319 body.append("\n" + getMessage(PdpKeyConstants.MESSAGE_PAYMENT_EMAIL_GO_TO_PDP) + "\n"); 320 321 message.setMessage(body.toString()); 322 323 // KFSMI-6475 - if not a production instance, replace the recipients with the testers list 324 alterMessageWhenNonProductionInstance(message, null); 325 326 try { 327 mailService.sendMessage(message); 328 } 329 catch (InvalidAddressException e) { 330 LOG.error("sendErrorEmail() Invalid email address. Message not sent", e); 331 } 332 } 333 334 /** 335 * @see org.kuali.kfs.pdp.service.PdpEmailService#sendLoadEmail(org.kuali.kfs.pdp.businessobject.Batch) 336 */ 337 public void sendLoadEmail(Batch batch) { 338 LOG.debug("sendLoadEmail() starting"); 339 340 // check email configuration 341 if (!isPaymentEmailEnabled()) { 342 return; 343 } 344 345 MailMessage message = new MailMessage(); 346 347 message.setFromAddress(mailService.getBatchMailingList()); 348 message.setSubject(getEmailSubject(PdpParameterConstants.PAYMENT_LOAD_SUCCESS_EMAIL_SUBJECT_PARAMETER_NAME)); 349 350 StringBuffer body = new StringBuffer(); 351 352 List<String> ccAddresses = parameterService.getParameterValues(LoadPaymentsStep.class, PdpParameterConstants.HARD_EDIT_CC); 353 message.getCcAddresses().addAll(ccAddresses); 354 message.getBccAddresses().addAll(ccAddresses); 355 356 CustomerProfile customer = batch.getCustomerProfile(); 357 String toAddresses = StringUtils.deleteWhitespace(customer.getProcessingEmailAddr()); 358 List<String> toAddressList = Arrays.asList(toAddresses.split(",")); 359 360 message.getToAddresses().addAll(toAddressList); 361 362 body.append(getMessage(PdpKeyConstants.MESSAGE_PAYMENT_EMAIL_FILE_LOADED) + "\n\n"); 363 addPaymentFieldsToBody(body, batch.getId().intValue(), customer.getChartCode(), customer.getUnitCode(), customer.getSubUnitCode(), batch.getCustomerFileCreateTimestamp(), batch.getPaymentCount().intValue(), batch.getPaymentTotalAmount()); 364 365 message.setMessage(body.toString()); 366 367 // KFSMI-6475 - if not a production instance, replace the recipients with the testers list 368 alterMessageWhenNonProductionInstance(message, null); 369 370 try { 371 mailService.sendMessage(message); 372 } 373 catch (InvalidAddressException e) { 374 LOG.error("sendErrorEmail() Invalid email address. Message not sent", e); 375 } 376 } 377 378 /** 379 * @see org.kuali.kfs.pdp.service.PdpEmailService#sendExceedsMaxNotesWarningEmail(java.util.List, java.util.List, int, int) 380 */ 381 public void sendExceedsMaxNotesWarningEmail(List<String> creditMemos, List<String> paymentRequests, int lineTotal, int maxNoteLines) { 382 LOG.debug("sendExceedsMaxNotesWarningEmail() starting"); 383 384 // check email configuration 385 if (!isPaymentEmailEnabled()) { 386 return; 387 } 388 389 MailMessage message = new MailMessage(); 390 message.setFromAddress(mailService.getBatchMailingList()); 391 392 StringBuffer body = new StringBuffer(); 393 394 String environmentCode = kualiConfigurationService.getPropertyString(KFSConstants.ENVIRONMENT_KEY); 395 message.setSubject(getMessage(PdpKeyConstants.MESSAGE_PURAP_EXTRACT_MAX_NOTES_SUBJECT)); 396 397 // Get recipient email address 398 String toAddresses = parameterService.getParameterValue(KfsParameterConstants.PRE_DISBURSEMENT_ALL.class, PdpParameterConstants.PDP_ERROR_EXCEEDS_NOTE_LIMIT_EMAIL); 399 List<String> toAddressList = Arrays.asList(toAddresses.split(",")); 400 message.getToAddresses().addAll(toAddressList); 401 402 List<String> ccAddresses = parameterService.getParameterValues(LoadPaymentsStep.class, PdpParameterConstants.SOFT_EDIT_CC); 403 message.getCcAddresses().addAll(ccAddresses); 404 405 406 message.getBccAddresses().addAll(ccAddresses); 407 408 body.append(getMessage(PdpKeyConstants.MESSAGE_PURAP_EXTRACT_MAX_NOTES_MESSAGE, StringUtils.join(creditMemos, ","), StringUtils.join(paymentRequests, ","), lineTotal, maxNoteLines)); 409 message.setMessage(body.toString()); 410 411 // KFSMI-6475 - if not a production instance, replace the recipients with the testers list 412 alterMessageWhenNonProductionInstance(message, null); 413 414 try { 415 mailService.sendMessage(message); 416 } 417 catch (InvalidAddressException e) { 418 LOG.error("sendExceedsMaxNotesWarningEmail() Invalid email address. Message not sent", e); 419 } 420 } 421 422 /** 423 * @see org.kuali.kfs.pdp.service.PdpEmailService#sendAchSummaryEmail(java.util.Map, java.util.Map, java.util.Date) 424 */ 425 public void sendAchSummaryEmail(Map<String, Integer> unitCounts, Map<String, KualiDecimal> unitTotals, Date disbursementDate) { 426 LOG.debug("sendAchSummaryEmail() starting"); 427 428 MailMessage message = new MailMessage(); 429 430 List<String> toAddressList = parameterService.getParameterValues(ExtractAchPaymentsStep.class, PdpParameterConstants.ACH_SUMMARY_TO_EMAIL_ADDRESS_PARMAETER_NAME); 431 message.getToAddresses().addAll(toAddressList); 432 message.getCcAddresses().addAll(toAddressList); 433 message.getBccAddresses().addAll(toAddressList); 434 435 message.setFromAddress(mailService.getBatchMailingList()); 436 437 String subject = parameterService.getParameterValue(ExtractAchPaymentsStep.class, PdpParameterConstants.ACH_SUMMARY_EMAIL_SUBJECT_PARAMETER_NAME); 438 message.setSubject(subject); 439 440 StringBuffer body = new StringBuffer(); 441 body.append(getMessage(PdpKeyConstants.MESSAGE_PDP_ACH_SUMMARY_EMAIL_DISB_DATE, disbursementDate) + "\n"); 442 443 Integer totalCount = 0; 444 KualiDecimal totalAmount = KualiDecimal.ZERO; 445 for (String unit : unitCounts.keySet()) { 446 body.append(getMessage(PdpKeyConstants.MESSAGE_PDP_ACH_SUMMARY_EMAIL_UNIT_TOTAL, StringUtils.leftPad(unit, 13), StringUtils.leftPad(unitCounts.get(unit).toString(), 10), StringUtils.leftPad(unitTotals.get(unit).toString(), 20)) + "\n"); 447 448 totalCount = totalCount + unitCounts.get(unit); 449 totalAmount = totalAmount.add(unitTotals.get(unit)); 450 } 451 452 body.append(getMessage(PdpKeyConstants.MESSAGE_PDP_ACH_SUMMARY_EMAIL_EXTRACT_TOTALS, StringUtils.leftPad(totalCount.toString(), 10), StringUtils.leftPad(totalAmount.toString(), 20)) + "\n"); 453 body.append(getMessage(PdpKeyConstants.MESSAGE_PDP_ACH_SUMMARY_EMAIL_COMPLETE)); 454 455 message.setMessage(body.toString()); 456 457 // KFSMI-6475 - if not a production instance, replace the recipients with the testers list 458 alterMessageWhenNonProductionInstance(message, null); 459 460 try { 461 mailService.sendMessage(message); 462 } 463 catch (InvalidAddressException e) { 464 LOG.error("sendAchSummaryEmail() Invalid email address. Message not sent", e); 465 } 466 } 467 468 /** 469 * @see org.kuali.kfs.pdp.service.PdpEmailService#sendAchAdviceEmail(org.kuali.kfs.pdp.businessobject.PaymentGroup, 470 * org.kuali.kfs.pdp.businessobject.CustomerProfile, org.kuali.kfs.pdp.businessobject.PaymentDetail) 471 */ 472 public void sendAchAdviceEmail(PaymentGroup paymentGroup, PaymentDetail paymentDetail, CustomerProfile customer) { 473 LOG.debug("sendAchAdviceEmail() starting"); 474 475 MailMessage message = new MailMessage(); 476 477 message.addToAddress(paymentGroup.getAdviceEmailAddress()); 478 message.addCcAddress(paymentGroup.getAdviceEmailAddress()); 479 message.addBccAddress(paymentGroup.getAdviceEmailAddress()); 480 message.setFromAddress(customer.getAdviceReturnEmailAddr()); 481 message.setSubject(customer.getAdviceSubjectLine()); 482 483 LOG.debug("sending email to " + paymentGroup.getAdviceEmailAddress() + " for disb # " + paymentGroup.getDisbursementNbr()); 484 485 StringBuffer body = new StringBuffer(); 486 body.append(getMessage(PdpKeyConstants.MESSAGE_PDP_ACH_ADVICE_EMAIL_TOFROM, paymentGroup.getPayeeName(), customer.getAchPaymentDescription())); 487 488 // formatter for payment amounts 489 Formatter formatter = new CurrencyFormatter(); 490 491 // get bank name to which the payment is being transferred 492 String bankName = ""; 493 494 ACHBank achBank = achBankService.getByPrimaryId(paymentGroup.getAchBankRoutingNbr()); 495 if (achBank == null) { 496 LOG.error("Bank cound not be found for routing number " + paymentGroup.getAchBankRoutingNbr()); 497 } 498 else { 499 bankName = achBank.getBankName(); 500 } 501 502 body.append(getMessage(PdpKeyConstants.MESSAGE_PDP_ACH_ADVICE_EMAIL_BANKAMOUNT, bankName, formatter.formatForPresentation(paymentDetail.getNetPaymentAmount()))); 503 504 // print detail amounts 505 int labelPad = 25; 506 507 String newPaymentAmountLabel = dataDictionaryService.getAttributeLabel(PaymentDetail.class, PdpPropertyConstants.PaymentDetail.PAYMENT_NET_AMOUNT); 508 body.append(StringUtils.rightPad(newPaymentAmountLabel, labelPad) + formatter.formatForPresentation(paymentDetail.getNetPaymentAmount()) + "\n"); 509 510 if (paymentDetail.getOrigInvoiceAmount().isNonZero()) { 511 String origInvoiceAmountLabel = dataDictionaryService.getAttributeLabel(PaymentDetail.class, PdpPropertyConstants.PaymentDetail.PAYMENT_ORIGINAL_INVOICE_AMOUNT); 512 body.append(StringUtils.rightPad(origInvoiceAmountLabel, labelPad) + formatter.formatForPresentation(paymentDetail.getOrigInvoiceAmount()) + "\n"); 513 } 514 515 if (paymentDetail.getInvTotDiscountAmount().isNonZero()) { 516 String invTotDiscountAmountLabel = dataDictionaryService.getAttributeLabel(PaymentDetail.class, PdpPropertyConstants.PaymentDetail.PAYMENT_INVOICE_TOTAL_DISCOUNT_AMOUNT); 517 body.append(StringUtils.rightPad(invTotDiscountAmountLabel, labelPad) + formatter.formatForPresentation(paymentDetail.getInvTotDiscountAmount()) + "\n"); 518 } 519 520 if (paymentDetail.getInvTotShipAmount().isNonZero()) { 521 String invTotShippingAmountLabel = dataDictionaryService.getAttributeLabel(PaymentDetail.class, PdpPropertyConstants.PaymentDetail.PAYMENT_INVOICE_TOTAL_SHIPPING_AMOUNT); 522 body.append(StringUtils.rightPad(invTotShippingAmountLabel, labelPad) + formatter.formatForPresentation(paymentDetail.getInvTotShipAmount()) + "\n"); 523 } 524 525 if (paymentDetail.getInvTotOtherDebitAmount().isNonZero()) { 526 String invTotOtherDebitAmountLabel = dataDictionaryService.getAttributeLabel(PaymentDetail.class, PdpPropertyConstants.PaymentDetail.PAYMENT_INVOICE_TOTAL_OTHER_DEBIT_AMOUNT); 527 body.append(StringUtils.rightPad(invTotOtherDebitAmountLabel, labelPad) + formatter.formatForPresentation(paymentDetail.getInvTotOtherDebitAmount()) + "\n"); 528 } 529 530 if (paymentDetail.getInvTotOtherCreditAmount().isNonZero()) { 531 String invTotOtherCreditAmountLabel = dataDictionaryService.getAttributeLabel(PaymentDetail.class, PdpPropertyConstants.PaymentDetail.PAYMENT_INVOICE_TOTAL_OTHER_CREDIT_AMOUNT); 532 body.append(StringUtils.rightPad(invTotOtherCreditAmountLabel, labelPad) + formatter.formatForPresentation(paymentDetail.getInvTotOtherCreditAmount()) + "\n"); 533 } 534 535 body.append("\n" + customer.getAdviceHeaderText() + "\n"); 536 537 if (StringUtils.isNotBlank(paymentDetail.getPurchaseOrderNbr())) { 538 String purchaseOrderNbrLabel = dataDictionaryService.getAttributeLabel(PaymentDetail.class, PdpPropertyConstants.PaymentDetail.PAYMENT_PURCHASE_ORDER_NUMBER); 539 body.append(StringUtils.rightPad(purchaseOrderNbrLabel, labelPad) + paymentDetail.getPurchaseOrderNbr() + "\n"); 540 } 541 542 if (StringUtils.isNotBlank(paymentDetail.getInvoiceNbr())) { 543 String invoiceNbrLabel = dataDictionaryService.getAttributeLabel(PaymentDetail.class, PdpPropertyConstants.PaymentDetail.PAYMENT_INVOICE_NUMBER); 544 body.append(StringUtils.rightPad(invoiceNbrLabel, labelPad) + paymentDetail.getInvoiceNbr() + "\n"); 545 } 546 547 if (StringUtils.isNotBlank(paymentDetail.getCustPaymentDocNbr())) { 548 String custPaymentDocNbrLabel = dataDictionaryService.getAttributeLabel(PaymentDetail.class, PdpPropertyConstants.PaymentDetail.PAYMENT_CUSTOMER_DOC_NUMBER); 549 body.append(StringUtils.rightPad(custPaymentDocNbrLabel, labelPad) + paymentDetail.getCustPaymentDocNbr() + "\n"); 550 } 551 552 if (StringUtils.isNotBlank(paymentGroup.getCustomerInstitutionNumber())) { 553 String customerInstituitionNbrLabel = dataDictionaryService.getAttributeLabel(PaymentGroup.class, PdpPropertyConstants.CUSTOMER_INSTITUTION_NUMBER); 554 body.append(StringUtils.rightPad(customerInstituitionNbrLabel, labelPad) + paymentGroup.getCustomerInstitutionNumber() + "\n"); 555 } 556 557 body.append("\n"); 558 559 // print payment notes 560 for (PaymentNoteText paymentNoteText : paymentDetail.getNotes()) { 561 body.append(paymentNoteText.getCustomerNoteText() + "\n"); 562 } 563 564 if (paymentDetail.getNotes().isEmpty()) { 565 body.append(getMessage(PdpKeyConstants.MESSAGE_PDP_ACH_ADVICE_EMAIL_NONOTES)); 566 } 567 568 message.setMessage(body.toString()); 569 570 // KFSMI-6475 - if not a production instance, replace the recipients with the testers list 571 alterMessageWhenNonProductionInstance(message, null); 572 573 try { 574 mailService.sendMessage(message); 575 } 576 catch (InvalidAddressException e) { 577 LOG.error("sendAchAdviceEmail() Invalid email address. Sending message to " + customer.getAdviceReturnEmailAddr(), e); 578 579 // send notification to advice return address with payment details 580 message.addToAddress(customer.getAdviceReturnEmailAddr()); 581 582 message.setFromAddress(mailService.getBatchMailingList()); 583 message.setSubject(getMessage(PdpKeyConstants.MESSAGE_PDP_ACH_ADVICE_INVALID_EMAIL_ADDRESS)); 584 585 LOG.debug("bouncing email to " + customer.getAdviceReturnEmailAddr() + " for disb # " + paymentGroup.getDisbursementNbr()); 586 // KFSMI-6475 - if not a production instance, replace the recipients with the testers list 587 alterMessageWhenNonProductionInstance(message, null); 588 589 try { 590 mailService.sendMessage(message); 591 } 592 catch (InvalidAddressException e1) { 593 LOG.error("Could not send email to advice return email address on customer profile: " + customer.getAdviceReturnEmailAddr(), e1); 594 throw new RuntimeException("Could not send email to advice return email address on customer profile: " + customer.getAdviceReturnEmailAddr()); 595 } 596 } 597 } 598 599 /** 600 * 601 * @see org.kuali.kfs.pdp.service.PdpEmailService#sendCancelEmail(org.kuali.kfs.pdp.businessobject.PaymentGroup, java.lang.String, org.kuali.rice.kim.bo.Person) 602 */ 603 public void sendCancelEmail(PaymentGroup paymentGroup, String note, Person user) { 604 LOG.debug("sendCancelEmail() starting"); 605 606 MailMessage message = new MailMessage(); 607 608 String environmentCode = kualiConfigurationService.getPropertyString(KFSConstants.ENVIRONMENT_KEY); 609 610 message.setSubject("PDP --- Cancelled Payment by Tax"); 611 612 CustomerProfile cp = paymentGroup.getBatch().getCustomerProfile(); 613 String toAddresses = cp.getAdviceReturnEmailAddr(); 614 String toAddressList[] = toAddresses.split(","); 615 616 if (toAddressList.length > 0) { 617 for (int i = 0; i < toAddressList.length; i++) { 618 if (toAddressList[i] != null) { 619 message.addToAddress(toAddressList[i].trim()); 620 message.addBccAddress(toAddressList[i].trim()); 621 } 622 } 623 } 624 // message.addToAddress(cp.getAdviceReturnEmailAddr()); 625 626 String ccAddresses = parameterService.getParameterValue(KfsParameterConstants.PRE_DISBURSEMENT_ALL.class, PdpParameterConstants.TAX_CANCEL_EMAIL_LIST); 627 String ccAddressList[] = ccAddresses.split(","); 628 629 if (ccAddressList.length > 0) { 630 for (int i = 0; i < ccAddressList.length; i++) { 631 if (ccAddressList[i] != null) { 632 message.addCcAddress(ccAddressList[i].trim()); 633 } 634 } 635 } 636 637 String fromAddressList[] = { mailService.getBatchMailingList() }; 638 639 if (fromAddressList.length > 0) { 640 for (int i = 0; i < fromAddressList.length; i++) { 641 if (fromAddressList[i] != null) { 642 message.setFromAddress(fromAddressList[i].trim()); 643 } 644 } 645 } 646 647 StringBuffer body = new StringBuffer(); 648 649 String messageKey = kualiConfigurationService.getPropertyString(PdpKeyConstants.MESSAGE_PDP_PAYMENT_MAINTENANCE_EMAIL_LINE_1); 650 body.append(MessageFormat.format(messageKey, new Object[] { null }) + " \n\n"); 651 652 body.append(note + "\n\n"); 653 String taxEmail = parameterService.getParameterValue(KfsParameterConstants.PRE_DISBURSEMENT_ALL.class, PdpParameterConstants.TAX_GROUP_EMAIL_ADDRESS); 654 String taxContactDepartment = parameterService.getParameterValue(KfsParameterConstants.PRE_DISBURSEMENT_ALL.class, PdpParameterConstants.TAX_CANCEL_CONTACT); 655 if (StringUtils.isBlank(taxEmail)) { 656 messageKey = kualiConfigurationService.getPropertyString(PdpKeyConstants.MESSAGE_PDP_PAYMENT_MAINTENANCE_EMAIL_LINE_2); 657 body.append(MessageFormat.format(messageKey, new Object[] { taxContactDepartment }) + " \n\n"); 658 } 659 else { 660 messageKey = kualiConfigurationService.getPropertyString(PdpKeyConstants.MESSAGE_PDP_PAYMENT_MAINTENANCE_EMAIL_LINE_3); 661 body.append(MessageFormat.format(messageKey, new Object[] { taxContactDepartment, taxEmail }) + " \n\n"); 662 } 663 664 messageKey = kualiConfigurationService.getPropertyString(PdpKeyConstants.MESSAGE_PDP_PAYMENT_MAINTENANCE_EMAIL_LINE_4); 665 body.append(MessageFormat.format(messageKey, new Object[] { null }) + " \n\n"); 666 667 for (PaymentDetail pd : paymentGroup.getPaymentDetails()) { 668 669 String payeeLabel = dataDictionaryService.getAttributeLabel(PaymentGroup.class, PdpPropertyConstants.PaymentGroup.PAYMENT_GROUP_PAYEE_NAME); 670 String netPaymentAccountLabel = dataDictionaryService.getAttributeLabel(PaymentDetail.class, PdpPropertyConstants.PaymentDetail.PAYMENT_NET_AMOUNT); 671 String sourceDocumentNumberLabel = dataDictionaryService.getAttributeLabel(PaymentDetail.class, PdpPropertyConstants.PaymentDetail.PAYMENT_DISBURSEMENT_CUST_PAYMENT_DOC_NBR); 672 String invoiceNumberLabel = dataDictionaryService.getAttributeLabel(PaymentDetail.class, PdpPropertyConstants.PaymentDetail.PAYMENT_INVOICE_NUMBER); 673 String purchaseOrderNumberLabel = dataDictionaryService.getAttributeLabel(PaymentDetail.class, PdpPropertyConstants.PaymentDetail.PAYMENT_PURCHASE_ORDER_NUMBER); 674 String paymentDetailIdLabel = dataDictionaryService.getAttributeLabel(PaymentDetail.class, PdpPropertyConstants.PaymentDetail.PAYMENT_ID); 675 676 body.append(payeeLabel + ": " + paymentGroup.getPayeeName() + " \n"); 677 body.append(netPaymentAccountLabel + ": " + pd.getNetPaymentAmount() + " \n"); 678 body.append(sourceDocumentNumberLabel + ": " + pd.getCustPaymentDocNbr() + " \n"); 679 body.append(invoiceNumberLabel + ": " + pd.getInvoiceNbr() + " \n"); 680 body.append(purchaseOrderNumberLabel + ": " + pd.getPurchaseOrderNbr() + " \n"); 681 body.append(paymentDetailIdLabel + ": " + pd.getId() + "\n"); 682 683 } 684 685 body.append(MessageFormat.format(messageKey, new Object[] { null }) + " \n\n"); 686 687 String batchIdLabel = dataDictionaryService.getAttributeLabel(Batch.class, PdpPropertyConstants.BatchConstants.BATCH_ID); 688 String chartMessageLabel = dataDictionaryService.getAttributeLabel(CustomerProfile.class, PdpPropertyConstants.CustomerProfile.CUSTOMER_PROFILE_CHART_CODE); 689 String organizationLabel = dataDictionaryService.getAttributeLabel(CustomerProfile.class, PdpPropertyConstants.CustomerProfile.CUSTOMER_PROFILE_UNIT_CODE); 690 String subUnitLabel = dataDictionaryService.getAttributeLabel(CustomerProfile.class, PdpPropertyConstants.CustomerProfile.CUSTOMER_PROFILE_SUB_UNIT_CODE); 691 String creationDateLabel = dataDictionaryService.getAttributeLabel(Batch.class, PdpPropertyConstants.BatchConstants.FILE_CREATION_TIME); 692 String paymentCountLabel = dataDictionaryService.getAttributeLabel(Batch.class, PdpPropertyConstants.BatchConstants.PAYMENT_COUNT); 693 String paymentTotalLabel = dataDictionaryService.getAttributeLabel(Batch.class, PdpPropertyConstants.BatchConstants.PAYMENT_TOTAL_AMOUNT); 694 695 body.append(batchIdLabel + ": " + paymentGroup.getBatch().getId() + " \n"); 696 body.append(chartMessageLabel + ": " + cp.getChartCode() + " \n"); 697 body.append(organizationLabel + ": " + cp.getUnitCode() + " \n"); 698 body.append(subUnitLabel + ": " + cp.getSubUnitCode() + " \n"); 699 body.append(creationDateLabel + ": " + paymentGroup.getBatch().getCustomerFileCreateTimestamp() + " \n\n"); 700 body.append(paymentCountLabel + ": " + paymentGroup.getBatch().getPaymentCount() + " \n\n"); 701 body.append(paymentTotalLabel + ": " + paymentGroup.getBatch().getPaymentTotalAmount() + " \n\n"); 702 703 message.setMessage(body.toString()); 704 705 // KFSMI-6475 - if not a production instance, replace the recipients with the testers list 706 alterMessageWhenNonProductionInstance(message, null); 707 708 try { 709 mailService.sendMessage(message); 710 } 711 catch (InvalidAddressException e) { 712 LOG.error("sendErrorEmail() Invalid email address. Message not sent", e); 713 } 714 } 715 716 /** 717 * Writes out payment file field labels and values to <code>StringBuffer</code> 718 * 719 * @param body <code>StringBuffer</code> 720 */ 721 protected void addPaymentFieldsToBody(StringBuffer body, Integer batchId, String chart, String unit, String subUnit, Date createDate, int paymentCount, KualiDecimal paymentTotal) { 722 String batchIdLabel = dataDictionaryService.getAttributeLabel(PaymentFileLoad.class, PdpPropertyConstants.BATCH_ID); 723 body.append(batchIdLabel + ": " + batchId + "\n"); 724 725 String chartLabel = dataDictionaryService.getAttributeLabel(PaymentFileLoad.class, KFSPropertyConstants.CHART); 726 body.append(chartLabel + ": " + chart + "\n"); 727 728 String orgLabel = dataDictionaryService.getAttributeLabel(PaymentFileLoad.class, PdpPropertyConstants.UNIT); 729 body.append(orgLabel + ": " + unit + "\n"); 730 731 String subUnitLabel = dataDictionaryService.getAttributeLabel(PaymentFileLoad.class, PdpPropertyConstants.SUB_UNIT); 732 body.append(subUnitLabel + ": " + subUnit + "\n"); 733 734 String createDateLabel = dataDictionaryService.getAttributeLabel(PaymentFileLoad.class, PdpPropertyConstants.CREATION_DATE); 735 body.append(createDateLabel + ": " + createDate + "\n"); 736 737 String paymentCountLabel = dataDictionaryService.getAttributeLabel(PaymentFileLoad.class, PdpPropertyConstants.PAYMENT_COUNT); 738 body.append("\n" + paymentCountLabel + ": " + paymentCount + "\n"); 739 740 String paymentTotalLabel = dataDictionaryService.getAttributeLabel(PaymentFileLoad.class, PdpPropertyConstants.PAYMENT_TOTAL_AMOUNT); 741 body.append(paymentTotalLabel + ": " + paymentTotal + "\n"); 742 } 743 744 /** 745 * Reads system parameter indicating whether to status emails should be sent 746 * 747 * @return true if email should be sent, false otherwise 748 */ 749 public boolean isPaymentEmailEnabled() { 750 boolean noEmail = parameterService.getIndicatorParameter(KfsParameterConstants.PRE_DISBURSEMENT_ALL.class, PdpParameterConstants.NO_PAYMENT_FILE_EMAIL); 751 if (noEmail) { 752 LOG.debug("sendLoadEmail() sending payment file email is disabled"); 753 return false; 754 } 755 756 return true; 757 } 758 759 /** 760 * Retrieves the email subject text from system parameter then checks environment code and prepends to message if not 761 * production. 762 * 763 * @param subjectParmaterName name of parameter giving the subject text 764 * @return subject text 765 */ 766 protected String getEmailSubject(String subjectParmaterName) { 767 String subject = parameterService.getParameterValue(LoadPaymentsStep.class, subjectParmaterName); 768 769 return subject; 770 } 771 772 /** 773 * Helper method to retrieve a message from resources and substitute place holder values 774 * 775 * @param messageKey key of message in resource file 776 * @param messageParameters parameter for message 777 * @return <code>String</code> Message with substituted values 778 */ 779 protected String getMessage(String messageKey, Object... messageParameters) { 780 String message = kualiConfigurationService.getPropertyString(messageKey); 781 return MessageFormat.format(message, messageParameters); 782 } 783 784 /** 785 * Sets the customerProfileService attribute value. 786 * 787 * @param customerProfileService The customerProfileService to set. 788 */ 789 public void setCustomerProfileService(CustomerProfileService customerProfileService) { 790 this.customerProfileService = customerProfileService; 791 } 792 793 /** 794 * Sets the kualiConfigurationService attribute value. 795 * 796 * @param kualiConfigurationService The kualiConfigurationService to set. 797 */ 798 public void setKualiConfigurationService(KualiConfigurationService kualiConfigurationService) { 799 this.kualiConfigurationService = kualiConfigurationService; 800 } 801 802 /** 803 * Sets the mailService attribute value. 804 * 805 * @param mailService The mailService to set. 806 */ 807 public void setMailService(MailService mailService) { 808 this.mailService = mailService; 809 } 810 811 /** 812 * Sets the parameterService attribute value. 813 * 814 * @param parameterService The parameterService to set. 815 */ 816 public void setParameterService(ParameterService parameterService) { 817 this.parameterService = parameterService; 818 } 819 820 /** 821 * Sets the dataDictionaryService attribute value. 822 * 823 * @param dataDictionaryService The dataDictionaryService to set. 824 */ 825 public void setDataDictionaryService(DataDictionaryService dataDictionaryService) { 826 this.dataDictionaryService = dataDictionaryService; 827 } 828 829 /** 830 * Sets the achBankService attribute value. 831 * 832 * @param achBankService The achBankService to set. 833 */ 834 public void setAchBankService(AchBankService achBankService) { 835 this.achBankService = achBankService; 836 } 837 838 }