From 27753f30ad64def6d539c17291d3256f51071970 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=8Carodej?= Date: Thu, 16 Dec 2021 13:44:36 +0100 Subject: [PATCH] format usage estimates refactoring & test --- .../Actions/FormatUsageEstimatesAction.php | 31 +++++++ src/App/Users/Resources/UserResource.php | 43 ++------- tests/App/Users/UserSubscriptionTest.php | 87 ++++++++++++++----- 3 files changed, 105 insertions(+), 56 deletions(-) create mode 100644 src/App/Users/Actions/FormatUsageEstimatesAction.php diff --git a/src/App/Users/Actions/FormatUsageEstimatesAction.php b/src/App/Users/Actions/FormatUsageEstimatesAction.php new file mode 100644 index 00000000..73f01684 --- /dev/null +++ b/src/App/Users/Actions/FormatUsageEstimatesAction.php @@ -0,0 +1,31 @@ +map(function ($estimate) use ($currency) { + + // Format usage + $usage = match ($estimate['feature']) { + 'bandwidth' => Metric::megabytes($estimate['usage'])->format(), + 'storage' => Metric::megabytes($estimate['usage'])->format(), + }; + + // Normalize units + $amount = $estimate['amount'] / 1000; + + return [ + 'feature' => $estimate['feature'], + 'amount' => $amount, + 'cost' => format_currency($amount, $currency), + 'usage' => $usage, + ]; + }); + } +} \ No newline at end of file diff --git a/src/App/Users/Resources/UserResource.php b/src/App/Users/Resources/UserResource.php index 9632ffb9..efd0b446 100644 --- a/src/App/Users/Resources/UserResource.php +++ b/src/App/Users/Resources/UserResource.php @@ -2,8 +2,10 @@ namespace App\Users\Resources; +use App\Users\Actions\FormatUsageEstimatesAction; use ByteUnits\Metric; use Domain\Folders\Resources\FolderCollection; +use VueFileManager\Subscription\Domain\Usage\Actions\SumUsageForCurrentPeriodAction; use Illuminate\Http\Resources\Json\JsonResource; use VueFileManager\Subscription\Domain\Credits\Resources\BalanceResource; use VueFileManager\Subscription\Domain\Subscriptions\Resources\SubscriptionResource; @@ -61,44 +63,17 @@ class UserResource extends JsonResource private function getUsageEstimates() { - $estimates = $this - ->subscription - ->plan - ->meteredFeatures - ->map(function ($feature) { + // Get plan currency + $currency = $this->subscription->plan->currency; - // Get first tier - $tier = $feature->tiers()->first(); + // Get usage + $usage = resolve(SumUsageForCurrentPeriodAction::class)($this->subscription); - $usageQuery = $this->subscription - ->usages() - ->where('created_at', '>=', now()->subDays(30)) - ->where('subscription_id', $this->subscription->id) - ->where('metered_feature_id', $feature->id); - - $usage = match ($feature->aggregate_strategy) { - 'sum_of_usage' => $usageQuery->sum('quantity'), - 'maximum_usage' => $usageQuery->max('quantity'), - }; - - $amount = ($tier->per_unit / 1000) * $usage; - - $formattedUsage = match ($feature->key) { - 'bandwidth' => Metric::megabytes($usage)->format(), - 'storage' => Metric::megabytes($usage)->format(), - }; - - // return sum of money - return [ - 'feature' => $feature->key, - 'amount' => $amount, - 'cost' => format_currency($amount, $this->subscription->plan->currency), - 'usage' => $formattedUsage, - ]; - }); + // Format usages + $estimates = resolve(FormatUsageEstimatesAction::class)($currency, $usage); return [ - 'costEstimate' => format_currency($estimates->sum('amount'), $this->subscription->plan->currency), + 'costEstimate' => format_currency($estimates->sum('amount'), $currency), 'featureEstimates' => $estimates->toArray(), ]; } diff --git a/tests/App/Users/UserSubscriptionTest.php b/tests/App/Users/UserSubscriptionTest.php index 4e2f165c..0d2e3a0a 100644 --- a/tests/App/Users/UserSubscriptionTest.php +++ b/tests/App/Users/UserSubscriptionTest.php @@ -1,10 +1,14 @@ has(PlanFeature::factory() - ->count(2) - ->sequence( - [ - 'key' => 'max_storage_amount', - 'value' => 200, - ], - [ - 'key' => 'max_team_members', - 'value' => 20, - ], - ), 'features') + ->count(2) + ->sequence( + [ + 'key' => 'max_storage_amount', + 'value' => 200, + ], + [ + 'key' => 'max_team_members', + 'value' => 20, + ], + ), 'features') ->create(); $user = User::factory() @@ -44,6 +48,7 @@ class UserSubscriptionTest extends TestCase 'max_team_members' => 20, ]); } + /** * @test */ @@ -51,17 +56,17 @@ class UserSubscriptionTest extends TestCase { $plan = Plan::factory() ->has(PlanFeature::factory() - ->count(2) - ->sequence( - [ - 'key' => 'max_storage_amount', - 'value' => 200, - ], - [ - 'key' => 'max_team_members', - 'value' => 20, - ], - ), 'features') + ->count(2) + ->sequence( + [ + 'key' => 'max_storage_amount', + 'value' => 200, + ], + [ + 'key' => 'max_team_members', + 'value' => 20, + ], + ), 'features') ->create(); $user = User::factory() @@ -99,4 +104,42 @@ class UserSubscriptionTest extends TestCase 'max_team_members' => 5, ]); } + + /** + * @test + */ + public function it_format_price_estimates() + { + $usages = collect([ + [ + 'feature' => 'bandwidth', + "amount" => 7546.96, + "usage" => 26024, + ], [ + "feature" => "storage", + "amount" => 476.28, + "usage" => 3969, + ] + ]); + + // Format usage estimates + $estimates = resolve(FormatUsageEstimatesAction::class)('USD', $usages) + ->toArray(); + + $expected = [ + [ + "feature" => "bandwidth", + "amount" => 7.54696, + "cost" => "$7.55", + "usage" => "26.02GB", + ], [ + "feature" => "storage", + "amount" => 0.47628, + "cost" => "$0.48", + "usage" => "3.97GB", + ] + ]; + + $this->assertEquals($expected, $estimates); + } }