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;
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.HashMap;
023 import java.util.Iterator;
024 import java.util.LinkedHashMap;
025 import java.util.List;
026 import java.util.Map;
027
028 import org.apache.commons.lang.StringUtils;
029 import org.kuali.kfs.coa.businessobject.Account;
030 import org.kuali.kfs.coa.businessobject.Chart;
031 import org.kuali.kfs.coa.businessobject.ObjectCode;
032 import org.kuali.kfs.coa.businessobject.Organization;
033 import org.kuali.kfs.coa.businessobject.ProjectCode;
034 import org.kuali.kfs.coa.businessobject.SubAccount;
035 import org.kuali.kfs.coa.businessobject.SubObjectCode;
036 import org.kuali.kfs.module.ar.ArConstants;
037 import org.kuali.kfs.module.ar.businessobject.AccountsReceivableDocumentHeader;
038 import org.kuali.kfs.module.ar.businessobject.Customer;
039 import org.kuali.kfs.module.ar.businessobject.CustomerAddress;
040 import org.kuali.kfs.module.ar.businessobject.CustomerInvoiceDetail;
041 import org.kuali.kfs.module.ar.businessobject.CustomerInvoiceRecurrenceDetails;
042 import org.kuali.kfs.module.ar.businessobject.CustomerProcessingType;
043 import org.kuali.kfs.module.ar.businessobject.InvoiceRecurrence;
044 import org.kuali.kfs.module.ar.businessobject.PrintInvoiceOptions;
045 import org.kuali.kfs.module.ar.businessobject.ReceivableCustomerInvoiceDetail;
046 import org.kuali.kfs.module.ar.businessobject.SalesTaxCustomerInvoiceDetail;
047 import org.kuali.kfs.module.ar.document.service.AccountsReceivableTaxService;
048 import org.kuali.kfs.module.ar.document.service.CustomerAddressService;
049 import org.kuali.kfs.module.ar.document.service.CustomerInvoiceDetailService;
050 import org.kuali.kfs.module.ar.document.service.CustomerInvoiceDocumentService;
051 import org.kuali.kfs.module.ar.document.service.CustomerInvoiceGLPEService;
052 import org.kuali.kfs.sys.KFSConstants;
053 import org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySequenceHelper;
054 import org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySourceDetail;
055 import org.kuali.kfs.sys.businessobject.TaxDetail;
056 import org.kuali.kfs.sys.context.SpringContext;
057 import org.kuali.kfs.sys.document.AccountingDocumentBase;
058 import org.kuali.kfs.sys.document.AmountTotaling;
059 import org.kuali.kfs.sys.document.Correctable;
060 import org.kuali.kfs.sys.service.GeneralLedgerPendingEntryService;
061 import org.kuali.kfs.sys.service.TaxService;
062 import org.kuali.rice.kew.dto.DocumentRouteStatusChangeDTO;
063 import org.kuali.rice.kew.exception.WorkflowException;
064 import org.kuali.rice.kns.UserSession;
065 import org.kuali.rice.kns.document.Copyable;
066 import org.kuali.rice.kns.document.MaintenanceDocument;
067 import org.kuali.rice.kns.service.BusinessObjectService;
068 import org.kuali.rice.kns.service.DateTimeService;
069 import org.kuali.rice.kns.service.DocumentService;
070 import org.kuali.rice.kns.service.ParameterService;
071 import org.kuali.rice.kns.util.DateUtils;
072 import org.kuali.rice.kns.util.GlobalVariables;
073 import org.kuali.rice.kns.util.KualiDecimal;
074 import org.kuali.rice.kns.util.ObjectUtils;
075 import org.kuali.rice.kns.util.TypedArrayList;
076
077 /**
078 * @author Kuali Nervous System Team (kualidev@oncourse.iu.edu)
079 */
080 public class CustomerInvoiceDocument extends AccountingDocumentBase implements AmountTotaling, Copyable, Correctable, Comparable<CustomerInvoiceDocument> {
081
082 protected static final String HAS_RECCURENCE_NODE = "HasReccurence";
083 protected static final String BATCH_GENERATED_NODE = "BatchGenerated";
084
085 protected String invoiceHeaderText;
086 protected String invoiceAttentionLineText;
087 protected Date invoiceDueDate;
088 protected Date billingDate;
089 protected Date closedDate;
090 protected Date billingDateForDisplay;
091 protected String invoiceTermsText;
092 protected String organizationInvoiceNumber;
093 protected String customerPurchaseOrderNumber;
094 protected String printInvoiceIndicator;
095 protected Date customerPurchaseOrderDate;
096 protected String billByChartOfAccountCode;
097 protected String billedByOrganizationCode;
098 protected Integer customerShipToAddressIdentifier;
099 protected Integer customerBillToAddressIdentifier;
100 protected String customerSpecialProcessingCode;
101 protected boolean customerRecordAttachmentIndicator;
102 protected boolean openInvoiceIndicator;
103 protected String paymentChartOfAccountsCode;
104 protected String paymentAccountNumber;
105 protected String paymentSubAccountNumber;
106 protected String paymentFinancialObjectCode;
107 protected String paymentFinancialSubObjectCode;
108 protected String paymentProjectCode;
109 protected String paymentOrganizationReferenceIdentifier;
110 protected Date printDate;
111 protected Integer age;
112 protected String customerName;
113 protected String billingAddressName;
114 protected String billingCityName;
115 protected String billingStateCode;
116 protected String billingZipCode;
117 protected String billingCountryCode;
118 protected String billingAddressInternationalProvinceName;
119 protected String billingInternationalMailCode;
120 protected String billingEmailAddress;
121 protected String billingAddressTypeCode;
122 protected String billingLine1StreetAddress;
123 protected String billingLine2StreetAddress;
124 protected String shippingLine1StreetAddress;
125 protected String shippingLine2StreetAddress;
126 protected String shippingAddressName;
127 protected String shippingCityName;
128 protected String shippingStateCode;
129 protected String shippingZipCode;
130 protected String shippingCountryCode;
131 protected String shippingAddressInternationalProvinceName;
132 protected String shippingInternationalMailCode;
133 protected String shippingEmailAddress;
134 protected String shippingAddressTypeCode;
135 protected boolean recurredInvoiceIndicator;
136
137 protected AccountsReceivableDocumentHeader accountsReceivableDocumentHeader;
138 protected Chart billByChartOfAccount;
139 protected Organization billedByOrganization;
140 protected CustomerProcessingType customerSpecialProcessing;
141 protected Account paymentAccount;
142 protected Chart paymentChartOfAccounts;
143 protected SubAccount paymentSubAccount;
144 protected ObjectCode paymentFinancialObject;
145 protected SubObjectCode paymentFinancialSubObject;
146 protected ProjectCode paymentProject;
147 protected PrintInvoiceOptions printInvoiceOption;
148 protected CustomerAddress customerShipToAddress;
149 protected CustomerAddress customerBillToAddress;
150 protected CustomerInvoiceRecurrenceDetails customerInvoiceRecurrenceDetails;
151
152 protected static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(CustomerInvoiceDocument.class);
153
154 // added for quick apply check control
155 //TODO Andrew
156 //protected boolean quickApply;
157
158 /**
159 * Default constructor.
160 */
161 public CustomerInvoiceDocument() {
162 super();
163 }
164
165 /**
166 * This method calculates the outstanding balance on an invoice.
167 *
168 * @return the outstanding balance on this invoice
169 */
170 public KualiDecimal getOpenAmount() {
171 return SpringContext.getBean(CustomerInvoiceDocumentService.class).getOpenAmountForCustomerInvoiceDocument(this);
172 }
173
174 //TODO Andrew
175 // public void setOpenAmount(KualiDecimal openAmount) {
176 // // do nothing
177 // }
178 //
179 // public void setBalance(KualiDecimal balance) {
180 // // do nothing
181 // }
182 //
183 // public void setSourceTotal(KualiDecimal sourceTotal) {
184 // // do nothing
185 // }
186
187 /**
188 * Gets the documentNumber attribute.
189 *
190 * @return Returns the documentNumber
191 */
192 public String getDocumentNumber() {
193 return documentNumber;
194 }
195
196 /**
197 * Sets the documentNumber attribute.
198 *
199 * @param documentNumber The documentNumber to set.
200 */
201 public void setDocumentNumber(String documentNumber) {
202 this.documentNumber = documentNumber;
203 }
204
205
206 /**
207 * Gets the invoiceHeaderText attribute.
208 *
209 * @return Returns the invoiceHeaderText
210 */
211 public String getInvoiceHeaderText() {
212 return invoiceHeaderText;
213 }
214
215 /**
216 * Sets the invoiceHeaderText attribute.
217 *
218 * @param invoiceHeaderText The invoiceHeaderText to set.
219 */
220 public void setInvoiceHeaderText(String invoiceHeaderText) {
221 this.invoiceHeaderText = invoiceHeaderText;
222 }
223
224
225 /**
226 * Gets the invoiceAttentionLineText attribute.
227 *
228 * @return Returns the invoiceAttentionLineText
229 */
230 public String getInvoiceAttentionLineText() {
231 return invoiceAttentionLineText;
232 }
233
234 /**
235 * Sets the invoiceAttentionLineText attribute.
236 *
237 * @param invoiceAttentionLineText The invoiceAttentionLineText to set.
238 */
239 public void setInvoiceAttentionLineText(String invoiceAttentionLineText) {
240 this.invoiceAttentionLineText = invoiceAttentionLineText;
241 }
242
243
244 /**
245 * Gets the invoiceDueDate attribute.
246 *
247 * @return Returns the invoiceDueDate
248 */
249 public Date getInvoiceDueDate() {
250 return invoiceDueDate;
251 }
252
253 /**
254 * Sets the invoiceDueDate attribute.
255 *
256 * @param invoiceDueDate The invoiceDueDate to set.
257 */
258 public void setInvoiceDueDate(Date invoiceDueDate) {
259 this.invoiceDueDate = invoiceDueDate;
260 }
261
262
263 /**
264 * Gets the billingDate attribute.
265 *
266 * @return Returns the billingDate
267 */
268 public Date getBillingDate() {
269 return billingDate;
270 }
271
272 /**
273 * This method returns the age of an invoice (i.e. current date - billing date)
274 *
275 * @return
276 */
277 public Integer getAge() {
278 if (ObjectUtils.isNotNull(billingDate)) {
279 return (int) DateUtils.getDifferenceInDays(new Timestamp(billingDate.getTime()), SpringContext.getBean(DateTimeService.class).getCurrentTimestamp());
280 }
281 // TODO should I be throwing an exception or throwing a null?
282 return null;
283 }
284
285 public void setAge(Integer age) {
286 this.age = age;
287 }
288
289 /**
290 * Sets the billingDate attribute.
291 *
292 * @param billingDate The billingDate to set.
293 */
294 public void setBillingDate(Date billingDate) {
295 this.billingDate = billingDate;
296 }
297
298
299 /**
300 * Gets the invoiceTermsText attribute.
301 *
302 * @return Returns the invoiceTermsText
303 */
304 public String getInvoiceTermsText() {
305 return invoiceTermsText;
306 }
307
308 /**
309 * Sets the invoiceTermsText attribute.
310 *
311 * @param invoiceTermsText The invoiceTermsText to set.
312 */
313 public void setInvoiceTermsText(String invoiceTermsText) {
314 this.invoiceTermsText = invoiceTermsText;
315 }
316
317
318 /**
319 * Gets the organizationInvoiceNumber attribute.
320 *
321 * @return Returns the organizationInvoiceNumber
322 */
323 public String getOrganizationInvoiceNumber() {
324 return organizationInvoiceNumber;
325 }
326
327 /**
328 * Sets the organizationInvoiceNumber attribute.
329 *
330 * @param organizationInvoiceNumber The organizationInvoiceNumber to set.
331 */
332 public void setOrganizationInvoiceNumber(String organizationInvoiceNumber) {
333 this.organizationInvoiceNumber = organizationInvoiceNumber;
334 }
335
336 /**
337 * Gets the customerPurchaseOrderNumber attribute.
338 *
339 * @return Returns the customerPurchaseOrderNumber
340 */
341 public String getCustomerPurchaseOrderNumber() {
342 return customerPurchaseOrderNumber;
343 }
344
345 /**
346 * Sets the customerPurchaseOrderNumber attribute.
347 *
348 * @param customerPurchaseOrderNumber The customerPurchaseOrderNumber to set.
349 */
350 public void setCustomerPurchaseOrderNumber(String customerPurchaseOrderNumber) {
351 this.customerPurchaseOrderNumber = customerPurchaseOrderNumber;
352 }
353
354 /**
355 * Gets the printInvoiceIndicator attribute.
356 *
357 * @return Returns the printInvoiceIndicator.
358 */
359 public String getPrintInvoiceIndicator() {
360 return printInvoiceIndicator;
361 }
362
363 /**
364 * Sets the printInvoiceIndicator attribute value.
365 *
366 * @param printInvoiceIndicator The printInvoiceIndicator to set.
367 */
368 public void setPrintInvoiceIndicator(String printInvoiceIndicator) {
369 this.printInvoiceIndicator = printInvoiceIndicator;
370 }
371
372 /**
373 * Gets the customerPurchaseOrderDate attribute.
374 *
375 * @return Returns the customerPurchaseOrderDate
376 */
377 public Date getCustomerPurchaseOrderDate() {
378 return customerPurchaseOrderDate;
379 }
380
381 /**
382 * Sets the customerPurchaseOrderDate attribute.
383 *
384 * @param customerPurchaseOrderDate The customerPurchaseOrderDate to set.
385 */
386 public void setCustomerPurchaseOrderDate(Date customerPurchaseOrderDate) {
387 this.customerPurchaseOrderDate = customerPurchaseOrderDate;
388 }
389
390
391 /**
392 * Gets the billByChartOfAccountCode attribute.
393 *
394 * @return Returns the billByChartOfAccountCode
395 */
396 public String getBillByChartOfAccountCode() {
397 return billByChartOfAccountCode;
398 }
399
400 /**
401 * Sets the billByChartOfAccountCode attribute.
402 *
403 * @param billByChartOfAccountCode The billByChartOfAccountCode to set.
404 */
405 public void setBillByChartOfAccountCode(String billByChartOfAccountCode) {
406 this.billByChartOfAccountCode = billByChartOfAccountCode;
407 }
408
409
410 /**
411 * Gets the billedByOrganizationCode attribute.
412 *
413 * @return Returns the billedByOrganizationCode
414 */
415 public String getBilledByOrganizationCode() {
416 return billedByOrganizationCode;
417 }
418
419 /**
420 * Sets the billedByOrganizationCode attribute.
421 *
422 * @param billedByOrganizationCode The billedByOrganizationCode to set.
423 */
424 public void setBilledByOrganizationCode(String billedByOrganizationCode) {
425 this.billedByOrganizationCode = billedByOrganizationCode;
426 }
427
428
429 /**
430 * Gets the customerShipToAddressIdentifier attribute.
431 *
432 * @return Returns the customerShipToAddressIdentifier
433 */
434 public Integer getCustomerShipToAddressIdentifier() {
435 return customerShipToAddressIdentifier;
436 }
437
438 /**
439 * Sets the customerShipToAddressIdentifier attribute.
440 *
441 * @param customerShipToAddressIdentifier The customerShipToAddressIdentifier to set.
442 */
443 public void setCustomerShipToAddressIdentifier(Integer customerShipToAddressIdentifier) {
444 this.customerShipToAddressIdentifier = customerShipToAddressIdentifier;
445 }
446
447
448 /**
449 * Gets the customerBillToAddressIdentifier attribute.
450 *
451 * @return Returns the customerBillToAddressIdentifier
452 */
453 public Integer getCustomerBillToAddressIdentifier() {
454 return customerBillToAddressIdentifier;
455 }
456
457 /**
458 * Sets the customerBillToAddressIdentifier attribute.
459 *
460 * @param customerBillToAddressIdentifier The customerBillToAddressIdentifier to set.
461 */
462 public void setCustomerBillToAddressIdentifier(Integer customerBillToAddressIdentifier) {
463 this.customerBillToAddressIdentifier = customerBillToAddressIdentifier;
464 }
465
466
467 /**
468 * Gets the customerSpecialProcessingCode attribute.
469 *
470 * @return Returns the customerSpecialProcessingCode
471 */
472 public String getCustomerSpecialProcessingCode() {
473 return customerSpecialProcessingCode;
474 }
475
476 /**
477 * Sets the customerSpecialProcessingCode attribute.
478 *
479 * @param customerSpecialProcessingCode The customerSpecialProcessingCode to set.
480 */
481 public void setCustomerSpecialProcessingCode(String customerSpecialProcessingCode) {
482 this.customerSpecialProcessingCode = customerSpecialProcessingCode;
483 }
484
485
486 /**
487 * Gets the customerRecordAttachmentIndicator attribute.
488 *
489 * @return Returns the customerRecordAttachmentIndicator
490 */
491 public boolean isCustomerRecordAttachmentIndicator() {
492 return customerRecordAttachmentIndicator;
493 }
494
495 /**
496 * Sets the customerRecordAttachmentIndicator attribute.
497 *
498 * @param customerRecordAttachmentIndicator The customerRecordAttachmentIndicator to set.
499 */
500 public void setCustomerRecordAttachmentIndicator(boolean customerRecordAttachmentIndicator) {
501 this.customerRecordAttachmentIndicator = customerRecordAttachmentIndicator;
502 }
503
504
505 /**
506 * Gets the openInvoiceIndicator attribute.
507 *
508 * @return Returns the openInvoiceIndicator
509 */
510 public boolean isOpenInvoiceIndicator() {
511 return openInvoiceIndicator;
512 }
513
514 /**
515 * Sets the openInvoiceIndicator attribute.
516 *
517 * @param openInvoiceIndicator The openInvoiceIndicator to set.
518 */
519 public void setOpenInvoiceIndicator(boolean openInvoiceIndicator) {
520 this.openInvoiceIndicator = openInvoiceIndicator;
521 }
522
523 /**
524 * Gets the paymentAccountNumber attribute.
525 *
526 * @return Returns the paymentAccountNumber.
527 */
528 public String getPaymentAccountNumber() {
529 return paymentAccountNumber;
530 }
531
532 /**
533 * Sets the paymentAccountNumber attribute value.
534 *
535 * @param paymentAccountNumber The paymentAccountNumber to set.
536 */
537 public void setPaymentAccountNumber(String paymentAccountNumber) {
538 this.paymentAccountNumber = paymentAccountNumber;
539 }
540
541 /**
542 * Gets the paymentChartOfAccountsCode attribute.
543 *
544 * @return Returns the paymentChartOfAccountsCode.
545 */
546 public String getPaymentChartOfAccountsCode() {
547 return paymentChartOfAccountsCode;
548 }
549
550 /**
551 * Sets the paymentChartOfAccountsCode attribute value.
552 *
553 * @param paymentChartOfAccountsCode The paymentChartOfAccountsCode to set.
554 */
555 public void setPaymentChartOfAccountsCode(String paymentChartOfAccountsCode) {
556 this.paymentChartOfAccountsCode = paymentChartOfAccountsCode;
557 }
558
559 /**
560 * Gets the paymentFinancialObjectCode attribute.
561 *
562 * @return Returns the paymentFinancialObjectCode.
563 */
564 public String getPaymentFinancialObjectCode() {
565 return paymentFinancialObjectCode;
566 }
567
568 /**
569 * Sets the paymentFinancialObjectCode attribute value.
570 *
571 * @param paymentFinancialObjectCode The paymentFinancialObjectCode to set.
572 */
573 public void setPaymentFinancialObjectCode(String paymentFinancialObjectCode) {
574 this.paymentFinancialObjectCode = paymentFinancialObjectCode;
575 }
576
577 /**
578 * Gets the paymentFinancialSubObjectCode attribute.
579 *
580 * @return Returns the paymentFinancialSubObjectCode.
581 */
582 public String getPaymentFinancialSubObjectCode() {
583 return paymentFinancialSubObjectCode;
584 }
585
586 /**
587 * Sets the paymentFinancialSubObjectCode attribute value.
588 *
589 * @param paymentFinancialSubObjectCode The paymentFinancialSubObjectCode to set.
590 */
591 public void setPaymentFinancialSubObjectCode(String paymentFinancialSubObjectCode) {
592 this.paymentFinancialSubObjectCode = paymentFinancialSubObjectCode;
593 }
594
595 /**
596 * Gets the paymentOrganizationReferenceIdentifier attribute.
597 *
598 * @return Returns the paymentOrganizationReferenceIdentifier.
599 */
600 public String getPaymentOrganizationReferenceIdentifier() {
601 return paymentOrganizationReferenceIdentifier;
602 }
603
604 /**
605 * Sets the paymentOrganizationReferenceIdentifier attribute value.
606 *
607 * @param paymentOrganizationReferenceIdentifier The paymentOrganizationReferenceIdentifier to set.
608 */
609 public void setPaymentOrganizationReferenceIdentifier(String paymentOrganizationReferenceIdentifier) {
610 this.paymentOrganizationReferenceIdentifier = paymentOrganizationReferenceIdentifier;
611 }
612
613 /**
614 * Gets the paymentProjectCode attribute.
615 *
616 * @return Returns the paymentProjectCode.
617 */
618 public String getPaymentProjectCode() {
619 return paymentProjectCode;
620 }
621
622 /**
623 * Sets the paymentProjectCode attribute value.
624 *
625 * @param paymentProjectCode The paymentProjectCode to set.
626 */
627 public void setPaymentProjectCode(String paymentProjectCode) {
628 this.paymentProjectCode = paymentProjectCode;
629 }
630
631 /**
632 * Gets the paymentSubAccountNumber attribute.
633 *
634 * @return Returns the paymentSubAccountNumber.
635 */
636 public String getPaymentSubAccountNumber() {
637 return paymentSubAccountNumber;
638 }
639
640 /**
641 * Sets the paymentSubAccountNumber attribute value.
642 *
643 * @param paymentSubAccountNumber The paymentSubAccountNumber to set.
644 */
645 public void setPaymentSubAccountNumber(String paymentSubAccountNumber) {
646 this.paymentSubAccountNumber = paymentSubAccountNumber;
647 }
648
649 /**
650 * Gets the printDate attribute.
651 *
652 * @return Returns the printDate
653 */
654 public Date getPrintDate() {
655 return printDate;
656 }
657
658 /**
659 * Sets the printDate attribute.
660 *
661 * @param printDate The printDate to set.
662 */
663 public void setPrintDate(Date printDate) {
664 this.printDate = printDate;
665 }
666
667 /**
668 * Gets the accountsReceivableDocumentHeader attribute.
669 *
670 * @return Returns the accountsReceivableDocumentHeader
671 */
672 public AccountsReceivableDocumentHeader getAccountsReceivableDocumentHeader() {
673 return accountsReceivableDocumentHeader;
674 }
675
676 /**
677 * Sets the accountsReceivableDocumentHeader attribute.
678 *
679 * @param accountsReceivableDocumentHeader The accountsReceivableDocumentHeader to set.
680 */
681 public void setAccountsReceivableDocumentHeader(AccountsReceivableDocumentHeader accountsReceivableDocumentHeader) {
682 this.accountsReceivableDocumentHeader = accountsReceivableDocumentHeader;
683 }
684
685 /**
686 *
687 * This method...
688 * @return
689 */
690 public String getParentInvoiceNumber() {
691 return getAccountsReceivableDocumentHeader().getDocumentHeader().getDocumentTemplateNumber();
692 }
693
694 /**
695 * Gets the billByChartOfAccount attribute.
696 *
697 * @return Returns the billByChartOfAccount
698 */
699 public Chart getBillByChartOfAccount() {
700 return billByChartOfAccount;
701 }
702
703 /**
704 * Sets the billByChartOfAccount attribute.
705 *
706 * @param billByChartOfAccount The billByChartOfAccount to set.
707 * @deprecated
708 */
709 public void setBillByChartOfAccount(Chart billByChartOfAccount) {
710 this.billByChartOfAccount = billByChartOfAccount;
711 }
712
713 /**
714 * Gets the billedByOrganization attribute.
715 *
716 * @return Returns the billedByOrganization
717 */
718 public Organization getBilledByOrganization() {
719 return billedByOrganization;
720 }
721
722 /**
723 * Sets the billedByOrganization attribute.
724 *
725 * @param billedByOrganization The billedByOrganization to set.
726 * @deprecated
727 */
728 public void setBilledByOrganization(Organization billedByOrganization) {
729 this.billedByOrganization = billedByOrganization;
730 }
731
732 /**
733 * Gets the customerSpecialProcessing attribute.
734 *
735 * @return Returns the customerSpecialProcessing
736 */
737 public CustomerProcessingType getCustomerSpecialProcessing() {
738 return customerSpecialProcessing;
739 }
740
741 /**
742 * Sets the customerSpecialProcessing attribute.
743 *
744 * @param customerSpecialProcessing The customerSpecialProcessing to set.
745 * @deprecated
746 */
747 public void setCustomerSpecialProcessing(CustomerProcessingType customerSpecialProcessing) {
748 this.customerSpecialProcessing = customerSpecialProcessing;
749 }
750
751 /**
752 * Gets the paymentAccount attribute.
753 *
754 * @return Returns the paymentAccount.
755 */
756 public Account getPaymentAccount() {
757 return paymentAccount;
758 }
759
760 /**
761 * Sets the paymentAccount attribute value.
762 *
763 * @param paymentAccount The paymentAccount to set.
764 * @deprecated
765 */
766 public void setPaymentAccount(Account paymentAccount) {
767 this.paymentAccount = paymentAccount;
768 }
769
770 /**
771 * Gets the paymentChartOfAccounts attribute.
772 *
773 * @return Returns the paymentChartOfAccounts.
774 */
775 public Chart getPaymentChartOfAccounts() {
776 return paymentChartOfAccounts;
777 }
778
779 /**
780 * Sets the paymentChartOfAccounts attribute value.
781 *
782 * @param paymentChartOfAccounts The paymentChartOfAccounts to set.
783 * @deprecated
784 */
785 public void setPaymentChartOfAccounts(Chart paymentChartOfAccounts) {
786 this.paymentChartOfAccounts = paymentChartOfAccounts;
787 }
788
789 /**
790 * Gets the paymentFinancialObject attribute.
791 *
792 * @return Returns the paymentFinancialObject.
793 */
794 public ObjectCode getPaymentFinancialObject() {
795 return paymentFinancialObject;
796 }
797
798 /**
799 * Sets the paymentFinancialObject attribute value.
800 *
801 * @param paymentFinancialObject The paymentFinancialObject to set.
802 * @deprecated
803 */
804 public void setPaymentFinancialObject(ObjectCode paymentFinancialObject) {
805 this.paymentFinancialObject = paymentFinancialObject;
806 }
807
808 /**
809 * Gets the paymentFinancialSubObject attribute.
810 *
811 * @return Returns the paymentFinancialSubObject.
812 */
813 public SubObjectCode getPaymentFinancialSubObject() {
814 return paymentFinancialSubObject;
815 }
816
817 /**
818 * Sets the paymentFinancialSubObject attribute value.
819 *
820 * @param paymentFinancialSubObject The paymentFinancialSubObject to set.
821 * @deprecated
822 */
823 public void setPaymentFinancialSubObject(SubObjectCode paymentFinancialSubObject) {
824 this.paymentFinancialSubObject = paymentFinancialSubObject;
825 }
826
827 /**
828 * Gets the paymentProject attribute.
829 *
830 * @return Returns the paymentProject.
831 */
832 public ProjectCode getPaymentProject() {
833 return paymentProject;
834 }
835
836 /**
837 * Sets the paymentProject attribute value.
838 *
839 * @param paymentProject The paymentProject to set.
840 * @deprecated
841 */
842 public void setPaymentProject(ProjectCode paymentProject) {
843 this.paymentProject = paymentProject;
844 }
845
846 /**
847 * Gets the paymentSubAccount attribute.
848 *
849 * @return Returns the paymentSubAccount.
850 */
851 public SubAccount getPaymentSubAccount() {
852 return paymentSubAccount;
853 }
854
855 /**
856 * Sets the paymentSubAccount attribute value.
857 *
858 * @param paymentSubAccount The paymentSubAccount to set.
859 * @deprecated
860 */
861 public void setPaymentSubAccount(SubAccount paymentSubAccount) {
862 this.paymentSubAccount = paymentSubAccount;
863 }
864
865 /**
866 * This method returns the billing date for display. If billing date hasn't been set yet, just display current date
867 *
868 * @return
869 */
870 public Date getBillingDateForDisplay() {
871 if (ObjectUtils.isNotNull(getBillingDate())) {
872 return getBillingDate();
873 }
874 else {
875 return SpringContext.getBean(DateTimeService.class).getCurrentSqlDate();
876 }
877 }
878
879 /**
880 * This method...
881 *
882 * @param date
883 */
884 public void setBillingDateForDisplay(Date date) {
885 // do nothing
886 }
887
888 public Date getClosedDate() {
889 return closedDate;
890 }
891
892 public void setClosedDate(Date closedDate) {
893 this.closedDate = closedDate;
894 }
895
896 /**
897 * @see org.kuali.rice.kns.bo.BusinessObjectBase#toStringMapper()
898 */
899 @SuppressWarnings("unchecked")
900 protected LinkedHashMap toStringMapper() {
901 LinkedHashMap m = new LinkedHashMap();
902 m.put("documentNumber", this.documentNumber);
903 return m;
904 }
905
906 /**
907 * This method returns true if this document is a reversal for another document
908 *
909 * @return
910 */
911 public boolean isInvoiceReversal() {
912 return ObjectUtils.isNotNull(getDocumentHeader().getFinancialDocumentInErrorNumber());
913 }
914
915 /**
916 * @see org.kuali.kfs.sys.document.AccountingDocumentBase#isDebit(org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySourceDetail)
917 */
918 @Override
919 public boolean isDebit(GeneralLedgerPendingEntrySourceDetail postable) {
920 return ((CustomerInvoiceDetail) postable).isDebit();
921 }
922
923 /**
924 * @see org.kuali.kfs.sys.document.AccountingDocumentBase#getSourceAccountingLineClass()
925 */
926 @Override
927 public Class<CustomerInvoiceDetail> getSourceAccountingLineClass() {
928 return CustomerInvoiceDetail.class;
929 }
930
931 /**
932 * Ensures that all the accounts receivable object codes are correctly updated
933 */
934 public void updateAccountReceivableObjectCodes() {
935 for (Iterator e = getSourceAccountingLines().iterator(); e.hasNext();) {
936 SpringContext.getBean(CustomerInvoiceDetailService.class).updateAccountsReceivableObjectCode(((CustomerInvoiceDetail) e.next()));
937 }
938 }
939
940 /**
941 * This method creates the following GLPE's for the invoice 1. Debit to receivable for total line amount ( including sales tax
942 * if it exists ). 2. Credit to income based on item price * quantity. 3. Credit to state sales tax account/object code if state
943 * sales tax exists. 4. Credit to district sales tax account/object code if district sales tax exists.
944 *
945 * @see org.kuali.kfs.service.impl.GenericGeneralLedgerPendingEntryGenerationProcessImpl#processGenerateGeneralLedgerPendingEntries(org.kuali.kfs.sys.document.GeneralLedgerPendingEntrySource,
946 * org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySourceDetail,
947 * org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySequenceHelper)
948 */
949 @Override
950 public boolean generateGeneralLedgerPendingEntries(GeneralLedgerPendingEntrySourceDetail glpeSourceDetail, GeneralLedgerPendingEntrySequenceHelper sequenceHelper) {
951
952 String receivableOffsetOption = SpringContext.getBean(ParameterService.class).getParameterValue(CustomerInvoiceDocument.class, ArConstants.GLPE_RECEIVABLE_OFFSET_GENERATION_METHOD);
953 boolean hasClaimOnCashOffset = ArConstants.GLPE_RECEIVABLE_OFFSET_GENERATION_METHOD_FAU.equals(receivableOffsetOption);
954
955 addReceivableGLPEs(sequenceHelper, glpeSourceDetail, hasClaimOnCashOffset);
956 sequenceHelper.increment();
957 addIncomeGLPEs(sequenceHelper, glpeSourceDetail, hasClaimOnCashOffset);
958
959 // if sales tax is enabled generate GLPEs
960 if (SpringContext.getBean(AccountsReceivableTaxService.class).isCustomerInvoiceDetailTaxable(this, (CustomerInvoiceDetail) glpeSourceDetail)) {
961 addSalesTaxGLPEs(sequenceHelper, glpeSourceDetail, hasClaimOnCashOffset);
962 }
963
964
965 return true;
966 }
967
968
969 /**
970 * This method creates the receivable GLPEs for each invoice detail line.
971 *
972 * @param poster
973 * @param sequenceHelper
974 * @param postable
975 * @param explicitEntry
976 */
977 protected void addReceivableGLPEs(GeneralLedgerPendingEntrySequenceHelper sequenceHelper, GeneralLedgerPendingEntrySourceDetail glpeSourceDetail, boolean hasClaimOnCashOffset) {
978
979 CustomerInvoiceDetail customerInvoiceDetail = (CustomerInvoiceDetail) glpeSourceDetail;
980 ReceivableCustomerInvoiceDetail receivableCustomerInvoiceDetail = new ReceivableCustomerInvoiceDetail(customerInvoiceDetail, this);
981 boolean isDebit = (!isInvoiceReversal() && !customerInvoiceDetail.isDiscountLine()) || (isInvoiceReversal() && customerInvoiceDetail.isDiscountLine());
982
983 CustomerInvoiceGLPEService service = SpringContext.getBean(CustomerInvoiceGLPEService.class);
984 service.createAndAddGenericInvoiceRelatedGLPEs(this, receivableCustomerInvoiceDetail, sequenceHelper, isDebit, hasClaimOnCashOffset, customerInvoiceDetail.getInvoiceItemPreTaxAmount());
985 }
986
987 /**
988 * This method adds pending entry with transaction ledger entry amount set to item price * quantity
989 *
990 * @param poster
991 * @param sequenceHelper
992 * @param postable
993 * @param explicitEntry
994 */
995 protected void addIncomeGLPEs(GeneralLedgerPendingEntrySequenceHelper sequenceHelper, GeneralLedgerPendingEntrySourceDetail glpeSourceDetail, boolean hasClaimOnCashOffset) {
996
997 CustomerInvoiceDetail customerInvoiceDetail = (CustomerInvoiceDetail) glpeSourceDetail;
998 boolean isDebit = (!isInvoiceReversal() && customerInvoiceDetail.isDiscountLine()) || (isInvoiceReversal() && !customerInvoiceDetail.isDiscountLine());
999
1000 CustomerInvoiceGLPEService service = SpringContext.getBean(CustomerInvoiceGLPEService.class);
1001 service.createAndAddGenericInvoiceRelatedGLPEs(this, customerInvoiceDetail, sequenceHelper, isDebit, hasClaimOnCashOffset, customerInvoiceDetail.getInvoiceItemPreTaxAmount());
1002
1003 }
1004
1005 /**
1006 * This method add pending entries for every tax detail that exists for a particular postal code
1007 *
1008 * @param sequenceHelper
1009 * @param glpeSourceDetail
1010 * @param hasClaimOnCashOffset
1011 */
1012 protected void addSalesTaxGLPEs(GeneralLedgerPendingEntrySequenceHelper sequenceHelper, GeneralLedgerPendingEntrySourceDetail glpeSourceDetail, boolean hasClaimOnCashOffset) {
1013
1014 CustomerInvoiceDetail customerInvoiceDetail = (CustomerInvoiceDetail) glpeSourceDetail;
1015 boolean isDebit = (!isInvoiceReversal() && customerInvoiceDetail.isDiscountLine()) || (isInvoiceReversal() && !customerInvoiceDetail.isDiscountLine());
1016
1017 String postalCode = SpringContext.getBean(AccountsReceivableTaxService.class).getPostalCodeForTaxation(this);
1018 Date dateOfTransaction = SpringContext.getBean(DateTimeService.class).getCurrentSqlDate();
1019
1020 List<TaxDetail> salesTaxDetails = SpringContext.getBean(TaxService.class).getSalesTaxDetails(dateOfTransaction, postalCode, customerInvoiceDetail.getInvoiceItemPreTaxAmount());
1021
1022 CustomerInvoiceGLPEService service = SpringContext.getBean(CustomerInvoiceGLPEService.class);
1023 SalesTaxCustomerInvoiceDetail salesTaxCustomerInvoiceDetail;
1024 ReceivableCustomerInvoiceDetail receivableCustomerInvoiceDetail;
1025 for (TaxDetail salesTaxDetail : salesTaxDetails) {
1026
1027 salesTaxCustomerInvoiceDetail = new SalesTaxCustomerInvoiceDetail(salesTaxDetail, customerInvoiceDetail);
1028 receivableCustomerInvoiceDetail = new ReceivableCustomerInvoiceDetail(salesTaxCustomerInvoiceDetail, this);
1029
1030 sequenceHelper.increment();
1031 service.createAndAddGenericInvoiceRelatedGLPEs(this, receivableCustomerInvoiceDetail, sequenceHelper, !isDebit, hasClaimOnCashOffset, salesTaxDetail.getTaxAmount());
1032
1033 sequenceHelper.increment();
1034 service.createAndAddGenericInvoiceRelatedGLPEs(this, salesTaxCustomerInvoiceDetail, sequenceHelper, isDebit, hasClaimOnCashOffset, salesTaxDetail.getTaxAmount());
1035 }
1036 }
1037
1038 /**
1039 * Returns an implementation of the GeneralLedgerPendingEntryService
1040 *
1041 * @return an implementation of the GeneralLedgerPendingEntryService
1042 */
1043 public GeneralLedgerPendingEntryService getGeneralLedgerPendingEntryService() {
1044 return SpringContext.getBean(GeneralLedgerPendingEntryService.class);
1045 }
1046
1047 /**
1048 * Returns a map with the primitive field names as the key and the primitive values as the map value.
1049 *
1050 * @return Map
1051 */
1052 @SuppressWarnings("unchecked")
1053 public Map getValuesMap() {
1054 Map valuesMap = new HashMap();
1055
1056 valuesMap.put("postingYear", getPostingYear());
1057 valuesMap.put("paymentChartOfAccountsCode", getPaymentChartOfAccountsCode());
1058 valuesMap.put("paymentAccountNumber", getPaymentAccountNumber());
1059 valuesMap.put("paymentFinancialObjectCode", getPaymentFinancialObjectCode());
1060 valuesMap.put("paymentSubAccountNumber", getPaymentSubAccountNumber());
1061 valuesMap.put("paymentFinancialSubObjectCode", getPaymentFinancialSubObjectCode());
1062 valuesMap.put("paymentProjectCode", getPaymentProjectCode());
1063 return valuesMap;
1064 }
1065
1066 @Override
1067 public List<Long> getWorkflowEngineDocumentIdsToLock() {
1068 // add the invoice number of the Error Corrected doc, if this is an error correction
1069 if (this.isInvoiceReversal()) {
1070 if (StringUtils.isNotBlank(getDocumentHeader().getFinancialDocumentInErrorNumber())) {
1071 List<Long> documentIds = new ArrayList<Long>();
1072 documentIds.add(new Long(getDocumentHeader().getFinancialDocumentInErrorNumber()));
1073 return documentIds;
1074 }
1075 }
1076 return null;
1077 }
1078
1079 /**
1080 * When document is processed do the following: 1) Set the billingDate to today's date if not already set 2) If there are
1081 * discounts, create corresponding invoice paid applied rows 3) If the document is a reversal, in addition to reversing paid
1082 * applied rows, update the open paid applied indicator
1083 *
1084 * @see org.kuali.kfs.sys.document.GeneralLedgerPostingDocumentBase#doRouteStatusChange()
1085 */
1086 @Override
1087 public void doRouteStatusChange(DocumentRouteStatusChangeDTO statusChangeEvent) {
1088 super.doRouteStatusChange(statusChangeEvent);
1089
1090 // fast-exit if status != P
1091 if (!getDocumentHeader().getWorkflowDocument().stateIsProcessed()) {
1092 return;
1093 }
1094
1095 // wire up the billing date
1096 if (ObjectUtils.isNull(getBillingDate())) {
1097 setBillingDate(SpringContext.getBean(DateTimeService.class).getCurrentSqlDateMidnight());
1098 }
1099
1100 // apply discounts
1101 CustomerInvoiceDocumentService invoiceService = SpringContext.getBean(CustomerInvoiceDocumentService.class);
1102 invoiceService.convertDiscountsToPaidApplieds(this);
1103
1104 // handle a Correction/Reversal document
1105 if (this.isInvoiceReversal()) {
1106 CustomerInvoiceDocument correctedCustomerInvoiceDocument;
1107 try {
1108 correctedCustomerInvoiceDocument = (CustomerInvoiceDocument) SpringContext.getBean(DocumentService.class).getByDocumentHeaderId(this.getDocumentHeader().getFinancialDocumentInErrorNumber());
1109 }
1110 catch (WorkflowException e) {
1111 throw new RuntimeException("Cannot find customer invoice document with id " + this.getDocumentHeader().getFinancialDocumentInErrorNumber());
1112 }
1113
1114 // if reversal, close both this reversal invoice and the original invoice
1115 SpringContext.getBean(CustomerInvoiceDocumentService.class).closeCustomerInvoiceDocument(correctedCustomerInvoiceDocument);
1116 SpringContext.getBean(CustomerInvoiceDocumentService.class).closeCustomerInvoiceDocument(this);
1117 }
1118
1119 // handle Recurrence
1120 if (ObjectUtils.isNull(this.getCustomerInvoiceRecurrenceDetails()) ||
1121 (ObjectUtils.isNull(this.getCustomerInvoiceRecurrenceDetails().getDocumentRecurrenceBeginDate())
1122 && ObjectUtils.isNull(this.getCustomerInvoiceRecurrenceDetails().getDocumentRecurrenceEndDate())
1123 && ObjectUtils.isNull(this.getCustomerInvoiceRecurrenceDetails().getDocumentRecurrenceIntervalCode())
1124 && ObjectUtils.isNull(this.getCustomerInvoiceRecurrenceDetails().getDocumentTotalRecurrenceNumber())
1125 && ObjectUtils.isNull(this.getCustomerInvoiceRecurrenceDetails().getDocumentInitiatorUserIdentifier()))) {
1126 }
1127 else {
1128 // set new user session to recurrence initiator
1129 UserSession currentSession = GlobalVariables.getUserSession();
1130 GlobalVariables.setUserSession(new UserSession(KFSConstants.SYSTEM_USER));
1131
1132 // populate InvoiceRecurrence business object
1133 InvoiceRecurrence newInvoiceRecurrence = new InvoiceRecurrence();
1134 newInvoiceRecurrence.setInvoiceNumber(this.getCustomerInvoiceRecurrenceDetails().getInvoiceNumber());
1135 newInvoiceRecurrence.setCustomerNumber(this.getCustomerInvoiceRecurrenceDetails().getCustomerNumber());
1136 newInvoiceRecurrence.setDocumentRecurrenceBeginDate(this.getCustomerInvoiceRecurrenceDetails().getDocumentRecurrenceBeginDate());
1137 newInvoiceRecurrence.setDocumentRecurrenceEndDate(this.getCustomerInvoiceRecurrenceDetails().getDocumentRecurrenceEndDate());
1138 newInvoiceRecurrence.setDocumentRecurrenceIntervalCode(this.getCustomerInvoiceRecurrenceDetails().getDocumentRecurrenceIntervalCode());
1139 newInvoiceRecurrence.setDocumentTotalRecurrenceNumber(this.getCustomerInvoiceRecurrenceDetails().getDocumentTotalRecurrenceNumber());
1140 newInvoiceRecurrence.setDocumentInitiatorUserIdentifier(this.getCustomerInvoiceRecurrenceDetails().getDocumentInitiatorUserIdentifier());
1141 newInvoiceRecurrence.setActive(this.getCustomerInvoiceRecurrenceDetails().isActive());
1142
1143 // create a new InvoiceRecurrenceMaintenanceDocument
1144 MaintenanceDocument invoiceRecurrenceMaintDoc = null;
1145 try {
1146 invoiceRecurrenceMaintDoc = (MaintenanceDocument) SpringContext.getBean(DocumentService.class).getNewDocument(getInvoiceRecurrenceMaintenanceDocumentTypeName());
1147 }
1148 catch (WorkflowException e1) {
1149 throw new RuntimeException("Cannot create new Invoice Recurrence Maintenance Document.");
1150 }
1151 invoiceRecurrenceMaintDoc.getDocumentHeader().setDocumentDescription("Automatically created from Invoice");
1152 invoiceRecurrenceMaintDoc.getNewMaintainableObject().setBusinessObject(newInvoiceRecurrence);
1153
1154 try {
1155 // blanket approve the INVR, bypassing everything
1156 //invoiceRecurrenceMaintDoc.getDocumentHeader().getWorkflowDocument().blanketApprove("Blanket Approved by the creating Invoice Document #" + getDocumentNumber());
1157 //TODO temporarily just do regular route until we can get blanket approve perms setup for KFS
1158 SpringContext.getBean(DocumentService.class).saveDocument(invoiceRecurrenceMaintDoc);
1159 invoiceRecurrenceMaintDoc.getDocumentHeader().getWorkflowDocument().routeDocument("Automatically created and routed by CustomerInvoiceDocument #" + getDocumentNumber() + ".");
1160 }
1161 catch (WorkflowException e) {
1162 throw new RuntimeException("Cannot route Invoice Recurrence Maintenance Document with id " + invoiceRecurrenceMaintDoc.getDocumentNumber() + ".");
1163 }
1164
1165 // return the session to the original initiator
1166 GlobalVariables.setUserSession(currentSession);
1167
1168 }
1169 }
1170
1171 protected String getInvoiceRecurrenceMaintenanceDocumentTypeName() {
1172 return "INVR";
1173 }
1174
1175 /**
1176 * If this invoice is a reversal, set the open indicator to false
1177 *
1178 * @see org.kuali.kfs.sys.document.FinancialSystemTransactionalDocumentBase#prepareForSave()
1179 */
1180 @Override
1181 public void prepareForSave() {
1182 if (this.isInvoiceReversal()) {
1183 setOpenInvoiceIndicator(false);
1184 }
1185
1186 // make sure the docHeader gets its doc total right. This is here because there's an ordering
1187 // bug in the struts classes for invoice that is preventing this from being set right. There is
1188 // probably a better way to fix this that can be pursued later.
1189 getDocumentHeader().setFinancialDocumentTotalAmount(getTotalDollarAmount());
1190
1191 // invoice recurrence stuff, if there is a recurrence object
1192 if (ObjectUtils.isNotNull(this.getCustomerInvoiceRecurrenceDetails()) && getProcessRecurrenceFlag()) {
1193
1194 // wire up the recurrence customer number if one exists
1195 if (ObjectUtils.isNull(this.getCustomerInvoiceRecurrenceDetails().getCustomerNumber())) {
1196 this.getCustomerInvoiceRecurrenceDetails().setCustomerNumber(this.getAccountsReceivableDocumentHeader().getCustomerNumber());
1197 }
1198
1199 customerInvoiceRecurrenceDetails.setInvoiceNumber(getDocumentNumber());
1200
1201 // calc recurrence number if only end-date specified
1202 if (ObjectUtils.isNull(this.getCustomerInvoiceRecurrenceDetails().getDocumentTotalRecurrenceNumber()) && ObjectUtils.isNotNull(this.getCustomerInvoiceRecurrenceDetails().getDocumentRecurrenceEndDate())) {
1203
1204 Calendar beginCalendar = Calendar.getInstance();
1205 beginCalendar.setTime(this.getCustomerInvoiceRecurrenceDetails().getDocumentRecurrenceBeginDate());
1206 Date beginDate = this.getCustomerInvoiceRecurrenceDetails().getDocumentRecurrenceBeginDate();
1207 Calendar endCalendar = Calendar.getInstance();
1208
1209 endCalendar.setTime(this.getCustomerInvoiceRecurrenceDetails().getDocumentRecurrenceEndDate());
1210 Date endDate = this.getCustomerInvoiceRecurrenceDetails().getDocumentRecurrenceEndDate();
1211 Calendar nextCalendar = Calendar.getInstance();
1212 Date nextDate = beginDate;
1213
1214 int totalRecurrences = 0;
1215 int addCounter = 0;
1216 String intervalCode = this.getCustomerInvoiceRecurrenceDetails().getDocumentRecurrenceIntervalCode();
1217 if (intervalCode.equals("M")) {
1218 addCounter = 1;
1219 }
1220 if (intervalCode.equals("Q")) {
1221 addCounter = 3;
1222 }
1223 /* perform this loop while begin_date is less than or equal to end_date */
1224 while (!(beginDate.after(endDate))) {
1225 beginCalendar.setTime(beginDate);
1226 beginCalendar.add(Calendar.MONTH, addCounter);
1227 beginDate = DateUtils.convertToSqlDate(beginCalendar.getTime());
1228 totalRecurrences++;
1229
1230 nextDate = beginDate;
1231 nextCalendar.setTime(nextDate);
1232 nextCalendar.add(Calendar.MONTH, addCounter);
1233 nextDate = DateUtils.convertToSqlDate(nextCalendar.getTime());
1234 if (endDate.after(beginDate) && endDate.before(nextDate)) {
1235 totalRecurrences++;
1236 break;
1237 }
1238 }
1239 if (totalRecurrences > 0) {
1240 this.getCustomerInvoiceRecurrenceDetails().setDocumentTotalRecurrenceNumber(totalRecurrences);
1241 }
1242 }
1243
1244 // calc end-date if only recurrence-number is specified
1245 if (ObjectUtils.isNotNull(this.getCustomerInvoiceRecurrenceDetails().getDocumentTotalRecurrenceNumber()) && ObjectUtils.isNull(this.getCustomerInvoiceRecurrenceDetails().getDocumentRecurrenceEndDate())) {
1246
1247 Calendar beginCalendar = Calendar.getInstance();
1248 beginCalendar.setTime(new Timestamp(this.getCustomerInvoiceRecurrenceDetails().getDocumentRecurrenceBeginDate().getTime()));
1249 Calendar endCalendar = Calendar.getInstance();
1250 endCalendar = beginCalendar;
1251
1252 int addCounter = 0;
1253 Integer documentTotalRecurrenceNumber = this.getCustomerInvoiceRecurrenceDetails().getDocumentTotalRecurrenceNumber();
1254 String intervalCode = this.getCustomerInvoiceRecurrenceDetails().getDocumentRecurrenceIntervalCode();
1255 if (intervalCode.equals("M")) {
1256 addCounter = -1;
1257 addCounter += documentTotalRecurrenceNumber * 1;
1258 }
1259 if (intervalCode.equals("Q")) {
1260 addCounter = -3;
1261 addCounter += documentTotalRecurrenceNumber * 3;
1262 }
1263 endCalendar.add(Calendar.MONTH, addCounter);
1264 this.getCustomerInvoiceRecurrenceDetails().setDocumentRecurrenceEndDate(DateUtils.convertToSqlDate(endCalendar.getTime()));
1265 }
1266 }
1267
1268 // Force upper case
1269 setBilledByOrganizationCode(getBilledByOrganizationCode().toUpperCase());
1270
1271 if (ObjectUtils.isNull(getCustomerShipToAddressIdentifier())) {
1272 setCustomerShipToAddress(null);
1273 setCustomerShipToAddressOnInvoice(null);
1274 }
1275
1276 }
1277
1278 // returns true only when there is all the required recurrence info
1279 public boolean getProcessRecurrenceFlag() {
1280 CustomerInvoiceRecurrenceDetails rec = this.getCustomerInvoiceRecurrenceDetails();
1281
1282 boolean processRecurrenceFlag = (null != rec.getDocumentRecurrenceIntervalCode());
1283 processRecurrenceFlag &= (null != rec.getDocumentRecurrenceBeginDate());
1284 processRecurrenceFlag &= ( (null != rec.getDocumentRecurrenceEndDate()) || (null != rec.getDocumentTotalRecurrenceNumber()));
1285 processRecurrenceFlag &= (rec.isActive());
1286 processRecurrenceFlag &= (null != rec.getDocumentInitiatorUserIdentifier());
1287
1288 return processRecurrenceFlag;
1289 }
1290
1291 // returns true only if there is no recurrence data at all in recurrence tab
1292 public boolean getNoRecurrenceDataFlag() {
1293 CustomerInvoiceRecurrenceDetails rec = this.getCustomerInvoiceRecurrenceDetails();
1294
1295 boolean noRecurrenceDataFlag = ObjectUtils.isNull(rec.getDocumentRecurrenceIntervalCode());
1296 noRecurrenceDataFlag &= ObjectUtils.isNull(rec.getDocumentRecurrenceBeginDate());
1297 noRecurrenceDataFlag &= ObjectUtils.isNull(rec.getDocumentRecurrenceEndDate());
1298 noRecurrenceDataFlag &= !rec.isActive();
1299 noRecurrenceDataFlag &= ObjectUtils.isNull(rec.getDocumentTotalRecurrenceNumber());
1300 noRecurrenceDataFlag &= ObjectUtils.isNull(rec.getDocumentInitiatorUserIdentifier());
1301
1302 return noRecurrenceDataFlag;
1303 }
1304
1305 /**
1306 * @see org.kuali.kfs.sys.document.AccountingDocumentBase#toCopy()
1307 */
1308 @Override
1309 public void toCopy() throws WorkflowException {
1310 super.toCopy();
1311 CustomerInvoiceDocumentService customerInvoiceDocumentService = SpringContext.getBean(CustomerInvoiceDocumentService.class);
1312 customerInvoiceDocumentService.setupDefaultValuesForCopiedCustomerInvoiceDocument(this);
1313 this.getDocumentHeader().setFinancialDocumentTotalAmount(getTotalDollarAmount());
1314 }
1315
1316 /**
1317 * @see org.kuali.kfs.sys.document.GeneralLedgerPostingDocumentBase#toErrorCorrection()
1318 */
1319 @Override
1320 public void toErrorCorrection() throws WorkflowException {
1321 super.toErrorCorrection();
1322 negateCustomerInvoiceDetailUnitPrices();
1323 this.setOpenInvoiceIndicator(false);
1324 this.getDocumentHeader().setFinancialDocumentTotalAmount(getTotalDollarAmount());
1325
1326 // if we dont force this on the error correction, the recurrence will
1327 // have the old doc number, and will revert the main doc due to OJB fun,
1328 // which will cause PK unique index failure.
1329 if (ObjectUtils.isNotNull(customerInvoiceRecurrenceDetails)) {
1330 customerInvoiceRecurrenceDetails.setInvoiceNumber(this.documentNumber);
1331 }
1332 }
1333
1334
1335 /**
1336 * This method...
1337 */
1338 @SuppressWarnings("unchecked")
1339 public void negateCustomerInvoiceDetailUnitPrices() {
1340 CustomerInvoiceDetail customerInvoiceDetail;
1341 for (Iterator i = getSourceAccountingLines().iterator(); i.hasNext();) {
1342 customerInvoiceDetail = (CustomerInvoiceDetail) i.next();
1343 customerInvoiceDetail.setInvoiceItemUnitPrice(customerInvoiceDetail.getInvoiceItemUnitPrice().negate());
1344
1345 //clear the old CustomerInvoiceDocument
1346 customerInvoiceDetail.setCustomerInvoiceDocument(null);
1347
1348 // revert changes for custom invoice error correction
1349 //SpringContext.getBean(CustomerInvoiceDetailService.class).prepareCustomerInvoiceDetailForErrorCorrection(customerInvoiceDetail, this);
1350 }
1351 }
1352
1353 /**
1354 * This method returns true if invoice document has at least one discount line
1355 *
1356 * @return
1357 */
1358 @SuppressWarnings("unchecked")
1359 public boolean hasAtLeastOneDiscount() {
1360
1361 CustomerInvoiceDetail customerInvoiceDetail;
1362 for (Iterator i = getSourceAccountingLines().iterator(); i.hasNext();) {
1363 customerInvoiceDetail = (CustomerInvoiceDetail) i.next();
1364 if (customerInvoiceDetail.isDiscountLineParent()) {
1365 return true;
1366 }
1367 }
1368 return false;
1369 }
1370
1371 /**
1372 * This method returns true if line number is discount line number based on sequence number
1373 *
1374 * @param sequenceNumber
1375 * @return
1376 */
1377 @SuppressWarnings("unchecked")
1378 public boolean isDiscountLineBasedOnSequenceNumber(Integer sequenceNumber) {
1379 if (ObjectUtils.isNull(sequenceNumber)) {
1380 return false;
1381 }
1382
1383 CustomerInvoiceDetail customerInvoiceDetail;
1384 for (Iterator i = getSourceAccountingLines().iterator(); i.hasNext();) {
1385 customerInvoiceDetail = (CustomerInvoiceDetail) i.next();
1386 Integer discLineNum = customerInvoiceDetail.getInvoiceItemDiscountLineNumber();
1387
1388 // check if sequence number is referenced as a discount line for another customer invoice detail (i.e. the parent line)
1389 if (ObjectUtils.isNotNull(discLineNum) && sequenceNumber.equals(customerInvoiceDetail.getInvoiceItemDiscountLineNumber())) {
1390 return true;
1391 }
1392 }
1393 return false;
1394 }
1395
1396 /**
1397 * This method returns parent customer invoice detail based on child discount sequence number
1398 *
1399 * @param sequenceNumber
1400 * @return
1401 */
1402 @SuppressWarnings("unchecked")
1403 public CustomerInvoiceDetail getParentLineBasedOnDiscountSequenceNumber(Integer discountSequenceNumber) {
1404
1405 if (ObjectUtils.isNull(discountSequenceNumber)) {
1406 return null;
1407 }
1408
1409 CustomerInvoiceDetail customerInvoiceDetail;
1410 for (Iterator i = getSourceAccountingLines().iterator(); i.hasNext();) {
1411 customerInvoiceDetail = (CustomerInvoiceDetail) i.next();
1412 Integer discLineNum = customerInvoiceDetail.getInvoiceItemDiscountLineNumber();
1413 if (ObjectUtils.isNotNull(discLineNum) && discountSequenceNumber.equals(customerInvoiceDetail.getInvoiceItemDiscountLineNumber())) {
1414 return customerInvoiceDetail;
1415 }
1416 }
1417 return null;
1418 }
1419
1420
1421 /**
1422 * This method is called on CustomerInvoiceDocumentAction.execute() to set isDiscount to true if it truly is a discount line
1423 */
1424 @SuppressWarnings("unchecked")
1425 public void updateDiscountAndParentLineReferences() {
1426
1427 CustomerInvoiceDetail discount;
1428 for (Iterator i = getSourceAccountingLines().iterator(); i.hasNext();) {
1429 discount = (CustomerInvoiceDetail) i.next();
1430
1431 // get sequence number and check if theres a corresponding parent line for that discount line
1432 CustomerInvoiceDetail parent = getParentLineBasedOnDiscountSequenceNumber(discount.getSequenceNumber());
1433 if (ObjectUtils.isNotNull(parent)) {
1434 discount.setParentDiscountCustomerInvoiceDetail(parent);
1435 parent.setDiscountCustomerInvoiceDetail(discount);
1436 }
1437 else {
1438 discount.setParentDiscountCustomerInvoiceDetail(null);
1439 }
1440 }
1441 }
1442
1443 /**
1444 * This method removes the corresponding discount line based on the index of the parent line index. This assumes that the
1445 * discount line is ALWAYS after the index of the parent line.
1446 *
1447 * @param deleteIndex
1448 */
1449 public void removeDiscountLineBasedOnParentLineIndex(int parentLineIndex) {
1450 // get parent line line
1451 CustomerInvoiceDetail parentLine = (CustomerInvoiceDetail) getSourceAccountingLines().get(parentLineIndex);
1452
1453 // get index for discount line
1454 int discountLineIndex = -1; // this should ALWAYS get set
1455 for (int i = 0; i < getSourceAccountingLines().size(); i++) {
1456 if (parentLine.getInvoiceItemDiscountLineNumber().equals(((CustomerInvoiceDetail) getSourceAccountingLines().get(i)).getSequenceNumber())) {
1457 discountLineIndex = i;
1458 }
1459 }
1460 // remove discount line
1461 getSourceAccountingLines().remove(discountLineIndex);
1462 }
1463
1464 public CustomerInvoiceRecurrenceDetails getCustomerInvoiceRecurrenceDetails() {
1465 return customerInvoiceRecurrenceDetails;
1466 }
1467
1468 public void setCustomerInvoiceRecurrenceDetails(CustomerInvoiceRecurrenceDetails customerInvoiceRecurrenceDetails) {
1469 this.customerInvoiceRecurrenceDetails = customerInvoiceRecurrenceDetails;
1470 }
1471
1472 public CustomerAddress getCustomerShipToAddress() {
1473 return customerShipToAddress;
1474 }
1475
1476 public void setCustomerShipToAddress(CustomerAddress customerShipToAddress) {
1477 this.customerShipToAddress = customerShipToAddress;
1478 }
1479
1480 public CustomerAddress getCustomerBillToAddress() {
1481 return customerBillToAddress;
1482 }
1483
1484 public void setCustomerBillToAddress(CustomerAddress customerBillToAddress) {
1485 this.customerBillToAddress = customerBillToAddress;
1486 }
1487
1488 public PrintInvoiceOptions getPrintInvoiceOption() {
1489 if (ObjectUtils.isNull(printInvoiceOption) && StringUtils.isNotEmpty(printInvoiceIndicator)){
1490 refreshReferenceObject("printInvoiceOption");
1491 }
1492 return printInvoiceOption;
1493 }
1494
1495 public void setPrintInvoiceOption(PrintInvoiceOptions printInvoiceOption) {
1496 this.printInvoiceOption = printInvoiceOption;
1497 }
1498
1499 /**
1500 * This method returns the total of all pre tax amounts for all customer invoice detail lines
1501 *
1502 * @return
1503 */
1504 public KualiDecimal getInvoiceItemPreTaxAmountTotal() {
1505
1506 KualiDecimal invoiceItemPreTaxAmountTotal = new KualiDecimal(0);
1507 for (Iterator i = getSourceAccountingLines().iterator(); i.hasNext();) {
1508 invoiceItemPreTaxAmountTotal = invoiceItemPreTaxAmountTotal.add(((CustomerInvoiceDetail) i.next()).getInvoiceItemPreTaxAmount());
1509 }
1510 return invoiceItemPreTaxAmountTotal;
1511 }
1512
1513 /**
1514 * This method returns the total of all tax amounts for all customer invoice detail lines
1515 *
1516 * @return
1517 */
1518 public KualiDecimal getInvoiceItemTaxAmountTotal() {
1519
1520 KualiDecimal invoiceItemTaxAmountTotal = new KualiDecimal(0);
1521 for (Iterator i = getSourceAccountingLines().iterator(); i.hasNext();) {
1522 invoiceItemTaxAmountTotal = invoiceItemTaxAmountTotal.add(((CustomerInvoiceDetail) i.next()).getInvoiceItemTaxAmount());
1523 }
1524 return invoiceItemTaxAmountTotal;
1525 }
1526
1527 /**
1528 * This method returns the primary customer address for the customer number provided.
1529 *
1530 * @return
1531 */
1532 public CustomerAddress getPrimaryAddressForCustomerNumber() {
1533 if (ObjectUtils.isNotNull(accountsReceivableDocumentHeader) && StringUtils.isNotEmpty(accountsReceivableDocumentHeader.getCustomerNumber())) {
1534 return SpringContext.getBean(CustomerAddressService.class).getPrimaryAddress(accountsReceivableDocumentHeader.getCustomerNumber());
1535 }
1536 return null;
1537 }
1538
1539 /**
1540 * This method returns the customer object for the invoice
1541 *
1542 * @return
1543 */
1544 public Customer getCustomer() {
1545 if (ObjectUtils.isNotNull(accountsReceivableDocumentHeader)) {
1546 return accountsReceivableDocumentHeader.getCustomer();
1547 }
1548 return null;
1549 }
1550
1551 /**
1552 * This method will return all the customer invoice details excluding discount invoice detail lines.
1553 *
1554 * @return
1555 */
1556 public List<CustomerInvoiceDetail> getCustomerInvoiceDetailsWithoutDiscounts() {
1557 List<CustomerInvoiceDetail> customerInvoiceDetailsWithoutDiscounts = new TypedArrayList(CustomerInvoiceDetail.class);
1558
1559 updateDiscountAndParentLineReferences();
1560
1561 List<CustomerInvoiceDetail> customerInvoiceDetailsWithDiscounts = getSourceAccountingLines();
1562 for (CustomerInvoiceDetail customerInvoiceDetail : customerInvoiceDetailsWithDiscounts) {
1563 if (!customerInvoiceDetail.isDiscountLine()) {
1564 customerInvoiceDetail.setDocumentNumber(getDocumentNumber());
1565 customerInvoiceDetailsWithoutDiscounts.add(customerInvoiceDetail);
1566 }
1567 }
1568
1569 return customerInvoiceDetailsWithoutDiscounts;
1570 }
1571
1572 //TODO Andrew
1573 // /**
1574 // * This method could be a bit dangerous. It's meant to be used only on the payment application document, where the modified
1575 // * invoice is never saved.
1576 // *
1577 // * @param customerInvoiceDetails
1578 // */
1579 // public void setCustomerInvoiceDetailsWithoutDiscounts(List<CustomerInvoiceDetail> customerInvoiceDetails) {
1580 // List<CustomerInvoiceDetail> customerInvoiceDetailsWithoutDiscounts = getSourceAccountingLines();
1581 // int sequenceCounter = 0;
1582 // for (CustomerInvoiceDetail customerInvoiceDetail : customerInvoiceDetailsWithoutDiscounts) {
1583 // for (CustomerInvoiceDetail revisedCustomerInvoiceDetail : customerInvoiceDetails) {
1584 // if (!customerInvoiceDetail.isDiscountLine() && customerInvoiceDetail.getSequenceNumber().equals(revisedCustomerInvoiceDetail.getSequenceNumber())) {
1585 // customerInvoiceDetailsWithoutDiscounts.remove(sequenceCounter);
1586 // customerInvoiceDetailsWithoutDiscounts.add(sequenceCounter, revisedCustomerInvoiceDetail);
1587 // }
1588 // }
1589 // sequenceCounter += 1;
1590 // }
1591 // setSourceAccountingLines(customerInvoiceDetailsWithoutDiscounts);
1592 // }
1593
1594 /**
1595 * This method will return all the customer invoice details that are discounts
1596 *
1597 * @return
1598 */
1599 public List<CustomerInvoiceDetail> getDiscounts() {
1600 List<CustomerInvoiceDetail> discounts = new TypedArrayList(CustomerInvoiceDetail.class);
1601
1602 updateDiscountAndParentLineReferences();
1603
1604 List<CustomerInvoiceDetail> customerInvoiceDetailsWithDiscounts = getSourceAccountingLines();
1605 for (CustomerInvoiceDetail customerInvoiceDetail : customerInvoiceDetailsWithDiscounts) {
1606 if (customerInvoiceDetail.isDiscountLine()) {
1607 customerInvoiceDetail.setDocumentNumber(getDocumentNumber());
1608 discounts.add(customerInvoiceDetail);
1609 }
1610 }
1611
1612 return discounts;
1613 }
1614
1615 public int compareTo(CustomerInvoiceDocument customerInvoiceDocument) {
1616 if (this.getBillByChartOfAccountCode().equals(customerInvoiceDocument.getBillByChartOfAccountCode()))
1617 if (this.getBilledByOrganizationCode().equals(customerInvoiceDocument.getBilledByOrganizationCode()))
1618 return 0;
1619 return -1;
1620 }
1621
1622 /**
1623 *
1624 * Returns whether or not the Invoice would be paid off by applying the additional amount, passed in
1625 * by the parameter.
1626 *
1627 * @param additionalAmountToApply The additional applied amount to test against.
1628 * @return True if applying the additionalAmountToApply parameter amount would bring the OpenAmount to zero.
1629 */
1630 public boolean wouldPayOff(KualiDecimal additionalAmountToApply) {
1631 KualiDecimal openAmount = getOpenAmount();
1632 return KualiDecimal.ZERO.isGreaterEqual(openAmount.subtract(additionalAmountToApply));
1633 }
1634
1635 @Override
1636 public KualiDecimal getTotalDollarAmount() {
1637 return getSourceTotal();
1638 }
1639
1640 public String getBillingAddressInternationalProvinceName() {
1641 return billingAddressInternationalProvinceName;
1642 }
1643
1644 public void setBillingAddressInternationalProvinceName(String billingAddressInternationalProvinceName) {
1645 this.billingAddressInternationalProvinceName = billingAddressInternationalProvinceName;
1646 }
1647
1648 public String getBillingAddressName() {
1649 return billingAddressName;
1650 }
1651
1652 public void setBillingAddressName(String billingAddressName) {
1653 this.billingAddressName = billingAddressName;
1654 }
1655
1656 public String getBillingAddressTypeCode() {
1657 return billingAddressTypeCode;
1658 }
1659
1660 public void setBillingAddressTypeCode(String billingAddressTypeCode) {
1661 this.billingAddressTypeCode = billingAddressTypeCode;
1662 }
1663
1664 public String getBillingCityName() {
1665 return billingCityName;
1666 }
1667
1668 public void setBillingCityName(String billingCityName) {
1669 this.billingCityName = billingCityName;
1670 }
1671
1672 public String getBillingCountryCode() {
1673 return billingCountryCode;
1674 }
1675
1676 public void setBillingCountryCode(String billingCountryCode) {
1677 this.billingCountryCode = billingCountryCode;
1678 }
1679
1680 public String getBillingEmailAddress() {
1681 return billingEmailAddress;
1682 }
1683
1684 public void setBillingEmailAddress(String billingEmailAddress) {
1685 this.billingEmailAddress = billingEmailAddress;
1686 }
1687
1688 public String getBillingInternationalMailCode() {
1689 return billingInternationalMailCode;
1690 }
1691
1692 public void setBillingInternationalMailCode(String billingInternationalMailCode) {
1693 this.billingInternationalMailCode = billingInternationalMailCode;
1694 }
1695
1696 public String getBillingStateCode() {
1697 return billingStateCode;
1698 }
1699
1700 public void setBillingStateCode(String billingStateCode) {
1701 this.billingStateCode = billingStateCode;
1702 }
1703
1704 public String getBillingZipCode() {
1705 return billingZipCode;
1706 }
1707
1708 public void setBillingZipCode(String billingZipCode) {
1709 this.billingZipCode = billingZipCode;
1710 }
1711
1712 public String getCustomerName() {
1713 return customerName;
1714 }
1715
1716 public void setCustomerName(String customerName) {
1717 this.customerName = customerName;
1718 }
1719
1720 public String getShippingAddressInternationalProvinceName() {
1721 return shippingAddressInternationalProvinceName;
1722 }
1723
1724 public void setShippingAddressInternationalProvinceName(String shippingAddressInternationalProvinceName) {
1725 this.shippingAddressInternationalProvinceName = shippingAddressInternationalProvinceName;
1726 }
1727
1728 public String getShippingAddressName() {
1729 return shippingAddressName;
1730 }
1731
1732 public void setShippingAddressName(String shippingAddressName) {
1733 this.shippingAddressName = shippingAddressName;
1734 }
1735
1736 public String getShippingAddressTypeCode() {
1737 return shippingAddressTypeCode;
1738 }
1739
1740 public void setShippingAddressTypeCode(String shippingAddressTypeCode) {
1741 this.shippingAddressTypeCode = shippingAddressTypeCode;
1742 }
1743
1744 public String getShippingCityName() {
1745 return shippingCityName;
1746 }
1747
1748 public void setShippingCityName(String shippingCityName) {
1749 this.shippingCityName = shippingCityName;
1750 }
1751
1752 public String getShippingCountryCode() {
1753 return shippingCountryCode;
1754 }
1755
1756 public void setShippingCountryCode(String shippingCountryCode) {
1757 this.shippingCountryCode = shippingCountryCode;
1758 }
1759
1760 public String getShippingEmailAddress() {
1761 return shippingEmailAddress;
1762 }
1763
1764 public void setShippingEmailAddress(String shippingEmailAddress) {
1765 this.shippingEmailAddress = shippingEmailAddress;
1766 }
1767
1768 public String getShippingInternationalMailCode() {
1769 return shippingInternationalMailCode;
1770 }
1771
1772 public void setShippingInternationalMailCode(String shippingInternationalMailCode) {
1773 this.shippingInternationalMailCode = shippingInternationalMailCode;
1774 }
1775
1776 public String getShippingStateCode() {
1777 return shippingStateCode;
1778 }
1779
1780 public void setShippingStateCode(String shippingStateCode) {
1781 this.shippingStateCode = shippingStateCode;
1782 }
1783
1784 public String getShippingZipCode() {
1785 return shippingZipCode;
1786 }
1787
1788 public void setShippingZipCode(String shippingZipCode) {
1789 this.shippingZipCode = shippingZipCode;
1790 }
1791
1792 public String getBillingLine1StreetAddress() {
1793 return billingLine1StreetAddress;
1794 }
1795
1796 public void setBillingLine1StreetAddress(String billingLine1StreetAddress) {
1797 this.billingLine1StreetAddress = billingLine1StreetAddress;
1798 }
1799
1800 public String getBillingLine2StreetAddress() {
1801 return billingLine2StreetAddress;
1802 }
1803
1804 public void setBillingLine2StreetAddress(String billingLine2StreetAddress) {
1805 this.billingLine2StreetAddress = billingLine2StreetAddress;
1806 }
1807
1808 public String getShippingLine1StreetAddress() {
1809 return shippingLine1StreetAddress;
1810 }
1811
1812 public void setShippingLine1StreetAddress(String shippingLine1StreetAddress) {
1813 this.shippingLine1StreetAddress = shippingLine1StreetAddress;
1814 }
1815
1816 public String getShippingLine2StreetAddress() {
1817 return shippingLine2StreetAddress;
1818 }
1819
1820 public void setShippingLine2StreetAddress(String shippingLine2StreetAddress) {
1821 this.shippingLine2StreetAddress = shippingLine2StreetAddress;
1822 }
1823
1824 public boolean getRecurredInvoiceIndicator() {
1825 return recurredInvoiceIndicator;
1826 }
1827
1828 public void setRecurredInvoiceIndicator(boolean recurredInvoiceIndicator) {
1829 this.recurredInvoiceIndicator = recurredInvoiceIndicator;
1830 }
1831
1832 /**
1833 * Get a string representation for billing chart/organization
1834 *
1835 * @return
1836 */
1837 public String getBilledByChartOfAccCodeAndOrgCode() {
1838 String returnVal = getBillByChartOfAccountCode() + "/" + getBilledByOrganizationCode();
1839
1840 return returnVal;
1841 }
1842
1843 /**
1844 * Populate Customer Billing Address fields on Customer Invoice.
1845 *
1846 * @return
1847 */
1848 public void setCustomerBillToAddressOnInvoice(CustomerAddress customerBillToAddress) {
1849 accountsReceivableDocumentHeader.refreshReferenceObject("customer");
1850 if (ObjectUtils.isNotNull(accountsReceivableDocumentHeader.getCustomer())) {
1851 this.setCustomerName(accountsReceivableDocumentHeader.getCustomer().getCustomerName());
1852 }
1853
1854 if (ObjectUtils.isNotNull(customerBillToAddress)) {
1855 this.setBillingAddressTypeCode(customerBillToAddress.getCustomerAddressTypeCode());
1856 this.setBillingAddressName(customerBillToAddress.getCustomerAddressName());
1857 this.setBillingLine1StreetAddress(customerBillToAddress.getCustomerLine1StreetAddress());
1858 this.setBillingLine2StreetAddress(customerBillToAddress.getCustomerLine2StreetAddress());
1859 this.setBillingCityName(customerBillToAddress.getCustomerCityName());
1860 this.setBillingStateCode(customerBillToAddress.getCustomerStateCode());
1861 this.setBillingZipCode(customerBillToAddress.getCustomerZipCode());
1862 this.setBillingCountryCode(customerBillToAddress.getCustomerCountryCode());
1863 this.setBillingAddressInternationalProvinceName(customerBillToAddress.getCustomerAddressInternationalProvinceName());
1864 this.setBillingInternationalMailCode(customerBillToAddress.getCustomerInternationalMailCode());
1865 this.setBillingEmailAddress(customerBillToAddress.getCustomerEmailAddress());
1866 }
1867 }
1868
1869 /**
1870 * Populate Customer Shipping Address fields on Customer Invoice.
1871 *
1872 * @return
1873 */
1874 public void setCustomerShipToAddressOnInvoice(CustomerAddress customerShipToAddress) {
1875
1876 accountsReceivableDocumentHeader.refreshReferenceObject("customer");
1877 Customer customer = accountsReceivableDocumentHeader.getCustomer();
1878 if (ObjectUtils.isNotNull(customer))
1879 this.setCustomerName(customer.getCustomerName());
1880
1881 if (ObjectUtils.isNotNull(customerShipToAddress)) {
1882 this.setShippingAddressTypeCode(customerShipToAddress.getCustomerAddressTypeCode());
1883 this.setShippingAddressName(customerShipToAddress.getCustomerAddressName());
1884 this.setShippingLine1StreetAddress(customerShipToAddress.getCustomerLine1StreetAddress());
1885 this.setShippingLine2StreetAddress(customerShipToAddress.getCustomerLine2StreetAddress());
1886 this.setShippingCityName(customerShipToAddress.getCustomerCityName());
1887 this.setShippingStateCode(customerShipToAddress.getCustomerStateCode());
1888 this.setShippingZipCode(customerShipToAddress.getCustomerZipCode());
1889 this.setShippingCountryCode(customerShipToAddress.getCustomerCountryCode());
1890 this.setShippingAddressInternationalProvinceName(customerShipToAddress.getCustomerAddressInternationalProvinceName());
1891 this.setShippingInternationalMailCode(customerShipToAddress.getCustomerInternationalMailCode());
1892 this.setShippingEmailAddress(customerShipToAddress.getCustomerEmailAddress());
1893 }
1894 else {
1895 this.setShippingAddressTypeCode(null);
1896 this.setShippingAddressName(null);
1897 this.setShippingLine1StreetAddress(null);
1898 this.setShippingLine2StreetAddress(null);
1899 this.setShippingCityName(null);
1900 this.setShippingStateCode(null);
1901 this.setShippingZipCode(null);
1902 this.setShippingCountryCode(null);
1903 this.setShippingAddressInternationalProvinceName(null);
1904 this.setShippingInternationalMailCode(null);
1905 this.setShippingEmailAddress(null);
1906 }
1907 }
1908
1909 /**
1910 * Gets the quickApply attribute.
1911 *
1912 * @return Returns the quickApply.
1913 */
1914 //TODO Andrew - this is payapp specific stuff and needs to go
1915 // public boolean isQuickApply() {
1916 // return quickApply;
1917 // }
1918 //
1919 // //TODO Andrew - this is payapp specific stuff and needs to go
1920 // public boolean getQuickApply() {
1921 // return isQuickApply();
1922 // }
1923 //
1924 // /**
1925 // * Sets the quickApply attribute value.
1926 // *
1927 // * @param quickApply The quickApply to set.
1928 // */
1929 // //TODO Andrew - this is payapp specific stuff and needs to go
1930 // public void setQuickApply(boolean quickApply) {
1931 // this.quickApply = quickApply;
1932 // }
1933
1934
1935 /**
1936 * Answers true when invoice recurrence details are provided by the user
1937 *
1938 * @see org.kuali.kfs.sys.document.FinancialSystemTransactionalDocumentBase#answerSplitNodeQuestion(java.lang.String)
1939 */
1940 @Override
1941 public boolean answerSplitNodeQuestion(String nodeName) throws UnsupportedOperationException {
1942 if (HAS_RECCURENCE_NODE.equals(nodeName)) {
1943 return hasRecurrence();
1944 }
1945 if (BATCH_GENERATED_NODE.equals(nodeName)) {
1946 return isBatchGenerated();
1947 }
1948 throw new UnsupportedOperationException("answerSplitNode('" + nodeName + "') was called but no handler for nodeName specified.");
1949 }
1950
1951 /**
1952 *
1953 * Determines whether this document was generated from a recurrence batch. Returns true if so, false if not.
1954 * @return
1955 */
1956 protected boolean isBatchGenerated() {
1957 return recurredInvoiceIndicator;
1958 }
1959
1960 /**
1961 *
1962 * Determines whether this document has a Recurrence filled out enough to create an INVR doc.
1963 * @return
1964 */
1965 protected boolean hasRecurrence() {
1966 return (ObjectUtils.isNotNull(getCustomerInvoiceRecurrenceDetails()) && getCustomerInvoiceRecurrenceDetails().isActive());
1967 }
1968
1969 }