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.module.ar.batch.service.impl; 017 018 import java.sql.Date; 019 import java.sql.Timestamp; 020 import java.util.ArrayList; 021 import java.util.Calendar; 022 import java.util.Iterator; 023 import java.util.List; 024 025 import org.apache.log4j.Logger; 026 import org.kuali.kfs.module.ar.batch.service.InvoiceRecurrenceService; 027 import org.kuali.kfs.module.ar.businessobject.InvoiceRecurrence; 028 import org.kuali.kfs.module.ar.dataaccess.InvoiceRecurrenceDao; 029 import org.kuali.kfs.module.ar.document.CustomerInvoiceDocument; 030 import org.kuali.rice.kew.exception.WorkflowException; 031 import org.kuali.rice.kew.util.KEWConstants; 032 import org.kuali.rice.kns.UserSession; 033 import org.kuali.rice.kns.bo.AdHocRoutePerson; 034 import org.kuali.rice.kns.bo.AdHocRouteRecipient; 035 import org.kuali.rice.kns.bo.AdHocRouteWorkgroup; 036 import org.kuali.rice.kns.document.MaintenanceDocument; 037 import org.kuali.rice.kns.service.BusinessObjectService; 038 import org.kuali.rice.kns.service.DateTimeService; 039 import org.kuali.rice.kns.service.DocumentService; 040 import org.kuali.rice.kns.util.DateUtils; 041 import org.kuali.rice.kns.util.GlobalVariables; 042 import org.kuali.rice.kns.util.KNSConstants; 043 import org.kuali.rice.kns.util.ObjectUtils; 044 import org.springframework.transaction.annotation.Transactional; 045 046 /** 047 * 048 * Lockbox Iterators are sorted by processedInvoiceDate and batchSequenceNumber. 049 * Potentially there could be many batches on the same date. 050 * For each set of records with the same processedInvoiceDate and batchSequenceNumber, 051 * there will be one Cash-Control document. Each record within this set will create one Application document. 052 * 053 */ 054 055 @Transactional 056 public class InvoiceRecurrenceServiceImpl implements InvoiceRecurrenceService { 057 058 public InvoiceRecurrenceDao invoiceRecurrenceDao; 059 private static Logger LOG = org.apache.log4j.Logger.getLogger(InvoiceRecurrenceServiceImpl.class); 060 private DocumentService documentService; 061 private DateTimeService dateTimeService; 062 private BusinessObjectService boService; 063 public DateTimeService getDateTimeService() { 064 return dateTimeService; 065 } 066 067 public void setDateTimeService(DateTimeService dateTimeService) { 068 this.dateTimeService = dateTimeService; 069 } 070 071 public DocumentService getDocumentService() { 072 return documentService; 073 } 074 075 public void setDocumentService(DocumentService documentService) { 076 this.documentService = documentService; 077 } 078 079 public boolean processInvoiceRecurrence() throws WorkflowException { 080 081 Iterator<InvoiceRecurrence> itr = invoiceRecurrenceDao.getAllActiveInvoiceRecurrences(); 082 CustomerInvoiceDocument customerInvoiceDocument = new CustomerInvoiceDocument(); 083 while (itr.hasNext()) { 084 InvoiceRecurrence invoiceRecurrence = (InvoiceRecurrence)itr.next(); 085 086 /* Get some dates and calendars */ 087 Date currentDate = getDateTimeService().getCurrentSqlDate(); 088 Calendar currentCalendar = Calendar.getInstance(); 089 currentCalendar.setTime(getDateTimeService().getCurrentTimestamp()); 090 091 Date currentMonthProcessDate; 092 Calendar currentMonthProcessCalendar = Calendar.getInstance(); 093 094 Date nextProcessDate; 095 Calendar nextProcessCalendar = Calendar.getInstance(); 096 097 Date lastProcessDate; 098 Calendar lastProcessCalendar = Calendar.getInstance(); 099 100 Date beginDate = invoiceRecurrence.getDocumentRecurrenceBeginDate(); 101 Calendar beginCalendar = Calendar.getInstance(); 102 beginCalendar.setTime(new Timestamp(invoiceRecurrence.getDocumentRecurrenceBeginDate().getTime())); 103 104 Date endDate = invoiceRecurrence.getDocumentRecurrenceEndDate(); 105 Date lastCreateDate = invoiceRecurrence.getDocumentLastCreateDate(); 106 String intervalCode = invoiceRecurrence.getDocumentRecurrenceIntervalCode(); 107 Integer totalRecurrenceNumber = invoiceRecurrence.getDocumentTotalRecurrenceNumber(); 108 109 110 /* Calculate currentMonthProcessDate*/ 111 currentMonthProcessCalendar = currentCalendar; 112 int day = beginCalendar.get(Calendar.DAY_OF_MONTH); 113 currentMonthProcessCalendar.set(Calendar.DAY_OF_MONTH, day); 114 currentMonthProcessDate = DateUtils.convertToSqlDate(currentMonthProcessCalendar.getTime()); 115 116 /* Calculate the nextProcessDate */ 117 if (currentDate.after(currentMonthProcessDate)) { 118 nextProcessCalendar = currentMonthProcessCalendar; 119 nextProcessCalendar.add(Calendar.MONTH, 1); 120 } 121 else { 122 /* currentDate is less than or equal to currentMonthProcessDate 123 * so the nextProcessDate is equal to the currentMonthProcessDate */ 124 nextProcessCalendar = currentMonthProcessCalendar; 125 } 126 nextProcessDate = DateUtils.convertToSqlDate(nextProcessCalendar.getTime()); 127 128 /* Calculate the lastProcessDate by subtracting one month from nextProcessingDate */ 129 lastProcessCalendar = nextProcessCalendar; 130 lastProcessCalendar.add(Calendar.MONTH, -1); 131 lastProcessDate = DateUtils.convertToSqlDate(lastProcessCalendar.getTime()); 132 if (lastProcessDate.before(beginDate)) { 133 lastProcessCalendar.clear(); 134 } 135 lastProcessDate = DateUtils.convertToSqlDate(lastProcessCalendar.getTime()); 136 /* if nextProcessDate is equal to currentDate create INV document */ 137 if (nextProcessDate.equals(currentDate)) { 138 /* copy INV document to a new INV document */ 139 String initiator = invoiceRecurrence.getDocumentInitiatorUserPersonUserIdentifier(); 140 GlobalVariables.setUserSession(new UserSession(initiator)); 141 142 customerInvoiceDocument = (CustomerInvoiceDocument)getDocumentService().getByDocumentHeaderId(invoiceRecurrence.getInvoiceNumber()); 143 customerInvoiceDocument.toCopy(); 144 List<AdHocRouteRecipient> adHocRouteRecipients = new ArrayList<AdHocRouteRecipient>(); 145 adHocRouteRecipients.add(buildApprovePersonRecipient(initiator)); 146 //adHocRouteRecipients.add(buildApproveWorkgroupRecipient(workgroup)); 147 getDocumentService().routeDocument(customerInvoiceDocument, "This is a recurred Customer Invoice", adHocRouteRecipients); 148 invoiceRecurrence.setDocumentLastCreateDate(currentDate); 149 boService.save(invoiceRecurrence); 150 151 } 152 153 /* if nextProcessDate is greater than currentDate BUT less than or equal to endDate */ 154 if (nextProcessDate.after(currentDate) && (!nextProcessDate.after(endDate))) { 155 if ((ObjectUtils.isNotNull(lastCreateDate) && lastProcessDate.after(lastCreateDate)) || 156 (ObjectUtils.isNull(lastCreateDate) && beginDate.before(currentDate)) ) { 157 /* copy INV document to a new INV document */ 158 String initiator = invoiceRecurrence.getDocumentInitiatorUserPersonUserIdentifier(); 159 GlobalVariables.setUserSession(new UserSession(initiator)); 160 161 customerInvoiceDocument = (CustomerInvoiceDocument)getDocumentService().getByDocumentHeaderId(invoiceRecurrence.getInvoiceNumber()); 162 customerInvoiceDocument.toCopy(); 163 List<AdHocRouteRecipient> adHocRouteRecipients = new ArrayList<AdHocRouteRecipient>(); 164 adHocRouteRecipients.add(buildApprovePersonRecipient(initiator)); 165 //adHocRouteRecipients.add(buildApproveWorkgroupRecipient(workgroup)); 166 getDocumentService().routeDocument(customerInvoiceDocument, "This is a recurred Customer Invoice", adHocRouteRecipients); 167 invoiceRecurrence.setDocumentLastCreateDate(currentDate); 168 boService.save(invoiceRecurrence); 169 } 170 } 171 172 /* Check if this is the last recurrence. If yes, inactivate the INVR and send an FYI to the initiator and workgroup. */ 173 if (!nextProcessDate.before(endDate)) { 174 /* Change the active indicator to 'N' and send an FYI */ 175 String initiator = invoiceRecurrence.getDocumentInitiatorUserPersonUserIdentifier(); 176 GlobalVariables.setUserSession(new UserSession(initiator)); 177 178 MaintenanceDocument newMaintDoc = (MaintenanceDocument) getDocumentService().getNewDocument(getInvoiceRecurrenceMaintenanceDocumentTypeName()); 179 newMaintDoc.getOldMaintainableObject().setBusinessObject(invoiceRecurrence); 180 InvoiceRecurrence newInvoiceRecurrence = invoiceRecurrence; 181 newInvoiceRecurrence.setActive(false); 182 newMaintDoc.getDocumentHeader().setDocumentDescription("Generated by Batch process"); 183 newMaintDoc.getDocumentHeader().setExplanation("Inactivated by the Batch process"); 184 newMaintDoc.getNewMaintainableObject().setBusinessObject(newInvoiceRecurrence); 185 newMaintDoc.getNewMaintainableObject().setMaintenanceAction(KNSConstants.MAINTENANCE_EDIT_ACTION); 186 List<AdHocRouteRecipient> adHocRouteRecipients = new ArrayList<AdHocRouteRecipient>(); 187 adHocRouteRecipients.add(buildFyiPersonRecipient(initiator)); 188 //adHocRouteRecipients.add(buildFyiWorkgroupRecipient(workgroup)); 189 getDocumentService().routeDocument(newMaintDoc, null, adHocRouteRecipients); 190 newInvoiceRecurrence.setDocumentLastCreateDate(currentDate); 191 boService.save(newInvoiceRecurrence); 192 } 193 } 194 return true; 195 196 } 197 198 protected String getInvoiceRecurrenceMaintenanceDocumentTypeName() { 199 return "INVR"; 200 } 201 202 /** 203 * 204 * This method builds a FYI recipient. 205 * @param userId 206 * @return 207 */ 208 protected AdHocRouteRecipient buildFyiPersonRecipient(String userId) { 209 AdHocRouteRecipient adHocRouteRecipient = new AdHocRoutePerson(); 210 adHocRouteRecipient.setActionRequested(KEWConstants.ACTION_REQUEST_FYI_REQ); 211 adHocRouteRecipient.setId(userId); 212 return adHocRouteRecipient; 213 } 214 215 /** 216 * 217 * This method builds a recipient for Approval. 218 * @param userId 219 * @return 220 */ 221 protected AdHocRouteRecipient buildApprovePersonRecipient(String userId) { 222 AdHocRouteRecipient adHocRouteRecipient = new AdHocRoutePerson(); 223 adHocRouteRecipient.setActionRequested(KEWConstants.ACTION_REQUEST_APPROVE_REQ); 224 adHocRouteRecipient.setId(userId); 225 return adHocRouteRecipient; 226 } 227 228 /** 229 * 230 * This method builds a FYI workgroup recipient. 231 * @param userId 232 * @return 233 */ 234 protected AdHocRouteRecipient buildFyiWorkgroupRecipient(String workgroupId) { 235 AdHocRouteRecipient adHocRouteRecipient = new AdHocRouteWorkgroup(); 236 adHocRouteRecipient.setActionRequested(KEWConstants.ACTION_REQUEST_FYI_REQ); 237 adHocRouteRecipient.setId(workgroupId); 238 return adHocRouteRecipient; 239 } 240 241 /** 242 * 243 * This method builds a workgroup recipient for Approval. 244 * @param userId 245 * @return 246 */ 247 protected AdHocRouteRecipient buildApproveWorkgroupRecipient(String workgroupId) { 248 AdHocRouteRecipient adHocRouteRecipient = new AdHocRouteWorkgroup(); 249 adHocRouteRecipient.setActionRequested(KEWConstants.ACTION_REQUEST_APPROVE_REQ); 250 adHocRouteRecipient.setId(workgroupId); 251 return adHocRouteRecipient; 252 } 253 254 public InvoiceRecurrenceDao getInvoiceRecurrenceDao() { 255 return invoiceRecurrenceDao; 256 } 257 258 public void setInvoiceRecurrenceDao(InvoiceRecurrenceDao invoiceRecurrenceDao) { 259 this.invoiceRecurrenceDao = invoiceRecurrenceDao; 260 } 261 262 public void setBusinessObjectService (BusinessObjectService boService) 263 { 264 this.boService = boService; 265 } 266 }