Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

ChartOfAccountsService.php 3.7KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. <?php
  2. namespace App\Services;
  3. use App\Enums\Accounting\AccountType;
  4. use App\Enums\Banking\BankAccountType;
  5. use App\Models\Accounting\AccountSubtype;
  6. use App\Models\Banking\BankAccount;
  7. use App\Models\Company;
  8. use App\Utilities\Currency\CurrencyAccessor;
  9. use Exception;
  10. class ChartOfAccountsService
  11. {
  12. public function createChartOfAccounts(Company $company): void
  13. {
  14. $chartOfAccounts = config('chart-of-accounts.default');
  15. foreach ($chartOfAccounts as $type => $subtypes) {
  16. foreach ($subtypes as $subtypeName => $subtypeConfig) {
  17. $subtype = $company->accountSubtypes()
  18. ->createQuietly([
  19. 'multi_currency' => $subtypeConfig['multi_currency'] ?? false,
  20. 'category' => AccountType::from($type)->getCategory()->value,
  21. 'type' => $type,
  22. 'name' => $subtypeName,
  23. 'description' => $subtypeConfig['description'] ?? 'No description available.',
  24. ]);
  25. try {
  26. $this->createDefaultAccounts($company, $subtype, $subtypeConfig);
  27. } catch (Exception $e) {
  28. // Log the error
  29. logger()->alert('Failed to create a company with its defaults, blocking critical business functionality.', [
  30. 'error' => $e->getMessage(),
  31. 'userId' => $company->owner->id,
  32. 'companyId' => $company->id,
  33. ]);
  34. throw $e;
  35. }
  36. }
  37. }
  38. }
  39. private function createDefaultAccounts(Company $company, AccountSubtype $subtype, array $subtypeConfig): void
  40. {
  41. if (isset($subtypeConfig['accounts']) && is_array($subtypeConfig['accounts'])) {
  42. $baseCode = $subtypeConfig['base_code'];
  43. $defaultCurrencyCode = CurrencyAccessor::getDefaultCurrency();
  44. if (empty($defaultCurrencyCode)) {
  45. throw new Exception('No default currency available for creating accounts.');
  46. }
  47. foreach ($subtypeConfig['accounts'] as $accountName => $accountDetails) {
  48. $bankAccount = null;
  49. if ($subtypeConfig['multi_currency'] && isset($subtypeConfig['bank_account_type'])) {
  50. $bankAccount = $this->createBankAccountForMultiCurrency($company, $subtypeConfig['bank_account_type']);
  51. }
  52. $company->accounts()->createQuietly([
  53. 'bank_account_id' => $bankAccount?->id,
  54. 'subtype_id' => $subtype->id,
  55. 'category' => $subtype->type->getCategory()->value,
  56. 'type' => $subtype->type->value,
  57. 'code' => $baseCode++,
  58. 'name' => $accountName,
  59. 'currency_code' => $defaultCurrencyCode,
  60. 'description' => $accountDetails['description'] ?? 'No description available.',
  61. 'default' => true,
  62. 'created_by' => $company->owner->id,
  63. 'updated_by' => $company->owner->id,
  64. ]);
  65. }
  66. }
  67. }
  68. private function createBankAccountForMultiCurrency(Company $company, string $bankAccountType): BankAccount
  69. {
  70. $noDefaultBankAccount = $company->bankAccounts()->where('enabled', true)->doesntExist();
  71. return $company->bankAccounts()->createQuietly([
  72. 'type' => BankAccountType::from($bankAccountType) ?? BankAccountType::Other,
  73. 'enabled' => $noDefaultBankAccount,
  74. 'created_by' => $company->owner->id,
  75. 'updated_by' => $company->owner->id,
  76. ]);
  77. }
  78. }