Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

IncomeStatementReportTransformer.php 6.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. <?php
  2. namespace App\Transformers;
  3. use App\DTO\AccountDTO;
  4. use App\DTO\ReportCategoryDTO;
  5. use App\DTO\ReportDTO;
  6. use App\Utilities\Currency\CurrencyAccessor;
  7. class IncomeStatementReportTransformer extends SummaryReportTransformer
  8. {
  9. protected string $totalRevenue;
  10. protected string $totalCogs;
  11. protected string $totalExpenses;
  12. public function __construct(ReportDTO $report)
  13. {
  14. parent::__construct($report);
  15. $this->calculateTotals();
  16. }
  17. public function getSummaryPdfView(): string
  18. {
  19. return 'components.company.reports.income-statement-summary-pdf';
  20. }
  21. public function getTitle(): string
  22. {
  23. return 'Income Statement';
  24. }
  25. public function calculateTotals(): void
  26. {
  27. foreach ($this->report->categories as $accountCategoryName => $accountCategory) {
  28. match ($accountCategoryName) {
  29. 'Revenue' => $this->totalRevenue = $accountCategory->summary->netMovement ?? '',
  30. 'Cost of Goods Sold' => $this->totalCogs = $accountCategory->summary->netMovement ?? '',
  31. 'Expenses' => $this->totalExpenses = $accountCategory->summary->netMovement ?? '',
  32. };
  33. }
  34. }
  35. public function getCategories(): array
  36. {
  37. $categories = [];
  38. foreach ($this->report->categories as $accountCategoryName => $accountCategory) {
  39. $header = [];
  40. foreach ($this->getColumns() as $column) {
  41. $header[$column->getName()] = $column->getName() === 'account_name' ? $accountCategoryName : '';
  42. }
  43. $data = array_map(function (AccountDTO $account) {
  44. $row = [];
  45. foreach ($this->getColumns() as $column) {
  46. $row[$column->getName()] = match ($column->getName()) {
  47. 'account_code' => $account->accountCode,
  48. 'account_name' => [
  49. 'name' => $account->accountName,
  50. 'id' => $account->accountId ?? null,
  51. 'start_date' => $account->startDate,
  52. 'end_date' => $account->endDate,
  53. ],
  54. 'net_movement' => $account->balance->netMovement ?? '',
  55. default => '',
  56. };
  57. }
  58. return $row;
  59. }, $accountCategory->accounts);
  60. $summary = [];
  61. foreach ($this->getColumns() as $column) {
  62. $summary[$column->getName()] = match ($column->getName()) {
  63. 'account_name' => 'Total ' . $accountCategoryName,
  64. 'net_movement' => $accountCategory->summary->netMovement ?? '',
  65. default => '',
  66. };
  67. }
  68. $categories[] = new ReportCategoryDTO(
  69. header: $header,
  70. data: $data,
  71. summary: $summary,
  72. );
  73. }
  74. return $categories;
  75. }
  76. public function getSummaryCategories(): array
  77. {
  78. $summaryCategories = [];
  79. $columns = $this->getSummaryColumns();
  80. foreach ($this->report->categories as $accountCategoryName => $accountCategory) {
  81. // Category-level summary
  82. $categorySummary = [];
  83. foreach ($columns as $column) {
  84. $categorySummary[$column->getName()] = match ($column->getName()) {
  85. 'account_name' => $accountCategoryName,
  86. 'net_movement' => $accountCategory->summary->netMovement ?? '',
  87. default => '',
  88. };
  89. }
  90. // Add the category summary to the final array
  91. $summaryCategories[$accountCategoryName] = new ReportCategoryDTO(
  92. header: [],
  93. data: [], // No direct accounts are needed here, only summaries
  94. summary: $categorySummary,
  95. types: [] // No types for the income statement
  96. );
  97. }
  98. return $summaryCategories;
  99. }
  100. public function getGrossProfit(): array
  101. {
  102. $grossProfit = [];
  103. $columns = $this->getSummaryColumns();
  104. $revenue = money($this->totalRevenue, CurrencyAccessor::getDefaultCurrency())->getAmount();
  105. $cogs = money($this->totalCogs, CurrencyAccessor::getDefaultCurrency())->getAmount();
  106. $grossProfitAmount = $revenue - $cogs;
  107. $grossProfitFormatted = money($grossProfitAmount, CurrencyAccessor::getDefaultCurrency(), true)->format();
  108. foreach ($columns as $column) {
  109. $grossProfit[$column->getName()] = match ($column->getName()) {
  110. 'account_name' => 'Gross Profit',
  111. 'net_movement' => $grossProfitFormatted,
  112. default => '',
  113. };
  114. }
  115. return $grossProfit;
  116. }
  117. public function getOverallTotals(): array
  118. {
  119. $totals = [];
  120. foreach ($this->getColumns() as $column) {
  121. $totals[$column->getName()] = match ($column->getName()) {
  122. 'account_name' => 'Net Earnings',
  123. 'net_movement' => $this->report->overallTotal->netMovement ?? '',
  124. default => '',
  125. };
  126. }
  127. return $totals;
  128. }
  129. public function getSummaryOverallTotals(): array
  130. {
  131. $totals = [];
  132. $columns = $this->getSummaryColumns();
  133. foreach ($columns as $column) {
  134. $totals[$column->getName()] = match ($column->getName()) {
  135. 'account_name' => 'Net Earnings',
  136. 'net_movement' => $this->report->overallTotal->netMovement ?? '',
  137. default => '',
  138. };
  139. }
  140. return $totals;
  141. }
  142. public function getSummary(): array
  143. {
  144. return [
  145. [
  146. 'label' => 'Revenue',
  147. 'value' => $this->totalRevenue,
  148. ],
  149. [
  150. 'label' => 'Cost of Goods Sold',
  151. 'value' => $this->totalCogs,
  152. ],
  153. [
  154. 'label' => 'Expenses',
  155. 'value' => $this->totalExpenses,
  156. ],
  157. [
  158. 'label' => 'Net Earnings',
  159. 'value' => $this->report->overallTotal->netMovement ?? '',
  160. ],
  161. ];
  162. }
  163. }