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.service.impl;
017    
018    import java.sql.Date;
019    import java.sql.Timestamp;
020    import java.util.Calendar;
021    import java.util.HashMap;
022    import java.util.List;
023    import java.util.Map;
024    
025    import org.apache.commons.lang.StringUtils;
026    import org.kuali.kfs.module.ar.ArConstants;
027    import org.kuali.kfs.module.ar.businessobject.CustomerAddress;
028    import org.kuali.kfs.module.ar.businessobject.CustomerInvoiceDetail;
029    import org.kuali.kfs.module.ar.businessobject.InvoiceRecurrence;
030    import org.kuali.kfs.module.ar.businessobject.OrganizationOptions;
031    import org.kuali.kfs.module.ar.document.CustomerInvoiceDocument;
032    import org.kuali.kfs.module.ar.document.service.CustomerAddressService;
033    import org.kuali.kfs.module.ar.document.service.InvoiceRecurrenceDocumentService;
034    import org.kuali.kfs.sys.context.SpringContext;
035    import org.kuali.kfs.sys.service.impl.KfsParameterConstants;
036    import org.kuali.rice.kew.exception.WorkflowException;
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.service.ParameterService;
041    import org.kuali.rice.kns.util.DateUtils;
042    import org.kuali.rice.kns.util.ObjectUtils;
043    import org.kuali.rice.kns.workflow.service.KualiWorkflowDocument;
044    
045    public class InvoiceRecurrenceDocumentServiceImpl implements InvoiceRecurrenceDocumentService {
046        
047        private ParameterService parameterService;
048        private BusinessObjectService businessObjectService;
049        
050        /**
051         * @see org.kuali.kfs.module.ar.document.service.AccountsReceivableTaxService#isCustomerInvoiceDetailTaxable(org.kuali.kfs.module.ar.document.CustomerInvoiceDocument, org.kuali.kfs.module.ar.businessobject.CustomerInvoiceDetail)
052         */
053        public boolean isCustomerInvoiceDetailTaxable(CustomerInvoiceDocument customerInvoiceDocument, CustomerInvoiceDetail customerInvoiceDetail) {
054    
055            //check if sales tax is enabled
056            if( !parameterService.getIndicatorParameter(KfsParameterConstants.ACCOUNTS_RECEIVABLE_DOCUMENT.class, ArConstants.ENABLE_SALES_TAX_IND) ){
057                return false;
058            }
059    
060            //check if customer is tax exempt
061            if( ObjectUtils.isNotNull(customerInvoiceDocument.getCustomer() ) ){
062                if( customerInvoiceDocument.getCustomer().isCustomerTaxExemptIndicator()){
063                    return false;
064                }
065            }
066            
067            //check item if the taxable indicator is checked
068            if (!customerInvoiceDetail.isTaxableIndicator()) {
069                return false;
070            }
071            
072            //check item if item is taxable
073            /*
074            if( StringUtils.isNotEmpty(customerInvoiceDetail.getInvoiceItemCode()) ){
075                Map<String, String> criteria = new HashMap<String, String>();
076                criteria.put("invoiceItemCode", customerInvoiceDetail.getInvoiceItemCode());
077                criteria.put("chartOfAccountsCode", customerInvoiceDocument.getAccountsReceivableDocumentHeader().getProcessingChartOfAccountCode());
078                criteria.put("organizationCode", customerInvoiceDocument.getAccountsReceivableDocumentHeader().getProcessingOrganizationCode());
079                CustomerInvoiceItemCode customerInvoiceItemCode = (CustomerInvoiceItemCode) businessObjectService.findByPrimaryKey(CustomerInvoiceItemCode.class, criteria);
080                
081                if (ObjectUtils.isNotNull(customerInvoiceItemCode) && !customerInvoiceItemCode.isTaxableIndicator()){
082                    return false;
083                }
084            }
085            */
086            
087            //if address of billing org's postal code isn't the same as shipping address, return false??? 
088            
089            return true;
090        }
091        
092        /**
093         * @see org.kuali.kfs.module.ar.document.service.AccountsReceivableTaxService#getPostalCodeForTaxation(org.kuali.kfs.module.ar.document.CustomerInvoiceDocument)
094         */
095        public String getPostalCodeForTaxation(CustomerInvoiceDocument document) {
096            
097            String postalCode = null;
098            String customerNumber = document.getAccountsReceivableDocumentHeader().getCustomerNumber();
099            Integer shipToAddressIdentifier = document.getCustomerShipToAddressIdentifier();
100            
101            //if customer number or ship to address id isn't provided, go to org options
102            if (ObjectUtils.isNotNull(shipToAddressIdentifier) && StringUtils.isNotEmpty(customerNumber) ) {
103                
104                CustomerAddressService customerAddressService = SpringContext.getBean(CustomerAddressService.class);
105                CustomerAddress customerShipToAddress = customerAddressService.getByPrimaryKey(customerNumber, shipToAddressIdentifier);
106                if( ObjectUtils.isNotNull(customerShipToAddress) ){
107                    postalCode = customerShipToAddress.getCustomerZipCode();
108                }
109            }
110            else {
111                Map<String, String> criteria = new HashMap<String, String>();
112                criteria.put("chartOfAccountsCode", document.getBillByChartOfAccountCode());
113                criteria.put("organizationCode", document.getBilledByOrganizationCode());
114                OrganizationOptions organizationOptions = (OrganizationOptions) businessObjectService.findByPrimaryKey(OrganizationOptions.class, criteria);
115    
116                if (ObjectUtils.isNotNull(organizationOptions)) {
117                    postalCode = organizationOptions.getOrganizationPostalZipCode();
118                }
119    
120               
121            }
122            return postalCode;
123        }        
124    
125        /**
126         * @see org.kuali.kfs.module.ar.document.service.InvoiceRecurrenceService#isInvoiceApproved(String)
127         */
128        public boolean isInvoiceApproved( String invoiceNumber ) {
129            boolean success = true;
130            
131            if (ObjectUtils.isNull(invoiceNumber)) {
132                return success;
133            }
134            
135            CustomerInvoiceDocument customerInvoiceDocument = null;
136            try {
137                customerInvoiceDocument = (CustomerInvoiceDocument)SpringContext.getBean(DocumentService.class).getByDocumentHeaderId(invoiceNumber);
138            } catch (WorkflowException e){
139                
140            }
141            if (ObjectUtils.isNotNull(customerInvoiceDocument)) {
142                KualiWorkflowDocument workflowDocument = customerInvoiceDocument.getDocumentHeader().getWorkflowDocument();
143                if (!(workflowDocument.stateIsApproved())) {
144                    success = false;
145                }
146            }
147            else {
148                success = false;
149            }
150            return success;
151        }
152            
153        /**
154         * @see org.kuali.kfs.module.ar.document.service.InvoiceRecurrenceService#isValidRecurrenceBeginDate(Date)
155         */
156        public boolean isValidRecurrenceBeginDate(Date beginDate) {
157            boolean success = true;
158            if (ObjectUtils.isNull(beginDate)) {
159                return success;
160            }
161            Timestamp currentDate = new Timestamp(SpringContext.getBean(DateTimeService.class).getCurrentDate().getTime());
162            Timestamp beginDateTimestamp = new Timestamp(beginDate.getTime());
163            if (beginDateTimestamp.before(currentDate) || beginDateTimestamp.equals(currentDate)) {
164                return false;
165            }
166            return success;
167        }
168            
169        /**
170         * @see org.kuali.kfs.module.ar.document.service.InvoiceRecurrenceService#isValidRecurrenceEndDate(Date)
171         */
172        public boolean isValidRecurrenceEndDate(Date beginDate, Date endDate) {
173            boolean success = true;
174            if (ObjectUtils.isNull(beginDate) || 
175                ObjectUtils.isNull(endDate)) {
176                return success;
177            }
178            Timestamp beginDateTimestamp = new Timestamp(beginDate.getTime());
179            Timestamp endDateTimestamp = new Timestamp(endDate.getTime());
180            if ((ObjectUtils.isNotNull(endDateTimestamp)) &&
181                (endDateTimestamp.before(beginDateTimestamp) || endDateTimestamp.equals(beginDateTimestamp))) {
182                return false;
183            }
184            return success;
185        }
186            
187        /**
188         * @see org.kuali.kfs.module.ar.document.service.InvoiceRecurrenceService#isValidEndDateAndTotalRecurrenceNumber(Date,Date,int,String)
189         */
190        public boolean isValidEndDateAndTotalRecurrenceNumber( Date recurrenceBeginDate, Date recurrenceEndDate, Integer totalRecurrenceNumber, String recurrenceIntervalCode ) {
191    
192            if (ObjectUtils.isNull(recurrenceBeginDate) || 
193                ObjectUtils.isNull(recurrenceIntervalCode) ||
194                ObjectUtils.isNull(recurrenceEndDate) ||
195                ObjectUtils.isNull(totalRecurrenceNumber)) {
196                return true;
197            }
198    
199            Calendar beginCalendar = Calendar.getInstance();
200            beginCalendar.setTime(recurrenceBeginDate);
201            Date beginDate = recurrenceBeginDate;
202            Calendar endCalendar = Calendar.getInstance();
203            endCalendar.setTime(recurrenceEndDate);
204            Date endDate = recurrenceEndDate;
205            Calendar nextCalendar = Calendar.getInstance();
206            Date nextDate = beginDate;
207                    
208            int totalRecurrences = 0;
209            int addCounter = 0;
210            String intervalCode = recurrenceIntervalCode;
211            if (intervalCode.equals("M")) {
212                addCounter = 1;
213            }
214            if (intervalCode.equals("Q")) {
215                addCounter = 3;
216            }
217            /* perform this loop while begin_date is less than or equal to end_date */
218            while (!(beginDate.after(endDate))){
219                beginCalendar.setTime(beginDate);
220                beginCalendar.add(Calendar.MONTH, addCounter);
221                beginDate = DateUtils.convertToSqlDate(beginCalendar.getTime());
222                totalRecurrences++;
223    
224                nextDate = beginDate;
225                nextCalendar.setTime(nextDate);
226                nextCalendar.add(Calendar.MONTH, addCounter);
227                nextDate = DateUtils.convertToSqlDate(nextCalendar.getTime());
228                if (endDate.after(beginDate) && endDate.before(nextDate)) {
229                    totalRecurrences++;
230                    break;
231                }
232            }
233            if (totalRecurrences != totalRecurrenceNumber.intValue()) {
234                return false;
235            }
236            
237            return true;
238        }
239        
240        /**
241         * @see org.kuali.kfs.module.ar.document.service.InvoiceRecurrenceService#isValidEndDateOrTotalRecurrenceNumber(Date,int)
242         */
243        public boolean isValidEndDateOrTotalRecurrenceNumber( Date endDate, Integer totalRecurrenceNumber ) {
244            boolean success = true;
245            if (ObjectUtils.isNull(endDate) && ObjectUtils.isNull(totalRecurrenceNumber)) {
246                return false;
247            }
248            return success;
249        }
250    
251        /**
252         * @see org.kuali.kfs.module.ar.document.service.InvoiceRecurrenceService#isValidMaximumNumberOfRecurrences(int,String)
253         */
254        public boolean isValidMaximumNumberOfRecurrences( Integer totalRecurrenceNumber, String intervalCode ) {
255    
256            if (ObjectUtils.isNull(intervalCode) ||
257                ObjectUtils.isNull(totalRecurrenceNumber)) {
258                return true;
259            }
260            Integer maximumRecurrencesByInterval;
261            if (ObjectUtils.isNotNull(intervalCode)) {
262                List<String> maximumRecurrences = SpringContext.getBean(ParameterService.class).getParameterValues(InvoiceRecurrence.class, ArConstants.MAXIMUM_RECURRENCES_BY_INTERVAL, intervalCode);
263                if (maximumRecurrences.size() > 0 && StringUtils.isNotBlank(maximumRecurrences.get(0))) {
264                    maximumRecurrencesByInterval = Integer.valueOf(maximumRecurrences.get(0));
265                    if (totalRecurrenceNumber > maximumRecurrencesByInterval) {
266                        return false;
267                    }
268                }
269            }
270            return true;
271        }
272            
273        /**
274         * @see org.kuali.kfs.module.ar.document.service.InvoiceRecurrenceService#isValidInitiator(String)
275         */
276        public boolean isValidInitiator( String initiator ) {
277            return true;
278        }
279            
280        public ParameterService getParameterService() {
281            return parameterService;
282        }
283    
284        public void setParameterService(ParameterService parameterService) {
285            this.parameterService = parameterService;
286        }
287    
288        public BusinessObjectService getBusinessObjectService() {
289            return businessObjectService;
290        }
291    
292        public void setBusinessObjectService(BusinessObjectService businessObjectService) {
293            this.businessObjectService = businessObjectService;
294        }
295    }