Changeset View
Changeset View
Standalone View
Standalone View
src/app/Observers/EntitlementObserver.php
Show First 20 Lines • Show All 100 Lines • ▼ Show 20 Lines | class EntitlementObserver | ||||
* Handle the entitlement "deleting" event. | * Handle the entitlement "deleting" event. | ||||
* | * | ||||
* @param \App\Entitlement $entitlement The entitlement. | * @param \App\Entitlement $entitlement The entitlement. | ||||
* | * | ||||
* @return void | * @return void | ||||
*/ | */ | ||||
public function deleting(Entitlement $entitlement) | public function deleting(Entitlement $entitlement) | ||||
{ | { | ||||
if ($entitlement->trashed()) { | $entitlement->wallet->chargeEntitlement($entitlement); | ||||
return; | |||||
} | |||||
// Start calculating the costs for the consumption of this entitlement if the | |||||
// existing consumption spans >= 14 days. | |||||
// | |||||
// Effect is that anything's free for the first 14 days | |||||
if ($entitlement->created_at >= Carbon::now()->subDays(14)) { | |||||
return; | |||||
} | |||||
$owner = $entitlement->wallet->owner; | |||||
if ($owner->isDegraded()) { | |||||
return; | |||||
} | |||||
$now = Carbon::now(); | |||||
// Determine if we're still within the trial period | |||||
$trial = $entitlement->wallet->trialInfo(); | |||||
if ( | |||||
!empty($trial) | |||||
&& $entitlement->updated_at < $trial['end'] | |||||
&& in_array($entitlement->sku_id, $trial['skus']) | |||||
) { | |||||
if ($trial['end'] >= $now) { | |||||
return; | |||||
} | |||||
$entitlement->updated_at = $trial['end']; | |||||
} | |||||
// get the discount rate applied to the wallet. | |||||
$discount = $entitlement->wallet->getDiscountRate(); | |||||
// just in case this had not been billed yet, ever | |||||
$diffInMonths = $entitlement->updated_at->diffInMonths($now); | |||||
$cost = (int) ($entitlement->cost * $discount * $diffInMonths); | |||||
$fee = (int) ($entitlement->fee * $diffInMonths); | |||||
// this moves the hypothetical updated at forward to however many months past the original | |||||
$updatedAt = $entitlement->updated_at->copy()->addMonthsWithoutOverflow($diffInMonths); | |||||
// now we have the diff in days since the last "billed" period end. | |||||
// This may be an entitlement paid up until February 28th, 2020, with today being March | |||||
// 12th 2020. Calculating the costs for the entitlement is based on the daily price | |||||
// the price per day is based on the number of days in the last month | |||||
// or the current month if the period does not overlap with the previous month | |||||
// FIXME: This really should be simplified to $daysInMonth=30 | |||||
$diffInDays = $updatedAt->diffInDays($now); | |||||
if ($now->day >= $diffInDays) { | |||||
$daysInMonth = $now->daysInMonth; | |||||
} else { | |||||
$daysInMonth = \App\Utils::daysInLastMonth(); | |||||
} | |||||
$pricePerDay = $entitlement->cost / $daysInMonth; | |||||
$feePerDay = $entitlement->fee / $daysInMonth; | |||||
$cost += (int) (round($pricePerDay * $discount * $diffInDays, 0)); | |||||
$fee += (int) (round($feePerDay * $diffInDays, 0)); | |||||
$profit = $cost - $fee; | |||||
if ($profit != 0 && $owner->tenant && ($wallet = $owner->tenant->wallet())) { | |||||
$desc = "Charged user {$owner->email}"; | |||||
$method = $profit > 0 ? 'credit' : 'debit'; | |||||
$wallet->{$method}(abs($profit), $desc); | |||||
} | |||||
if ($cost == 0) { | |||||
return; | |||||
} | |||||
// FIXME: Shouldn't we create per-entitlement transaction record? | |||||
$entitlement->wallet->debit($cost); | |||||
} | } | ||||
} | } |