Fixes for subscriptions

This commit is contained in:
David Bomba 2021-06-27 21:55:15 +10:00
parent 021761d33d
commit d7e551fc95
6 changed files with 125 additions and 26 deletions

View File

@ -90,24 +90,40 @@ class SubscriptionPlanSwitch extends Component
$this->state['show_loading_bar'] = true;
$this->state['invoice'] = $this->target->service()->createChangePlanInvoice([
$payment_required = $this->target->service()->changePlanPaymentCheck([
'recurring_invoice' => $this->recurring_invoice,
'subscription' => $this->subscription,
'target' => $this->target,
'hash' => $this->hash,
]);
Cache::put($this->hash, [
'subscription_id' => $this->target->id,
'target_id' => $this->target->id,
'recurring_invoice' => $this->recurring_invoice->id,
'client_id' => $this->recurring_invoice->client->id,
'invoice_id' => $this->state['invoice']->id,
'context' => 'change_plan',
now()->addMinutes(60)]
);
if($payment_required)
{
$this->state['invoice'] = $this->target->service()->createChangePlanInvoice([
'recurring_invoice' => $this->recurring_invoice,
'subscription' => $this->subscription,
'target' => $this->target,
'hash' => $this->hash,
]);
Cache::put($this->hash, [
'subscription_id' => $this->target->id,
'target_id' => $this->target->id,
'recurring_invoice' => $this->recurring_invoice->id,
'client_id' => $this->recurring_invoice->client->id,
'invoice_id' => $this->state['invoice']->id,
'context' => 'change_plan',
now()->addMinutes(60)]
);
$this->state['payment_initialised'] = true;
}
else
$this->handlePaymentNotRequired();
$this->state['payment_initialised'] = true;
$this->emit('beforePaymentEventsCompleted');
}

View File

@ -78,7 +78,7 @@ class CreateAccount
$sp794f3f->save();
if(Ninja::isHosted())
$sp794f3f->startTrial();
$sp794f3f->startTrial('pro');
$sp035a66 = CreateCompany::dispatchNow($this->request, $sp794f3f);
$sp035a66->load('account');

View File

@ -96,8 +96,9 @@ class SubscriptionRepository extends BaseRepository
return $data;
}
public function generateLineItems($subscription, $is_recurring = false)
public function generateLineItems($subscription, $is_recurring = false, $is_credit = false)
{
$multiplier = $is_credit ? -1 : 1;
$line_items = [];
@ -105,13 +106,13 @@ class SubscriptionRepository extends BaseRepository
{
foreach($subscription->service()->products() as $product)
{
$line_items[] = (array)$this->makeLineItem($product);
$line_items[] = (array)$this->makeLineItem($product, $multiplier);
}
}
foreach($subscription->service()->recurring_products() as $product)
{
$line_items[] = (array)$this->makeLineItem($product);
$line_items[] = (array)$this->makeLineItem($product, $multiplier);
}
$line_items = $this->cleanItems($line_items);
@ -120,13 +121,13 @@ class SubscriptionRepository extends BaseRepository
}
private function makeLineItem($product)
private function makeLineItem($product, $multiplier)
{
$item = new InvoiceItem;
$item->quantity = $product->quantity;
$item->product_key = $product->product_key;
$item->notes = $product->notes;
$item->cost = $product->price;
$item->cost = $product->price*$multiplier;
$item->tax_rate1 = $product->tax_rate1 ?: 0;
$item->tax_name1 = $product->tax_name1 ?: '';
$item->tax_rate2 = $product->tax_rate2 ?: 0;

View File

@ -214,11 +214,11 @@ class SubscriptionService
if ($outstanding->count() == 0){
//nothing outstanding
return $target->price - $this->calculateProRataRefund($outstanding_invoice);
return $target->price - $this->calculateProRataRefundForSubscription($outstanding_invoice);
}
elseif ($outstanding->count() == 1){
//user has multiple amounts outstanding
return $target->price - $this->calculateProRataRefund($outstanding_invoice);
return $target->price - $this->calculateProRataRefundForSubscription($outstanding_invoice);
}
elseif ($outstanding->count() > 1) {
//user is changing plan mid frequency cycle
@ -230,6 +230,35 @@ class SubscriptionService
}
/**
* We refund unused days left.
*
* @param Invoice $invoice
* @return float
*/
private function calculateProRataRefundForSubscription($invoice) :float
{
if(!$invoice->date)
return 0;
$start_date = Carbon::parse($invoice->date);
$current_date = now();
$days_of_subscription_used = $start_date->diffInDays($current_date);
$days_in_frequency = $this->getDaysInFrequency();
$pro_rata_refund = round((($days_in_frequency - $days_of_subscription_used)/$days_in_frequency) * $this->subscription->price ,2);
// nlog("days in frequency = {$days_in_frequency} - days of subscription used {$days_of_subscription_used}");
// nlog("invoice amount = {$invoice->amount}");
// nlog("pro rata refund = {$pro_rata_refund}");
return $pro_rata_refund;
}
/**
* We refund unused days left.
*
@ -251,6 +280,10 @@ class SubscriptionService
$pro_rata_refund = round((($days_in_frequency - $days_of_subscription_used)/$days_in_frequency) * $invoice->amount ,2);
// nlog("days in frequency = {$days_in_frequency} - days of subscription used {$days_of_subscription_used}");
// nlog("invoice amount = {$invoice->amount}");
// nlog("pro rata refund = {$pro_rata_refund}");
return $pro_rata_refund;
}
@ -384,6 +417,44 @@ class SubscriptionService
}
public function changePlanPaymentCheck($data)
{
$recurring_invoice = $data['recurring_invoice'];
$old_subscription = $data['subscription'];
$target_subscription = $data['target'];
$pro_rata_charge_amount = 0;
$pro_rata_refund_amount = 0;
$last_invoice = Invoice::where('subscription_id', $recurring_invoice->subscription_id)
->where('client_id', $recurring_invoice->client_id)
->where('is_deleted', 0)
->withTrashed()
->orderBy('id', 'desc')
->first();
if($last_invoice->balance > 0)
{
$pro_rata_charge_amount = $this->calculateProRataCharge($last_invoice, $old_subscription);
nlog("pro rata charge = {$pro_rata_charge_amount}");
}
else
{
$pro_rata_refund_amount = $this->calculateProRataRefund($last_invoice, $old_subscription) * -1;
nlog("pro rata refund = {$pro_rata_refund_amount}");
}
$total_payable = $pro_rata_refund_amount + $pro_rata_charge_amount + $this->subscription->price;
if($total_payable > 0)
return true;
return false;
}
/**
* When changing plans, we need to generate a pro rata invoice
*
@ -392,6 +463,7 @@ class SubscriptionService
*/
public function createChangePlanInvoice($data)
{
$recurring_invoice = $data['recurring_invoice'];
$old_subscription = $data['subscription'];
$target_subscription = $data['target'];
@ -500,7 +572,7 @@ class SubscriptionService
$credit->date = now()->format('Y-m-d');
$credit->subscription_id = $this->subscription->id;
$line_items = $subscription_repo->generateLineItems($target);
$line_items = $subscription_repo->generateLineItems($target, false, true);
$credit->line_items = array_merge($line_items, $this->calculateProRataRefundItems($last_invoice, true));

View File

@ -4272,6 +4272,7 @@ $LANG = array(
'default_payment_method' => 'Make this your preferred way of paying.',
'already_default_payment_method' => 'This is your preferred way of paying.',
'auto_bill_disabled' => 'Auto Bill Disabled',
'select_payment_method' => 'Select a payment method:',
);
return $LANG;

View File

@ -10,11 +10,10 @@
</div>
<div class="relative flex justify-center text-sm leading-5">
<span class="font-bold tracking-wide bg-gray-100 px-6 py-0">Select a payment method:</span>
{{-- <h1 class="text-2xl font-bold tracking-wide bg-gray-100 px-6 py-0">--}}
{{-- {{ ctrans('texts.total') }}: {{ \App\Utils\Number::formatMoney($total, $subscription->company) }}--}}
{{-- <small class="ml-1 line-through text-gray-500">{{ \App\Utils\Number::formatMoney($subscription->price, $subscription->company) }}</small>--}}
{{-- </h1>--}}
<span class="font-bold tracking-wide bg-gray-100 px-6 py-0">{{ ctrans('texts.select_payment_method')}}</span>
<h1 class="text-2xl font-bold tracking-wide bg-gray-100 px-6 py-0">
{{ ctrans('texts.total') }}: {{ \App\Utils\Number::formatMoney($amount, $subscription->company) }}
</h1>
</div>
</div>
@ -63,9 +62,19 @@
</div>
</div>
@elseif($amount < 0)
<button wire:click="handlePaymentNotRequired"class="px-3 py-2 border rounded mr-4 hover:border-blue-600">
<div class="relative flex justify-center text-sm leading-5">
<h1 class="text-2xl font-bold tracking-wide bg-gray-100 px-6 py-0">
{{ ctrans('texts.total') }}: {{ \App\Utils\Number::formatMoney($amount, $subscription->company) }}
</h1>
</div>
<div class="relative flex justify-center text-sm leading-5 mt-10">
<button wire:click="handlePaymentNotRequired" class="px-3 py-2 border rounded mr-4 hover:border-blue-600">
{{ ctrans('texts.click_to_continue') }}
</button>
</div>
@endif
</div>
</div>