package net.billforward.model; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; 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.amendments.CancellationAmendment; import net.billforward.model.amendments.CancellationAmendment.ServiceEndState; import net.billforward.model.amendments.ComponentChange; import net.billforward.model.amendments.PricingComponentValueChangeAmendment; import com.google.gson.annotations.Expose; import com.google.gson.reflect.TypeToken; public class Subscription extends MutableEntity<Subscription> { @Expose protected String id; @Expose protected String accountID; @Expose protected String organizationID; @Expose protected String productID; @Expose protected String productRatePlanID; @Expose protected String name; @Expose protected String description; @Expose protected String type; @Expose protected String state; @Expose protected Date currentPeriodStart; @Expose protected Date currentPeriodEnd; @Expose protected Date effectiveStartDate; @Expose protected Date actualStartDate; @Expose protected Date subscriptionEnd; @Expose protected Date currentPeriodEndExplicit; @Expose protected String locked; @Expose protected String managedBy; @Expose protected Date updated; @Expose protected String changedBy; @Expose protected Date created; @Expose protected RatePlan productRatePlan; @Expose protected List<PricingComponentValue> pricingComponentValues = new ArrayList<PricingComponentValue>(); public String getID() { return id; } public String getAccountID() { return accountID; } public void setAccountID(String accountID) { this.accountID = accountID; } public String getProductID() { return productID; } public void setProductID(String productID) { this.productID = productID; } public String getProductRatePlanID() { return productRatePlanID; } public void setProductRatePlanID(String productRatePlanID) { this.productRatePlanID = productRatePlanID; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public String getTypeAsString() { return type; } public SubscriptionType getType() { return SubscriptionType.valueOf(type); } public void setType(SubscriptionType type) { this.type = type.toString(); } public String getStateAsString() { return state; } public SubscriptionState getState() { return SubscriptionState.valueOf(state); } public void setState(SubscriptionState state) { this.state = state.toString(); } public Date getCurrentPeriodStart() { return currentPeriodStart; } public void setCurrentPeriodStart(Date currentPeriodStart) { this.currentPeriodStart = currentPeriodStart; } public Date getCurrentPeriodEnd() { return currentPeriodEnd; } public void setCurrentPeriodEnd(Date currentPeriodEnd) { this.currentPeriodEnd = currentPeriodEnd; } public Date getEffectiveStartDate() { return effectiveStartDate; } public void setEffectiveStartDate(Date effectiveStartDate) { this.effectiveStartDate = effectiveStartDate; } public Date getActualStartDate() { return actualStartDate; } public void setActualStartDate(Date actualStartDate) { this.actualStartDate = actualStartDate; } public Date getSubscriptionEnd() { return subscriptionEnd; } public void setSubscriptionEnd(Date subscriptionEnd) { this.subscriptionEnd = subscriptionEnd; } public Date getCurrentPeriodEndExplicit() { return currentPeriodEndExplicit; } public void setCurrentPeriodEndExplicit(Date currentPeriodEndExplicit) { this.currentPeriodEndExplicit = currentPeriodEndExplicit; } public String getManagedBy() { return managedBy; } public void setManagedBy(String managedBy) { this.managedBy = managedBy; } public Date getUpdated() { return updated; } public String getChangedBy() { return changedBy; } public Date getCreated() { return created; } public RatePlan getProductRatePlan() { if(productRatePlan == null) { try { productRatePlan = RatePlan.getByID(this.productRatePlanID); } catch (Exception e) { e.printStackTrace(); } } return productRatePlan; } public List<PricingComponentValue> getPricingComponentValues() { return pricingComponentValues; } public void setPricingComponentValues( List<PricingComponentValue> pricingComponentValues) { this.pricingComponentValues = pricingComponentValues; } public static Subscription create(Subscription subscription) throws AuthenticationException, InvalidRequestException, APIConnectionException, CardException, APIException { return create(subscription, ResourcePath())[0]; } public static Subscription getByID(String ID) throws AuthenticationException, InvalidRequestException, APIConnectionException, CardException, APIException { Subscription[] subs = getByID(ID, ResourcePath()); if(subs == null || subs.length == 0) return null; return subs[0]; } public static Subscription[] getByAccountID(String accountID) throws AuthenticationException, InvalidRequestException, APIConnectionException, CardException, APIException { return getByID(accountID, "account", ResourcePath()); } public static Subscription[] getByState(SubscriptionState state_) throws AuthenticationException, InvalidRequestException, APIConnectionException, CardException, APIException { return getByID(state_.toString(), "state", ResourcePath()); } public static Subscription[] getByRatePlanID(String ratePlanID) throws AuthenticationException, InvalidRequestException, APIConnectionException, CardException, APIException { return getByID(ratePlanID, "product-rate-plan", ResourcePath()); } public static Subscription[] getByProductID(String productID) throws AuthenticationException, InvalidRequestException, APIConnectionException, CardException, APIException { return getByID(productID, "product", ResourcePath()); } public static Subscription[] getAll() throws AuthenticationException, InvalidRequestException, APIConnectionException, CardException, APIException { return getAll(ResourcePath()); } protected static ResourcePath resourcePath; public Subscription(BillForwardClient client_) { super(client_); } public Subscription() { } protected ResourcePath getResourcePath() { return resourcePath; } protected static ResourcePath ResourcePath() { return resourcePath; } static { resourcePath = new ResourcePath("subscriptions", "subscription", new TypeToken<APIResponse<Subscription>>() {}.getType()); } public enum SubscriptionType { Adhoc, Subscription, FixedTerm, Trial; } public enum SubscriptionState { Trial, Provisioned, Paid, AwaitingPayment, Cancelled, Failed, Expired; } public PaymentMethod[] getPaymentMethods() throws AuthenticationException, InvalidRequestException, APIConnectionException, CardException, APIException { return PaymentMethod.getForSubscription(this.id); } public PaymentMethod removePaymentMethod(String paymentMethodID) throws AuthenticationException, InvalidRequestException, APIConnectionException, CardException, APIException { return PaymentMethod.removeFromSubscription(this.id, paymentMethodID); } public PaymentMethod addPaymentMethod(String paymentMethodID) throws AuthenticationException, InvalidRequestException, APIConnectionException, CardException, APIException { return PaymentMethod.addToSubscription(this.id, paymentMethodID); } /** Cancels a subscription immediately * @return The amendment associated with the cancellation **/ public CancellationAmendment cancelImmediately() throws AuthenticationException, InvalidRequestException, APIConnectionException, CardException, APIException { CancellationAmendment amendment = new CancellationAmendment(); amendment.setSubscriptionID(this.getID()); amendment.setServiceEnd(ServiceEndState.Immediate); amendment = CancellationAmendment.create(amendment); return amendment; } /*** * Cancel subscription at the current period end * @return The amendment associated with the cancellation */ public CancellationAmendment cancelAtPeriodEnd() throws AuthenticationException, InvalidRequestException, APIConnectionException, CardException, APIException { CancellationAmendment amendment = new CancellationAmendment(); amendment.setSubscriptionID(this.getID()); amendment.setServiceEnd(ServiceEndState.AtPeriodEnd); amendment = CancellationAmendment.create(amendment); return amendment; } /** * Upgrade or downgrade the subscription to the new value. * * <p> * If the new value is greater than the existing value a downgrade will occur. * If the new value is less than the existing value an upgrade will occur. * * By default upgrades happen immediately and the upgrade cost is added to the next invoice. * Downgrades happen at the end of the current billing period, with no refunds. * </p> * * @param name The name of the Pricing Component to upgrade * @param newValue The new value of the pricing component * @return The component change amendment which encapsulates the upgrade. */ public PricingComponentValueChangeAmendment upgrade(String name, int newValue) throws AuthenticationException, InvalidRequestException, APIConnectionException, CardException, APIException { HashMap<String, Integer> changes = new HashMap<String, Integer>(); changes.put(name, newValue); return this.upgrade(changes); } /** * Upgrade or downgrade the subscription to the new value. * * <p> * If the new value is greater than the existing value a downgrade will occur. * If the new value is less than the existing value an upgrade will occur. * * By default upgrades happen immediately and the upgrade cost is added to the next invoice. * Downgrades happen at the end of the current billing period, with no refunds. * </p> * * @param name The name of the Pricing Component to upgrade * @param newValue The new value of the pricing component * @return The component change amendment which encapsulates the upgrade. */ public PricingComponentValueChangeAmendment upgrade(HashMap<String, Integer> changes_) throws AuthenticationException, InvalidRequestException, APIConnectionException, CardException, APIException { PricingComponentValueChangeAmendment pricingComponentValueChangeAmendment = new PricingComponentValueChangeAmendment(); for (Map.Entry<String, Integer> entry : changes_.entrySet()) { ComponentChange change = new ComponentChange(entry.getKey(), entry.getValue()); pricingComponentValueChangeAmendment.addComponentChange(change); } pricingComponentValueChangeAmendment.setSubscriptionID(this.getID()); return PricingComponentValueChangeAmendment.create(pricingComponentValueChangeAmendment); } /** * Upgrade or downgrade the subscription to the new value. * * <p> * If the new value is greater than the existing value a downgrade will occur. * If the new value is less than the existing value an upgrade will occur. * * By default upgrades happen immediately and the upgrade cost is added to the next invoice. * Downgrades happen at the end of the current billing period, with no refunds. * </p> * * @param name The name of the Pricing Component to upgrade * @param newValue The new value of the pricing component * @return The component change amendment which encapsulates the upgrade. */ public PricingComponentValueChangeAmendment upgrade(List<ComponentChange> changes_) throws AuthenticationException, InvalidRequestException, APIConnectionException, CardException, APIException { PricingComponentValueChangeAmendment pricingComponentValueChangeAmendment = new PricingComponentValueChangeAmendment(); for(ComponentChange change : changes_) { pricingComponentValueChangeAmendment.addComponentChange(change); } pricingComponentValueChangeAmendment.setSubscriptionID(this.getID()); return PricingComponentValueChangeAmendment.create(pricingComponentValueChangeAmendment); } public Coupon addCouponCode(String couponCode) throws AuthenticationException, InvalidRequestException, APIConnectionException, CardException, APIException { return Coupon.addCouponCodeToSubscription(couponCode, this.id); } public Coupon[] getCouponCodes() throws AuthenticationException, InvalidRequestException, APIConnectionException, CardException, APIException { return Coupon.getCouponsForSubscription(this.id); } public Coupon removeCouponCode(String couponCode) throws AuthenticationException, InvalidRequestException, APIConnectionException, CardException, APIException { return Coupon.removeCouponCode(couponCode); } // public PricingComponentValue setActivePricingComponentValue(String pricingComponentName, int value) { // return PricingComponentValue.setActivePricingComponentValue(this.id, pricingComponentName, value); // } public PricingComponentValue[] getActivePricingComponentValues() throws AuthenticationException, InvalidRequestException, APIConnectionException, CardException, APIException { return PricingComponentValue.getActiveForSubscription(this.id); } }