Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

BalanceSheetReportTransformer.php 9.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  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. if ($totalOtherEquity != 0) {
  167. $totalOtherEquityFormatted = money($totalOtherEquity, CurrencyAccessor::getDefaultCurrency(), true)->format();
  168. // Add "Total Other Equity" as a new "type"
  169. $otherEquitySummary = [];
  170. foreach ($columns as $column) {
  171. $otherEquitySummary[$column->getName()] = match ($column->getName()) {
  172. 'account_name' => 'Total Other Equity',
  173. 'ending_balance' => $totalOtherEquityFormatted,
  174. default => '',
  175. };
  176. }
  177. $types['Total Other Equity'] = new ReportTypeDTO(
  178. header: [],
  179. data: [],
  180. summary: $otherEquitySummary,
  181. );
  182. }
  183. }
  184. // Add the category with its types and summary to the final array
  185. $summaryCategories[$accountCategoryName] = new ReportCategoryDTO(
  186. header: $categoryHeader,
  187. data: [],
  188. summary: $categorySummary,
  189. types: $types,
  190. );
  191. }
  192. return $summaryCategories;
  193. }
  194. public function getOverallTotals(): array
  195. {
  196. return [];
  197. }
  198. public function getSummaryOverallTotals(): array
  199. {
  200. return [];
  201. }
  202. public function getSummary(): array
  203. {
  204. return [
  205. [
  206. 'label' => 'Total Assets',
  207. 'value' => $this->totalAssets,
  208. ],
  209. [
  210. 'label' => 'Total Liabilities',
  211. 'value' => $this->totalLiabilities,
  212. ],
  213. [
  214. 'label' => 'Net Assets',
  215. 'value' => $this->report->overallTotal->endingBalance ?? '',
  216. ],
  217. ];
  218. }
  219. }