Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. <?php
  2. namespace App\Utilities\Accounting;
  3. use App\Enums\Accounting\AccountType;
  4. use App\Models\Accounting\AccountSubtype;
  5. use RuntimeException;
  6. class AccountCode
  7. {
  8. public static function isValidCode($code, AccountType $type): bool
  9. {
  10. $range = self::getRangeForType($type);
  11. $mainAccountPart = explode('-', $code)[0];
  12. $numericValue = (int) $mainAccountPart;
  13. return $numericValue >= $range[0] && $numericValue <= $range[1];
  14. }
  15. public static function getMessage(AccountType $type): string
  16. {
  17. $range = self::getRangeForType($type);
  18. return "The account code must range from {$range[0]} to {$range[1]} for a {$type->getLabel()}.";
  19. }
  20. public static function getRangeForType(AccountType $type): array
  21. {
  22. return match ($type) {
  23. AccountType::CurrentAsset => [1000, 1499],
  24. AccountType::NonCurrentAsset => [1500, 1899],
  25. AccountType::ContraAsset => [1900, 1999],
  26. AccountType::CurrentLiability => [2000, 2499],
  27. AccountType::NonCurrentLiability => [2500, 2899],
  28. AccountType::ContraLiability => [2900, 2999],
  29. AccountType::Equity => [3000, 3899],
  30. AccountType::ContraEquity => [3900, 3999],
  31. AccountType::OperatingRevenue => [4000, 4499],
  32. AccountType::NonOperatingRevenue => [4500, 4899],
  33. AccountType::ContraRevenue => [4900, 4949],
  34. AccountType::UncategorizedRevenue => [4950, 4999],
  35. AccountType::OperatingExpense => [5000, 5499],
  36. AccountType::NonOperatingExpense => [5500, 5899],
  37. AccountType::ContraExpense => [5900, 5949],
  38. AccountType::UncategorizedExpense => [5950, 5999],
  39. };
  40. }
  41. public static function generate(AccountSubtype $accountSubtype): string
  42. {
  43. $subtypeName = $accountSubtype->name;
  44. $typeEnum = $accountSubtype->type;
  45. $typeValue = $typeEnum->value;
  46. $baseCode = config("chart-of-accounts.default.{$typeValue}.{$subtypeName}.base_code");
  47. $range = self::getRangeForType($typeEnum);
  48. $lastAccount = $accountSubtype->accounts()
  49. ->whereNotNull('code')
  50. ->orderBy('code', 'desc')
  51. ->first();
  52. $nextNumericValue = $lastAccount ? (int) explode('-', $lastAccount->code)[0] + 1 : (int) $baseCode;
  53. if ($nextNumericValue > $range[1]) {
  54. throw new RuntimeException("The account code range for a {$typeEnum->getLabel()} has been exceeded.");
  55. }
  56. while ($accountSubtype->accounts()->where('code', '=', (string) $nextNumericValue)->exists()) {
  57. $nextNumericValue++;
  58. if ($nextNumericValue > $range[1]) {
  59. throw new RuntimeException("The account code range for a {$typeEnum->getLabel()} has been exceeded.");
  60. }
  61. }
  62. return (string) $nextNumericValue;
  63. }
  64. }