Commit 72e359bf by Nilu

multiple plans in one subscription and create seperate charge when upgradig a…

multiple plans in one subscription and create seperate charge when upgradig a plan - as proration should be disabled and when disabled only at the next billing cycle the payment will be charged.
parent 2f2126fd
......@@ -21,11 +21,14 @@
<column name="manage_own_billing" type="Boolean" nullable="true"/>
<column name="stripe_reference" type="String" nullable="true" length="100"/>
<column name="stripe_subscription" type="String" nullable="true" length="100"/>
<column name="stripe_fixed_sub_item" type="String" nullable="true" length="100"/>
<column name="stripe_metered_sub_item" type="String" nullable="true" length="100"/>
<column name="name_on_card" type="String" nullable="true" length="100"/>
<column name="card_post_code" type="String" nullable="true" length="10"/>
<column name="card_id" type="String" nullable="true" length="100"/>
<column name="plan_renewed_on" type="Date" nullable="true"/>
<column name="used_credits" type="Long" nullable="true"/>
<column name="available_credits" type="Long" nullable="true"/>
<column name="is_ppj" type="Boolean" nullable="true"/>
<column name="has_cap" type="Boolean" nullable="true"/>
<column name="max_cap" type="Long" nullable="true"/>
......
......@@ -21,11 +21,14 @@ CREATE TABLE tl_hiring_team (
manage_own_billing char(1) NULL,
stripe_reference varchar(100) NULL,
stripe_subscription varchar(100) NULL,
stripe_fixed_sub_item varchar(100) NULL,
stripe_metered_sub_item varchar(100) NULL,
name_on_card varchar(100) NULL,
card_post_code varchar(10) NULL,
card_id varchar(100) NULL,
plan_renewed_on datetime NULL,
used_credits numeric(12) NULL,
available_credits numeric(12) NULL,
is_ppj char(1) NULL,
has_cap char(1) NULL,
max_cap numeric(12) NULL,
......
......@@ -22,11 +22,14 @@ CREATE TABLE tl_hiring_team (
manage_own_billing char(1) NULL,
stripe_reference varchar2(100) NULL,
stripe_subscription varchar2(100) NULL,
stripe_fixed_sub_item varchar2(100) NULL,
stripe_metered_sub_item varchar2(100) NULL,
name_on_card varchar2(100) NULL,
card_post_code varchar2(10) NULL,
card_id varchar2(100) NULL,
plan_renewed_on date NULL,
used_credits number(12) NULL,
available_credits number(12) NULL,
is_ppj char(1) NULL,
has_cap char(1) NULL,
max_cap number(12) NULL,
......
......@@ -22,11 +22,14 @@ CREATE TABLE tl_hiring_team (
manage_own_billing char(1) NULL,
stripe_reference varchar(100) NULL,
stripe_subscription varchar(100) NULL,
stripe_fixed_sub_item varchar(100) NULL,
stripe_metered_sub_item varchar(100) NULL,
name_on_card varchar(100) NULL,
card_post_code varchar(10) NULL,
card_id varchar(100) NULL,
plan_renewed_on timestamp NULL,
used_credits numeric(12) NULL,
available_credits numeric(12) NULL,
is_ppj char(1) NULL,
has_cap char(1) NULL,
max_cap numeric(12) NULL,
......
......@@ -81,7 +81,7 @@ public class MakePaymentFP extends SaveFP
{
LogMgr.log(LOG, LogLevel.PROCESSING1, e, "Error while making a payment of company stripe " + company.getStripeReference());
throw new BusinessException("Stripe payment was failed, Please contact adminstrator for more info.");
throw new BusinessException("Stripe payment failed, Please contact adminstrator for more info.");
}
}
......
package performa.form;
import com.stripe.model.Subscription;
import java.util.Date;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import oneit.logging.LogLevel;
......@@ -59,11 +60,36 @@ public class SaveCompanyFP extends SaveFP
}
// cannot subscribe a user to a plan without card details
Subscription updatedSubscription = StripeUtils.updatePlan(hiringTeam);
Subscription subscription = StripeUtils.retrieveSubscription(hiringTeam.getStripeSubscription());
Subscription updatedSubscription = StripeUtils.updatePlan(hiringTeam, subscription, paymentPlan);
if(updatedSubscription == null)
{
throw new BusinessException("Problem with changing your plan. Please contact admin.");
throw new BusinessException("Problem with changing your plan. Please contact adminstrator for more info.");
}
PaymentPlan currentPlan = hiringTeam.getPaymentPlan();
if(currentPlan != null && currentPlan.getActiveJobCount() < paymentPlan.getActiveJobCount())
{
double discountPercentage = 0d;
if(subscription.getDiscount() != null && subscription.getDiscount().getCoupon() != null && subscription.getDiscount().getCoupon().getPercentOff() != null)
{
discountPercentage = subscription.getDiscount().getCoupon().getPercentOff().doubleValue();
}
boolean hasValidCoupon = hiringTeam.hasValidCouponOn(new Date(subscription.getCurrentPeriodEnd() * 1000));
double currentPlanCost = discountPercentage > 0 ? currentPlan.getAmount() * discountPercentage * 0.01 : currentPlan.getAmount();
double newPlanCost = hasValidCoupon ? paymentPlan.getAmount() * hiringTeam.getCoupon().getPercentageOff() * 0.01 : paymentPlan.getAmount();
double costDiff = newPlanCost - currentPlanCost;
StripeUtils.chargeUpgradePlanDifference(hiringTeam, costDiff);
}
if(currentPlan == null || currentPlan.getActiveJobCount() < paymentPlan.getActiveJobCount())
{
hiringTeam.setAvailableCredits(paymentPlan.getActiveJobCount());
}
hiringTeam.setPaymentPlan(paymentPlan);
......
......@@ -113,9 +113,23 @@ public class HiringTeam extends BaseHiringTeam
public boolean hasValidCoupon() throws FieldException
{
return hasValidCouponOn(DateDiff.getToday());
if(getCoupon() != null)
{
Coupon coupon = StripeUtils.retrieveCoupon(getCoupon().getCouponCode());
if(coupon.getValid() && (getCouponExpiryDate() == null || DateDiff.getToday().before(getCouponExpiryDate())))
{
return true;
}
}
setCoupon(null);
setCouponExpiryDate(null);
return false;
}
public boolean hasValidCouponOn(Date date) throws FieldException
{
if(getCoupon() != null)
......@@ -128,9 +142,6 @@ public class HiringTeam extends BaseHiringTeam
}
}
setCoupon(null);
setCouponExpiryDate(null);
return false;
}
}
\ No newline at end of file
......@@ -31,11 +31,14 @@
<ATTRIB name="ManageOwnBilling" type="Boolean" dbcol="manage_own_billing" mandatory="false" defaultValue="Boolean.TRUE"/>
<ATTRIB name="StripeReference" type="String" dbcol="stripe_reference" length="100" />
<ATTRIB name="StripeSubscription" type="String" dbcol="stripe_subscription" length="100" />
<ATTRIB name="StripeFixedSubItem" type="String" dbcol="stripe_fixed_sub_item" length="100" />
<ATTRIB name="StripeMeteredSubItem" type="String" dbcol="stripe_metered_sub_item" length="100" />
<ATTRIB name="NameOnCard" type="String" dbcol="name_on_card" length="100" />
<ATTRIB name="CardPostCode" type="String" dbcol="card_post_code" length="10" />
<ATTRIB name="CardID" type="String" dbcol="card_id" length="100" />
<ATTRIB name="PlanRenewedOn" type="Date" dbcol="plan_renewed_on" mandatory="false" />
<ATTRIB name="UsedCredits" type="Integer" dbcol="used_credits" />
<ATTRIB name="AvailableCredits" type="Integer" dbcol="available_credits" />
<ATTRIB name="IsPPJ" type="Boolean" dbcol="is_ppj" defaultValue="Boolean.TRUE"/>
<ATTRIB name="HasCap" type="Boolean" dbcol="has_cap" defaultValue="Boolean.FALSE"/>
<ATTRIB name="MaxCap" type="Integer" dbcol="max_cap" />
......
......@@ -3,6 +3,7 @@ package performa.utils;
import com.stripe.Stripe;
import com.stripe.exception.StripeException;
import com.stripe.model.Card;
import com.stripe.model.Charge;
import com.stripe.model.Coupon;
import com.stripe.model.Customer;
import com.stripe.model.Event;
......@@ -27,11 +28,14 @@ import oneit.logging.LoggingArea;
import oneit.objstore.ObjectTransaction;
import oneit.objstore.rdbms.filters.EqualsFilter;
import oneit.security.SecUser;
import oneit.utils.BusinessException;
import oneit.utils.DateDiff;
import oneit.utils.math.NullArith;
import oneit.utils.parsers.FieldException;
import performa.orm.Company;
import performa.orm.HiringTeam;
import performa.orm.PaymentPlan;
import performa.orm.types.AssessmentType;
import spark.utils.IOUtils;
......@@ -204,20 +208,15 @@ public class StripeUtils
}
public static Subscription updatePlan(HiringTeam hiringTeam) throws FieldException
public static Subscription updatePlan(HiringTeam hiringTeam, Subscription subscription, PaymentPlan paymentPlan) throws FieldException
{
try
{
Subscription subscription = null;
PaymentPlan paymentPlan = hiringTeam.getPaymentPlan();
Map<String, Object> itemA = new HashMap<>();
Map<String, Object> itemB = new HashMap<>();
if(hiringTeam.getStripeSubscription() != null)
if(subscription != null)
{
subscription = Subscription.retrieve(hiringTeam.getStripeSubscription());
itemA.put("id", subscription.getSubscriptionItems().getData().get(0).getId());
itemB.put("id", subscription.getSubscriptionItems().getData().get(1).getId());
}
......@@ -252,6 +251,8 @@ public class StripeUtils
LogMgr.log(LoggingArea.ALL, LogLevel.PROCESSING1, "Subscribing customer in stripe : ", subscription);
hiringTeam.setStripeSubscription(subscription.getId());
hiringTeam.setStripeFixedSubItem(subscription.getSubscriptionItems().getData().get(0).getId());
hiringTeam.setStripeMeteredSubItem(subscription.getSubscriptionItems().getData().get(1).getId());
return subscription;
}
......@@ -264,6 +265,28 @@ public class StripeUtils
}
public static void chargeUpgradePlanDifference(HiringTeam hiringTeam, double costDifference) throws BusinessException
{
try
{
Map<String, Object> chargeParams = new HashMap<>();
chargeParams.put("amount", NullArith.intVal(NullArith.multiply(costDifference, 100, 0d)));
chargeParams.put("currency", "sgd");
chargeParams.put("description", "Charges of upgrading plan");
chargeParams.put("customer", hiringTeam.getStripeReference());
Charge.create(chargeParams);
}
catch (StripeException ex)
{
LogMgr.log(LoggingArea.ALL, LogLevel.PROCESSING1, ex, "Error while charging plan upgrade difference in stripe");
throw new BusinessException("Problem with charging for your plan upgrade. Please contact adminstrator for more info.");
}
}
public static void recordUsage(HiringTeam hiringTeam)
{
try
......@@ -271,11 +294,11 @@ public class StripeUtils
Map<String, Object> params = new HashMap<>();
Date now = new Date();
String subscription = hiringTeam.getManageOwnBilling() ? hiringTeam.getStripeSubscription() : hiringTeam.getBillingTeam().getStripeSubscription();
HiringTeam billingTeam = hiringTeam.getManageOwnBilling() ? hiringTeam: hiringTeam.getBillingTeam();
params.put("quantity", 1);
params.put("timestamp", now.getTime() / 1000L);
params.put("subscription_item", subscription);
params.put("subscription_item", billingTeam.getStripeMeteredSubItem());
params.put("action", "increment");
UsageRecord.create(params, null);
......@@ -305,24 +328,25 @@ public class StripeUtils
if(invoice.getBilling().equals("charge_automatically"))
{
Company[] companies = Company.SearchByAll().andStripeReference(new EqualsFilter<>(invoice.getCustomer())).search(objTran);
HiringTeam[] hiringTeams = HiringTeam.SearchByAll().andStripeReference(new EqualsFilter<>(invoice.getCustomer())).search(objTran);
if(companies != null && companies.length > 0)
if(hiringTeams != null && hiringTeams.length > 0)
{
Company company = companies[0];
HiringTeam hiringTeam = hiringTeams[0];
Date invoiceDate = new Date(invoice.getDate() * 1000L);
if(company.getPlanRenewedOn() == null || !DateDiff.startOfDay(invoiceDate).equals(DateDiff.startOfDay(company.getPlanRenewedOn())))
if(hiringTeam.getPlanRenewedOn() == null || !DateDiff.startOfDay(invoiceDate).equals(DateDiff.startOfDay(hiringTeam.getPlanRenewedOn())))
{
if(company.getPlanRenewedOn() != null)
if(hiringTeam.getPlanRenewedOn() != null)
{
company.setUsedCredits(0);
hiringTeam.setUsedCredits(0);
hiringTeam.setAvailableCredits(hiringTeam.getPaymentPlan().getActiveJobCount());
}
company.setPlanRenewedOn(invoiceDate);
hiringTeam.setPlanRenewedOn(invoiceDate);
}
LogMgr.log(LoggingArea.ALL, LogLevel.PROCESSING1, "Setting company with reset plan details : ", company);
LogMgr.log(LoggingArea.ALL, LogLevel.PROCESSING1, "Setting hiring team with reset plan details : ", hiringTeam);
}
}
}
......
......@@ -36,6 +36,7 @@
subscription = StripeUtils.retrieveSubscription(hiringTeam.getStripeSubscription());
}
System.out.println(subscription);
%>
<script type="text/javascript">
var Popup = null;
......@@ -79,6 +80,11 @@
setTabingSideBarHeight();
});
});
function paymentPlanChanged()
{
$("#savePaymentPlan").click();
}
</script>
<div class="container-fluid">
......@@ -151,7 +157,7 @@
<div class="manage-plan-row">
<div class="radio">
<label>
<oneit:ormInput obj="<%= hiringTeam %>" type="radio" attributeName="IsPPJ" value="true"/>
<oneit:ormInput obj="<%= hiringTeam %>" type="radio" attributeName="IsPPJ" value="true" onchange="paymentPlanChanged()"/>
</label>
</div>
<div class="manage-plan-title">
......@@ -179,7 +185,7 @@
<div class="manage-plan-row">
<div class="radio">
<label>
<oneit:ormInput obj="<%= hiringTeam %>" type="radio" attributeName="IsPPJ" value="false"/>
<oneit:ormInput obj="<%= hiringTeam %>" type="radio" attributeName="IsPPJ" value="false" onchange="paymentPlanChanged()"/>
</label>
</div>
<div class="manage-plan-title">
......@@ -383,20 +389,18 @@
</div>
</div>
<div class="form-group row">
<oneit:button value="Update Subscription" name="saveCompany" cssClass="btn btn-primary largeBtn btn-green save-btn" style="display:inline;"
requestAttribs="<%= CollectionUtils.mapEntry("nextPage", nextPage)
.mapEntry ("restartProcess", Boolean.TRUE)
.mapEntry ("Company", company)
.mapEntry ("IsPayment", Boolean.TRUE)
.mapEntry ("PaymentPlan", null)
.mapEntry ("attribNamesToRestore", Collections.singleton("HiringTeam"))
.toMap() %>" />
</div>
</div>
</div>
</div>
</div>
<div class="form-group row">
<oneit:button value=" " name="saveCompany" cssClass="btn btn-primary largeBtn btn-green save-btn" style="display:none;" id="savePaymentPlan"
requestAttribs="<%= CollectionUtils.mapEntry("nextPage", nextPage)
.mapEntry ("restartProcess", Boolean.TRUE)
.mapEntry(NotificationUtils.DISPLAY_NOTIFICATION_PARAM, false)
.mapEntry ("attribNamesToRestore", Collections.singleton("HiringTeam"))
.toMap() %>" />
</div>
<div class="text-center footer-note">
Looking to cancel your account? Please <a href="http://www.talentology.com/">contact us.</a>
......
<?xml version="1.0" encoding="UTF-8"?>
<!-- @AutoRun -->
<OBJECTS name="" xmlns:oneit="http://www.1iT.com.au">
<NODE name="Script" factory="Vector">
<NODE name="DDL" factory="Participant" class="oneit.sql.transfer.RedefineTableOperation">
<tableName factory="String">tl_hiring_team</tableName>
<column name="stripe_fixed_sub_item" type="String" nullable="true" length="100"/>
<column name="stripe_metered_sub_item" type="String" nullable="true" length="100"/>
<column name="available_credits" type="Long" nullable="true"/>
</NODE>
</NODE>
</OBJECTS>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment