Skip to content

Commit

Permalink
Initial API refactoring for catalog override prices
Browse files Browse the repository at this point in the history
  • Loading branch information
sbrossie committed Mar 24, 2015
1 parent 97975d8 commit 445c377
Show file tree
Hide file tree
Showing 55 changed files with 614 additions and 164 deletions.
Expand Up @@ -25,6 +25,7 @@
import org.killbill.billing.catalog.api.BillingPeriod;
import org.killbill.billing.catalog.api.Plan;
import org.killbill.billing.catalog.api.PlanPhase;
import org.killbill.billing.catalog.api.PlanPhasePriceOverride;
import org.killbill.billing.catalog.api.PriceList;
import org.killbill.billing.catalog.api.Product;
import org.killbill.billing.catalog.api.ProductCategory;
Expand All @@ -51,15 +52,15 @@ public boolean uncancel(final CallContext context)
throws SubscriptionBaseApiException;

// Return the effective date of the change
public DateTime changePlan(final String productName, final BillingPeriod term, final String priceList, final CallContext context)
public DateTime changePlan(final String productName, final BillingPeriod term, final String priceList, final List<PlanPhasePriceOverride> overrides, final CallContext context)
throws SubscriptionBaseApiException;

// Return the effective date of the change
public DateTime changePlanWithDate(final String productName, final BillingPeriod term, final String priceList, final DateTime requestedDate, final CallContext context)
public DateTime changePlanWithDate(final String productName, final BillingPeriod term, final String priceList, final List<PlanPhasePriceOverride> overrides, final DateTime requestedDate, final CallContext context)
throws SubscriptionBaseApiException;

// Return the effective date of the change
public DateTime changePlanWithPolicy(final String productName, final BillingPeriod term, final String priceList,
public DateTime changePlanWithPolicy(final String productName, final BillingPeriod term, final String priceList, final List<PlanPhasePriceOverride> overrides,
final BillingActionPolicy policy, final CallContext context)
throws SubscriptionBaseApiException;

Expand Down
Expand Up @@ -26,6 +26,7 @@

import org.killbill.billing.callcontext.InternalCallContext;
import org.killbill.billing.callcontext.InternalTenantContext;
import org.killbill.billing.catalog.api.PlanPhasePriceOverride;
import org.killbill.billing.catalog.api.PlanPhaseSpecifier;
import org.killbill.billing.entitlement.api.EntitlementAOStatusDryRun;
import org.killbill.billing.events.EffectiveSubscriptionInternalEvent;
Expand All @@ -36,7 +37,7 @@

public interface SubscriptionBaseInternalApi {

public SubscriptionBase createSubscription(UUID bundleId, PlanPhaseSpecifier spec, DateTime requestedDateWithMs,
public SubscriptionBase createSubscription(UUID bundleId, PlanPhaseSpecifier spec, List<PlanPhasePriceOverride> overrides, DateTime requestedDateWithMs,
InternalCallContext context) throws SubscriptionBaseApiException;

public SubscriptionBaseBundle createBundleForAccount(UUID accountId, String bundleName, InternalCallContext context)
Expand Down
Expand Up @@ -50,6 +50,7 @@
import org.killbill.billing.catalog.api.BillingPeriod;
import org.killbill.billing.catalog.api.Currency;
import org.killbill.billing.catalog.api.PhaseType;
import org.killbill.billing.catalog.api.PlanPhasePriceOverride;
import org.killbill.billing.catalog.api.PlanPhaseSpecifier;
import org.killbill.billing.catalog.api.PriceListSet;
import org.killbill.billing.catalog.api.ProductCategory;
Expand Down Expand Up @@ -567,7 +568,7 @@ public Entitlement apply(@Nullable final Void dontcare) {
try {
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier(productName, productCategory, billingPeriod, PriceListSet.DEFAULT_PRICELIST_NAME, null);
final LocalDate effectiveDate = new LocalDate(clock.getUTCNow());
final Entitlement entitlement = entitlementApi.createBaseEntitlement(accountId, spec, bundleExternalKey, effectiveDate, callContext);
final Entitlement entitlement = entitlementApi.createBaseEntitlement(accountId, spec, bundleExternalKey, null, effectiveDate, callContext);
assertNotNull(entitlement);
return entitlement;
} catch (final EntitlementApiException e) {
Expand All @@ -593,7 +594,7 @@ public Entitlement apply(@Nullable final Void dontcare) {
try {
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier(productName, productCategory, billingPeriod, PriceListSet.DEFAULT_PRICELIST_NAME, null);
final LocalDate effectiveDate = new LocalDate(clock.getUTCNow());
final Entitlement entitlement = entitlementApi.addEntitlement(bundleId, spec, effectiveDate, callContext);
final Entitlement entitlement = entitlementApi.addEntitlement(bundleId, spec, null, effectiveDate, callContext);
assertNotNull(entitlement);
return entitlement;
} catch (final EntitlementApiException e) {
Expand All @@ -617,9 +618,9 @@ public Entitlement apply(@Nullable final Void dontcare) {
// Need to fetch again to get latest CTD updated from the system
Entitlement refreshedEntitlement = entitlementApi.getEntitlementForId(entitlement.getId(), callContext);
if (billingPolicy == null) {
refreshedEntitlement = refreshedEntitlement.changePlan(productName, billingPeriod, priceList, callContext);
refreshedEntitlement = refreshedEntitlement.changePlan(productName, billingPeriod, priceList, null, callContext);
} else {
refreshedEntitlement = refreshedEntitlement.changePlanOverrideBillingPolicy(productName, billingPeriod, priceList, clock.getUTCNow().toLocalDate(), billingPolicy, callContext);
refreshedEntitlement = refreshedEntitlement.changePlanOverrideBillingPolicy(productName, billingPeriod, priceList, null, clock.getUTCNow().toLocalDate(), billingPolicy, callContext);
}
return refreshedEntitlement;
} catch (final EntitlementApiException e) {
Expand Down Expand Up @@ -781,5 +782,10 @@ public UUID getBundleId() {
public BillingActionPolicy getBillingActionPolicy() {
return billingPolicy;
}

@Override
public List<PlanPhasePriceOverride> getPlanPhasePriceoverrides() {

This comment has been minimized.

Copy link
@pierre

pierre Mar 25, 2015

Member

getPlanPhasePrice*O*verrides?

return null;
}
}
}
Expand Up @@ -985,7 +985,7 @@ public int compare(final Invoice i1, final Invoice i2) {
private void checkChangePlanWithOverdueState(final Entitlement entitlement, final boolean shouldFail, final boolean expectedPayment) {
if (shouldFail) {
try {
entitlement.changePlan("Pistol", term, PriceListSet.DEFAULT_PRICELIST_NAME, callContext);
entitlement.changePlan("Pistol", term, PriceListSet.DEFAULT_PRICELIST_NAME, null, callContext);
} catch (EntitlementApiException e) {
assertTrue(e.getCause() instanceof BlockingApiException || e.getCode() == ErrorCode.SUB_CHANGE_NON_ACTIVE.getCode(),
String.format("Cause is %s, message is %s", e.getCause(), e.getMessage()));
Expand Down
@@ -0,0 +1,66 @@
/*
* Copyright 2014-2015 Groupon, Inc
* Copyright 2014-2015 The Billing Project, LLC
*
* The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/

package org.killbill.billing.catalog;

import java.math.BigDecimal;

import org.killbill.billing.catalog.api.Currency;
import org.killbill.billing.catalog.api.PlanPhasePriceOverride;
import org.killbill.billing.catalog.api.PlanPhaseSpecifier;

public class DefaultPlanPhasePriceOverride implements PlanPhasePriceOverride {

private final String phaseName;
private final PlanPhaseSpecifier planPhaseSpecifier;
private final Currency currency;
private final BigDecimal fixedPrice;
private final BigDecimal recurringPrice;

public DefaultPlanPhasePriceOverride(final String phaseName, final PlanPhaseSpecifier planPhaseSpecifier, final Currency currency, final BigDecimal fixedPrice, final BigDecimal recurringPrice) {
this.phaseName = phaseName;
this.planPhaseSpecifier = planPhaseSpecifier;
this.currency = currency;
this.fixedPrice = fixedPrice;
this.recurringPrice = recurringPrice;
}

@Override
public String getPhaseName() {
return phaseName;
}

@Override
public PlanPhaseSpecifier getPlanPhaseSpecifier() {
return planPhaseSpecifier;
}

@Override
public Currency getCurrency() {
return currency;
}

@Override
public BigDecimal getFixedPrice() {
return fixedPrice;
}

@Override
public BigDecimal getRecurringPrice() {
return recurringPrice;
}
}
Expand Up @@ -41,6 +41,7 @@
import org.killbill.billing.catalog.api.PlanAlignmentCreate;
import org.killbill.billing.catalog.api.PlanChangeResult;
import org.killbill.billing.catalog.api.PlanPhase;
import org.killbill.billing.catalog.api.PlanPhasePriceOverride;
import org.killbill.billing.catalog.api.PlanPhaseSpecifier;
import org.killbill.billing.catalog.api.PlanSpecifier;
import org.killbill.billing.catalog.api.PriceList;
Expand All @@ -51,6 +52,8 @@
import org.killbill.xmlloader.ValidatingConfig;
import org.killbill.xmlloader.ValidationErrors;

import com.google.common.collect.ImmutableList;

@XmlRootElement(name = "catalog")
@XmlAccessorType(XmlAccessType.NONE)
public class StandaloneCatalog extends ValidatingConfig<StandaloneCatalog> implements StaticCatalog {
Expand Down Expand Up @@ -158,7 +161,7 @@ public DefaultPriceListSet getPriceLists() {
* @see org.killbill.billing.catalog.ICatalog#getPlan(java.lang.String, java.lang.String)
*/
@Override
public DefaultPlan findCurrentPlan(final String productName, final BillingPeriod period, final String priceListName) throws CatalogApiException {
public DefaultPlan findCurrentPlan(final String productName, final BillingPeriod period, final String priceListName, List<PlanPhasePriceOverride> overrides) throws CatalogApiException {
if (productName == null) {
throw new CatalogApiException(ErrorCode.CAT_NULL_PRODUCT_NAME);
}
Expand Down Expand Up @@ -344,7 +347,7 @@ protected StandaloneCatalog setPriceLists(final DefaultPriceListSet priceLists)
@Override
public boolean canCreatePlan(final PlanSpecifier specifier) throws CatalogApiException {
final Product product = findCurrentProduct(specifier.getProductName());
final Plan plan = findCurrentPlan(specifier.getProductName(), specifier.getBillingPeriod(), specifier.getPriceListName());
final Plan plan = findCurrentPlan(specifier.getProductName(), specifier.getBillingPeriod(), specifier.getPriceListName(), ImmutableList.<PlanPhasePriceOverride>of());
final DefaultPriceList priceList = findCurrentPriceList(specifier.getPriceListName());

return (!product.isRetired()) &&
Expand Down
Expand Up @@ -47,6 +47,7 @@
import org.killbill.billing.catalog.api.PlanAlignmentCreate;
import org.killbill.billing.catalog.api.PlanChangeResult;
import org.killbill.billing.catalog.api.PlanPhase;
import org.killbill.billing.catalog.api.PlanPhasePriceOverride;
import org.killbill.billing.catalog.api.PlanPhaseSpecifier;
import org.killbill.billing.catalog.api.PlanSpecifier;
import org.killbill.billing.catalog.api.PriceList;
Expand All @@ -57,6 +58,8 @@
import org.killbill.xmlloader.ValidatingConfig;
import org.killbill.xmlloader.ValidationErrors;

import com.google.common.collect.ImmutableList;

@XmlRootElement(name = "catalog")
@XmlAccessorType(XmlAccessType.NONE)
public class VersionedCatalog extends ValidatingConfig<StandaloneCatalog> implements Catalog, StaticCatalog {
Expand Down Expand Up @@ -110,29 +113,35 @@ private class PlanRequestWrapper {
String productName;
BillingPeriod bp;
String priceListName;
List<PlanPhasePriceOverride> overrides;

public PlanRequestWrapper(final String name) {
super();
this.name = name;
}

public PlanRequestWrapper(final String productName, final BillingPeriod bp,
final String priceListName) {
super();
this(productName, bp, priceListName, ImmutableList.<PlanPhasePriceOverride>of());
}

public PlanRequestWrapper(final String productName, final BillingPeriod bp,
final String priceListName, List<PlanPhasePriceOverride> overrides) {
this.productName = productName;
this.bp = bp;
this.priceListName = priceListName;
this.overrides = overrides;
}

public Plan findPlan(final StandaloneCatalog catalog) throws CatalogApiException {
if (name != null) {
return catalog.findCurrentPlan(name);
} else {
return catalog.findCurrentPlan(productName, bp, priceListName);
return catalog.findCurrentPlan(productName, bp, priceListName, overrides);
}
}
}

// STEPH_PO implement catalog logic...
private Plan findPlan(final PlanRequestWrapper wrapper,
final DateTime requestedDate,
final DateTime subscriptionStartDate)
Expand Down Expand Up @@ -244,9 +253,10 @@ public Plan findPlan(final String name,
public Plan findPlan(final String productName,
final BillingPeriod term,
final String priceListName,
final List<PlanPhasePriceOverride> overrides,
final DateTime requestedDate)
throws CatalogApiException {
return versionForDate(requestedDate).findCurrentPlan(productName, term, priceListName);
return versionForDate(requestedDate).findCurrentPlan(productName, term, priceListName, overrides);
}

@Override
Expand All @@ -261,6 +271,7 @@ public Plan findPlan(final String name,
public Plan findPlan(final String productName,
final BillingPeriod term,
final String priceListName,
final List<PlanPhasePriceOverride> overrides,
final DateTime requestedDate,
final DateTime subscriptionStartDate)
throws CatalogApiException {
Expand Down Expand Up @@ -398,8 +409,8 @@ public Plan[] getCurrentPlans() throws CatalogApiException {

@Override
public Plan findCurrentPlan(final String productName, final BillingPeriod term,
final String priceList) throws CatalogApiException {
return versionForDate(clock.getUTCNow()).findCurrentPlan(productName, term, priceList);
final String priceList, List<PlanPhasePriceOverride> overrides) throws CatalogApiException {
return versionForDate(clock.getUTCNow()).findCurrentPlan(productName, term, priceList, overrides);
}

@Override
Expand Down
@@ -0,0 +1,4 @@
package org.killbill.billing.catalog.dao;

public class CatalogOverrideDao {
}
@@ -0,0 +1,33 @@
/*
* Copyright 2014-2015 Groupon, Inc
* Copyright 2014-2015 The Billing Project, LLC
*
* The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/

package org.killbill.billing.catalog.dao;

import org.skife.jdbi.v2.sqlobject.Bind;
import org.skife.jdbi.v2.sqlobject.SqlQuery;
import org.skife.jdbi.v2.sqlobject.customizers.Define;
import org.skife.jdbi.v2.sqlobject.mixins.CloseMe;
import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
import org.skife.jdbi.v2.sqlobject.stringtemplate.UseStringTemplate3StatementLocator;

@UseStringTemplate3StatementLocator
public interface CatalogOverridePhaseDefinitionSqlDao extends Transactional<CatalogOverridePhaseDefinitionSqlDao>, CloseMe {

@SqlQuery
public Long getRecordIdFromObject(@Bind("id") String id, @Define("tableName") final String tableName);

}
@@ -0,0 +1,4 @@
package org.killbill.billing.catalog.dao;

public class CatalogOverridePlanDefinitionModelDao {
}
@@ -0,0 +1,33 @@
/*
* Copyright 2014-2015 Groupon, Inc
* Copyright 2014-2015 The Billing Project, LLC
*
* The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/

package org.killbill.billing.catalog.dao;

import org.skife.jdbi.v2.sqlobject.Bind;
import org.skife.jdbi.v2.sqlobject.SqlQuery;
import org.skife.jdbi.v2.sqlobject.customizers.Define;
import org.skife.jdbi.v2.sqlobject.mixins.CloseMe;
import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
import org.skife.jdbi.v2.sqlobject.stringtemplate.UseStringTemplate3StatementLocator;

@UseStringTemplate3StatementLocator
public interface CatalogOverridePlanDefinitionSqlDao extends Transactional<CatalogOverridePlanDefinitionSqlDao>, CloseMe {

@SqlQuery
public Long getRecordIdFromObject(@Bind("id") String id, @Define("tableName") final String tableName);

}

1 comment on commit 445c377

@pierre
Copy link
Member

@pierre pierre commented on 445c377 Mar 25, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Please sign in to comment.