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