package net.billforward.model;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import net.billforward.BillForwardClient;
import net.billforward.exception.APIConnectionException;
import net.billforward.exception.APIException;
import net.billforward.exception.AuthenticationException;
import net.billforward.exception.CardException;
import net.billforward.exception.InvalidRequestException;
import net.billforward.model.PricingComponent.PricingComponentChargeType;
import net.billforward.model.amendments.InvoiceNextExecutionAttemptAmendment;
import net.billforward.model.amendments.InvoiceRecalculationAmendment;
import net.billforward.model.amendments.IssueInvoiceAmendment;
import com.google.gson.annotations.Expose;
import com.google.gson.reflect.TypeToken;
public class Invoice extends BillingEntity {
@Expose protected String id;
@Expose protected String versionID;
@Expose protected String subscriptionID;
@Expose protected String accountID;
@Expose protected String organizationID;
@Expose protected String state;
@Expose protected Date periodStart;
@Expose protected Date periodEnd;
@Expose protected Boolean deleted = false;
@Expose protected int totalExecutionAttempts;
@Expose protected Date lastExecutionAttempt;
@Expose protected Date nextExecutionAttempt;
@Expose protected Date finalExecutionAttempt;
@Expose protected Date paymentReceived;
@Expose protected String currency;
@Expose protected BigDecimal costExcludingTax;
@Expose protected BigDecimal invoiceCost;
@Expose protected BigDecimal invoicePaid;
@Expose protected BigDecimal discountAmount;
@Expose protected BigDecimal invoiceRefunded;
@Expose protected String type;
@Expose protected String locked;
@Expose protected String managedBy;
@Expose protected Boolean initialInvoice;
@Expose protected int versionNumber;
@Expose protected Date updated;
@Expose protected String changedBy;
@Expose protected Date created;
protected InvoiceLine[] invoiceLines;
protected InvoicePayment[] invoicePayments;
public String getID() {
return id;
}
public String getVersionID() {
return versionID;
}
public String getSubscriptionID() {
return subscriptionID;
}
public String getAccountID() {
return accountID;
}
public String getOrganizationID() {
return organizationID;
}
public String getStateAsString() {
return state;
}
public InvoiceState getState() {
return InvoiceState.valueOf(state);
}
public Date getPeriodStart() {
return periodStart;
}
public Date getPeriodEnd() {
return periodEnd;
}
public Boolean getDeleted() {
return deleted;
}
public int getTotalExecutionAttempts() {
return totalExecutionAttempts;
}
public Date getLastExecutionAttempt() {
return lastExecutionAttempt;
}
public Date getNextExecutionAttempt() {
return nextExecutionAttempt;
}
public Date getFinalExecutionAttempt() {
return finalExecutionAttempt;
}
public Date getPaymentReceived() {
return paymentReceived;
}
public String getCurrency() {
return currency;
}
public BigDecimal getCostExcludingTax() {
return costExcludingTax;
}
public BigDecimal getInvoiceCost() {
return invoiceCost;
}
public BigDecimal getInvoicePaid() {
return invoicePaid;
}
public BigDecimal getDiscountAmount() {
return discountAmount;
}
public BigDecimal getInvoiceRefunded() {
return invoiceRefunded;
}
public String getTypeAsString() {
return type;
}
public InvoiceType getType() {
return InvoiceType.valueOf(type);
}
public String getLocked() {
return locked;
}
public String getManagedBy() {
return managedBy;
}
public Boolean getInitialInvoice() {
return initialInvoice;
}
public int getVersionNumber() {
return versionNumber;
}
public Date getUpdated() {
return updated;
}
public String getChangedBy() {
return changedBy;
}
public Date getCreated() {
return created;
}
public InvoiceLine[] getInvoiceLines() {
return invoiceLines;
}
public InvoicePayment[] getInvoicePayments() {
return invoicePayments;
}
public static Invoice getByID(String ID) throws AuthenticationException, InvalidRequestException, APIConnectionException, CardException, APIException {
Invoice[] invoices = getByID(ID, ResourcePath());
return invoices[0];
}
public static Invoice[] getBySubscriptionID(String subscriptionID) throws AuthenticationException, InvalidRequestException, APIConnectionException, CardException, APIException {
return getByID(subscriptionID, "subscription", ResourcePath());
}
public static Invoice[] getByState(InvoiceState invoiceState_) throws AuthenticationException, InvalidRequestException, APIConnectionException, CardException, APIException {
return getByID(invoiceState_.name(), "state", ResourcePath());
}
protected static ResourcePath resourcePath;
protected Invoice(BillForwardClient client_) {
super(client_);
}
protected Invoice() {
}
protected ResourcePath getResourcePath() {
return resourcePath;
}
protected static ResourcePath ResourcePath() {
return resourcePath;
}
static {
resourcePath = new ResourcePath("invoices", "invoice", new TypeToken<APIResponse<Invoice>>() {}.getType());
}
public InvoiceRecalculationAmendment recalculate() throws AuthenticationException, InvalidRequestException, APIConnectionException, CardException, APIException {
return this.recalculate(this.getState());
}
public InvoiceRecalculationAmendment recalculate(InvoiceState newInvoiceState) throws AuthenticationException, InvalidRequestException, APIConnectionException, CardException, APIException {
InvoiceRecalculationAmendment amendment = new InvoiceRecalculationAmendment();
amendment.setSubscriptionID(this.subscriptionID);
amendment.setInvoiceID(this.id);
amendment.setNewInvoiceState(newInvoiceState);
amendment = InvoiceRecalculationAmendment.create(amendment);
return amendment;
}
public InvoiceNextExecutionAttemptAmendment retryTakingPayment() throws AuthenticationException, InvalidRequestException, APIConnectionException, CardException, APIException {
return retryTakingPayment(null);
}
public InvoiceNextExecutionAttemptAmendment retryTakingPayment(Date dateToExecute_) throws AuthenticationException, InvalidRequestException, APIConnectionException, CardException, APIException {
InvoiceNextExecutionAttemptAmendment amendment = new InvoiceNextExecutionAttemptAmendment();
amendment.setSubscriptionID(this.subscriptionID);
amendment.setInvoiceID(this.id);
if(dateToExecute_ != null) {
amendment.setActioningTime(dateToExecute_);
}
amendment = InvoiceNextExecutionAttemptAmendment.create(amendment);
return amendment;
}
public IssueInvoiceAmendment issue() throws AuthenticationException, InvalidRequestException, APIConnectionException, CardException, APIException {
IssueInvoiceAmendment amendment = new IssueInvoiceAmendment();
amendment.setSubscriptionID(this.subscriptionID);
amendment.setInvoiceID(this.id);
amendment = IssueInvoiceAmendment.create(amendment);
return amendment ;
}
public enum InvoiceState {
Paid,
Unpaid,
Pending,
Voided
}
public enum InvoiceType {
Subscription,
Amendment,
Adhoc,
Trial,
FinalArrears
}
public void setUsage(int usage) throws AuthenticationException, InvalidRequestException, APIConnectionException, CardException, APIException {
Subscription subscription = Subscription.getByID(this.subscriptionID);
RatePlan ratePlan = subscription.getProductRatePlan();
List<PricingComponentValue> newPricingComponentValues = new ArrayList<PricingComponentValue>();
for(PricingComponent pricingComponent: ratePlan.getPricingComponents()) {
if(pricingComponent.getChargeType() == PricingComponentChargeType.usage) {
PricingComponentValue value = new PricingComponentValue();
value.setSubscriptionID(this.subscriptionID);
value.setPricingComponentID(pricingComponent.getID());
value.setValue(usage);
value.setAppliesFrom(this.getPeriodStart());
value.setAppliesTill(this.getPeriodStart());
newPricingComponentValues.add(value);
}
}
for(PricingComponentValue value : newPricingComponentValues) {
boolean update = false;
for(PricingComponentValue currentValue : subscription.getPricingComponentValues()) {
if(currentValue.getAppliesFrom().equals(value.getAppliesFrom()) &&
currentValue.getAppliesTill().equals(value.getAppliesTill())) {
update = true;
value = currentValue;
break;
}
}
if(update) {
value.save();
} else {
PricingComponentValue.create(value);
}
}
}
}