001/*
002 * Copyright 2010-2014 Ning, Inc.
003 * Copyright 2014-2015 The Billing Project, LLC
004 *
005 * The Billing Project licenses this file to you under the Apache License, version 2.0
006 * (the "License"); you may not use this file except in compliance with the
007 * License.  You may obtain a copy of the License at:
008 *
009 *    http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
013 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
014 * License for the specific language governing permissions and limitations
015 * under the License.
016 */
017
018package com.ning.billing.recurly.model;
019
020import com.google.common.base.Objects;
021import org.joda.time.DateTime;
022
023import javax.xml.bind.annotation.XmlElement;
024import javax.xml.bind.annotation.XmlElementWrapper;
025import javax.xml.bind.annotation.XmlRootElement;
026import java.math.BigDecimal;
027
028@XmlRootElement(name = "invoice")
029public class Invoice extends RecurlyObject {
030
031    @XmlElement(name = "account")
032    private Account account;
033
034    @XmlElement(name = "original_invoice")
035    private Invoice originalInvoice;
036
037    @XmlElement(name = "original_invoices")
038    private Invoice originalInvoices;
039
040    @XmlElement(name = "uuid")
041    private String uuid;
042
043    @XmlElement(name = "state")
044    private String state;
045
046    @XmlElement(name = "invoice_number")
047    private Integer invoiceNumber;
048
049    @XmlElement(name = "invoice_number_prefix")
050    private String invoiceNumberPrefix;
051
052    @XmlElement(name = "po_number")
053    private String poNumber;
054
055    @XmlElement(name = "vat_number")
056    private String vatNumber;
057
058    @XmlElement(name = "billing_info_uuid")
059    private String billingInfoUuid;
060
061    @XmlElement(name = "subtotal_in_cents")
062    private Integer subtotalInCents;
063
064    @XmlElement(name = "tax_in_cents")
065    private Integer taxInCents;
066
067    @XmlElement(name = "total_in_cents")
068    private Integer totalInCents;
069
070    @XmlElement(name = "currency")
071    private String currency;
072
073    @XmlElement(name = "tax_region")
074    private String taxRegion;
075
076    @XmlElement(name = "tax_type")
077    private String taxType;
078
079    @XmlElement(name = "tax_rate")
080    private BigDecimal taxRate;
081
082    @XmlElement(name = "created_at")
083    private DateTime createdAt;
084
085    @XmlElement(name = "updated_at")
086    private DateTime updatedAt;
087
088    @XmlElement(name = "closed_at")
089    private DateTime closedAt;
090
091    @XmlElement(name = "collection_method")
092    private String collectionMethod;
093
094    @XmlElement(name = "net_terms")
095    private Integer netTerms;
096
097    @XmlElement(name = "attempt_next_collection_at")
098    private DateTime attemptNextCollectionAt;
099
100    @XmlElement(name = "recovery_reason")
101    private String recoveryReason;
102
103    @XmlElementWrapper(name = "line_items")
104    @XmlElement(name = "adjustment")
105    private Adjustments lineItems;
106
107    @XmlElementWrapper(name = "transactions")
108    @XmlElement(name = "transaction")
109    private Transactions transactions;
110
111    @XmlElementWrapper(name = "credit_payments")
112    @XmlElement(name = "credit_payment")
113    private CreditPayments creditPayments;
114
115    @XmlElement(name = "customer_notes")
116    private String customerNotes;
117
118    @XmlElement(name = "terms_and_conditions")
119    private String termsAndConditions;
120
121    @XmlElement(name = "vat_reverse_charge_notes")
122    private String vatReverseChargeNotes;
123
124    @XmlElement(name = "gateway_code")
125    private String gatewayCode;
126
127    @XmlElement(name = "subtotal_before_discount_in_cents")
128    private Integer subtotalBeforeDiscountInCents;
129
130    @XmlElement(name = "discount_in_cents")
131    private Integer discountInCents;
132
133    @XmlElement(name = "balance_in_cents")
134    private Integer balanceInCents;
135
136    @XmlElement(name = "refundable_total_in_cents")
137    private Integer refundableTotalInCents;
138
139    @XmlElement(name = "due_on")
140    private DateTime dueOn;
141
142    @XmlElement(name = "type")
143    private String type;
144
145    @XmlElement(name = "origin")
146    private String origin;
147
148    @XmlElement(name = "address")
149    private Address address;
150
151    @XmlElement(name = "shipping_address")
152    private ShippingAddress shippingAddress;
153
154    @XmlElement(name = "surcharge_in_cents")
155    private Integer surchargeInCents;
156
157    @XmlElement(name = "transaction_type")
158    private String transactionType;
159
160    public Account getAccount() {
161        if (account != null && account.getCreatedAt() == null) {
162            account = fetch(account, Account.class);
163        }
164        return account;
165    }
166
167    /**
168     * Set this original invoice to the passed in original invoice.
169     *
170     * @param originalInvoice original invoice
171     *
172     */
173    public void setOriginalInvoice(Invoice originalInvoice) {
174        this.originalInvoice = originalInvoice;
175    }
176
177    /**
178     * Fetches the original invoice if the href is populated, otherwise return the current original invoice.
179     *
180     * @return fully loaded original invoice
181     */
182    public Invoice getOriginalInvoice() {
183        if (originalInvoice != null && originalInvoice.getHref() != null && !originalInvoice.getHref().isEmpty()) {
184            originalInvoice = fetch(originalInvoice, Invoice.class);
185        }
186        return originalInvoice;
187    }
188
189    /**
190     * For use with RecurlyClient.getOriginalInvoices(). Check if an invoice had an <original_invoices> link
191     * in the XML from the API.
192     *
193     * @return true if there are original invoices associated with this invoice
194     */
195    public Boolean hasOriginalInvoices() {
196        return originalInvoices != null && originalInvoices.getHref() != null && !originalInvoices.getHref().isEmpty();
197    }
198
199    public String getId() {
200        if (invoiceNumber == null) return null;
201        if (invoiceNumberPrefix == null) return invoiceNumber.toString();
202        return invoiceNumberPrefix + invoiceNumber.toString();
203    }
204
205    public void setAccount(final Account account) {
206        this.account = account;
207    }
208
209    public String getUuid() {
210        return uuid;
211    }
212
213    public void setUuid(final Object uuid) {
214        this.uuid = stringOrNull(uuid);
215    }
216
217    public String getState() {
218        return state;
219    }
220
221    public void setState(final Object state) {
222        this.state = stringOrNull(state);
223    }
224
225    public Integer getInvoiceNumber() {
226        return invoiceNumber;
227    }
228
229    public void setInvoiceNumber(final Object invoiceNumber) {
230        this.invoiceNumber = integerOrNull(invoiceNumber);
231    }
232
233    public String getInvoiceNumberPrefix() {
234        return invoiceNumberPrefix;
235    }
236
237    public void setInvoiceNumberPrefix(final Object invoiceNumberPrefix) {
238        this.invoiceNumberPrefix = stringOrNull(invoiceNumberPrefix);
239    }
240
241    public String getPoNumber() {
242        return poNumber;
243    }
244
245    public void setPoNumber(final Object poNumber) {
246        this.poNumber = stringOrNull(poNumber);
247    }
248
249    public String getVatNumber() {
250        return vatNumber;
251    }
252
253    public void setVatNumber(final Object varNumber) {
254        this.vatNumber = stringOrNull(varNumber);
255    }
256
257    public String getBillingInfoUuid() {
258      return billingInfoUuid;
259    }
260
261    public void setBillingInfoUuid(final Object billingInfoUuid) {
262        this.billingInfoUuid = stringOrNull(billingInfoUuid);
263    }
264
265    public Integer getSubtotalInCents() {
266        return subtotalInCents;
267    }
268
269    public void setSubtotalInCents(final Object subtotalInCents) {
270        this.subtotalInCents = integerOrNull(subtotalInCents);
271    }
272
273    public Integer getTaxInCents() {
274        return taxInCents;
275    }
276
277    public void setTaxInCents(final Object taxInCents) {
278        this.taxInCents = integerOrNull(taxInCents);
279    }
280
281    public Integer getTotalInCents() {
282        return totalInCents;
283    }
284
285    public void setTotalInCents(final Object totalInCents) {
286        this.totalInCents = integerOrNull(totalInCents);
287    }
288
289    public String getCurrency() {
290        return currency;
291    }
292
293    public void setCurrency(final Object currency) {
294        this.currency = stringOrNull(currency);
295    }
296
297    public void setTaxRegion(final Object taxRegion) {
298      this.taxRegion = stringOrNull(taxRegion);
299    }
300
301    public String getTaxRegion() {
302      return taxRegion;
303    }
304
305    public void setTaxRate(final Object taxRate) {
306      this.taxRate = bigDecimalOrNull(taxRate);
307    }
308
309    public BigDecimal getTaxRate() {
310      return taxRate;
311    }
312
313    public void setTaxType(final Object taxType) {
314      this.taxType = stringOrNull(taxType);
315    }
316
317    public String getTaxType() {
318      return taxType;
319    }
320
321    public DateTime getCreatedAt() {
322        return createdAt;
323    }
324
325    public void setClosedAt(final Object closedAt) {
326        this.closedAt = dateTimeOrNull(closedAt);
327    }
328
329    public DateTime getClosedAt() {
330        return closedAt;
331    }
332
333    public void setCreatedAt(final Object createdAt) {
334        this.createdAt = dateTimeOrNull(createdAt);
335    }
336
337    public DateTime getUpdatedAt() {
338        return updatedAt;
339    }
340
341    public void setUpdatedAt(final Object updatedAt) {
342        this.updatedAt = dateTimeOrNull(updatedAt);
343    }
344
345    public String getCollectionMethod() {
346        return collectionMethod;
347    }
348
349    public void setCollectionMethod(final Object collectionMethod) {
350        this.collectionMethod = stringOrNull(collectionMethod);
351    }
352
353    public Integer getNetTerms() {
354        return netTerms;
355    }
356
357    public void setNetTerms(final Object netTerms) {
358        this.netTerms = integerOrNull(netTerms);
359    }
360
361    public DateTime getAttemptNextCollectionAt() {
362        return this.attemptNextCollectionAt;
363    }
364
365    public void setAttemptNextCollectionAt(final Object attemptNextCollectionAt) {
366        this.attemptNextCollectionAt = dateTimeOrNull(attemptNextCollectionAt);
367    }
368
369    public String getRecoveryReason() {
370        return this.recoveryReason;
371    }
372
373    public void setRecoveryReason(final Object recoveryReason) {
374        this.recoveryReason = stringOrNull(recoveryReason);
375    }
376
377    public Adjustments getLineItems() {
378        return lineItems;
379    }
380
381    public void setLineItems(final Adjustments lineItems) {
382        this.lineItems = lineItems;
383    }
384
385    public Transactions getTransactions() {
386        return transactions;
387    }
388
389    public void setTransactions(final Transactions transactions) {
390        this.transactions = transactions;
391    }
392
393    public CreditPayments getCreditPayments() {
394        return creditPayments;
395    }
396
397    public void setCreditPayments(final CreditPayments creditPayments) {
398        this.creditPayments = creditPayments;
399    }
400
401    public String getCustomerNotes() {
402        return customerNotes;
403    }
404
405    public void setCustomerNotes(final Object customerNotes) {
406        this.customerNotes = stringOrNull(customerNotes);
407    }
408
409    public String getTermsAndConditions() {
410        return termsAndConditions;
411    }
412
413    public void setTermsAndConditions(final Object termsAndConditions) {
414        this.termsAndConditions = stringOrNull(termsAndConditions);
415    }
416
417    public String getVatReverseChargeNotes() {
418        return vatReverseChargeNotes;
419    }
420
421    public void setVatReverseChargeNotes(final Object vatReverseChargeNotes) {
422        this.vatReverseChargeNotes = stringOrNull(vatReverseChargeNotes);
423    }
424
425    public String getGatewayCode() {
426        return gatewayCode;
427    }
428
429    public void setGatewayCode(final Object gatewayCode) {
430        this.gatewayCode = stringOrNull(gatewayCode);
431    }
432
433    public Integer getSubtotalBeforeDiscountInCents() {
434        return subtotalBeforeDiscountInCents;
435    }
436
437    public void setSubtotalBeforeDiscountInCents(final Object subtotalBeforeDiscountInCents) {
438        this.subtotalBeforeDiscountInCents = integerOrNull(subtotalBeforeDiscountInCents);
439    }
440
441    public Integer getDiscountInCents() {
442        return discountInCents;
443    }
444
445    public void setDiscountInCents(final Object discountInCents) {
446        this.discountInCents = integerOrNull(discountInCents);
447    }
448
449    public Integer getBalanceInCents() {
450        return balanceInCents;
451    }
452
453    public void setBalanceInCents(final Object balanceInCents) {
454        this.balanceInCents = integerOrNull(balanceInCents);
455    }
456
457    public Integer getRefundableTotalInCents() {
458        return refundableTotalInCents;
459    }
460
461    public void setRefundableTotalInCents(final Object refundableTotalInCents) {
462        this.refundableTotalInCents = integerOrNull(refundableTotalInCents);
463    }
464
465
466    public DateTime getDueOn() {
467        return dueOn;
468    }
469
470    public void setDueOn(final Object dueOn) {
471        this.dueOn = dateTimeOrNull(dueOn);
472    }
473
474    public String getType() {
475        return type;
476    }
477
478    public void setType(final Object type) {
479        this.type = stringOrNull(type);
480    }
481
482    public String getOrigin() {
483        return origin;
484    }
485
486    public void setOrigin(final Object origin) {
487        this.origin = stringOrNull(origin);
488    }
489
490    public Address getAddress() {
491        return address;
492    }
493
494    public void setAddress(final Address address) {
495        this.address = address;
496    }
497
498    public ShippingAddress getShippingAddress() {
499        return shippingAddress;
500    }
501
502    public void setShippingAddress(final ShippingAddress shippingAddress) {
503        this.shippingAddress = shippingAddress;
504    }
505
506    public Integer getSurchargeInCents() {
507        return surchargeInCents;
508    }
509
510    public void setSurchargeInCents(final Object surchargeInCents) {
511        this.surchargeInCents = integerOrNull(surchargeInCents);
512    }
513
514    public String getTransactionType() {
515        return transactionType;
516    }
517
518    public void setTransactionType(final Object transactionType) {
519        this.transactionType = stringOrNull(transactionType);
520    }
521
522    @Override
523    public String toString() {
524        final StringBuilder sb = new StringBuilder("Invoice{");
525        sb.append("account=").append(account);
526        sb.append(", originalInvoice='").append(originalInvoice).append('\'');
527        sb.append(", originalInvoices='").append(originalInvoices).append('\'');
528        sb.append(", uuid='").append(uuid).append('\'');
529        sb.append(", state='").append(state).append('\'');
530        sb.append(", invoiceNumber=").append(invoiceNumber);
531        sb.append(", invoiceNumberPrefix=").append(invoiceNumberPrefix);
532        sb.append(", poNumber=").append(poNumber);
533        sb.append(", vatNumber='").append(vatNumber).append('\'');
534        sb.append(", billingInfoUuid='").append(billingInfoUuid).append('\'');
535        sb.append(", subtotalInCents=").append(subtotalInCents);
536        sb.append(", taxInCents=").append(taxInCents);
537        sb.append(", totalInCents=").append(totalInCents);
538        sb.append(", currency='").append(currency).append('\'');
539        sb.append(", taxRegion=").append(taxRegion);
540        sb.append(", taxType=").append(taxType);
541        sb.append(", taxRate=").append(taxRate);
542        sb.append(", createdAt=").append(createdAt);
543        sb.append(", updatedAt=").append(updatedAt);
544        sb.append(", closedAt=").append(closedAt);
545        sb.append(", collectionMethod='").append(collectionMethod).append('\'');
546        sb.append(", netTerms=").append(netTerms);
547        sb.append(", attemptNextCollectionAt=").append(attemptNextCollectionAt);
548        sb.append(", recoveryReason=").append(recoveryReason);
549        sb.append(", lineItems=").append(lineItems);
550        sb.append(", transactions=").append(transactions);
551        sb.append(", creditPayments=").append(creditPayments);
552        sb.append(", customerNotes='").append(customerNotes).append('\'');
553        sb.append(", termsAndConditions='").append(termsAndConditions).append('\'');
554        sb.append(", vatReverseChargeNotes='").append(vatReverseChargeNotes).append('\'');
555        sb.append(", gatewayCode='").append(gatewayCode).append('\'');
556        sb.append(", subtotalBeforeDiscountInCents=").append(subtotalBeforeDiscountInCents);
557        sb.append(", discountInCents=").append(discountInCents);
558        sb.append(", balanceInCents=").append(balanceInCents);
559        sb.append(", refundableTotalInCents=").append(refundableTotalInCents);
560        sb.append(", dueOn=").append(dueOn);
561        sb.append(", type=").append(type);
562        sb.append(", origin=").append(origin);
563        sb.append(", address=").append(address);
564        sb.append(", shippingAddress=").append(shippingAddress);
565        sb.append(", surchargeInCents=").append(surchargeInCents);
566        sb.append('}');
567        return sb.toString();
568    }
569
570    @Override
571    public boolean equals(final Object o) {
572        if (this == o) return true;
573        if (o == null || getClass() != o.getClass()) return false;
574
575        final Invoice invoice = (Invoice) o;
576
577        if (account != null ? !account.equals(invoice.account) : invoice.account != null) {
578            return false;
579        }
580        if (address != null ? !address.equals(invoice.address) : invoice.address != null) {
581            return false;
582        }
583        if (attemptNextCollectionAt != null ? attemptNextCollectionAt.compareTo(invoice.attemptNextCollectionAt) != 0 : invoice.attemptNextCollectionAt != null) {
584            return false;
585        }
586        if (balanceInCents != null ? !balanceInCents.equals(invoice.balanceInCents) : invoice.balanceInCents != null) {
587            return false;
588        }
589        if (closedAt != null ? closedAt.compareTo(invoice.closedAt) != 0 : invoice.closedAt != null) {
590            return false;
591        }
592        if (collectionMethod != null ? !collectionMethod.equals(invoice.collectionMethod) : invoice.collectionMethod != null) {
593            return false;
594        }
595        if (createdAt != null ? createdAt.compareTo(invoice.createdAt) != 0 : invoice.createdAt != null) {
596            return false;
597        }
598        if (currency != null ? !currency.equals(invoice.currency) : invoice.currency != null) {
599            return false;
600        }
601        if (customerNotes != null ? !customerNotes.equals(invoice.customerNotes) : invoice.customerNotes != null) {
602            return false;
603        }
604        if (discountInCents != null ? !discountInCents.equals(invoice.discountInCents) : invoice.discountInCents != null) {
605            return false;
606        }
607        if (invoiceNumber != null ? !invoiceNumber.equals(invoice.invoiceNumber) : invoice.invoiceNumber != null) {
608            return false;
609        }
610        if (invoiceNumberPrefix != null ? !invoiceNumberPrefix.equals(invoice.invoiceNumberPrefix) : invoice.invoiceNumberPrefix != null) {
611            return false;
612        }
613        if (lineItems != null ? !lineItems.equals(invoice.lineItems) : invoice.lineItems != null) {
614            return false;
615        }
616        if (netTerms != null ? !netTerms.equals(invoice.netTerms) : invoice.netTerms != null) {
617            return false;
618        }
619        if (originalInvoice != null ? !originalInvoice.equals(invoice.originalInvoice) : invoice.originalInvoice != null) {
620            return false;
621        }
622        if (originalInvoices != null ? !originalInvoices.equals(invoice.originalInvoices) : invoice.originalInvoices != null) {
623            return false;
624        }
625        if (origin != null ? !origin.equals(invoice.origin) : invoice.origin != null) {
626            return false;
627        }
628        if (poNumber != null ? !poNumber.equals(invoice.poNumber) : invoice.poNumber != null) {
629            return false;
630        }
631        if (recoveryReason != null ? !recoveryReason.equals(invoice.recoveryReason) : invoice.recoveryReason != null) {
632            return false;
633        }
634        if (shippingAddress != null ? !shippingAddress.equals(invoice.shippingAddress) : invoice.shippingAddress != null) {
635            return false;
636        }
637        if (state != null ? !state.equals(invoice.state) : invoice.state != null) {
638            return false;
639        }
640        if (subtotalBeforeDiscountInCents != null ? !subtotalBeforeDiscountInCents.equals(invoice.subtotalBeforeDiscountInCents) : invoice.subtotalBeforeDiscountInCents != null) {
641            return false;
642        }
643        if (subtotalInCents != null ? !subtotalInCents.equals(invoice.subtotalInCents) : invoice.subtotalInCents != null) {
644            return false;
645        }
646        if (surchargeInCents != null ? !surchargeInCents.equals(invoice.surchargeInCents) : invoice.surchargeInCents != null) {
647            return false;
648        }
649        if (refundableTotalInCents != null ? !refundableTotalInCents.equals(invoice.refundableTotalInCents) : invoice.refundableTotalInCents != null) {
650            return false;
651        }
652        if (taxInCents != null ? !taxInCents.equals(invoice.taxInCents) : invoice.taxInCents != null) {
653            return false;
654        }
655        if (totalInCents != null ? !totalInCents.equals(invoice.totalInCents) : invoice.totalInCents != null) {
656            return false;
657        }
658        if (taxRegion != null ? !taxRegion.equals(invoice.taxRegion) : invoice.taxRegion != null) {
659            return false;
660        }
661        if (taxType != null ? !taxType.equals(invoice.taxType) : invoice.taxType != null) {
662            return false;
663        }
664        if (taxRate != null ? !taxRate.equals(invoice.taxRate) : invoice.taxRate != null) {
665            return false;
666        }
667        if (termsAndConditions != null ? !termsAndConditions.equals(invoice.termsAndConditions) : invoice.termsAndConditions != null) {
668            return false;
669        }
670        if (transactions != null ? !transactions.equals(invoice.transactions) : invoice.transactions != null) {
671            return false;
672        }
673        if (creditPayments != null ? !creditPayments.equals(invoice.creditPayments) : invoice.creditPayments != null) {
674            return false;
675        }
676        if (type != null ? !type.equals(invoice.type) : invoice.type != null) {
677            return false;
678        }
679        if (updatedAt != null ? updatedAt.compareTo(invoice.updatedAt) != 0 : invoice.updatedAt != null) {
680            return false;
681        }
682        if (uuid != null ? !uuid.equals(invoice.uuid) : invoice.uuid != null) {
683            return false;
684        }
685        if (vatNumber != null ? !vatNumber.equals(invoice.vatNumber) : invoice.vatNumber != null) {
686            return false;
687        }
688        if (billingInfoUuid != null ? !billingInfoUuid.equals(invoice.billingInfoUuid) : invoice.billingInfoUuid != null) {
689            return false;
690        }
691        if (vatReverseChargeNotes != null ? !vatReverseChargeNotes.equals(invoice.vatReverseChargeNotes) : invoice.vatReverseChargeNotes != null) {
692            return false;
693        }
694        if (gatewayCode != null ? !gatewayCode.equals(invoice.gatewayCode) : invoice.gatewayCode != null) {
695            return false;
696        }
697        if (transactionType != null ? !transactionType.equals(invoice.transactionType) : invoice.transactionType != null) {
698            return false;
699        }
700
701        return true;
702    }
703
704    @Override
705    public int hashCode() {
706        return Objects.hashCode(
707                account,
708                originalInvoice,
709                originalInvoices,
710                uuid,
711                state,
712                invoiceNumber,
713                invoiceNumberPrefix,
714                poNumber,
715                vatNumber,
716                billingInfoUuid,
717                subtotalInCents,
718                totalInCents,
719                taxInCents,
720                taxRegion,
721                taxType,
722                taxRate,
723                currency,
724                createdAt,
725                updatedAt,
726                closedAt,
727                collectionMethod,
728                netTerms,
729                attemptNextCollectionAt,
730                recoveryReason,
731                lineItems,
732                transactions,
733                creditPayments,
734                customerNotes,
735                termsAndConditions,
736                vatReverseChargeNotes,
737                gatewayCode,
738                subtotalBeforeDiscountInCents,
739                discountInCents,
740                balanceInCents,
741                refundableTotalInCents,
742                type,
743                origin,
744                address,
745                shippingAddress,
746                surchargeInCents,
747                transactionType
748        );
749    }
750
751}