diff --git a/app/src/Service/Limit/LimitService.php b/app/src/Service/Limit/LimitService.php index aa52cf9..061676d 100644 --- a/app/src/Service/Limit/LimitService.php +++ b/app/src/Service/Limit/LimitService.php @@ -31,12 +31,27 @@ public function calculate(array $limits): array // TODO. Aggregate all limits using 1 query foreach ($limits as $limit) { - $amount = $this->chargeRepository->totalByWalletPKAndTagPKs( + $tagIds = array_map(fn (Tag $tag) => (int) $tag->id, $limit->getTags()); + + $limitAmount = $this->chargeRepository->totalByWalletPKAndTagPKs( $limit->walletId, - array_map(fn (Tag $tag) => (int) $tag->id, $limit->getTags()), + $tagIds, $limit->type ); + // calculate total for opposite limit type to get the correction amount + $correctionAmount = $this->chargeRepository->totalByWalletPKAndTagPKs( + $limit->walletId, + $tagIds, + $limit->type == Limit::TYPE_INCOME ? Limit::TYPE_EXPENSE : Limit::TYPE_INCOME, + ); + + $amount = 0; + + if ($correctionAmount < $limitAmount) { + $amount = round($limitAmount - $correctionAmount, 2); + } + $list[] = new WalletLimit($limit, $amount); } diff --git a/tests/Feature/Controller/Wallets/Limits/LimitsControllerTest.php b/tests/Feature/Controller/Wallets/Limits/LimitsControllerTest.php index 8c64871..53d1681 100644 --- a/tests/Feature/Controller/Wallets/Limits/LimitsControllerTest.php +++ b/tests/Feature/Controller/Wallets/Limits/LimitsControllerTest.php @@ -110,21 +110,35 @@ public function testListReturnLimits(): void $chargesWithTwoTags = $this->chargeFactory->forUser($user)->forWallet($wallet)->withTags($tags->toArray())->createMany(4); $chargesTotal = 0; + $chargesCorrectionTotal = 0; foreach ($charges as $charge) { /** @var \App\Database\Charge $charge */ if ($limit->type === $charge->type) { $chargesTotal += $charge->amount; + } else { + $chargesCorrectionTotal += $charge->amount; } } - $chargesTotal = round($chargesTotal, 2); + if ($chargesCorrectionTotal >= $chargesTotal) { + $chargesTotal = 0.0; + } else { + $chargesTotal = round($chargesTotal - $chargesCorrectionTotal, 2); + } $chargesWithTwoTagsTotal = 0; + $chargesWithTwoTagsCorrectionTotal = 0; foreach ($chargesWithTwoTags as $charge) { if ($limitWithTwoTags->type === $charge->type) { $chargesWithTwoTagsTotal += $charge->amount; + } else { + $chargesWithTwoTagsCorrectionTotal += $charge->amount; } } - $chargesWithTwoTagsTotal = round($chargesWithTwoTagsTotal, 2); + if ($chargesWithTwoTagsCorrectionTotal >= $chargesWithTwoTagsTotal) { + $chargesWithTwoTagsTotal = 0; + } else { + $chargesWithTwoTagsTotal = round($chargesWithTwoTagsTotal - $chargesWithTwoTagsCorrectionTotal, 2); + } $response = $this->withAuth($auth)->get("/wallets/{$wallet->id}/limits");