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.document.validation.impl;
017    
018    import java.sql.Date;
019    import java.sql.Timestamp;
020    import java.util.Calendar;
021    
022    import org.kuali.kfs.module.ar.businessobject.InvoiceRecurrence;
023    import org.kuali.kfs.module.ar.document.CustomerInvoiceDocument;
024    import org.kuali.kfs.sys.context.SpringContext;
025    import org.kuali.rice.kew.exception.WorkflowException;
026    import org.kuali.rice.kns.document.Document;
027    import org.kuali.rice.kns.document.MaintenanceDocument;
028    import org.kuali.rice.kns.exception.UnknownDocumentIdException;
029    import org.kuali.rice.kns.rules.PromptBeforeValidationBase;
030    import org.kuali.rice.kns.service.DocumentService;
031    import org.kuali.rice.kns.util.DateUtils;
032    import org.kuali.rice.kns.util.ObjectUtils;
033    
034    public class InvoiceRecurrencePreRules extends PromptBeforeValidationBase {
035        private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(InvoiceRecurrencePreRules.class);
036        /**
037         * @see org.kuali.rice.kns.rules.PromptBeforeValidationBase#doRules(org.kuali.rice.kns.document.Document)
038         */
039        @Override
040        public boolean doPrompts(Document document) {
041            boolean preRulesOK = true;
042            preRulesOK &= setCustomerNumberIfInvoiceIsEntered(document);
043            preRulesOK &= setEndDateIfTotalRecurrenceNumberIsEntered(document);
044            preRulesOK &= setTotalRecurrenceNumberIfEndDateIsEntered(document);
045            return preRulesOK;
046        }
047    
048        /**
049         * @param document the maintenance document
050         * @return
051         */
052        protected boolean setCustomerNumberIfInvoiceIsEntered(Document document) {
053    
054    
055            MaintenanceDocument maintenanceDocument = (MaintenanceDocument) document;
056            InvoiceRecurrence newInvoiceRecurrence = (InvoiceRecurrence) maintenanceDocument.getNewMaintainableObject().getBusinessObject();
057    
058            if (ObjectUtils.isNull(newInvoiceRecurrence.getInvoiceNumber()) ||
059                ObjectUtils.isNotNull(newInvoiceRecurrence.getCustomerNumber())) {
060                return true;
061            }
062            
063            try {
064                if ( SpringContext.getBean(DocumentService.class).documentExists(newInvoiceRecurrence.getInvoiceNumber()) ) {
065                    CustomerInvoiceDocument customerInvoiceDocument = (CustomerInvoiceDocument)SpringContext.getBean(DocumentService.class).getByDocumentHeaderId(newInvoiceRecurrence.getInvoiceNumber());
066                    newInvoiceRecurrence.setCustomerNumber(customerInvoiceDocument.getCustomer().getCustomerNumber());
067                }
068            } catch (WorkflowException ex ) {
069                LOG.error( "Unable to retrieve document " + newInvoiceRecurrence.getInvoiceNumber() + " from workflow.", ex );
070            } catch ( UnknownDocumentIdException ex ) {
071                LOG.error( "Document " + newInvoiceRecurrence.getInvoiceNumber() + " does not exist." );
072            }
073            
074            return true;
075        }
076    
077        /**
078         * This method checks if there is another customer with the same name and generates yes/no question
079         * 
080         * @param document the maintenance document
081         * @return
082         */
083        protected boolean setEndDateIfTotalRecurrenceNumberIsEntered(Document document) {
084    
085    
086            MaintenanceDocument maintenanceDocument = (MaintenanceDocument) document;
087            InvoiceRecurrence newInvoiceRecurrence = (InvoiceRecurrence) maintenanceDocument.getNewMaintainableObject().getBusinessObject();
088    
089            if (ObjectUtils.isNull(newInvoiceRecurrence.getDocumentTotalRecurrenceNumber())) {
090                return true;
091            }
092            if (ObjectUtils.isNotNull(newInvoiceRecurrence.getDocumentRecurrenceEndDate()) && ObjectUtils.isNotNull(newInvoiceRecurrence.getDocumentTotalRecurrenceNumber())) {
093                return true;
094            }
095            
096            Calendar beginCalendar = Calendar.getInstance();
097            beginCalendar.setTime(new Timestamp(newInvoiceRecurrence.getDocumentRecurrenceBeginDate().getTime()));
098            Calendar endCalendar = Calendar.getInstance();
099            endCalendar = beginCalendar;
100            
101            int addCounter = 0;
102            Integer documentTotalRecurrenceNumber = newInvoiceRecurrence.getDocumentTotalRecurrenceNumber();
103            String intervalCode = newInvoiceRecurrence.getDocumentRecurrenceIntervalCode();
104            if (intervalCode.equals("M")) {
105                addCounter = -1;
106                addCounter += documentTotalRecurrenceNumber * 1;
107            }
108            if (intervalCode.equals("Q")) {
109                addCounter = -3;
110                addCounter += documentTotalRecurrenceNumber * 3;
111            }
112            endCalendar.add(Calendar.MONTH, addCounter);
113            newInvoiceRecurrence.setDocumentRecurrenceEndDate(DateUtils.convertToSqlDate(endCalendar.getTime()));
114            
115            return true;
116        }
117    
118        /**
119         * This method calculates the total number of recurrences when a begin date and end date is entered.
120         * 
121         * @param document the maintenance document
122         * @return
123         */
124        protected boolean setTotalRecurrenceNumberIfEndDateIsEntered(Document document) {
125    
126            MaintenanceDocument maintenanceDocument = (MaintenanceDocument) document;
127            InvoiceRecurrence newInvoiceRecurrence = (InvoiceRecurrence) maintenanceDocument.getNewMaintainableObject().getBusinessObject();
128            
129            if (ObjectUtils.isNull(newInvoiceRecurrence.getDocumentRecurrenceEndDate())) {
130                return true;            
131            }
132            if (ObjectUtils.isNotNull(newInvoiceRecurrence.getDocumentRecurrenceEndDate()) && ObjectUtils.isNotNull(newInvoiceRecurrence.getDocumentTotalRecurrenceNumber())) {
133                return true;
134            }
135            
136            Calendar beginCalendar = Calendar.getInstance();
137    /*
138     *      beginCalendar.setTime(new Timestamp(newInvoiceRecurrence.getDocumentRecurrenceBeginDate().getTime()));
139     */
140            beginCalendar.setTime(newInvoiceRecurrence.getDocumentRecurrenceBeginDate());
141            Date beginDate = newInvoiceRecurrence.getDocumentRecurrenceBeginDate();
142            Calendar endCalendar = Calendar.getInstance();
143    /*
144     *      endCalendar.setTime(new Timestamp(newInvoiceRecurrence.getDocumentRecurrenceEndDate().getTime()));
145     */
146            endCalendar.setTime(newInvoiceRecurrence.getDocumentRecurrenceEndDate());
147            Date endDate = newInvoiceRecurrence.getDocumentRecurrenceEndDate();
148            Calendar nextCalendar = Calendar.getInstance();
149            Date nextDate = beginDate;
150            
151            int totalRecurrences = 0;
152            int addCounter = 0;
153            String intervalCode = newInvoiceRecurrence.getDocumentRecurrenceIntervalCode();
154            if (intervalCode.equals("M")) {
155                addCounter = 1;
156            }
157            if (intervalCode.equals("Q")) {
158                addCounter = 3;
159            }
160            /* perform this loop while begin_date is less than or equal to end_date */
161            while (!(beginDate.after(endDate))){
162                beginCalendar.setTime(beginDate);
163                beginCalendar.add(Calendar.MONTH, addCounter);
164                beginDate = DateUtils.convertToSqlDate(beginCalendar.getTime());
165                totalRecurrences++;
166    
167                nextDate = beginDate;
168                nextCalendar.setTime(nextDate);
169                nextCalendar.add(Calendar.MONTH, addCounter);
170                nextDate = DateUtils.convertToSqlDate(nextCalendar.getTime());
171                if (endDate.after(beginDate) && endDate.before(nextDate)) {
172                    totalRecurrences++;
173                    break;
174                }
175            }
176            if (totalRecurrences > 0) {
177                newInvoiceRecurrence.setDocumentTotalRecurrenceNumber(totalRecurrences);
178            }
179            return true;
180        }
181    
182    }