Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

BalanceSheetReportTransformer.php 9.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. <?php
  2. namespace App\Transformers;
  3. use App\DTO\AccountDTO;
  4. use App\DTO\ReportCategoryDTO;
  5. use App\DTO\ReportDTO;
  6. use App\DTO\ReportTypeDTO;
  7. use App\Utilities\Currency\CurrencyAccessor;
  8. class BalanceSheetReportTransformer extends SummaryReportTransformer
  9. {
  10. protected string $totalAssets;
  11. protected string $totalLiabilities;
  12. protected string $totalEquity;
  13. public function __construct(ReportDTO $report)
  14. {
  15. parent::__construct($report);
  16. $this->calculateTotals();
  17. }
  18. public function getTitle(): string
  19. {
  20. return 'Balance Sheet';
  21. }
  22. public function calculateTotals(): void
  23. {
  24. foreach ($this->report->categories as $accountCategoryName => $accountCategory) {
  25. match ($accountCategoryName) {
  26. 'Assets' => $this->totalAssets = $accountCategory->summary->endingBalance ?? '',
  27. 'Liabilities' => $this->totalLiabilities = $accountCategory->summary->endingBalance ?? '',
  28. 'Equity' => $this->totalEquity = $accountCategory->summary->endingBalance ?? '',
  29. };
  30. }
  31. }
  32. public function getCategories(): array
  33. {
  34. $categories = [];
  35. foreach ($this->report->categories as $accountCategoryName => $accountCategory) {
  36. // Header for the main category
  37. $header = [];
  38. foreach ($this->getColumns() as $column) {
  39. $header[$column->getName()] = $column->getName() === 'account_name' ? $accountCategoryName : '';
  40. }
  41. // Category-level summary
  42. $categorySummary = [];
  43. foreach ($this->getColumns() as $column) {
  44. $categorySummary[$column->getName()] = match ($column->getName()) {
  45. 'account_name' => 'Total ' . $accountCategoryName,
  46. 'ending_balance' => $accountCategory->summary->endingBalance ?? '',
  47. default => '',
  48. };
  49. }
  50. // Accounts directly under the main category
  51. $data = array_map(function (AccountDTO $account) {
  52. $row = [];
  53. foreach ($this->getColumns() as $column) {
  54. $row[$column->getName()] = match ($column->getName()) {
  55. 'account_code' => $account->accountCode,
  56. 'account_name' => [
  57. 'name' => $account->accountName,
  58. 'id' => $account->accountId ?? null,
  59. 'start_date' => $account->startDate,
  60. 'end_date' => $account->endDate,
  61. ],
  62. 'ending_balance' => $account->balance->endingBalance ?? '',
  63. default => '',
  64. };
  65. }
  66. return $row;
  67. }, $accountCategory->accounts ?? []);
  68. // Subcategories (types) under the main category
  69. $types = [];
  70. foreach ($accountCategory->types as $typeName => $type) {
  71. // Header for subcategory (type)
  72. $typeHeader = [];
  73. foreach ($this->getColumns() as $column) {
  74. $typeHeader[$column->getName()] = $column->getName() === 'account_name' ? $typeName : '';
  75. }
  76. // Account data for the subcategory
  77. $typeData = array_map(function (AccountDTO $account) {
  78. $row = [];
  79. foreach ($this->getColumns() as $column) {
  80. $row[$column->getName()] = match ($column->getName()) {
  81. 'account_code' => $account->accountCode,
  82. 'account_name' => [
  83. 'name' => $account->accountName,
  84. 'id' => $account->accountId ?? null,
  85. 'start_date' => $account->startDate,
  86. 'end_date' => $account->endDate,
  87. ],
  88. 'ending_balance' => $account->balance->endingBalance ?? '',
  89. default => '',
  90. };
  91. }
  92. return $row;
  93. }, $type->accounts);
  94. // Subcategory (type) summary
  95. $typeSummary = [];
  96. foreach ($this->getColumns() as $column) {
  97. $typeSummary[$column->getName()] = match ($column->getName()) {
  98. 'account_name' => 'Total ' . $typeName,
  99. 'ending_balance' => $type->summary->endingBalance ?? '',
  100. default => '',
  101. };
  102. }
  103. // Add subcategory (type) to the list
  104. $types[$typeName] = new ReportTypeDTO(
  105. header: $typeHeader,
  106. data: $typeData,
  107. summary: $typeSummary,
  108. );
  109. }
  110. // Add the category to the final array with its direct accounts and subcategories (types)
  111. $categories[$accountCategoryName] = new ReportCategoryDTO(
  112. header: $header,
  113. data: $data, // Direct accounts under the category
  114. summary: $categorySummary,
  115. types: $types, // Subcategories (types) under the category
  116. );
  117. }
  118. return $categories;
  119. }
  120. public function getSummaryCategories(): array
  121. {
  122. $summaryCategories = [];
  123. $columns = $this->getSummaryColumns();
  124. foreach ($this->report->categories as $accountCategoryName => $accountCategory) {
  125. $categoryHeader = [];
  126. foreach ($columns as $column) {
  127. $categoryHeader[$column->getName()] = $column->getName() === 'account_name' ? $accountCategoryName : '';
  128. }
  129. $categorySummary = [];
  130. foreach ($columns as $column) {
  131. $categorySummary[$column->getName()] = match ($column->getName()) {
  132. 'account_name' => 'Total ' . $accountCategoryName,
  133. 'ending_balance' => $accountCategory->summary->endingBalance ?? '',
  134. default => '',
  135. };
  136. }
  137. $types = [];
  138. $totalTypeSummaries = 0;
  139. // Iterate through each account type and calculate type summaries
  140. foreach ($accountCategory->types as $typeName => $type) {
  141. $typeSummary = [];
  142. $typeEndingBalance = 0;
  143. foreach ($columns as $column) {
  144. $typeSummary[$column->getName()] = match ($column->getName()) {
  145. 'account_name' => 'Total ' . $typeName,
  146. 'ending_balance' => $type->summary->endingBalance ?? '',
  147. default => '',
  148. };
  149. if ($column->getName() === 'ending_balance') {
  150. $typeEndingBalance = $type->summary->endingBalance ?? 0;
  151. }
  152. }
  153. $typeEndingBalance = money($typeEndingBalance, CurrencyAccessor::getDefaultCurrency())->getAmount();
  154. $totalTypeSummaries += $typeEndingBalance;
  155. $types[$typeName] = new ReportTypeDTO(
  156. header: [],
  157. data: [],
  158. summary: $typeSummary,
  159. );
  160. }
  161. // Only for the "Equity" category, calculate and add "Total Other Equity"
  162. if ($accountCategoryName === 'Equity') {
  163. $totalEquitySummary = $accountCategory->summary->endingBalance ?? 0;
  164. $totalEquitySummary = money($totalEquitySummary, CurrencyAccessor::getDefaultCurrency())->getAmount();
  165. $totalOtherEquity = $totalEquitySummary - $totalTypeSummaries;
  166. $totalOtherEquity = money($totalOtherEquity, CurrencyAccessor::getDefaultCurrency(), true)->format();
  167. // Add "Total Other Equity" as a new "type"
  168. $otherEquitySummary = [];
  169. foreach ($columns as $column) {
  170. $otherEquitySummary[$column->getName()] = match ($column->getName()) {
  171. 'account_name' => 'Total Other Equity',
  172. 'ending_balance' => $totalOtherEquity,
  173. default => '',
  174. };
  175. }
  176. $types['Total Other Equity'] = new ReportTypeDTO(
  177. header: [],
  178. data: [],
  179. summary: $otherEquitySummary,
  180. );
  181. }
  182. // Add the category with its types and summary to the final array
  183. $summaryCategories[$accountCategoryName] = new ReportCategoryDTO(
  184. header: $categoryHeader,
  185. data: [],
  186. summary: $categorySummary,
  187. types: $types,
  188. );
  189. }
  190. return $summaryCategories;
  191. }
  192. public function getOverallTotals(): array
  193. {
  194. return [];
  195. }
  196. public function getSummaryOverallTotals(): array
  197. {
  198. return [];
  199. }
  200. public function getSummary(): array
  201. {
  202. return [
  203. [
  204. 'label' => 'Total Assets',
  205. 'value' => $this->totalAssets,
  206. ],
  207. [
  208. 'label' => 'Total Liabilities',
  209. 'value' => $this->totalLiabilities,
  210. ],
  211. [
  212. 'label' => 'Net Assets',
  213. 'value' => $this->report->overallTotal->endingBalance ?? '',
  214. ],
  215. ];
  216. }
  217. }