Andrew Wallo 1 år sedan
förälder
incheckning
f511f7bd0e

+ 0
- 16
app/DTO/ReportDatesDTO.php Visa fil

@@ -1,16 +0,0 @@
1
-<?php
2
-
3
-namespace App\DTO;
4
-
5
-use Illuminate\Support\Carbon;
6
-
7
-class ReportDatesDTO
8
-{
9
-    public function __construct(
10
-        public Carbon $fiscalYearStartDate,
11
-        public Carbon $fiscalYearEndDate,
12
-        public string $defaultDateRange,
13
-        public Carbon $defaultStartDate,
14
-        public Carbon $defaultEndDate,
15
-    ) {}
16
-}

+ 47
- 12
app/Factories/ReportDateFactory.php Visa fil

@@ -2,27 +2,62 @@
2 2
 
3 3
 namespace App\Factories;
4 4
 
5
-use App\DTO\ReportDatesDTO;
6 5
 use App\Models\Company;
7 6
 use Illuminate\Support\Carbon;
8 7
 
9 8
 class ReportDateFactory
10 9
 {
11
-    public static function create(Company $company): ReportDatesDTO
10
+    public Carbon $fiscalYearStartDate;
11
+
12
+    public Carbon $fiscalYearEndDate;
13
+
14
+    public string $defaultDateRange;
15
+
16
+    public Carbon $defaultStartDate;
17
+
18
+    public Carbon $defaultEndDate;
19
+
20
+    public Carbon $earliestTransactionDate;
21
+
22
+    protected Company $company;
23
+
24
+    public function __construct(Company $company)
25
+    {
26
+        $this->company = $company;
27
+        $this->buildReportDates();
28
+    }
29
+
30
+    protected function buildReportDates(): void
12 31
     {
13
-        $fiscalYearStartDate = Carbon::parse($company->locale->fiscalYearStartDate())->startOfDay();
14
-        $fiscalYearEndDate = Carbon::parse($company->locale->fiscalYearEndDate())->endOfDay();
32
+        $fiscalYearStartDate = Carbon::parse($this->company->locale->fiscalYearStartDate())->startOfDay();
33
+        $fiscalYearEndDate = Carbon::parse($this->company->locale->fiscalYearEndDate())->endOfDay();
15 34
         $defaultDateRange = 'FY-' . now()->year;
16 35
         $defaultStartDate = $fiscalYearStartDate->startOfDay();
17 36
         $defaultEndDate = $fiscalYearEndDate->isFuture() ? now()->endOfDay() : $fiscalYearEndDate->endOfDay();
18 37
 
19
-        // Return a new DTO with the calculated values
20
-        return new ReportDatesDTO(
21
-            $fiscalYearStartDate,
22
-            $fiscalYearEndDate,
23
-            $defaultDateRange,
24
-            $defaultStartDate,
25
-            $defaultEndDate
26
-        );
38
+        // Calculate the earliest transaction date based on the company's transactions
39
+        $earliestTransactionDate = $this->company->transactions()->min('posted_at')
40
+            ? Carbon::parse($this->company->transactions()->min('posted_at'))->startOfDay()
41
+            : $defaultStartDate;
42
+
43
+        // Assign values to properties
44
+        $this->fiscalYearStartDate = $fiscalYearStartDate;
45
+        $this->fiscalYearEndDate = $fiscalYearEndDate;
46
+        $this->defaultDateRange = $defaultDateRange;
47
+        $this->defaultStartDate = $defaultStartDate;
48
+        $this->defaultEndDate = $defaultEndDate;
49
+        $this->earliestTransactionDate = $earliestTransactionDate;
50
+    }
51
+
52
+    public function refresh(): self
53
+    {
54
+        $this->buildReportDates();
55
+
56
+        return $this;
57
+    }
58
+
59
+    public static function create(Company $company): self
60
+    {
61
+        return new static($company);
27 62
     }
28 63
 }

+ 8
- 4
app/Repositories/Accounting/JournalEntryRepository.php Visa fil

@@ -4,6 +4,7 @@ namespace App\Repositories\Accounting;
4 4
 
5 5
 use App\Models\Accounting\Account;
6 6
 use Illuminate\Database\Eloquent\Builder;
7
+use Illuminate\Support\Carbon;
7 8
 
8 9
 class JournalEntryRepository
9 10
 {
@@ -11,13 +12,16 @@ class JournalEntryRepository
11 12
     {
12 13
         $query = $account->journalEntries()->where('type', $type);
13 14
 
15
+        $startDateCarbon = Carbon::parse($startDate)->startOfDay();
16
+        $endDateCarbon = Carbon::parse($endDate)->endOfDay();
17
+
14 18
         if ($startDate && $endDate) {
15
-            $query->whereHas('transaction', static function (Builder $query) use ($startDate, $endDate) {
16
-                $query->whereBetween('posted_at', [$startDate, $endDate]);
19
+            $query->whereHas('transaction', static function (Builder $query) use ($startDateCarbon, $endDateCarbon) {
20
+                $query->whereBetween('posted_at', [$startDateCarbon, $endDateCarbon]);
17 21
             });
18 22
         } elseif ($startDate) {
19
-            $query->whereHas('transaction', static function (Builder $query) use ($startDate) {
20
-                $query->where('posted_at', '<=', $startDate);
23
+            $query->whereHas('transaction', static function (Builder $query) use ($startDateCarbon) {
24
+                $query->where('posted_at', '<=', $startDateCarbon);
21 25
             });
22 26
         }
23 27
 

+ 2
- 3
app/Services/AccountService.php Visa fil

@@ -240,9 +240,8 @@ class AccountService implements AccountHandler
240 240
 
241 241
     public function getEarliestTransactionDate(): string
242 242
     {
243
-        $earliestDate = Transaction::oldest('posted_at')
244
-            ->value('posted_at');
243
+        $earliestDate = Transaction::min('posted_at');
245 244
 
246
-        return $earliestDate ?? now()->toDateString();
245
+        return $earliestDate ?? now()->toDateTimeString();
247 246
     }
248 247
 }

+ 1
- 1
app/Services/ReportService.php Visa fil

@@ -96,7 +96,7 @@ class ReportService
96 96
         return new ReportDTO($accountCategories, $formattedReportTotalBalances, $columns);
97 97
     }
98 98
 
99
-    private function calculateAccountBalances(Account $account, AccountCategory $category): array
99
+    public function calculateAccountBalances(Account $account, AccountCategory $category): array
100 100
     {
101 101
         $balances = [
102 102
             'debit_balance' => $account->total_debit ?? 0,

+ 33
- 33
composer.lock Visa fil

@@ -8,16 +8,16 @@
8 8
     "packages": [
9 9
         {
10 10
             "name": "akaunting/laravel-money",
11
-            "version": "5.2.1",
11
+            "version": "5.2.2",
12 12
             "source": {
13 13
                 "type": "git",
14 14
                 "url": "https://github.com/akaunting/laravel-money.git",
15
-                "reference": "6cc8abb912286c671de5993ffbcd3225588aeace"
15
+                "reference": "d99a9e8e576cac40668d0a5afaf7ea153590aff9"
16 16
             },
17 17
             "dist": {
18 18
                 "type": "zip",
19
-                "url": "https://api.github.com/repos/akaunting/laravel-money/zipball/6cc8abb912286c671de5993ffbcd3225588aeace",
20
-                "reference": "6cc8abb912286c671de5993ffbcd3225588aeace",
19
+                "url": "https://api.github.com/repos/akaunting/laravel-money/zipball/d99a9e8e576cac40668d0a5afaf7ea153590aff9",
20
+                "reference": "d99a9e8e576cac40668d0a5afaf7ea153590aff9",
21 21
                 "shasum": ""
22 22
             },
23 23
             "require": {
@@ -71,9 +71,9 @@
71 71
             ],
72 72
             "support": {
73 73
                 "issues": "https://github.com/akaunting/laravel-money/issues",
74
-                "source": "https://github.com/akaunting/laravel-money/tree/5.2.1"
74
+                "source": "https://github.com/akaunting/laravel-money/tree/5.2.2"
75 75
             },
76
-            "time": "2024-07-23T15:01:26+00:00"
76
+            "time": "2024-09-25T10:06:11+00:00"
77 77
         },
78 78
         {
79 79
             "name": "andrewdwallo/filament-companies",
@@ -497,16 +497,16 @@
497 497
         },
498 498
         {
499 499
             "name": "aws/aws-sdk-php",
500
-            "version": "3.322.4",
500
+            "version": "3.322.5",
501 501
             "source": {
502 502
                 "type": "git",
503 503
                 "url": "https://github.com/aws/aws-sdk-php.git",
504
-                "reference": "f6d2c64cb87d9e70ad99aeaffcd879a412d2ccb5"
504
+                "reference": "968fe51da0854eac0e0aeac6ec8b86856c6bd83e"
505 505
             },
506 506
             "dist": {
507 507
                 "type": "zip",
508
-                "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/f6d2c64cb87d9e70ad99aeaffcd879a412d2ccb5",
509
-                "reference": "f6d2c64cb87d9e70ad99aeaffcd879a412d2ccb5",
508
+                "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/968fe51da0854eac0e0aeac6ec8b86856c6bd83e",
509
+                "reference": "968fe51da0854eac0e0aeac6ec8b86856c6bd83e",
510 510
                 "shasum": ""
511 511
             },
512 512
             "require": {
@@ -589,9 +589,9 @@
589 589
             "support": {
590 590
                 "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80",
591 591
                 "issues": "https://github.com/aws/aws-sdk-php/issues",
592
-                "source": "https://github.com/aws/aws-sdk-php/tree/3.322.4"
592
+                "source": "https://github.com/aws/aws-sdk-php/tree/3.322.5"
593 593
             },
594
-            "time": "2024-09-24T18:10:10+00:00"
594
+            "time": "2024-09-25T18:14:27+00:00"
595 595
         },
596 596
         {
597 597
             "name": "aws/aws-sdk-php-laravel",
@@ -2981,16 +2981,16 @@
2981 2981
         },
2982 2982
         {
2983 2983
             "name": "laravel/framework",
2984
-            "version": "v11.24.0",
2984
+            "version": "v11.24.1",
2985 2985
             "source": {
2986 2986
                 "type": "git",
2987 2987
                 "url": "https://github.com/laravel/framework.git",
2988
-                "reference": "557da2b02e298acbd12b3fb7d04d16ea253c5f20"
2988
+                "reference": "e063fa80ac5818099f45a3a57dd803476c8f3a2a"
2989 2989
             },
2990 2990
             "dist": {
2991 2991
                 "type": "zip",
2992
-                "url": "https://api.github.com/repos/laravel/framework/zipball/557da2b02e298acbd12b3fb7d04d16ea253c5f20",
2993
-                "reference": "557da2b02e298acbd12b3fb7d04d16ea253c5f20",
2992
+                "url": "https://api.github.com/repos/laravel/framework/zipball/e063fa80ac5818099f45a3a57dd803476c8f3a2a",
2993
+                "reference": "e063fa80ac5818099f45a3a57dd803476c8f3a2a",
2994 2994
                 "shasum": ""
2995 2995
             },
2996 2996
             "require": {
@@ -3186,7 +3186,7 @@
3186 3186
                 "issues": "https://github.com/laravel/framework/issues",
3187 3187
                 "source": "https://github.com/laravel/framework"
3188 3188
             },
3189
-            "time": "2024-09-24T14:46:11+00:00"
3189
+            "time": "2024-09-25T07:21:24+00:00"
3190 3190
         },
3191 3191
         {
3192 3192
             "name": "laravel/prompts",
@@ -9450,26 +9450,26 @@
9450 9450
         },
9451 9451
         {
9452 9452
             "name": "filp/whoops",
9453
-            "version": "2.15.4",
9453
+            "version": "2.16.0",
9454 9454
             "source": {
9455 9455
                 "type": "git",
9456 9456
                 "url": "https://github.com/filp/whoops.git",
9457
-                "reference": "a139776fa3f5985a50b509f2a02ff0f709d2a546"
9457
+                "reference": "befcdc0e5dce67252aa6322d82424be928214fa2"
9458 9458
             },
9459 9459
             "dist": {
9460 9460
                 "type": "zip",
9461
-                "url": "https://api.github.com/repos/filp/whoops/zipball/a139776fa3f5985a50b509f2a02ff0f709d2a546",
9462
-                "reference": "a139776fa3f5985a50b509f2a02ff0f709d2a546",
9461
+                "url": "https://api.github.com/repos/filp/whoops/zipball/befcdc0e5dce67252aa6322d82424be928214fa2",
9462
+                "reference": "befcdc0e5dce67252aa6322d82424be928214fa2",
9463 9463
                 "shasum": ""
9464 9464
             },
9465 9465
             "require": {
9466
-                "php": "^5.5.9 || ^7.0 || ^8.0",
9466
+                "php": "^7.1 || ^8.0",
9467 9467
                 "psr/log": "^1.0.1 || ^2.0 || ^3.0"
9468 9468
             },
9469 9469
             "require-dev": {
9470
-                "mockery/mockery": "^0.9 || ^1.0",
9471
-                "phpunit/phpunit": "^4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.3",
9472
-                "symfony/var-dumper": "^2.6 || ^3.0 || ^4.0 || ^5.0"
9470
+                "mockery/mockery": "^1.0",
9471
+                "phpunit/phpunit": "^7.5.20 || ^8.5.8 || ^9.3.3",
9472
+                "symfony/var-dumper": "^4.0 || ^5.0"
9473 9473
             },
9474 9474
             "suggest": {
9475 9475
                 "symfony/var-dumper": "Pretty print complex values better with var-dumper available",
@@ -9509,7 +9509,7 @@
9509 9509
             ],
9510 9510
             "support": {
9511 9511
                 "issues": "https://github.com/filp/whoops/issues",
9512
-                "source": "https://github.com/filp/whoops/tree/2.15.4"
9512
+                "source": "https://github.com/filp/whoops/tree/2.16.0"
9513 9513
             },
9514 9514
             "funding": [
9515 9515
                 {
@@ -9517,7 +9517,7 @@
9517 9517
                     "type": "github"
9518 9518
                 }
9519 9519
             ],
9520
-            "time": "2023-11-03T12:00:00+00:00"
9520
+            "time": "2024-09-25T12:00:00+00:00"
9521 9521
         },
9522 9522
         {
9523 9523
             "name": "hamcrest/hamcrest-php",
@@ -10000,16 +10000,16 @@
10000 10000
         },
10001 10001
         {
10002 10002
             "name": "pestphp/pest",
10003
-            "version": "v3.2.2",
10003
+            "version": "v3.2.3",
10004 10004
             "source": {
10005 10005
                 "type": "git",
10006 10006
                 "url": "https://github.com/pestphp/pest.git",
10007
-                "reference": "989e43d1a01e5a3b5333cffe5c8e633ac4d17da2"
10007
+                "reference": "4e2987d438a3c3b2f291d2c991049544ab2f52bb"
10008 10008
             },
10009 10009
             "dist": {
10010 10010
                 "type": "zip",
10011
-                "url": "https://api.github.com/repos/pestphp/pest/zipball/989e43d1a01e5a3b5333cffe5c8e633ac4d17da2",
10012
-                "reference": "989e43d1a01e5a3b5333cffe5c8e633ac4d17da2",
10011
+                "url": "https://api.github.com/repos/pestphp/pest/zipball/4e2987d438a3c3b2f291d2c991049544ab2f52bb",
10012
+                "reference": "4e2987d438a3c3b2f291d2c991049544ab2f52bb",
10013 10013
                 "shasum": ""
10014 10014
             },
10015 10015
             "require": {
@@ -10095,7 +10095,7 @@
10095 10095
             ],
10096 10096
             "support": {
10097 10097
                 "issues": "https://github.com/pestphp/pest/issues",
10098
-                "source": "https://github.com/pestphp/pest/tree/v3.2.2"
10098
+                "source": "https://github.com/pestphp/pest/tree/v3.2.3"
10099 10099
             },
10100 10100
             "funding": [
10101 10101
                 {
@@ -10107,7 +10107,7 @@
10107 10107
                     "type": "github"
10108 10108
                 }
10109 10109
             ],
10110
-            "time": "2024-09-24T09:23:43+00:00"
10110
+            "time": "2024-09-25T15:19:39+00:00"
10111 10111
         },
10112 10112
         {
10113 10113
             "name": "pestphp/pest-plugin",

+ 14
- 14
package-lock.json Visa fil

@@ -955,9 +955,9 @@
955 955
             }
956 956
         },
957 957
         "node_modules/browserslist": {
958
-            "version": "4.23.3",
959
-            "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz",
960
-            "integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==",
958
+            "version": "4.24.0",
959
+            "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.0.tgz",
960
+            "integrity": "sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==",
961 961
             "dev": true,
962 962
             "funding": [
963 963
                 {
@@ -975,8 +975,8 @@
975 975
             ],
976 976
             "license": "MIT",
977 977
             "dependencies": {
978
-                "caniuse-lite": "^1.0.30001646",
979
-                "electron-to-chromium": "^1.5.4",
978
+                "caniuse-lite": "^1.0.30001663",
979
+                "electron-to-chromium": "^1.5.28",
980 980
                 "node-releases": "^2.0.18",
981 981
                 "update-browserslist-db": "^1.1.0"
982 982
             },
@@ -998,9 +998,9 @@
998 998
             }
999 999
         },
1000 1000
         "node_modules/caniuse-lite": {
1001
-            "version": "1.0.30001663",
1002
-            "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001663.tgz",
1003
-            "integrity": "sha512-o9C3X27GLKbLeTYZ6HBOLU1tsAcBZsLis28wrVzddShCS16RujjHp9GDHKZqrB3meE0YjhawvMFsGb/igqiPzA==",
1001
+            "version": "1.0.30001664",
1002
+            "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001664.tgz",
1003
+            "integrity": "sha512-AmE7k4dXiNKQipgn7a2xg558IRqPN3jMQY/rOsbxDhrd0tyChwbITBfiwtnqz8bi2M5mIWbxAYBvk7W7QBUS2g==",
1004 1004
             "dev": true,
1005 1005
             "funding": [
1006 1006
                 {
@@ -1159,9 +1159,9 @@
1159 1159
             "license": "MIT"
1160 1160
         },
1161 1161
         "node_modules/electron-to-chromium": {
1162
-            "version": "1.5.28",
1163
-            "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.28.tgz",
1164
-            "integrity": "sha512-VufdJl+rzaKZoYVUijN13QcXVF5dWPZANeFTLNy+OSpHdDL5ynXTF35+60RSBbaQYB1ae723lQXHCrf4pyLsMw==",
1162
+            "version": "1.5.29",
1163
+            "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.29.tgz",
1164
+            "integrity": "sha512-PF8n2AlIhCKXQ+gTpiJi0VhcHDb69kYX4MtCiivctc2QD3XuNZ/XIOlbGzt7WAjjEev0TtaH6Cu3arZExm5DOw==",
1165 1165
             "dev": true,
1166 1166
             "license": "ISC"
1167 1167
         },
@@ -2550,9 +2550,9 @@
2550 2550
             "license": "MIT"
2551 2551
         },
2552 2552
         "node_modules/vite": {
2553
-            "version": "5.4.7",
2554
-            "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.7.tgz",
2555
-            "integrity": "sha512-5l2zxqMEPVENgvzTuBpHer2awaetimj2BGkhBPdnwKbPNOlHsODU+oiazEZzLK7KhAnOrO+XGYJYn4ZlUhDtDQ==",
2553
+            "version": "5.4.8",
2554
+            "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.8.tgz",
2555
+            "integrity": "sha512-FqrItQ4DT1NC4zCUqMB4c4AZORMKIa0m8/URVCZ77OZ/QSNeJ54bU1vrFADbDsuwfIPcgknRkmqakQcgnL4GiQ==",
2556 2556
             "dev": true,
2557 2557
             "license": "MIT",
2558 2558
             "dependencies": {

+ 59
- 12
tests/Feature/Reports/AccountBalancesReportTest.php Visa fil

@@ -7,20 +7,19 @@ use App\Models\Accounting\Transaction;
7 7
 
8 8
 use function Pest\Livewire\livewire;
9 9
 
10
-it('correctly builds a account balances report', function () {
10
+it('correctly builds an account balances report for the current fiscal year', function () {
11 11
     $testCompany = $this->testCompany;
12 12
 
13
-    $reportDatesDTO = ReportDateFactory::create($testCompany);
14
-    $defaultDateRange = $reportDatesDTO->defaultDateRange;
15
-    $defaultStartDate = $reportDatesDTO->defaultStartDate->toImmutable();
16
-    $defaultEndDate = $reportDatesDTO->defaultEndDate->toImmutable();
13
+    $reportDates = ReportDateFactory::create($testCompany);
14
+    $defaultDateRange = $reportDates->defaultDateRange;
15
+    $defaultStartDate = $reportDates->defaultStartDate->toImmutable();
16
+    $defaultEndDate = $reportDates->defaultEndDate->toImmutable();
17 17
 
18 18
     $depositAmount = 1000;
19 19
     $withdrawalAmount = 1000;
20 20
     $depositCount = 10;
21 21
     $withdrawalCount = 10;
22 22
 
23
-    // Create transactions for the company
24 23
     Transaction::factory()
25 24
         ->forDefaultBankAccount()
26 25
         ->forUncategorizedRevenue()
@@ -41,11 +40,16 @@ it('correctly builds a account balances report', function () {
41 40
         ])
42 41
         ->create();
43 42
 
44
-    $defaultBankAccount = $testCompany->default->bankAccount->account;
43
+    $defaultBankAccountAccount = $testCompany->default->bankAccount->account;
45 44
 
46
-    $fields = $defaultBankAccount->category->getRelevantBalanceFields();
45
+    $fields = $defaultBankAccountAccount->category->getRelevantBalanceFields();
47 46
 
48
-    $expectedBalances = Accounting::getBalances($defaultBankAccount, $defaultStartDate->toDateString(), $defaultEndDate->toDateString(), $fields);
47
+    $expectedBalances = Accounting::getBalances(
48
+        $defaultBankAccountAccount,
49
+        $defaultStartDate->toDateString(),
50
+        $defaultEndDate->toDateString(),
51
+        $fields
52
+    );
49 53
 
50 54
     $formattedExpectedBalances = formatReportBalances($expectedBalances);
51 55
 
@@ -62,7 +66,7 @@ it('correctly builds a account balances report', function () {
62 66
         ])
63 67
         ->call('applyFilters')
64 68
         ->assertSeeTextInOrder([
65
-            'Cash on Hand',
69
+            $defaultBankAccountAccount->name,
66 70
             $formattedExpectedBalances->startingBalance,
67 71
             $formattedExpectedBalances->debitBalance,
68 72
             $formattedExpectedBalances->creditBalance,
@@ -70,8 +74,51 @@ it('correctly builds a account balances report', function () {
70 74
             $formattedExpectedBalances->endingBalance,
71 75
         ])
72 76
         ->assertReportTableData();
77
+});
78
+
79
+it('correctly builds an account balances report for the previous fiscal year', function () {
80
+    $testCompany = $this->testCompany;
81
+
82
+    $reportDatesDTO = ReportDateFactory::create($testCompany);
83
+    $defaultDateRange = $reportDatesDTO->defaultDateRange;
84
+    $defaultStartDate = $reportDatesDTO->defaultStartDate->toImmutable();
85
+    $defaultEndDate = $reportDatesDTO->defaultEndDate->toImmutable();
86
+
87
+    $depositAmount = 1000;
88
+    $withdrawalAmount = 1000;
89
+    $depositCount = 10;
90
+    $withdrawalCount = 10;
91
+
92
+    Transaction::factory()
93
+        ->forDefaultBankAccount()
94
+        ->forUncategorizedRevenue()
95
+        ->asDeposit($depositAmount)
96
+        ->count($depositCount)
97
+        ->state([
98
+            'posted_at' => $defaultStartDate->subWeek(),
99
+        ])
100
+        ->create();
101
+
102
+    Transaction::factory()
103
+        ->forDefaultBankAccount()
104
+        ->forUncategorizedExpense()
105
+        ->asWithdrawal($withdrawalAmount)
106
+        ->count($withdrawalCount)
107
+        ->state([
108
+            'posted_at' => $defaultEndDate,
109
+        ])
110
+        ->create();
111
+
112
+    $defaultBankAccountAccount = $testCompany->default->bankAccount->account;
113
+
114
+    $fields = $defaultBankAccountAccount->category->getRelevantBalanceFields();
73 115
 
74
-    $expectedBalancesSubYear = Accounting::getBalances($defaultBankAccount, $defaultStartDate->subYear()->startOfYear()->toDateString(), $defaultEndDate->subYear()->endOfYear()->toDateString(), $fields);
116
+    $expectedBalancesSubYear = Accounting::getBalances(
117
+        $defaultBankAccountAccount,
118
+        $defaultStartDate->subYear()->startOfYear()->toDateString(),
119
+        $defaultEndDate->subYear()->endOfYear()->toDateString(),
120
+        $fields
121
+    );
75 122
 
76 123
     $formattedExpectedBalancesSubYear = formatReportBalances($expectedBalancesSubYear);
77 124
 
@@ -92,7 +139,7 @@ it('correctly builds a account balances report', function () {
92 139
         ])
93 140
         ->call('applyFilters')
94 141
         ->assertSeeTextInOrder([
95
-            'Cash on Hand',
142
+            $defaultBankAccountAccount->name,
96 143
             $formattedExpectedBalancesSubYear->startingBalance,
97 144
             $formattedExpectedBalancesSubYear->debitBalance,
98 145
             $formattedExpectedBalancesSubYear->creditBalance,

+ 86
- 38
tests/Feature/Reports/TrialBalanceReportTest.php Visa fil

@@ -1,33 +1,64 @@
1 1
 <?php
2 2
 
3
+use App\Facades\Accounting;
3 4
 use App\Factories\ReportDateFactory;
4 5
 use App\Filament\Company\Pages\Reports\TrialBalance;
5 6
 use App\Models\Accounting\Transaction;
6
-use App\Utilities\Currency\CurrencyAccessor;
7
+use App\Services\AccountService;
8
+use App\Services\ReportService;
7 9
 
8 10
 use function Pest\Livewire\livewire;
9 11
 
10 12
 it('correctly builds a standard trial balance report', function () {
11 13
     $testCompany = $this->testCompany;
12 14
 
13
-    $reportDatesDTO = ReportDateFactory::create($testCompany);
14
-    $defaultDateRange = $reportDatesDTO->defaultDateRange;
15
-    $defaultEndDate = $reportDatesDTO->defaultEndDate;
15
+    $reportDates = ReportDateFactory::create($testCompany);
16
+    $defaultDateRange = $reportDates->defaultDateRange;
17
+    $defaultStartDate = $reportDates->defaultStartDate->toImmutable();
18
+    $defaultEndDate = $reportDates->defaultEndDate->toImmutable();
16 19
 
17 20
     $defaultReportType = 'standard';
18 21
 
19
-    // Create transactions for the company
22
+    $depositAmount = 1000;
23
+    $withdrawalAmount = 1000;
24
+    $depositCount = 10;
25
+    $withdrawalCount = 10;
26
+
20 27
     Transaction::factory()
21 28
         ->forDefaultBankAccount()
22 29
         ->forUncategorizedRevenue()
23
-        ->asDeposit(1000)
24
-        ->count(10)
30
+        ->asDeposit($depositAmount)
31
+        ->count($depositCount)
32
+        ->state([
33
+            'posted_at' => $defaultStartDate->subWeek(),
34
+        ])
35
+        ->create();
36
+
37
+    Transaction::factory()
38
+        ->forDefaultBankAccount()
39
+        ->forUncategorizedExpense()
40
+        ->asWithdrawal($withdrawalAmount)
41
+        ->count($withdrawalCount)
42
+        ->state([
43
+            'posted_at' => now()->subWeek(),
44
+        ])
25 45
         ->create();
26 46
 
27
-    $expectedBankAccountDebit = 10000;
28
-    $expectedBankAccountCredit = 0;
47
+    $defaultBankAccountAccount = $testCompany->default->bankAccount->account;
48
+    $earliestTransactionDate = $reportDates->refresh()->earliestTransactionDate;
49
+
50
+    $fields = $defaultBankAccountAccount->category->getRelevantBalanceFields();
51
+
52
+    $expectedBalances = Accounting::getBalances(
53
+        $defaultBankAccountAccount,
54
+        $earliestTransactionDate->toDateString(),
55
+        $defaultEndDate->toDateString(),
56
+        $fields
57
+    );
58
+
59
+    $calculatedTrialBalances = calculateTrialBalances($defaultBankAccountAccount->category, $expectedBalances['ending_balance']);
29 60
 
30
-    $defaultCurrencyCode = CurrencyAccessor::getDefaultCurrency();
61
+    $formattedExpectedBalances = formatReportBalances($calculatedTrialBalances);
31 62
 
32 63
     livewire(TrialBalance::class)
33 64
         ->assertFormSet([
@@ -43,9 +74,9 @@ it('correctly builds a standard trial balance report', function () {
43 74
         ->call('applyFilters')
44 75
         ->assertDontSeeText('Retained Earnings')
45 76
         ->assertSeeTextInOrder([
46
-            'Cash on Hand',
47
-            money($expectedBankAccountDebit, $defaultCurrencyCode, true),
48
-            money($expectedBankAccountCredit, $defaultCurrencyCode, true),
77
+            $defaultBankAccountAccount->name,
78
+            $formattedExpectedBalances->debitBalance,
79
+            $formattedExpectedBalances->creditBalance,
49 80
         ])
50 81
         ->assertReportTableData();
51 82
 });
@@ -53,59 +84,76 @@ it('correctly builds a standard trial balance report', function () {
53 84
 it('correctly builds a post-closing trial balance report', function () {
54 85
     $testCompany = $this->testCompany;
55 86
 
56
-    $reportDatesDTO = ReportDateFactory::create($testCompany);
57
-    $defaultDateRange = $reportDatesDTO->defaultDateRange;
58
-    $defaultEndDate = $reportDatesDTO->defaultEndDate;
87
+    $reportDates = ReportDateFactory::create($testCompany);
88
+    $defaultDateRange = $reportDates->defaultDateRange;
89
+    $defaultStartDate = $reportDates->defaultStartDate->toImmutable();
90
+    $defaultEndDate = $reportDates->defaultEndDate->toImmutable();
59 91
 
60 92
     $defaultReportType = 'postClosing';
61 93
 
62
-    // Create transactions for the company
94
+    $depositAmount = 2000;
95
+    $withdrawalAmount = 1000;
96
+    $depositCount = 5;
97
+    $withdrawalCount = 5;
98
+
63 99
     Transaction::factory()
64 100
         ->forDefaultBankAccount()
65 101
         ->forUncategorizedRevenue()
66
-        ->asDeposit(1000)
102
+        ->asDeposit($depositAmount)
103
+        ->count($depositCount)
104
+        ->state([
105
+            'posted_at' => $defaultStartDate->subWeek(),
106
+        ])
67 107
         ->create();
68 108
 
69 109
     Transaction::factory()
70 110
         ->forDefaultBankAccount()
71 111
         ->forUncategorizedExpense()
72
-        ->asWithdrawal(500)
112
+        ->asWithdrawal($withdrawalAmount)
113
+        ->count($withdrawalCount)
114
+        ->state([
115
+            'posted_at' => now()->subWeek(),
116
+        ])
73 117
         ->create();
74 118
 
75
-    $expectedRetainedEarningsDebit = 0;
76
-    $expectedRetainedEarningsCredit = 500;
119
+    $defaultBankAccountAccount = $testCompany->default->bankAccount->account;
120
+    $earliestTransactionDate = $reportDates->refresh()->earliestTransactionDate->toImmutable();
77 121
 
78
-    $defaultCurrencyCode = CurrencyAccessor::getDefaultCurrency();
122
+    $fields = $defaultBankAccountAccount->category->getRelevantBalanceFields();
79 123
 
124
+    $accountService = app(AccountService::class);
125
+
126
+    $balances = $accountService->getAccountBalances($earliestTransactionDate->toDateTimeString(), $defaultEndDate->toDateTimeString(), [$defaultBankAccountAccount->id]);
127
+
128
+    $account = $balances->find($defaultBankAccountAccount->id);
129
+
130
+    $reportService = app(ReportService::class);
131
+
132
+    $calculatedBalances = $reportService->calculateAccountBalances($account, $account->category);
133
+
134
+    $calculatedTrialBalances = calculateTrialBalances($defaultBankAccountAccount->category, $calculatedBalances['ending_balance']);
135
+
136
+    $formattedExpectedBalances = formatReportBalances($calculatedTrialBalances);
137
+
138
+    // Use Livewire to assert the report's filters and displayed data
80 139
     livewire(TrialBalance::class)
81 140
         ->set('deferredFilters.reportType', $defaultReportType)
82
-        ->call('applyFilters')
83 141
         ->assertFormSet([
84 142
             'deferredFilters.reportType' => $defaultReportType,
85 143
             'deferredFilters.dateRange' => $defaultDateRange,
86 144
             'deferredFilters.asOfDate' => $defaultEndDate->toDateTimeString(),
87 145
         ])
146
+        ->call('applyFilters')
88 147
         ->assertSet('filters', [
89 148
             'reportType' => $defaultReportType,
90 149
             'dateRange' => $defaultDateRange,
91 150
             'asOfDate' => $defaultEndDate->toDateString(),
92 151
         ])
93
-        ->call('applyFilters')
94
-        ->assertSeeTextInOrder([
95
-            'RE',
96
-            'Retained Earnings',
97
-            money($expectedRetainedEarningsDebit, $defaultCurrencyCode, true),
98
-            money($expectedRetainedEarningsCredit, $defaultCurrencyCode, true),
99
-        ])
100
-        ->assertSeeTextInOrder([
101
-            'Total Revenue',
102
-            money(0, $defaultCurrencyCode, true),
103
-            money(0, $defaultCurrencyCode, true),
104
-        ])
152
+        ->assertSeeText('Retained Earnings')
105 153
         ->assertSeeTextInOrder([
106
-            'Total Expenses',
107
-            money(0, $defaultCurrencyCode, true),
108
-            money(0, $defaultCurrencyCode, true),
154
+            $defaultBankAccountAccount->name,
155
+            $formattedExpectedBalances->debitBalance,
156
+            $formattedExpectedBalances->creditBalance,
109 157
         ])
110 158
         ->assertReportTableData();
111 159
 });

+ 8
- 0
tests/Helpers/helpers.php Visa fil

@@ -1,6 +1,7 @@
1 1
 <?php
2 2
 
3 3
 use App\DTO\AccountBalanceDTO;
4
+use App\Enums\Accounting\AccountCategory;
4 5
 use App\Enums\Setting\EntityType;
5 6
 use App\Filament\Company\Pages\CreateCompany;
6 7
 use App\Models\Company;
@@ -45,3 +46,10 @@ function formatReportBalances(array $balances): AccountBalanceDTO
45 46
 
46 47
     return $reportService->formatBalances($balances);
47 48
 }
49
+
50
+function calculateTrialBalances(AccountCategory $accountCategory, int $endingBalance): array
51
+{
52
+    $reportService = app(ReportService::class);
53
+
54
+    return $reportService->calculateTrialBalance($accountCategory, $endingBalance);
55
+}

Laddar…
Avbryt
Spara