1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.kuali.kfs.module.ar.service.impl;
20
21 import java.io.IOException;
22 import java.sql.Date;
23 import java.text.MessageFormat;
24 import java.util.Collection;
25 import java.util.HashMap;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.Properties;
29
30 import javax.mail.MessagingException;
31 import javax.mail.Session;
32
33 import org.apache.commons.io.IOUtils;
34 import org.apache.commons.lang.StringUtils;
35 import org.kuali.kfs.coa.businessobject.Organization;
36 import org.kuali.kfs.integration.cg.ContractsAndGrantsBillingAward;
37 import org.kuali.kfs.module.ar.ArConstants;
38 import org.kuali.kfs.module.ar.ArKeyConstants;
39 import org.kuali.kfs.module.ar.ArPropertyConstants;
40 import org.kuali.kfs.module.ar.batch.UpcomingMilestoneNotificationStep;
41 import org.kuali.kfs.module.ar.businessobject.CustomerAddress;
42 import org.kuali.kfs.module.ar.businessobject.InvoiceAddressDetail;
43 import org.kuali.kfs.module.ar.businessobject.Milestone;
44 import org.kuali.kfs.module.ar.document.ContractsGrantsInvoiceDocument;
45 import org.kuali.kfs.module.ar.service.AREmailService;
46 import org.kuali.kfs.module.ar.service.ContractsGrantsBillingUtilityService;
47 import org.kuali.kfs.sys.KFSConstants;
48 import org.kuali.kfs.sys.KFSPropertyConstants;
49 import org.kuali.kfs.sys.mail.AttachmentMailMessage;
50 import org.kuali.kfs.sys.service.AttachmentMailService;
51 import org.kuali.kfs.sys.service.NonTransactional;
52 import org.kuali.rice.core.api.config.property.ConfigContext;
53 import org.kuali.rice.core.api.config.property.ConfigurationService;
54 import org.kuali.rice.core.api.mail.MailMessage;
55 import org.kuali.rice.coreservice.framework.parameter.ParameterService;
56 import org.kuali.rice.kns.service.DataDictionaryService;
57 import org.kuali.rice.krad.bo.Attachment;
58 import org.kuali.rice.krad.bo.Note;
59 import org.kuali.rice.krad.exception.InvalidAddressException;
60 import org.kuali.rice.krad.service.BusinessObjectService;
61 import org.kuali.rice.krad.service.DocumentService;
62 import org.kuali.rice.krad.service.KualiModuleService;
63 import org.kuali.rice.krad.service.NoteService;
64 import org.kuali.rice.krad.service.impl.MailServiceImpl;
65 import org.kuali.rice.krad.util.ObjectUtils;
66
67
68
69
70
71 public class AREmailServiceImpl implements AREmailService {
72 private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(AREmailServiceImpl.class);
73
74 protected AttachmentMailService mailService;
75 protected ParameterService parameterService;
76 protected DataDictionaryService dataDictionaryService;
77 protected ConfigurationService kualiConfigurationService;
78 protected BusinessObjectService businessObjectService;
79 protected DocumentService documentService;
80 protected NoteService noteService;
81 protected KualiModuleService kualiModuleService;
82 protected ContractsGrantsBillingUtilityService contractsGrantsBillingUtilityService;
83
84
85
86
87
88
89 @NonTransactional
90 public void setKualiModuleService(KualiModuleService kualiModuleService) {
91 this.kualiModuleService = kualiModuleService;
92 }
93
94 public void setBusinessObjectService(BusinessObjectService businessObjectService) {
95 this.businessObjectService = businessObjectService;
96 }
97
98
99
100
101
102
103 public DocumentService getDocumentService() {
104 return documentService;
105 }
106
107
108
109
110
111
112 public void setDocumentService(DocumentService documentService) {
113 this.documentService = documentService;
114 }
115
116
117
118
119
120 @Override
121 public boolean sendInvoicesViaEmail(Collection<ContractsGrantsInvoiceDocument> invoices) throws InvalidAddressException, MessagingException {
122 LOG.debug("sendInvoicesViaEmail() starting.");
123
124 boolean success = true;
125 Properties props = getConfigProperties();
126
127
128 Session session = Session.getInstance(props, null);
129 for (ContractsGrantsInvoiceDocument invoice : invoices) {
130 List<InvoiceAddressDetail> invoiceAddressDetails = invoice.getInvoiceAddressDetails();
131 for (InvoiceAddressDetail invoiceAddressDetail : invoiceAddressDetails) {
132 if (ArConstants.InvoiceTransmissionMethod.EMAIL.equals(invoiceAddressDetail.getInvoiceTransmissionMethodCode())) {
133 Note note = noteService.getNoteByNoteId(invoiceAddressDetail.getNoteId());
134
135 if (ObjectUtils.isNotNull(note)) {
136 AttachmentMailMessage message = new AttachmentMailMessage();
137
138 String sender = parameterService.getParameterValueAsString(KFSConstants.OptionalModuleNamespaces.ACCOUNTS_RECEIVABLE, ArConstants.CONTRACTS_GRANTS_INVOICE_COMPONENT, ArConstants.FROM_EMAIL_ADDRESS);
139 message.setFromAddress(sender);
140
141 CustomerAddress customerAddress = invoiceAddressDetail.getCustomerAddress();
142 String recipients = invoiceAddressDetail.getCustomerEmailAddress();
143 if (StringUtils.isNotEmpty(recipients)) {
144 message.getToAddresses().add(recipients);
145 }
146 else {
147 LOG.warn("No recipients indicated.");
148 }
149
150 String subject = getSubject(invoice);
151 message.setSubject(subject);
152 if (StringUtils.isEmpty(subject)) {
153 LOG.warn("Empty subject being sent.");
154 }
155
156 String bodyText = getMessageBody(invoice, customerAddress);
157 message.setMessage(bodyText);
158 if (StringUtils.isEmpty(bodyText)) {
159 LOG.warn("Empty bodyText being sent.");
160 }
161
162 Attachment attachment = note.getAttachment();
163 if (ObjectUtils.isNotNull(attachment)) {
164 try {
165 message.setContent(IOUtils.toByteArray(attachment.getAttachmentContents()));
166 }
167 catch (IOException ex) {
168 LOG.error("Error setting attachment contents", ex);
169 throw new RuntimeException(ex);
170 }
171 message.setFileName(attachment.getAttachmentFileName());
172 message.setType(attachment.getAttachmentMimeTypeCode());
173 }
174
175 setupMailServiceForNonProductionInstance();
176 mailService.sendMessage(message);
177
178 invoiceAddressDetail.setInitialTransmissionDate(new Date(new java.util.Date().getTime()));
179 documentService.updateDocument(invoice);
180 } else {
181 success = false;
182 }
183 }
184 }
185 }
186 return success;
187 }
188
189 protected String getSubject(ContractsGrantsInvoiceDocument invoice) {
190 String subject = kualiConfigurationService.getPropertyValueAsString(ArKeyConstants.CGINVOICE_EMAIL_SUBJECT);
191
192 return MessageFormat.format(subject, invoice.getInvoiceGeneralDetail().getAward().getProposal().getGrantNumber(),
193 invoice.getInvoiceGeneralDetail().getProposalNumber(),
194 invoice.getDocumentNumber());
195 }
196
197 protected String getMessageBody(ContractsGrantsInvoiceDocument invoice, CustomerAddress customerAddress) {
198 String message = kualiConfigurationService.getPropertyValueAsString(ArKeyConstants.CGINVOICE_EMAIL_BODY);
199
200 String department = "";
201 String[] orgCode = invoice.getInvoiceGeneralDetail().getAward().getAwardPrimaryFundManager().getFundManager().getPrimaryDepartmentCode().split("-");
202 Map<String, Object> key = new HashMap<String, Object>();
203 key.put(KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE, orgCode[0].trim());
204 key.put(KFSPropertyConstants.ORGANIZATION_CODE, orgCode[1].trim());
205 Organization org = businessObjectService.findByPrimaryKey(Organization.class, key);
206 if (ObjectUtils.isNotNull(org)) {
207 department = org.getOrganizationName();
208 }
209
210 return MessageFormat.format(message, customerAddress.getCustomer().getCustomerName(),
211 customerAddress.getCustomerAddressName(),
212 invoice.getInvoiceGeneralDetail().getAward().getAwardPrimaryFundManager().getFundManager().getName(),
213 invoice.getInvoiceGeneralDetail().getAward().getAwardPrimaryFundManager().getProjectTitle(),
214 department,
215 invoice.getInvoiceGeneralDetail().getAward().getAwardPrimaryFundManager().getFundManager().getPhoneNumber(),
216 invoice.getInvoiceGeneralDetail().getAward().getAwardPrimaryFundManager().getFundManager().getEmailAddress());
217 }
218
219
220
221
222
223
224
225 public void setupMailServiceForNonProductionInstance() {
226 if (!ConfigContext.getCurrentContextConfig().isProductionEnvironment()) {
227 ((MailServiceImpl)mailService).setRealNotificationsEnabled(false);
228 ((MailServiceImpl)mailService).setNonProductionNotificationMailingList(mailService.getBatchMailingList());
229 }
230 }
231
232
233
234
235
236
237 public void setMailService(AttachmentMailService mailService) {
238 this.mailService = mailService;
239 }
240
241
242
243
244
245
246 public void setParameterService(ParameterService parameterService) {
247 this.parameterService = parameterService;
248 }
249
250
251
252
253
254
255 public void setDataDictionaryService(DataDictionaryService dataDictionaryService) {
256 this.dataDictionaryService = dataDictionaryService;
257 }
258
259
260
261
262
263
264
265 protected Properties getConfigProperties() {
266 return ConfigContext.getCurrentContextConfig().getProperties();
267 }
268
269
270
271
272
273
274 @Override
275 public void sendEmailNotificationsForMilestones(List<Milestone> milestones, ContractsAndGrantsBillingAward award) {
276 LOG.debug("sendEmail() starting");
277
278 MailMessage message = new MailMessage();
279
280 message.setFromAddress(mailService.getBatchMailingList());
281 message.setSubject(getEmailSubject(ArConstants.REMINDER_EMAIL_SUBJECT));
282 message.getToAddresses().add(award.getAwardPrimaryFundManager().getFundManager().getEmailAddress());
283 StringBuffer body = new StringBuffer();
284
285 String messageKey = kualiConfigurationService.getPropertyValueAsString(ArKeyConstants.MESSAGE_CG_UPCOMING_MILESTONES_EMAIL_LINE_1);
286 body.append(messageKey + "\n\n");
287
288 for (Milestone milestone : milestones) {
289 String proposalNumber = dataDictionaryService.getAttributeLabel(Milestone.class, KFSPropertyConstants.PROPOSAL_NUMBER);
290 String milestoneNumber = dataDictionaryService.getAttributeLabel(Milestone.class, ArPropertyConstants.MilestoneFields.MILESTONE_NUMBER);
291 String milestoneDescription = dataDictionaryService.getAttributeLabel(Milestone.class, ArPropertyConstants.MilestoneFields.MILESTONE_DESCRIPTION);
292 String milestoneAmount = dataDictionaryService.getAttributeLabel(Milestone.class, ArPropertyConstants.MilestoneFields.MILESTONE_AMOUNT);
293 String milestoneExpectedCompletionDate = dataDictionaryService.getAttributeLabel(Milestone.class, ArPropertyConstants.MilestoneFields.MILESTONE_EXPECTED_COMPLETION_DATE);
294
295 body.append(proposalNumber + ": " + milestone.getProposalNumber() + " \n");
296 body.append(milestoneNumber + ": " + milestone.getMilestoneNumber() + " \n");
297 body.append(milestoneDescription + ": " + milestone.getMilestoneDescription() + " \n");
298 body.append(milestoneAmount + ": " + milestone.getMilestoneAmount() + " \n");
299 body.append(milestoneExpectedCompletionDate + ": " + milestone.getMilestoneExpectedCompletionDate() + " \n");
300
301 body.append("\n\n");
302 }
303 body.append("\n\n");
304
305 messageKey = kualiConfigurationService.getPropertyValueAsString(ArKeyConstants.MESSAGE_CG_UPCOMING_MILESTONES_EMAIL_LINE_2);
306 body.append(MessageFormat.format(messageKey, new Object[] { null }) + "\n\n");
307
308 message.setMessage(body.toString());
309
310 try {
311 mailService.sendMessage(message);
312 }
313 catch (InvalidAddressException | MessagingException ex) {
314 LOG.error("Problems sending milestones e-mail", ex);
315 throw new RuntimeException("Problems sending milestones e-mail", ex);
316 }
317 }
318
319
320
321
322
323
324
325
326 protected String getEmailSubject(String subjectParmaterName) {
327 String subject = parameterService.getParameterValueAsString(UpcomingMilestoneNotificationStep.class, subjectParmaterName);
328
329 String productionEnvironmentCode = kualiConfigurationService.getPropertyValueAsString(KFSConstants.PROD_ENVIRONMENT_CODE_KEY);
330 String environmentCode = kualiConfigurationService.getPropertyValueAsString(KFSConstants.ENVIRONMENT_KEY);
331 if (!StringUtils.equals(productionEnvironmentCode, environmentCode)) {
332 subject = environmentCode + ": " + subject;
333 }
334
335 return subject;
336 }
337
338
339
340
341
342
343 public void setNoteService(NoteService noteService) {
344 this.noteService = noteService;
345 }
346
347 public ConfigurationService getKualiConfigurationService() {
348 return kualiConfigurationService;
349 }
350
351 public void setKualiConfigurationService(ConfigurationService kualiConfigurationService) {
352 this.kualiConfigurationService = kualiConfigurationService;
353 }
354
355 public ContractsGrantsBillingUtilityService getContractsGrantsBillingUtilityService() {
356 return contractsGrantsBillingUtilityService;
357 }
358
359 public void setContractsGrantsBillingUtilityService(ContractsGrantsBillingUtilityService contractsGrantsBillingUtilityService) {
360 this.contractsGrantsBillingUtilityService = contractsGrantsBillingUtilityService;
361 }
362 }