View Javadoc
1   /*
2    * Copyright 2006-2009 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  /*
17   * Created on Feb 13, 2006
18   *
19   */
20  package org.kuali.ole.module.purap.businessobject;
21  
22  import org.apache.commons.lang.builder.ToStringBuilder;
23  import org.kuali.ole.module.purap.PurapConstants;
24  import org.kuali.ole.module.purap.util.ElectronicInvoiceUtils;
25  
26  import java.math.BigDecimal;
27  import java.util.*;
28  
29  public class ElectronicInvoiceOrder {
30      private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(ElectronicInvoiceOrder.class);
31  
32      public static boolean INVOICE_ORDER_REJECTED = true;
33      public static boolean INVOICE_ORDER_NOT_REJECTED = false;
34  
35      // the following fields come from the <InvoiceDetailOrderInfo> tag
36      private String orderReferenceOrderID;
37      private String orderReferenceDocumentRefPayloadID;
38      private String orderReferenceDocumentRef;
39      private String masterAgreementReferenceID;
40      private Date masterAgreementReferenceDate;
41      private String masterAgreementReferenceDateString;
42      private String masterAgreementIDInfoID;
43      private Date masterAgreementIDInfoDate;
44      private String masterAgreementIDInfoDateString;
45      private String orderIDInfoID;
46      private Date orderIDInfoDate;
47      private String orderIDInfoDateString;
48      private String supplierOrderInfoID;
49  
50      private String invoicePurchaseOrderID;
51      private String orderReferenceOrderDateString;
52      private Integer purchaseOrderID = null;
53      private String purchaseOrderCampusCode;
54  
55      private boolean rejected = INVOICE_ORDER_NOT_REJECTED;
56      private List orderRejectReasons = new ArrayList();
57  
58      private List invoiceItems = new ArrayList();
59  
60      public ElectronicInvoiceOrder() {
61          super();
62      }
63  
64      public ElectronicInvoiceItem getElectronicInvoiceItemByPOLineNumber(Integer poLineNumber) {
65          for (Iterator iter = this.invoiceItems.iterator(); iter.hasNext(); ) {
66              ElectronicInvoiceItem eii = (ElectronicInvoiceItem) iter.next();
67              if ((poLineNumber.compareTo(eii.getReferenceLineNumberInteger())) == 0) {
68                  return eii;
69              }
70          }
71          return null;
72      }
73  
74      /**
75       * This method takes in a roleID string and an addressName (constants from mapping file)
76       * and returns a valid ElectronicInvoicePostalAddress or null if not found.  If the addressName string
77       * is null then the roleID is used to find the first available
78       *
79       * @param roleID      Cxml role id attribute value
80       * @param addressName Cxml name attribute of postaladdress tag
81       * @return CxmlPostal Address relating to given parameters
82       */
83      public ElectronicInvoicePostalAddress getCxmlPostalAddressByRoleID(String roleID, String addressName) {
84          if (roleID != null) {
85              ElectronicInvoiceContact contact = this.getCxmlContactByRoleID(roleID);
86              if (contact != null) {
87                  for (Iterator iterator = contact.getPostalAddresses().iterator(); iterator.hasNext(); ) {
88                      ElectronicInvoicePostalAddress cpa = (ElectronicInvoicePostalAddress) iterator.next();
89                      if (addressName == null) {
90                          return cpa;
91                      } else {
92                          if (addressName.equalsIgnoreCase(cpa.getName())) {
93                              return cpa;
94                          }
95                      }
96                  }
97              }
98          }
99          return null;
100     }
101 
102     public ElectronicInvoiceContact getCxmlContactByRoleID(String roleID) {
103         if (roleID != null) {
104             for (Iterator itemIter = this.invoiceItems.iterator(); itemIter.hasNext(); ) {
105                 ElectronicInvoiceItem eii = (ElectronicInvoiceItem) itemIter.next();
106                 for (Iterator iter = eii.getInvoiceShippingContacts().iterator(); iter.hasNext(); ) {
107                     ElectronicInvoiceContact contact = (ElectronicInvoiceContact) iter.next();
108                     if (roleID.equalsIgnoreCase(contact.getRole())) {
109                         return contact;
110                     }
111                 }
112             }
113         }
114         return null;
115     }
116 
117     /**
118      * This method returns the first shipping date found in the list of items.  This
119      * is called if shipping information is in line. Since system only allows for one
120      * shipping date per invoice-order we take the first date we find
121      *
122      * @return Date defining first shipping date found or null if none are found
123      */
124     public Date getInvoiceShippingDate() {
125         for (Iterator iter = this.invoiceItems.iterator(); iter.hasNext(); ) {
126             ElectronicInvoiceItem eii = (ElectronicInvoiceItem) iter.next();
127             Date testDate = eii.getShippingDate();
128             if (testDate != null) {
129                 return testDate;
130             }
131         }
132         return null;
133     }
134 
135     /**
136      * This method returns the first shipping date string found in the list of items.  This
137      * is called if shipping information is in line. Since system only allows for one shipping
138      * date per invoice-order we take the first date string we find
139      *
140      * @return Date defining first shipping date found or null if none are found
141      */
142     public String getInvoiceShippingDateString() {
143         for (Iterator iter = this.invoiceItems.iterator(); iter.hasNext(); ) {
144             ElectronicInvoiceItem eii = (ElectronicInvoiceItem) iter.next();
145             String testDateString = eii.getShippingDateString();
146             if ((testDateString != null) && (!("".equals(testDateString)))) {
147                 return testDateString;
148             }
149         }
150         return null;
151     }
152 
153     public String getInvoiceTaxDescription() {
154         BigDecimal total = BigDecimal.ZERO;
155         for (Iterator iter = this.invoiceItems.iterator(); iter.hasNext(); ) {
156             ElectronicInvoiceItem eii = (ElectronicInvoiceItem) iter.next();
157             BigDecimal taxAmount = eii.getInvoiceLineTaxAmountBigDecimal();
158             if ((taxAmount != null) && (BigDecimal.ZERO.compareTo(taxAmount) != 0)) {
159                 return eii.getTaxDescription();
160             }
161         }
162         return null;
163     }
164 
165     public String getInvoiceShippingDescription() {
166         BigDecimal total = BigDecimal.ZERO;
167         for (Iterator iter = this.invoiceItems.iterator(); iter.hasNext(); ) {
168             ElectronicInvoiceItem eii = (ElectronicInvoiceItem) iter.next();
169             BigDecimal shippingAmount = eii.getInvoiceLineShippingAmountBigDecimal();
170             if ((shippingAmount != null) && (BigDecimal.ZERO.compareTo(shippingAmount) != 0)) {
171                 return PurapConstants.ElectronicInvoice.DEFAULT_SHIPPING_DESCRIPTION;
172             }
173         }
174         return null;
175     }
176 
177     public String getInvoiceSpecialHandlingDescription() {
178         BigDecimal total = BigDecimal.ZERO;
179         for (Iterator iter = this.invoiceItems.iterator(); iter.hasNext(); ) {
180             ElectronicInvoiceItem eii = (ElectronicInvoiceItem) iter.next();
181             BigDecimal specialHandlingAmount = eii.getInvoiceLineSpecialHandlingAmountBigDecimal();
182             if ((specialHandlingAmount != null) && (BigDecimal.ZERO.compareTo(specialHandlingAmount) != 0)) {
183                 return PurapConstants.ElectronicInvoice.DEFAULT_SPECIAL_HANDLING_DESCRIPTION;
184             }
185         }
186         return null;
187     }
188 
189 
190     public BigDecimal getInvoiceSubTotalAmount() {
191         BigDecimal total = BigDecimal.ZERO;
192         for (Iterator iter = this.invoiceItems.iterator(); iter.hasNext(); ) {
193             ElectronicInvoiceItem eii = (ElectronicInvoiceItem) iter.next();
194             total = total.add(eii.getInvoiceLineSubTotalAmountBigDecimal());
195         }
196         return total;
197     }
198 
199     public BigDecimal getInvoiceTaxAmount() {
200         BigDecimal total = BigDecimal.ZERO;
201         for (Iterator iter = this.invoiceItems.iterator(); iter.hasNext(); ) {
202             ElectronicInvoiceItem eii = (ElectronicInvoiceItem) iter.next();
203             total = total.add(eii.getInvoiceLineTaxAmountBigDecimal());
204         }
205         return total;
206     }
207 
208     public BigDecimal getInvoiceSpecialHandlingAmount() {
209         BigDecimal total = BigDecimal.ZERO;
210         for (Iterator iter = this.invoiceItems.iterator(); iter.hasNext(); ) {
211             ElectronicInvoiceItem eii = (ElectronicInvoiceItem) iter.next();
212             total = total.add(eii.getInvoiceLineSpecialHandlingAmountBigDecimal());
213         }
214         return total;
215     }
216 
217     public BigDecimal getInvoiceShippingAmount() {
218         BigDecimal total = BigDecimal.ZERO;
219         for (Iterator iter = this.invoiceItems.iterator(); iter.hasNext(); ) {
220             ElectronicInvoiceItem eii = (ElectronicInvoiceItem) iter.next();
221             total = total.add(eii.getInvoiceLineShippingAmountBigDecimal());
222         }
223         return total;
224     }
225 
226     public BigDecimal getInvoiceGrossAmount() {
227         BigDecimal total = BigDecimal.ZERO;
228         for (Iterator iter = this.invoiceItems.iterator(); iter.hasNext(); ) {
229             ElectronicInvoiceItem eii = (ElectronicInvoiceItem) iter.next();
230             total = total.add(eii.getInvoiceLineGrossAmountBigDecimal());
231         }
232         return total;
233     }
234 
235     public BigDecimal getInvoiceDiscountAmount() {
236         BigDecimal total = BigDecimal.ZERO;
237         for (Iterator iter = this.invoiceItems.iterator(); iter.hasNext(); ) {
238             ElectronicInvoiceItem eii = (ElectronicInvoiceItem) iter.next();
239             total = total.add(eii.getInvoiceLineDiscountAmountBigDecimal());
240         }
241         return total;
242     }
243 
244     public BigDecimal getInvoiceNetAmount() {
245         BigDecimal total = BigDecimal.ZERO;
246         for (Iterator iter = this.invoiceItems.iterator(); iter.hasNext(); ) {
247             ElectronicInvoiceItem eii = (ElectronicInvoiceItem) iter.next();
248             total = total.add(eii.getInvoiceLineNetAmountBigDecimal());
249         }
250         return total;
251     }
252 
253     public void addRejectReasonToList(ElectronicInvoiceRejectReason reason) {
254         this.orderRejectReasons.add(reason);
255     }
256 
257     /**
258      * Altered for special circumstances
259      *
260      * @param masterAgreementIDInfoDateString
261      *         The masterAgreementIDInfoDateString to set.
262      */
263     public void setMasterAgreementIDInfoDateString(String masterAgreementIDInfoDateString) {
264         this.masterAgreementIDInfoDateString = masterAgreementIDInfoDateString;
265     /*if ( (masterAgreementIDInfoDateString != null) && (!("".equals(masterAgreementIDInfoDateString))) ) {
266       SimpleDateFormat sdf = new SimpleDateFormat(PurapConstants.ElectronicInvoice.CXML_DATE_FORMAT, Locale.US);
267       try {
268         this.masterAgreementIDInfoDate = sdf.parse(masterAgreementIDInfoDateString);
269       } catch (ParseException e) {
270         // setting invoice date to null to identify problem
271         LOG.error("setInvoiceDateString() SimpleDateFormat parser error attempting to set invalid date string " + masterAgreementIDInfoDateString + " in masterAgreementIDInfoDate field... setting date to null");
272         this.masterAgreementIDInfoDate = null;
273       }
274     } else {
275       this.masterAgreementIDInfoDate = null;
276     }*/
277         setMasterAgreementIDInfoDate(ElectronicInvoiceUtils.getDate(masterAgreementIDInfoDateString));
278     }
279 
280     /**
281      * Altered for special circumstances
282      *
283      * @param masterAgreementReferenceDateString
284      *         The masterAgreementReferenceDateString to set.
285      */
286     public void setMasterAgreementReferenceDateString(String masterAgreementReferenceDateString) {
287         this.masterAgreementReferenceDateString = masterAgreementReferenceDateString;
288     /*if ( (masterAgreementReferenceDateString != null) && (!("".equals(masterAgreementReferenceDateString))) ) {
289       SimpleDateFormat sdf = new SimpleDateFormat(PurapConstants.ElectronicInvoice.CXML_DATE_FORMAT, Locale.US);
290       try {
291         this.masterAgreementReferenceDate = sdf.parse(masterAgreementReferenceDateString);
292       } catch (ParseException e) {
293         // setting invoice date to null to identify problem
294         LOG.error("setInvoiceDateString() SimpleDateFormat parser error attempting to set invalid date string " + masterAgreementReferenceDateString + " in masterAgreementReferenceDate field... setting date to null");
295         this.masterAgreementReferenceDate = null;
296       }
297     } else {
298       this.masterAgreementIDInfoDate = null;
299     }*/
300         setMasterAgreementIDInfoDate(ElectronicInvoiceUtils.getDate(masterAgreementReferenceDateString));
301     }
302 
303     /**
304      * Altered for special circumstances
305      *
306      * @param orderIDInfoDateString The orderIDInfoDateString to set.
307      */
308     public void setOrderIDInfoDateString(String orderIDInfoDateString) {
309         this.orderIDInfoDateString = orderIDInfoDateString;
310     /*if ( (orderIDInfoDateString != null) && (!("".equals(orderIDInfoDateString))) ) {
311       SimpleDateFormat sdf = new SimpleDateFormat(PurapConstants.ElectronicInvoice.CXML_DATE_FORMAT, Locale.US);
312       try {
313         this.orderIDInfoDate = sdf.parse(orderIDInfoDateString);
314       } catch (ParseException e) {
315         // setting invoice date to null to identify problem
316         LOG.error("setInvoiceDateString() SimpleDateFormat parser error attempting to set invalid date string " + orderIDInfoDateString + " in orderIDInfoDate field... setting date to null");
317         this.orderIDInfoDate = null;
318       }
319     } else {
320       this.orderIDInfoDate = null;
321     }*/
322         setOrderIDInfoDate(ElectronicInvoiceUtils.getDate(orderIDInfoDateString));
323     }
324 
325     /**
326      * @return Returns the invoiceItems.
327      */
328     public List<ElectronicInvoiceItem> getInvoiceItems() {
329         return invoiceItems;
330     }
331 
332     /**
333      * @param invoiceItems The invoiceItems to set.
334      */
335     public void setInvoiceItems(List<ElectronicInvoiceItem> invoiceItems) {
336         this.invoiceItems = invoiceItems;
337     }
338 
339     /**
340      * @return Returns the invoicePurchaseOrderID.
341      */
342     public String getInvoicePurchaseOrderID() {
343         return invoicePurchaseOrderID;
344     }
345 
346     /**
347      * @param invoicePurchaseOrderID The invoicePurchaseOrderID to set.
348      */
349     public void setInvoicePurchaseOrderID(String invoicePurchaseOrderID) {
350         this.invoicePurchaseOrderID = invoicePurchaseOrderID;
351     }
352 
353     /**
354      * @return Returns the masterAgreementIDInfoDate.
355      */
356     public Date getMasterAgreementIDInfoDate() {
357         return masterAgreementIDInfoDate;
358     }
359 
360     /**
361      * @param masterAgreementIDInfoDate The masterAgreementIDInfoDate to set.
362      */
363     public void setMasterAgreementIDInfoDate(Date masterAgreementIDInfoDate) {
364         this.masterAgreementIDInfoDate = masterAgreementIDInfoDate;
365     }
366 
367     /**
368      * @return Returns the masterAgreementIDInfoID.
369      */
370     public String getMasterAgreementIDInfoID() {
371         return masterAgreementIDInfoID;
372     }
373 
374     /**
375      * @param masterAgreementIDInfoID The masterAgreementIDInfoID to set.
376      */
377     public void setMasterAgreementIDInfoID(String masterAgreementIDInfoID) {
378         this.masterAgreementIDInfoID = masterAgreementIDInfoID;
379     }
380 
381     /**
382      * @return Returns the masterAgreementReferenceDate.
383      */
384     public Date getMasterAgreementReferenceDate() {
385         return masterAgreementReferenceDate;
386     }
387 
388     /**
389      * @param masterAgreementReferenceDate The masterAgreementReferenceDate to set.
390      */
391     public void setMasterAgreementReferenceDate(Date masterAgreementReferenceDate) {
392         this.masterAgreementReferenceDate = masterAgreementReferenceDate;
393     }
394 
395     /**
396      * @return Returns the masterAgreementReferenceID.
397      */
398     public String getMasterAgreementReferenceID() {
399         return masterAgreementReferenceID;
400     }
401 
402     /**
403      * @param masterAgreementReferenceID The masterAgreementReferenceID to set.
404      */
405     public void setMasterAgreementReferenceID(String masterAgreementReferenceID) {
406         this.masterAgreementReferenceID = masterAgreementReferenceID;
407     }
408 
409     /**
410      * @return Returns the orderIDInfoDate.
411      */
412     public Date getOrderIDInfoDate() {
413         return orderIDInfoDate;
414     }
415 
416     /**
417      * @param orderIDInfoDate The orderIDInfoDate to set.
418      */
419     public void setOrderIDInfoDate(Date orderIDInfoDate) {
420         this.orderIDInfoDate = orderIDInfoDate;
421     }
422 
423     /**
424      * @return Returns the orderIDInfoID.
425      */
426     public String getOrderIDInfoID() {
427         return orderIDInfoID;
428     }
429 
430     /**
431      * @param orderIDInfoID The orderIDInfoID to set.
432      */
433     public void setOrderIDInfoID(String orderIDInfoID) {
434         this.orderIDInfoID = orderIDInfoID;
435     }
436 
437     /**
438      * @return Returns the orderReferenceDocumentRef.
439      */
440     public String getOrderReferenceDocumentRef() {
441         return orderReferenceDocumentRef;
442     }
443 
444     /**
445      * @param orderReferenceDocumentRef The orderReferenceDocumentRef to set.
446      */
447     public void setOrderReferenceDocumentRef(String orderReferenceDocumentRef) {
448         this.orderReferenceDocumentRef = orderReferenceDocumentRef;
449     }
450 
451     /**
452      * @return Returns the orderReferenceDocumentRefPayloadID.
453      */
454     public String getOrderReferenceDocumentRefPayloadID() {
455         return orderReferenceDocumentRefPayloadID;
456     }
457 
458     /**
459      * @param orderReferenceDocumentRefPayloadID
460      *         The orderReferenceDocumentRefPayloadID to set.
461      */
462     public void setOrderReferenceDocumentRefPayloadID(String orderReferenceDocumentRefPayloadID) {
463         this.orderReferenceDocumentRefPayloadID = orderReferenceDocumentRefPayloadID;
464     }
465 
466     /**
467      * @return Returns the orderReferenceOrderID.
468      */
469     public String getOrderReferenceOrderID() {
470         return orderReferenceOrderID;
471     }
472 
473     /**
474      * @param orderReferenceOrderID The orderReferenceOrderID to set.
475      */
476     public void setOrderReferenceOrderID(String orderReferenceOrderID) {
477         this.orderReferenceOrderID = orderReferenceOrderID;
478     }
479 
480     /**
481      * @return Returns the orderRejectReasons.
482      */
483     public List<ElectronicInvoiceRejectReason> getOrderRejectReasons() {
484         return orderRejectReasons;
485     }
486 
487     /**
488      * @param orderRejectReasons The orderRejectReasons to set.
489      */
490     public void setOrderRejectReasons(List<ElectronicInvoiceRejectReason> orderRejectReasons) {
491         this.orderRejectReasons = orderRejectReasons;
492     }
493 
494     /**
495      * @return Returns the purchaseOrderCampusCode.
496      */
497     public String getPurchaseOrderCampusCode() {
498         return purchaseOrderCampusCode;
499     }
500 
501     /**
502      * @param purchaseOrderCampusCode The purchaseOrderCampusCode to set.
503      */
504     public void setPurchaseOrderCampusCode(String purchaseOrderCampusCode) {
505         this.purchaseOrderCampusCode = purchaseOrderCampusCode;
506     }
507 
508     /**
509      * @return Returns the purchaseOrderID.
510      */
511     public Integer getPurchaseOrderID() {
512         return purchaseOrderID;
513     }
514 
515     /**
516      * @param purchaseOrderID The purchaseOrderID to set.
517      */
518     public void setPurchaseOrderID(Integer purchaseOrderID) {
519         this.purchaseOrderID = purchaseOrderID;
520     }
521 
522     /**
523      * @return Returns the rejected.
524      */
525     public boolean isRejected() {
526         return rejected;
527     }
528 
529     /**
530      * @param rejected The rejected to set.
531      */
532     public void setRejected(boolean rejected) {
533         this.rejected = rejected;
534     }
535 
536     /**
537      * @return Returns the supplierOrderInfoID.
538      */
539     public String getSupplierOrderInfoID() {
540         return supplierOrderInfoID;
541     }
542 
543     /**
544      * @param supplierOrderInfoID The supplierOrderInfoID to set.
545      */
546     public void setSupplierOrderInfoID(String supplierOrderInfoID) {
547         this.supplierOrderInfoID = supplierOrderInfoID;
548     }
549 
550     /**
551      * @return Returns the masterAgreementIDInfoDateString.
552      */
553     public String getMasterAgreementIDInfoDateString() {
554         return masterAgreementIDInfoDateString;
555     }
556 
557     /**
558      * @return Returns the masterAgreementReferenceDateString.
559      */
560     public String getMasterAgreementReferenceDateString() {
561         return masterAgreementReferenceDateString;
562     }
563 
564     /**
565      * @return Returns the orderIDInfoDateString.
566      */
567     public String getOrderIDInfoDateString() {
568         return orderIDInfoDateString;
569     }
570 
571     public void addInvoiceItem(ElectronicInvoiceItem electronicInvoiceItem) {
572         invoiceItems.add(electronicInvoiceItem);
573         /**
574          * TODO: This is not the right place for sorting... Have to move this to getter method with some flag to avoid
575          * this sorting whenever the getter is called
576          */
577         Collections.sort(invoiceItems, new Comparator() {
578             public int compare(Object o1, Object o2) {
579                 return (((ElectronicInvoiceItem) o1).getReferenceLineNumberInteger()).compareTo(((ElectronicInvoiceItem) o2).getReferenceLineNumberInteger());
580             }
581         }
582         );
583     }
584 
585     public ElectronicInvoiceItem[] getInvoiceItemsAsArray() {
586         if (invoiceItems.size() > 0) {
587             ElectronicInvoiceItem[] tempItems = new ElectronicInvoiceItem[invoiceItems.size()];
588             invoiceItems.toArray(tempItems);
589             return tempItems;
590         }
591         return null;
592     }
593 
594     public String getOrderReferenceOrderDateString() {
595         return orderReferenceOrderDateString;
596     }
597 
598     public void setOrderReferenceOrderDateString(String orderReferenceOrderDateString) {
599         this.orderReferenceOrderDateString = orderReferenceOrderDateString;
600     }
601 
602     public String toString() {
603 
604         ToStringBuilder toString = new ToStringBuilder(this);
605 
606         toString.append("orderReferenceOrderID", getOrderReferenceOrderID());
607         toString.append("orderReferenceOrderDate", getOrderReferenceOrderDateString());
608         toString.append("orderReferenceDocumentRefPayloadID", getOrderReferenceDocumentRefPayloadID());
609         toString.append("orderReferenceDocumentRef", getOrderReferenceDocumentRef());
610         toString.append("masterAgreementReferenceID", getMasterAgreementReferenceID());
611         toString.append("masterAgreementReferenceDateString", getMasterAgreementReferenceDateString());
612         toString.append("masterAgreementIDInfoID", getMasterAgreementIDInfoID());
613         toString.append("masterAgreementIDInfoDateString", getMasterAgreementIDInfoDateString());
614         toString.append("orderIDInfoID", getOrderIDInfoID());
615         toString.append("orderIDInfoDateString", getOrderIDInfoDateString());
616         toString.append("supplierOrderInfoID", getSupplierOrderInfoID());
617         toString.append("invoiceItems", getInvoiceItems());
618 
619         return toString.toString();
620 
621     }
622 
623 
624 }