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 }