diff --git a/src/app/Console/Commands/WalletCharge.php b/src/app/Console/Commands/WalletCharge.php --- a/src/app/Console/Commands/WalletCharge.php +++ b/src/app/Console/Commands/WalletCharge.php @@ -52,11 +52,6 @@ ); $wallet->chargeEntitlements(); - - if ($wallet->balance < 0) { - // Disabled for now - // \App\Jobs\WalletPayment::dispatch($wallet); - } } } } diff --git a/src/app/Console/Commands/WalletUntil.php b/src/app/Console/Commands/WalletUntil.php new file mode 100644 --- /dev/null +++ b/src/app/Console/Commands/WalletUntil.php @@ -0,0 +1,91 @@ +argument('wallet')); + + if (!$wallet) { + return 1; + } + + $balance = $wallet->balance; + + $discount = $wallet->getDiscountRate(); + + $costs = 0; + + $fromDate = \Carbon\Carbon::now()->subMonthsWithoutOverflow(6); + $toDate = \Carbon\Carbon::now()->subMonthsWithoutOverflow(6); + + $entitlements = \App\Entitlement::where('wallet_id', $wallet->id)->orderBy('updated_at'); + + foreach ($entitlements as $entitlement) { + if ($entitlement->cost == 0) { + continue; + } + + if ($entitlement->created_at > $fromDate) { + $fromDate = $entitlement->created_at->copy(); + } + + if ($entitlement->updated_at > $toDate) { + $toDate = $entitlement->updated_at->copy(); + } + } + + foreach ($entitlements->get() as $entitlement) { + if ($entitlement->cost == 0) { + continue; + } + + $newToDate = $entitlement->updated_at->copy()->addMonthsWithoutOverflow(1); + + $cost = $discount * $entitlement->cost; + $costs += $cost; + + if ($balance >= $cost) { + $balance -= $cost; + if ($newToDate > $toDate) { + $toDate = $newToDate; + } + } + } + + $this->info("{$wallet->balance} lasts until {$toDate} (a month costs {$costs})"); + } +} diff --git a/src/app/Entitlement.php b/src/app/Entitlement.php --- a/src/app/Entitlement.php +++ b/src/app/Entitlement.php @@ -52,6 +52,26 @@ 'cost' => 'integer', ]; + /** + * Return the costs per day for this entitlement. + * + * @return float + */ + public function costsPerDay() + { + if ($this->cost == 0) { + return (float) 0; + } + + $discount = $this->wallet->getDiscountRate(); + + $daysInLastMonth = \App\Utils::daysInLastMonth(); + + $costsPerDay = (float) ($this->cost * $discount) / $daysInLastMonth; + + return $costsPerDay; + } + /** * Create a transaction record for this entitlement. * diff --git a/src/app/Utils.php b/src/app/Utils.php --- a/src/app/Utils.php +++ b/src/app/Utils.php @@ -24,7 +24,7 @@ $start = new Carbon('first day of last month'); $end = new Carbon('last day of last month'); - return $start->diffInDays($end); + return $start->diffInDays($end) + 1; } /** diff --git a/src/tests/Feature/EntitlementTest.php b/src/tests/Feature/EntitlementTest.php --- a/src/tests/Feature/EntitlementTest.php +++ b/src/tests/Feature/EntitlementTest.php @@ -32,6 +32,25 @@ parent::tearDown(); } + public function testCostsPerDay(): void + { + // 444 + // 28 days: 15.86 + // 31 days: 14.32 + $user = $this->getTestUser('entitlement-test@kolabnow.com'); + $package = Package::where('title', 'kolab')->first(); + $mailbox = Sku::where('title', 'mailbox')->first(); + + $user->assignPackage($package); + + $entitlement = $user->entitlements->where('sku_id', $mailbox->id)->first(); + + $costsPerDay = $entitlement->costsPerDay(); + + $this->assertTrue($costsPerDay < 15.86); + $this->assertTrue($costsPerDay > 14.32); + } + /** * Tests for User::AddEntitlement() */