Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

ChartOfAccountsService.php 3.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  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. 'inverse_cash_flow' => $subtypeConfig['inverse_cash_flow'] ?? false,
  21. 'category' => AccountType::from($type)->getCategory()->value,
  22. 'type' => $type,
  23. 'name' => $subtypeName,
  24. 'description' => $subtypeConfig['description'] ?? 'No description available.',
  25. ]);
  26. try {
  27. $this->createDefaultAccounts($company, $subtype, $subtypeConfig);
  28. } catch (Exception $e) {
  29. // Log the error
  30. logger()->alert('Failed to create a company with its defaults, blocking critical business functionality.', [
  31. 'error' => $e->getMessage(),
  32. 'userId' => $company->owner->id,
  33. 'companyId' => $company->id,
  34. ]);
  35. throw $e;
  36. }
  37. }
  38. }
  39. }
  40. private function createDefaultAccounts(Company $company, AccountSubtype $subtype, array $subtypeConfig): void
  41. {
  42. if (isset($subtypeConfig['accounts']) && is_array($subtypeConfig['accounts'])) {
  43. $baseCode = $subtypeConfig['base_code'];
  44. $defaultCurrencyCode = CurrencyAccessor::getDefaultCurrency();
  45. if (empty($defaultCurrencyCode)) {
  46. throw new Exception('No default currency available for creating accounts.');
  47. }
  48. foreach ($subtypeConfig['accounts'] as $accountName => $accountDetails) {
  49. $bankAccount = null;
  50. if ($subtypeConfig['multi_currency'] && isset($subtypeConfig['bank_account_type'])) {
  51. $bankAccount = $this->createBankAccountForMultiCurrency($company, $subtypeConfig['bank_account_type']);
  52. }
  53. $company->accounts()->createQuietly([
  54. 'bank_account_id' => $bankAccount?->id,
  55. 'subtype_id' => $subtype->id,
  56. 'category' => $subtype->type->getCategory()->value,
  57. 'type' => $subtype->type->value,
  58. 'code' => $baseCode++,
  59. 'name' => $accountName,
  60. 'currency_code' => $defaultCurrencyCode,
  61. 'description' => $accountDetails['description'] ?? 'No description available.',
  62. 'default' => true,
  63. 'created_by' => $company->owner->id,
  64. 'updated_by' => $company->owner->id,
  65. ]);
  66. }
  67. }
  68. }
  69. private function createBankAccountForMultiCurrency(Company $company, string $bankAccountType): BankAccount
  70. {
  71. $noDefaultBankAccount = $company->bankAccounts()->where('enabled', true)->doesntExist();
  72. return $company->bankAccounts()->createQuietly([
  73. 'type' => BankAccountType::from($bankAccountType) ?? BankAccountType::Other,
  74. 'enabled' => $noDefaultBankAccount,
  75. 'created_by' => $company->owner->id,
  76. 'updated_by' => $company->owner->id,
  77. ]);
  78. }
  79. }