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    /*
017     * Created on Feb 13, 2006
018     *
019     */
020    package org.kuali.kfs.module.purap.businessobject;
021    
022    import java.math.BigDecimal;
023    import java.text.ParseException;
024    import java.text.SimpleDateFormat;
025    import java.util.ArrayList;
026    import java.util.Collections;
027    import java.util.Comparator;
028    import java.util.Date;
029    import java.util.Iterator;
030    import java.util.List;
031    import java.util.Locale;
032    
033    import org.apache.commons.lang.builder.ToStringBuilder;
034    import org.kuali.kfs.module.purap.PurapConstants;
035    import org.kuali.kfs.module.purap.service.ElectronicInvoiceMappingService;
036    import org.kuali.kfs.module.purap.util.ElectronicInvoiceUtils;
037    
038    public class ElectronicInvoiceOrder {
039      private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(ElectronicInvoiceOrder.class);
040      
041      public static boolean INVOICE_ORDER_REJECTED = true;
042      public static boolean INVOICE_ORDER_NOT_REJECTED = false;
043      
044      // the following fields come from the <InvoiceDetailOrderInfo> tag
045      private String orderReferenceOrderID;
046      private String orderReferenceDocumentRefPayloadID;
047      private String orderReferenceDocumentRef;
048      private String masterAgreementReferenceID;
049      private Date masterAgreementReferenceDate;
050      private String masterAgreementReferenceDateString;
051      private String masterAgreementIDInfoID;
052      private Date masterAgreementIDInfoDate;
053      private String masterAgreementIDInfoDateString;
054      private String orderIDInfoID;
055      private Date orderIDInfoDate;
056      private String orderIDInfoDateString;
057      private String supplierOrderInfoID;
058      
059      private String invoicePurchaseOrderID;
060      private String orderReferenceOrderDateString;
061      private Integer purchaseOrderID = null;
062      private String purchaseOrderCampusCode;
063      
064      private boolean rejected = INVOICE_ORDER_NOT_REJECTED;
065      private List orderRejectReasons = new ArrayList();
066      
067      private List invoiceItems = new ArrayList();
068      
069      public ElectronicInvoiceOrder() {
070        super();
071      }
072      
073      public ElectronicInvoiceItem getElectronicInvoiceItemByPOLineNumber(Integer poLineNumber) {
074        for (Iterator iter = this.invoiceItems.iterator(); iter.hasNext();) {
075          ElectronicInvoiceItem eii = (ElectronicInvoiceItem) iter.next();
076          if ((poLineNumber.compareTo(eii.getReferenceLineNumberInteger())) == 0) {
077            return eii;
078          }
079        }
080        return null;
081      }
082      
083      /**
084       * This method takes in a roleID string and an addressName (constants from mapping file)
085       * and returns a valid ElectronicInvoicePostalAddress or null if not found.  If the addressName string
086       * is null then the roleID is used to find the first available
087       * 
088       * @param roleID Cxml role id attribute value
089       * @param addressName Cxml name attribute of postaladdress tag
090       * @return CxmlPostal Address relating to given parameters
091       */
092      public ElectronicInvoicePostalAddress getCxmlPostalAddressByRoleID(String roleID,String addressName) {
093        if (roleID != null) {
094          ElectronicInvoiceContact contact = this.getCxmlContactByRoleID(roleID);
095          if (contact != null) {
096            for (Iterator iterator = contact.getPostalAddresses().iterator(); iterator.hasNext();) {
097              ElectronicInvoicePostalAddress cpa = (ElectronicInvoicePostalAddress) iterator.next();
098              if (addressName == null) {
099                return cpa;
100              } else {
101                if (addressName.equalsIgnoreCase(cpa.getName())) {
102                  return cpa;
103                }
104              }
105            }
106          }
107        }
108        return null;
109      }
110      
111      public ElectronicInvoiceContact getCxmlContactByRoleID(String roleID) {
112        if (roleID != null) {
113          for (Iterator itemIter = this.invoiceItems.iterator(); itemIter.hasNext();) {
114            ElectronicInvoiceItem eii = (ElectronicInvoiceItem) itemIter.next();
115            for (Iterator iter = eii.getInvoiceShippingContacts().iterator(); iter.hasNext();) {
116              ElectronicInvoiceContact contact = (ElectronicInvoiceContact) iter.next();
117              if (roleID.equalsIgnoreCase(contact.getRole())) {
118                return contact;
119              }
120            }
121          }
122        }
123        return null;
124      }
125      /**
126       * This method returns the first shipping date found in the list of items.  This 
127       * is called if shipping information is in line. Since system only allows for one 
128       * shipping date per invoice-order we take the first date we find
129       * 
130       * @return  Date defining first shipping date found or null if none are found
131       */
132      public Date getInvoiceShippingDate() {
133        for (Iterator iter = this.invoiceItems.iterator(); iter.hasNext();) {
134          ElectronicInvoiceItem eii = (ElectronicInvoiceItem) iter.next();
135          Date testDate = eii.getShippingDate();
136          if (testDate != null) {
137            return testDate;
138          }
139        }
140        return null;
141      }
142      
143      /**
144       * This method returns the first shipping date string found in the list of items.  This 
145       * is called if shipping information is in line. Since system only allows for one shipping 
146       * date per invoice-order we take the first date string we find
147       * 
148       * @return  Date defining first shipping date found or null if none are found
149       */
150      public String getInvoiceShippingDateString() {
151        for (Iterator iter = this.invoiceItems.iterator(); iter.hasNext();) {
152          ElectronicInvoiceItem eii = (ElectronicInvoiceItem) iter.next();
153          String testDateString = eii.getShippingDateString();
154          if ( (testDateString != null) && (!("".equals(testDateString))) ) {
155            return testDateString;
156          }
157        }
158        return null;
159      }
160      
161      public String getInvoiceTaxDescription() {
162        BigDecimal total = BigDecimal.ZERO;
163        for (Iterator iter = this.invoiceItems.iterator(); iter.hasNext();) {
164          ElectronicInvoiceItem eii = (ElectronicInvoiceItem) iter.next();
165          BigDecimal taxAmount = eii.getInvoiceLineTaxAmountBigDecimal(); 
166          if ( (taxAmount != null) && (BigDecimal.ZERO.compareTo(taxAmount) != 0) ) {
167            return eii.getTaxDescription();
168          }
169        }
170        return null;
171      }
172    
173      public String getInvoiceShippingDescription() {
174        BigDecimal total = BigDecimal.ZERO;
175        for (Iterator iter = this.invoiceItems.iterator(); iter.hasNext();) {
176          ElectronicInvoiceItem eii = (ElectronicInvoiceItem) iter.next();
177          BigDecimal shippingAmount = eii.getInvoiceLineShippingAmountBigDecimal(); 
178          if ( (shippingAmount != null) && (BigDecimal.ZERO.compareTo(shippingAmount) != 0) ) {
179            return PurapConstants.ElectronicInvoice.DEFAULT_SHIPPING_DESCRIPTION;
180          }
181        }
182        return null;
183      }
184      
185      public String getInvoiceSpecialHandlingDescription() {
186          BigDecimal total = BigDecimal.ZERO;
187          for (Iterator iter = this.invoiceItems.iterator(); iter.hasNext();) {
188            ElectronicInvoiceItem eii = (ElectronicInvoiceItem) iter.next();
189            BigDecimal specialHandlingAmount = eii.getInvoiceLineSpecialHandlingAmountBigDecimal(); 
190            if ( (specialHandlingAmount != null) && (BigDecimal.ZERO.compareTo(specialHandlingAmount) != 0) ) {
191              return PurapConstants.ElectronicInvoice.DEFAULT_SPECIAL_HANDLING_DESCRIPTION;
192            }
193          }
194          return null;
195        }
196      
197    
198      public BigDecimal getInvoiceSubTotalAmount() {
199        BigDecimal total = BigDecimal.ZERO;
200        for (Iterator iter = this.invoiceItems.iterator(); iter.hasNext();) {
201          ElectronicInvoiceItem eii = (ElectronicInvoiceItem) iter.next();
202          total = total.add(eii.getInvoiceLineSubTotalAmountBigDecimal());
203        }
204        return total;
205      }
206    
207      public BigDecimal getInvoiceTaxAmount() {
208        BigDecimal total = BigDecimal.ZERO;
209        for (Iterator iter = this.invoiceItems.iterator(); iter.hasNext();) {
210          ElectronicInvoiceItem eii = (ElectronicInvoiceItem) iter.next();
211          total = total.add(eii.getInvoiceLineTaxAmountBigDecimal());
212        }
213        return total;
214      }
215    
216      public BigDecimal getInvoiceSpecialHandlingAmount() {
217        BigDecimal total = BigDecimal.ZERO;
218        for (Iterator iter = this.invoiceItems.iterator(); iter.hasNext();) {
219          ElectronicInvoiceItem eii = (ElectronicInvoiceItem) iter.next();
220          total = total.add(eii.getInvoiceLineSpecialHandlingAmountBigDecimal());
221        }
222        return total;
223      }
224    
225      public BigDecimal getInvoiceShippingAmount() {
226        BigDecimal total = BigDecimal.ZERO;
227        for (Iterator iter = this.invoiceItems.iterator(); iter.hasNext();) {
228          ElectronicInvoiceItem eii = (ElectronicInvoiceItem) iter.next();
229          total = total.add(eii.getInvoiceLineShippingAmountBigDecimal());
230        }
231        return total;
232      }
233    
234      public BigDecimal getInvoiceGrossAmount() {
235        BigDecimal total = BigDecimal.ZERO;
236        for (Iterator iter = this.invoiceItems.iterator(); iter.hasNext();) {
237          ElectronicInvoiceItem eii = (ElectronicInvoiceItem) iter.next();
238          total = total.add(eii.getInvoiceLineGrossAmountBigDecimal());
239        }
240        return total;
241      }
242    
243      public BigDecimal getInvoiceDiscountAmount() {
244        BigDecimal total = BigDecimal.ZERO;
245        for (Iterator iter = this.invoiceItems.iterator(); iter.hasNext();) {
246          ElectronicInvoiceItem eii = (ElectronicInvoiceItem) iter.next();
247          total = total.add(eii.getInvoiceLineDiscountAmountBigDecimal());
248        }
249        return total;
250      }
251    
252      public BigDecimal getInvoiceNetAmount() {
253        BigDecimal total = BigDecimal.ZERO;
254        for (Iterator iter = this.invoiceItems.iterator(); iter.hasNext();) {
255          ElectronicInvoiceItem eii = (ElectronicInvoiceItem) iter.next();
256          total = total.add(eii.getInvoiceLineNetAmountBigDecimal());
257        }
258        return total;
259      }
260      
261      public void addRejectReasonToList(ElectronicInvoiceRejectReason reason) {
262        this.orderRejectReasons.add(reason);
263      }
264        
265      /**
266       * Altered for special circumstances
267       * 
268       * @param masterAgreementIDInfoDateString The masterAgreementIDInfoDateString to set.
269       */
270      public void setMasterAgreementIDInfoDateString(String masterAgreementIDInfoDateString) {
271        this.masterAgreementIDInfoDateString = masterAgreementIDInfoDateString;
272        /*if ( (masterAgreementIDInfoDateString != null) && (!("".equals(masterAgreementIDInfoDateString))) ) {
273          SimpleDateFormat sdf = new SimpleDateFormat(PurapConstants.ElectronicInvoice.CXML_DATE_FORMAT, Locale.US);
274          try {
275            this.masterAgreementIDInfoDate = sdf.parse(masterAgreementIDInfoDateString);
276          } catch (ParseException e) {
277            // setting invoice date to null to identify problem
278            LOG.error("setInvoiceDateString() SimpleDateFormat parser error attempting to set invalid date string " + masterAgreementIDInfoDateString + " in masterAgreementIDInfoDate field... setting date to null");
279            this.masterAgreementIDInfoDate = null;
280          }
281        } else {
282          this.masterAgreementIDInfoDate = null;
283        }*/
284        setMasterAgreementIDInfoDate(ElectronicInvoiceUtils.getDate(masterAgreementIDInfoDateString));
285      }
286      /**
287       * Altered for special circumstances
288       * 
289       * @param masterAgreementReferenceDateString The masterAgreementReferenceDateString to set.
290       */
291      public void setMasterAgreementReferenceDateString(String masterAgreementReferenceDateString) {
292        this.masterAgreementReferenceDateString = masterAgreementReferenceDateString;
293        /*if ( (masterAgreementReferenceDateString != null) && (!("".equals(masterAgreementReferenceDateString))) ) {
294          SimpleDateFormat sdf = new SimpleDateFormat(PurapConstants.ElectronicInvoice.CXML_DATE_FORMAT, Locale.US);
295          try {
296            this.masterAgreementReferenceDate = sdf.parse(masterAgreementReferenceDateString);
297          } catch (ParseException e) {
298            // setting invoice date to null to identify problem
299            LOG.error("setInvoiceDateString() SimpleDateFormat parser error attempting to set invalid date string " + masterAgreementReferenceDateString + " in masterAgreementReferenceDate field... setting date to null");
300            this.masterAgreementReferenceDate = null;
301          }
302        } else {
303          this.masterAgreementIDInfoDate = null;
304        }*/
305        setMasterAgreementIDInfoDate(ElectronicInvoiceUtils.getDate(masterAgreementReferenceDateString));
306      }
307      /**
308       * Altered for special circumstances
309       * 
310       * @param orderIDInfoDateString The orderIDInfoDateString to set.
311       */
312      public void setOrderIDInfoDateString(String orderIDInfoDateString) {
313        this.orderIDInfoDateString = orderIDInfoDateString;
314        /*if ( (orderIDInfoDateString != null) && (!("".equals(orderIDInfoDateString))) ) {
315          SimpleDateFormat sdf = new SimpleDateFormat(PurapConstants.ElectronicInvoice.CXML_DATE_FORMAT, Locale.US);
316          try {
317            this.orderIDInfoDate = sdf.parse(orderIDInfoDateString);
318          } catch (ParseException e) {
319            // setting invoice date to null to identify problem
320            LOG.error("setInvoiceDateString() SimpleDateFormat parser error attempting to set invalid date string " + orderIDInfoDateString + " in orderIDInfoDate field... setting date to null");
321            this.orderIDInfoDate = null;
322          }
323        } else {
324          this.orderIDInfoDate = null;
325        }*/
326        setOrderIDInfoDate(ElectronicInvoiceUtils.getDate(orderIDInfoDateString));
327      }
328      /**
329       * @return Returns the invoiceItems.
330       */
331      public List<ElectronicInvoiceItem> getInvoiceItems() {
332        return invoiceItems;
333      }
334      /**
335       * @param invoiceItems The invoiceItems to set.
336       */
337      public void setInvoiceItems(List<ElectronicInvoiceItem> invoiceItems) {
338        this.invoiceItems = invoiceItems;
339      }
340      /**
341       * @return Returns the invoicePurchaseOrderID.
342       */
343      public String getInvoicePurchaseOrderID() {
344        return invoicePurchaseOrderID;
345      }
346      /**
347       * @param invoicePurchaseOrderID The invoicePurchaseOrderID to set.
348       */
349      public void setInvoicePurchaseOrderID(String invoicePurchaseOrderID) {
350        this.invoicePurchaseOrderID = invoicePurchaseOrderID;
351      }
352      /**
353       * @return Returns the masterAgreementIDInfoDate.
354       */
355      public Date getMasterAgreementIDInfoDate() {
356        return masterAgreementIDInfoDate;
357      }
358      /**
359       * @param masterAgreementIDInfoDate The masterAgreementIDInfoDate to set.
360       */
361      public void setMasterAgreementIDInfoDate(Date masterAgreementIDInfoDate) {
362        this.masterAgreementIDInfoDate = masterAgreementIDInfoDate;
363      }
364      /**
365       * @return Returns the masterAgreementIDInfoID.
366       */
367      public String getMasterAgreementIDInfoID() {
368        return masterAgreementIDInfoID;
369      }
370      /**
371       * @param masterAgreementIDInfoID The masterAgreementIDInfoID to set.
372       */
373      public void setMasterAgreementIDInfoID(String masterAgreementIDInfoID) {
374        this.masterAgreementIDInfoID = masterAgreementIDInfoID;
375      }
376      /**
377       * @return Returns the masterAgreementReferenceDate.
378       */
379      public Date getMasterAgreementReferenceDate() {
380        return masterAgreementReferenceDate;
381      }
382      /**
383       * @param masterAgreementReferenceDate The masterAgreementReferenceDate to set.
384       */
385      public void setMasterAgreementReferenceDate(Date masterAgreementReferenceDate) {
386        this.masterAgreementReferenceDate = masterAgreementReferenceDate;
387      }
388      /**
389       * @return Returns the masterAgreementReferenceID.
390       */
391      public String getMasterAgreementReferenceID() {
392        return masterAgreementReferenceID;
393      }
394      /**
395       * @param masterAgreementReferenceID The masterAgreementReferenceID to set.
396       */
397      public void setMasterAgreementReferenceID(String masterAgreementReferenceID) {
398        this.masterAgreementReferenceID = masterAgreementReferenceID;
399      }
400      /**
401       * @return Returns the orderIDInfoDate.
402       */
403      public Date getOrderIDInfoDate() {
404        return orderIDInfoDate;
405      }
406      /**
407       * @param orderIDInfoDate The orderIDInfoDate to set.
408       */
409      public void setOrderIDInfoDate(Date orderIDInfoDate) {
410        this.orderIDInfoDate = orderIDInfoDate;
411      }
412      /**
413       * @return Returns the orderIDInfoID.
414       */
415      public String getOrderIDInfoID() {
416        return orderIDInfoID;
417      }
418      /**
419       * @param orderIDInfoID The orderIDInfoID to set.
420       */
421      public void setOrderIDInfoID(String orderIDInfoID) {
422        this.orderIDInfoID = orderIDInfoID;
423      }
424      /**
425       * @return Returns the orderReferenceDocumentRef.
426       */
427      public String getOrderReferenceDocumentRef() {
428        return orderReferenceDocumentRef;
429      }
430      /**
431       * @param orderReferenceDocumentRef The orderReferenceDocumentRef to set.
432       */
433      public void setOrderReferenceDocumentRef(String orderReferenceDocumentRef) {
434        this.orderReferenceDocumentRef = orderReferenceDocumentRef;
435      }
436      /**
437       * @return Returns the orderReferenceDocumentRefPayloadID.
438       */
439      public String getOrderReferenceDocumentRefPayloadID() {
440        return orderReferenceDocumentRefPayloadID;
441      }
442      /**
443       * @param orderReferenceDocumentRefPayloadID The orderReferenceDocumentRefPayloadID to set.
444       */
445      public void setOrderReferenceDocumentRefPayloadID(String orderReferenceDocumentRefPayloadID) {
446        this.orderReferenceDocumentRefPayloadID = orderReferenceDocumentRefPayloadID;
447      }
448      /**
449       * @return Returns the orderReferenceOrderID.
450       */
451      public String getOrderReferenceOrderID() {
452        return orderReferenceOrderID;
453      }
454      /**
455       * @param orderReferenceOrderID The orderReferenceOrderID to set.
456       */
457      public void setOrderReferenceOrderID(String orderReferenceOrderID) {
458        this.orderReferenceOrderID = orderReferenceOrderID;
459      }
460      /**
461       * @return Returns the orderRejectReasons.
462       */
463      public List<ElectronicInvoiceRejectReason> getOrderRejectReasons() {
464        return orderRejectReasons;
465      }
466      /**
467       * @param orderRejectReasons The orderRejectReasons to set.
468       */
469      public void setOrderRejectReasons(List<ElectronicInvoiceRejectReason> orderRejectReasons) {
470        this.orderRejectReasons = orderRejectReasons;
471      }
472      /**
473       * @return Returns the purchaseOrderCampusCode.
474       */
475      public String getPurchaseOrderCampusCode() {
476        return purchaseOrderCampusCode;
477      }
478      /**
479       * @param purchaseOrderCampusCode The purchaseOrderCampusCode to set.
480       */
481      public void setPurchaseOrderCampusCode(String purchaseOrderCampusCode) {
482        this.purchaseOrderCampusCode = purchaseOrderCampusCode;
483      }
484      /**
485       * @return Returns the purchaseOrderID.
486       */
487      public Integer getPurchaseOrderID() {
488        return purchaseOrderID;
489      }
490      /**
491       * @param purchaseOrderID The purchaseOrderID to set.
492       */
493      public void setPurchaseOrderID(Integer purchaseOrderID) {
494        this.purchaseOrderID = purchaseOrderID;
495      }
496      /**
497       * @return Returns the rejected.
498       */
499      public boolean isRejected() {
500        return rejected;
501      }
502      /**
503       * @param rejected The rejected to set.
504       */
505      public void setRejected(boolean rejected) {
506        this.rejected = rejected;
507      }
508      /**
509       * @return Returns the supplierOrderInfoID.
510       */
511      public String getSupplierOrderInfoID() {
512        return supplierOrderInfoID;
513      }
514      /**
515       * @param supplierOrderInfoID The supplierOrderInfoID to set.
516       */
517      public void setSupplierOrderInfoID(String supplierOrderInfoID) {
518        this.supplierOrderInfoID = supplierOrderInfoID;
519      }
520      /**
521       * @return Returns the masterAgreementIDInfoDateString.
522       */
523      public String getMasterAgreementIDInfoDateString() {
524        return masterAgreementIDInfoDateString;
525      }
526      /**
527       * @return Returns the masterAgreementReferenceDateString.
528       */
529      public String getMasterAgreementReferenceDateString() {
530        return masterAgreementReferenceDateString;
531      }
532      /**
533       * @return Returns the orderIDInfoDateString.
534       */
535      public String getOrderIDInfoDateString() {
536        return orderIDInfoDateString;
537      }
538      
539      public void addInvoiceItem(ElectronicInvoiceItem electronicInvoiceItem){
540          invoiceItems.add(electronicInvoiceItem);
541          /**
542           * TODO: This is not the right place for sorting... Have to move this to getter method with some flag to avoid
543           * this sorting whenever the getter is called
544           */
545          Collections.sort(invoiceItems, new Comparator() {
546              public int compare (Object o1, Object o2) { 
547                return (((ElectronicInvoiceItem)o1).getReferenceLineNumberInteger()).compareTo(((ElectronicInvoiceItem)o2).getReferenceLineNumberInteger()); 
548              } 
549            }
550            );
551      }
552      
553      public ElectronicInvoiceItem[] getInvoiceItemsAsArray(){
554          if (invoiceItems.size() > 0){
555              ElectronicInvoiceItem[] tempItems = new ElectronicInvoiceItem[invoiceItems.size()];
556              invoiceItems.toArray(tempItems);
557              return tempItems;
558          }
559          return null;
560      }
561      
562      public String getOrderReferenceOrderDateString() {
563          return orderReferenceOrderDateString;
564      }
565    
566      public void setOrderReferenceOrderDateString(String orderReferenceOrderDateString) {
567          this.orderReferenceOrderDateString = orderReferenceOrderDateString;
568      }
569      
570      public String toString(){
571          
572          ToStringBuilder toString = new ToStringBuilder(this);
573          
574          toString.append("orderReferenceOrderID",getOrderReferenceOrderID());
575          toString.append("orderReferenceOrderDate",getOrderReferenceOrderDateString());
576          toString.append("orderReferenceDocumentRefPayloadID",getOrderReferenceDocumentRefPayloadID());
577          toString.append("orderReferenceDocumentRef",getOrderReferenceDocumentRef());
578          toString.append("masterAgreementReferenceID",getMasterAgreementReferenceID());
579          toString.append("masterAgreementReferenceDateString",getMasterAgreementReferenceDateString());
580          toString.append("masterAgreementIDInfoID",getMasterAgreementIDInfoID());
581          toString.append("masterAgreementIDInfoDateString",getMasterAgreementIDInfoDateString());
582          toString.append("orderIDInfoID",getOrderIDInfoID());
583          toString.append("orderIDInfoDateString",getOrderIDInfoDateString());
584          toString.append("supplierOrderInfoID",getSupplierOrderInfoID());
585          toString.append("invoiceItems",getInvoiceItems());
586          
587          return toString.toString();
588          
589      }
590    
591    
592    }