您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

TrialBalanceReportTest.php 8.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. <?php
  2. use App\Contracts\ExportableReport;
  3. use App\Enums\Accounting\AccountCategory;
  4. use App\Filament\Company\Pages\Reports\TrialBalance;
  5. use App\Models\Accounting\Transaction;
  6. use App\Services\AccountService;
  7. use App\Services\ReportService;
  8. use Filament\Facades\Filament;
  9. use Illuminate\Support\Carbon;
  10. use function Pest\Livewire\livewire;
  11. it('correctly builds a standard trial balance report', function () {
  12. $testUser = $this->testUser;
  13. $testCompany = $this->testCompany;
  14. $defaultBankAccount = $testCompany->default->bankAccount;
  15. $fiscalYearStartDate = $testCompany->locale->fiscalYearStartDate();
  16. $fiscalYearEndDate = $testCompany->locale->fiscalYearEndDate();
  17. $defaultEndDate = Carbon::parse($fiscalYearEndDate);
  18. $defaultAsOfDate = $defaultEndDate->isFuture() ? now()->endOfDay() : $defaultEndDate->endOfDay();
  19. $defaultDateRange = 'FY-' . now()->year;
  20. $defaultReportType = 'standard';
  21. // Create transactions for the company
  22. Transaction::factory()
  23. ->forCompanyAndBankAccount($testCompany, $defaultBankAccount)
  24. ->count(10)
  25. ->create();
  26. // Instantiate services
  27. $accountService = app(AccountService::class);
  28. $reportService = app(ReportService::class);
  29. // Calculate balances
  30. $asOfStartDate = $accountService->getEarliestTransactionDate();
  31. $netMovement = $accountService->getNetMovement($defaultBankAccount->account, $asOfStartDate, $defaultAsOfDate);
  32. $netMovementAmount = $netMovement->getAmount();
  33. // Verify trial balance calculations
  34. $trialBalance = $reportService->calculateTrialBalance($defaultBankAccount->account->category, $netMovementAmount);
  35. expect($trialBalance)->toMatchArray([
  36. 'debit_balance' => max($netMovementAmount, 0),
  37. 'credit_balance' => $netMovementAmount < 0 ? abs($netMovementAmount) : 0,
  38. ]);
  39. $formattedBalances = $reportService->formatBalances($trialBalance);
  40. $accountCategoryPluralLabels = array_map(fn ($category) => $category->getPluralLabel(), AccountCategory::getOrderedCategories());
  41. Filament::setTenant($testCompany);
  42. $component = livewire(TrialBalance::class)
  43. ->assertFormSet([
  44. 'deferredFilters.reportType' => $defaultReportType,
  45. 'deferredFilters.dateRange' => $defaultDateRange,
  46. 'deferredFilters.asOfDate' => $defaultAsOfDate->toDateTimeString(),
  47. ])
  48. ->assertSet('filters', [
  49. 'reportType' => $defaultReportType,
  50. 'dateRange' => $defaultDateRange,
  51. 'asOfDate' => $defaultAsOfDate->toDateString(),
  52. ])
  53. ->call('applyFilters')
  54. ->assertSeeTextInOrder($accountCategoryPluralLabels)
  55. ->assertDontSeeText('Retained Earnings')
  56. ->assertSeeTextInOrder([
  57. $formattedBalances->debitBalance,
  58. $formattedBalances->creditBalance,
  59. ]);
  60. /** @var ExportableReport $report */
  61. $report = $component->report;
  62. $columnLabels = array_map(static fn ($column) => $column->getLabel(), $report->getColumns());
  63. $component->assertSeeTextInOrder($columnLabels);
  64. $categories = $report->getCategories();
  65. foreach ($categories as $category) {
  66. $header = $category->header;
  67. $data = $category->data;
  68. $summary = $category->summary;
  69. $component->assertSeeTextInOrder($header);
  70. foreach ($data as $row) {
  71. $flatRow = [];
  72. foreach ($row as $value) {
  73. if (is_array($value)) {
  74. $flatRow[] = $value['name'];
  75. } else {
  76. $flatRow[] = $value;
  77. }
  78. }
  79. $component->assertSeeTextInOrder($flatRow);
  80. }
  81. $component->assertSeeTextInOrder($summary);
  82. }
  83. $overallTotals = $report->getOverallTotals();
  84. $component->assertSeeTextInOrder($overallTotals);
  85. });
  86. it('correctly builds a post-closing trial balance report', function () {
  87. $testUser = $this->testUser;
  88. $testCompany = $this->testCompany;
  89. $defaultBankAccount = $testCompany->default->bankAccount;
  90. $fiscalYearStartDate = $testCompany->locale->fiscalYearStartDate();
  91. $fiscalYearEndDate = $testCompany->locale->fiscalYearEndDate();
  92. $defaultEndDate = Carbon::parse($fiscalYearEndDate);
  93. $defaultAsOfDate = $defaultEndDate->isFuture() ? now()->endOfDay() : $defaultEndDate->endOfDay();
  94. $defaultDateRange = 'FY-' . now()->year;
  95. $defaultReportType = 'postClosing';
  96. // Create transactions for the company
  97. Transaction::factory()
  98. ->forCompanyAndBankAccount($testCompany, $defaultBankAccount)
  99. ->count(10)
  100. ->create();
  101. // Instantiate services
  102. $accountService = app(AccountService::class);
  103. $reportService = app(ReportService::class);
  104. // Calculate balances
  105. $asOfStartDate = $accountService->getEarliestTransactionDate();
  106. $netMovement = $accountService->getNetMovement($defaultBankAccount->account, $asOfStartDate, $defaultAsOfDate);
  107. $netMovementAmount = $netMovement->getAmount();
  108. // Verify trial balance calculations
  109. $trialBalance = $reportService->calculateTrialBalance($defaultBankAccount->account->category, $netMovementAmount);
  110. expect($trialBalance)->toMatchArray([
  111. 'debit_balance' => max($netMovementAmount, 0),
  112. 'credit_balance' => $netMovementAmount < 0 ? abs($netMovementAmount) : 0,
  113. ]);
  114. $formattedBalances = $reportService->formatBalances($trialBalance);
  115. $accountCategoryPluralLabels = array_map(fn ($category) => $category->getPluralLabel(), AccountCategory::getOrderedCategories());
  116. $retainedEarningsAmount = $reportService->calculateRetainedEarnings($asOfStartDate, $defaultAsOfDate)->getAmount();
  117. $isCredit = $retainedEarningsAmount >= 0;
  118. $retainedEarningsDebitAmount = $isCredit ? 0 : abs($retainedEarningsAmount);
  119. $retainedEarningsCreditAmount = $isCredit ? $retainedEarningsAmount : 0;
  120. $formattedRetainedEarnings = $reportService->formatBalances([
  121. 'debit_balance' => $retainedEarningsDebitAmount,
  122. 'credit_balance' => $retainedEarningsCreditAmount,
  123. ]);
  124. $retainedEarningsRow = [
  125. 'RE',
  126. 'Retained Earnings',
  127. $formattedRetainedEarnings->debitBalance,
  128. $formattedRetainedEarnings->creditBalance,
  129. ];
  130. Filament::setTenant($testCompany);
  131. $component = livewire(TrialBalance::class)
  132. ->set('deferredFilters.reportType', $defaultReportType)
  133. ->call('applyFilters')
  134. ->assertFormSet([
  135. 'deferredFilters.reportType' => $defaultReportType,
  136. 'deferredFilters.dateRange' => $defaultDateRange,
  137. 'deferredFilters.asOfDate' => $defaultAsOfDate->toDateTimeString(),
  138. ])
  139. ->assertSet('filters', [
  140. 'reportType' => $defaultReportType,
  141. 'dateRange' => $defaultDateRange,
  142. 'asOfDate' => $defaultAsOfDate->toDateString(),
  143. ])
  144. ->call('applyFilters')
  145. ->assertSeeTextInOrder($retainedEarningsRow)
  146. ->assertSeeTextInOrder([
  147. 'Total Revenue',
  148. '$0.00',
  149. '$0.00',
  150. ])
  151. ->assertSeeTextInOrder([
  152. 'Total Expenses',
  153. '$0.00',
  154. '$0.00',
  155. ])
  156. ->assertSeeTextInOrder($accountCategoryPluralLabels)
  157. ->assertSeeTextInOrder([
  158. $formattedBalances->debitBalance,
  159. $formattedBalances->creditBalance,
  160. ]);
  161. /** @var ExportableReport $report */
  162. $report = $component->report;
  163. $columnLabels = array_map(static fn ($column) => $column->getLabel(), $report->getColumns());
  164. $component->assertSeeTextInOrder($columnLabels);
  165. $categories = $report->getCategories();
  166. foreach ($categories as $category) {
  167. $header = $category->header;
  168. $data = $category->data;
  169. $summary = $category->summary;
  170. $component->assertSeeTextInOrder($header);
  171. foreach ($data as $row) {
  172. $flatRow = [];
  173. foreach ($row as $value) {
  174. if (is_array($value)) {
  175. $flatRow[] = $value['name'];
  176. } else {
  177. $flatRow[] = $value;
  178. }
  179. }
  180. $component->assertSeeTextInOrder($flatRow);
  181. }
  182. $component->assertSeeTextInOrder($summary);
  183. }
  184. $overallTotals = $report->getOverallTotals();
  185. $component->assertSeeTextInOrder($overallTotals);
  186. });