Page MenuHomePhorge

D1150.1775173862.diff
No OneTemporary

Authored By
Unknown
Size
6 KB
Referenced Files
None
Subscribers
None

D1150.1775173862.diff

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,50 @@
+<?php
+
+namespace App\Console\Commands;
+
+use Illuminate\Console\Command;
+
+class WalletUntil extends Command
+{
+ /**
+ * The name and signature of the console command.
+ *
+ * @var string
+ */
+ protected $signature = 'wallet:until {wallet}';
+
+ /**
+ * The console command description.
+ *
+ * @var string
+ */
+ protected $description = 'Show until when the balance on a wallet lasts.';
+
+ /**
+ * Create a new command instance.
+ *
+ * @return void
+ */
+ public function __construct()
+ {
+ parent::__construct();
+ }
+
+ /**
+ * Execute the console command.
+ *
+ * @return mixed
+ */
+ public function handle()
+ {
+ $wallet = \App\Wallet::find($this->argument('wallet'));
+
+ if (!$wallet) {
+ return 1;
+ }
+
+ $lastsUntil = $wallet->balanceLastsUntil();
+
+ $this->info("Lasts until: {$lastsUntil}");
+ }
+}
diff --git a/src/app/Entitlement.php b/src/app/Entitlement.php
--- a/src/app/Entitlement.php
+++ b/src/app/Entitlement.php
@@ -53,6 +53,26 @@
];
/**
+ * 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.
*
* @param string $type The type of transaction ('created', 'billed', 'deleted'), but use the
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/app/Wallet.php b/src/app/Wallet.php
--- a/src/app/Wallet.php
+++ b/src/app/Wallet.php
@@ -117,6 +117,30 @@
}
/**
+ * Calculate for how long the current balance will last.
+ *
+ * @return \Carbon\Carbon Date
+ */
+ public function balanceLastsUntil()
+ {
+ $balance = $this->balance;
+
+ // retrieve any expected charges
+ $expectedCharge = $this->expectedCharges();
+
+ // get the costs per day for all entitlements billed against this wallet
+ $costsPerDay = $this->costsPerDay();
+
+ // the number of days this balance, minus the expected charges, would last
+ $daysDelta = ($balance - $expectedCharge) / $costsPerDay;
+
+ // calculate from the last entitlement billed
+ $entitlement = $this->entitlements()->orderBy('updated_at', 'desc')->first();
+
+ return $entitlement->updated_at->copy()->addDays($daysDelta);
+ }
+
+ /**
* A helper to display human-readable amount of money using
* the wallet currency and specified locale.
*
@@ -156,6 +180,22 @@
}
/**
+ * Retrieve the costs per day of everything charged to this wallet.
+ *
+ * @return float
+ */
+ public function costsPerDay()
+ {
+ $costs = (float) 0;
+
+ foreach ($this->entitlements as $entitlement) {
+ $costs += $entitlement->costsPerDay();
+ }
+
+ return $costs;
+ }
+
+ /**
* Add an amount of pecunia to this wallet's balance.
*
* @param int $amount The amount of pecunia to add (in cents).
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()
*/
diff --git a/src/tests/Feature/WalletTest.php b/src/tests/Feature/WalletTest.php
--- a/src/tests/Feature/WalletTest.php
+++ b/src/tests/Feature/WalletTest.php
@@ -2,7 +2,9 @@
namespace Tests\Feature;
+use App\Package;
use App\User;
+use App\Sku;
use App\Wallet;
use Tests\TestCase;
use Illuminate\Foundation\Testing\WithFaker;
@@ -20,6 +22,7 @@
'WalletControllerB@WalletController.com',
'WalletController2A@WalletController.com',
'WalletController2B@WalletController.com',
+ 'jane@kolabnow.com'
];
public function setUp(): void
@@ -40,6 +43,44 @@
parent::tearDown();
}
+ public function testBalanceLastsUntil(): void
+ {
+ $user = $this->getTestUser('jane@kolabnow.com');
+ $package = Package::where('title', 'kolab')->first();
+ $mailbox = Sku::where('title', 'mailbox')->first();
+
+ $user->assignPackage($package);
+
+ $wallet = $user->wallets()->first();
+
+ $until = $wallet->balanceLastsUntil();
+
+ // TODO: Test this for typical cases
+ // TODO: Test this for a user with no entitlements
+ // TODO: Test this for a user with 100% discount
+ $this->markTestIncomplete();
+ }
+
+ public function testCostsPerDay(): void
+ {
+ // 999
+ // 28 days: 35.68
+ // 31 days: 32.22
+ $user = $this->getTestUser('jane@kolabnow.com');
+
+ $package = Package::where('title', 'kolab')->first();
+ $mailbox = Sku::where('title', 'mailbox')->first();
+
+ $user->assignPackage($package);
+
+ $wallet = $user->wallets()->first();
+
+ $costsPerDay = $wallet->costsPerDay();
+
+ $this->assertTrue($costsPerDay < 35.68);
+ $this->assertTrue($costsPerDay > 32.22);
+ }
+
/**
* Verify a wallet is created, when a user is created.
*/

File Metadata

Mime Type
text/plain
Expires
Thu, Apr 2, 11:51 PM (1 d, 2 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18816984
Default Alt Text
D1150.1775173862.diff (6 KB)

Event Timeline