Commit c52bd08f authored by Mahmoud Aglan's avatar Mahmoud Aglan

xbdfhmj

parent 72b344d1
<?php
declare(strict_types=1);
namespace App\Modules\Accounting;
final class AccountCodes
{
// ══════════════════════════════════════════════════════════
// ASSETS (1)
// ══════════════════════════════════════════════════════════
const CASH_ON_HAND = '12010101';
const CASH_AT_BANK = '12010201';
const ACCOUNTS_RECEIVABLE = '120103';
const INVENTORY = '120105';
const PREPAID_EXPENSES = '120106';
const EMPLOYEE_LOANS = '120107';
const INPUT_TAX = '120108';
// Fixed Assets
const LAND = '110101';
const BUILDINGS = '110102';
const FURNITURE = '110103';
const EQUIPMENT = '110104';
const VEHICLES = '110105';
const COMPUTERS = '110106';
const ACCUMULATED_DEPRECIATION = '1102';
// ══════════════════════════════════════════════════════════
// LIABILITIES & EQUITY (2)
// ══════════════════════════════════════════════════════════
const ACCOUNTS_PAYABLE = '210101';
const ACCRUED_EXPENSES = '210102';
const TAX_PAYABLE = '210103';
const INSURANCE_PAYABLE = '210104';
const DEFERRED_REVENUE = '210105';
const MEMBERSHIP_DEPOSITS = '210106';
const RENTAL_DEPOSITS = '210107';
const END_OF_SERVICE_PROV = '210108';
// Equity
const CAPITAL = '220101';
const RETAINED_EARNINGS = '220102';
const LEGAL_RESERVE = '220103';
const GENERAL_RESERVE = '220104';
// ══════════════════════════════════════════════════════════
// EXPENSES (3)
// ══════════════════════════════════════════════════════════
const SALARY_EXPENSE = '310101';
const INSURANCE_EXPENSE = '310102';
const ALLOWANCES_EXPENSE = '310103';
const TRAINING_EXPENSE = '310104';
const END_OF_SERVICE_EXP = '310105';
const COGS = '3102';
const BANK_CHARGES = '310301';
const RENT_EXPENSE = '310302';
const UTILITIES_EXPENSE = '310303';
const MAINTENANCE_EXPENSE = '310304';
const DEPRECIATION = '310305';
const CLEANING_EXPENSE = '310306';
const SECURITY_EXPENSE = '310307';
const PROPERTY_INSURANCE = '310308';
const COMMUNICATIONS_EXP = '310309';
const PRINTING_EXPENSE = '310310';
const HOSPITALITY_EXPENSE = '310311';
const TRANSPORT_EXPENSE = '310312';
const MARKETING_EXPENSE = '310313';
const GOVERNMENT_FEES = '310314';
const LEGAL_FEES = '310315';
const SHIPPING_EXPENSE = '310316';
const MISC_EXPENSES = '310399';
// Sports & Activities Expenses
const ACADEMY_EXPENSE = '310401';
const SPORTS_FACILITIES = '310402';
const EVENTS_EXPENSE = '310403';
// ══════════════════════════════════════════════════════════
// REVENUE (4) — Custom for this club
// ══════════════════════════════════════════════════════════
// Membership Revenue (4101)
const FORM_FEE_REVENUE = '410101';
const MEMBERSHIP_VALUE_REVENUE = '410102';
const DEPENDENT_ADDITION_REVENUE = '410103';
// Subscription Revenue (4102)
const ANNUAL_SUBSCRIPTION = '410201';
const DEVELOPMENT_FEE = '410202';
// Transfer & Cases Revenue (4103)
const SEPARATION_FEE_REVENUE = '410301';
const DIVORCE_FEE_REVENUE = '410302';
const DEATH_TRANSFER_REVENUE = '410303';
const WAIVER_FEE_REVENUE = '410304';
const SPORTS_CONVERSION_REVENUE = '410305';
// Special Memberships (4104)
const SEASONAL_MEMBERSHIP = '410401';
const CARNET_REPLACEMENT = '410402';
const FOREIGN_MEMBERSHIP = '410403';
// Activities & Sports (4105)
const ACTIVITY_SUBSCRIPTION = '410501';
const ACADEMY_REVENUE = '410502';
// Single-level revenue accounts
const FINE_REVENUE = '4106';
const SALES_REVENUE = '4107';
const RENTAL_REVENUE = '4108';
// Installment Revenue (4109)
const DOWN_PAYMENT_REVENUE = '410901';
const INSTALLMENT_REVENUE = '410902';
// Other Revenue (42)
const BANK_INTEREST_INCOME = '4201';
const MISCELLANEOUS_REVENUE = '4202';
// Service Revenue (catch-all for deposits reclassification etc.)
const SERVICE_REVENUE = '4110';
// ══════════════════════════════════════════════════════════
// HELPERS
// ══════════════════════════════════════════════════════════
public static function debitAccountForMethod(string $method): string
{
return match ($method) {
'cash' => self::CASH_ON_HAND,
'check' => self::CASH_AT_BANK,
'visa' => self::CASH_AT_BANK,
'bank_transfer' => self::CASH_AT_BANK,
default => self::CASH_ON_HAND,
};
}
public static function creditAccountForPaymentType(string $type): string
{
return match ($type) {
'form_fee' => self::FORM_FEE_REVENUE,
'membership_fee' => self::MEMBERSHIP_VALUE_REVENUE,
'addition_fee' => self::DEPENDENT_ADDITION_REVENUE,
'separation_fee' => self::SEPARATION_FEE_REVENUE,
'divorce_fee' => self::DIVORCE_FEE_REVENUE,
'death_fee' => self::DEATH_TRANSFER_REVENUE,
'waiver_fee' => self::WAIVER_FEE_REVENUE,
'sports_conversion' => self::SPORTS_CONVERSION_REVENUE,
'seasonal_fee' => self::SEASONAL_MEMBERSHIP,
'carnet_replacement' => self::CARNET_REPLACEMENT,
'annual_subscription' => self::ANNUAL_SUBSCRIPTION,
'development_fee' => self::DEVELOPMENT_FEE,
'activity_subscription' => self::ACTIVITY_SUBSCRIPTION,
'down_payment' => self::ACCOUNTS_RECEIVABLE,
'installment' => self::ACCOUNTS_RECEIVABLE,
'fine' => self::FINE_REVENUE,
'inventory_sale' => self::SALES_REVENUE,
default => self::SERVICE_REVENUE,
};
}
}
...@@ -5,28 +5,14 @@ namespace App\Modules\Accounting\Services; ...@@ -5,28 +5,14 @@ namespace App\Modules\Accounting\Services;
use App\Core\App; use App\Core\App;
use App\Core\Logger; use App\Core\Logger;
use App\Modules\Accounting\AccountCodes;
/** /**
* Auto-posting journal entries from other modules. * Auto-posting journal entries from other modules.
* Each method is called from bootstrap.php event listeners. * Each method is called from bootstrap.php event listeners.
* *
* Account codes used (Egyptian standard): * All account codes are centralized in AccountCodes class.
* 1101 - Cash (نقدية بالصندوق) * Uses Egyptian Standard Chart of Accounts numbering (8-digit codes).
* 1102 - Bank (نقدية بالبنك)
* 1103 - Accounts Receivable (حسابات مدينة)
* 1104 - Inventory (مخزون)
* 2101 - Accounts Payable (حسابات دائنة)
* 2103 - Tax Payable (ضرائب مستحقة)
* 2104 - Insurance Payable (تأمينات مستحقة)
* 2105 - Deferred Revenue (إيرادات مؤجلة)
* 4101 - Membership Revenue (إيرادات عضوية)
* 4102 - Subscription Revenue (إيرادات اشتراكات)
* 4103 - Sales Revenue (إيرادات مبيعات)
* 4104 - Fine Revenue (إيرادات غرامات)
* 4105 - Service Revenue (إيرادات خدمات)
* 5101 - Salary Expense (مصروفات رواتب)
* 5102 - Insurance Expense (مصروفات تأمينات — حصة صاحب العمل)
* 5106 - Cost of Goods Sold (تكلفة البضاعة المباعة)
*/ */
final class AccountingIntegrationService final class AccountingIntegrationService
{ {
...@@ -55,56 +41,11 @@ final class AccountingIntegrationService ...@@ -55,56 +41,11 @@ final class AccountingIntegrationService
} }
// Determine debit account (where money goes) // Determine debit account (where money goes)
$debitAccountCode = match ($method) { $debitAccountCode = AccountCodes::debitAccountForMethod($method);
'cash' => '1101',
'check' => '1102',
'visa' => '1102',
'bank_transfer' => '1102',
default => '1101',
};
// Determine credit account (revenue type) // Determine credit account (revenue type)
// Uses granular sub-accounts (4110+) with fallback to legacy accounts (4101+) $creditAccountCode = AccountCodes::creditAccountForPaymentType($type);
$creditAccountCode = match ($type) {
'form_fee' => '4110', // Form Fee Revenue
'membership_fee' => '4111', // Membership Value Revenue
'addition_fee' => '4112', // Dependent Addition Revenue
'separation_fee' => '4120', // Separation Fee Revenue
'divorce_fee' => '4121', // Divorce Fee Revenue
'death_fee' => '4122', // Death Transfer Fee Revenue
'waiver_fee' => '4123', // Waiver Fee Revenue
'sports_conversion' => '4124', // Sports Conversion Revenue
'seasonal_fee' => '4130', // Seasonal Membership Revenue
'carnet_replacement' => '4131', // Carnet Replacement Revenue
'annual_subscription' => '4140', // Annual Subscription Revenue
'development_fee' => '4141', // Development Fee Revenue
'activity_subscription' => '4150', // Activity Subscription Revenue
'down_payment' => '1103', // Accounts Receivable (reducing AR)
'installment' => '1103', // Accounts Receivable (reducing AR)
'fine' => '4104', // Fine Revenue
'inventory_sale' => '4103', // Sales Revenue
default => '4105', // Service Revenue (catch-all)
};
// Fallback: if the granular account doesn't exist yet, use legacy grouping
$creditAccount = self::getAccountByCode($creditAccountCode); $creditAccount = self::getAccountByCode($creditAccountCode);
if (!$creditAccount) {
$fallbackCode = match ($type) {
'form_fee', 'membership_fee', 'addition_fee', 'separation_fee',
'divorce_fee', 'death_fee', 'waiver_fee', 'sports_conversion',
'carnet_replacement', 'seasonal_fee'
=> '4101', // Membership Revenue (legacy)
'annual_subscription', 'development_fee'
=> '4102', // Subscription Revenue (legacy)
'activity_subscription'
=> '4105', // Service Revenue (legacy)
default => null,
};
if ($fallbackCode) {
$creditAccountCode = $fallbackCode;
$creditAccount = self::getAccountByCode($creditAccountCode);
}
}
$debitAccount = self::getAccountByCode($debitAccountCode); $debitAccount = self::getAccountByCode($debitAccountCode);
...@@ -212,10 +153,10 @@ final class AccountingIntegrationService ...@@ -212,10 +153,10 @@ final class AccountingIntegrationService
); );
$totalCost = (string) ($costRow['total_cost'] ?? '0.00'); $totalCost = (string) ($costRow['total_cost'] ?? '0.00');
$salesRevenue = self::getAccountByCode('4103'); $salesRevenue = self::getAccountByCode(AccountCodes::SALES_REVENUE);
$cashAccount = self::getAccountByCode('1101'); $cashAccount = self::getAccountByCode(AccountCodes::CASH_ON_HAND);
$cogsAccount = self::getAccountByCode('5106'); $cogsAccount = self::getAccountByCode(AccountCodes::COGS);
$inventoryAccount = self::getAccountByCode('1104'); $inventoryAccount = self::getAccountByCode(AccountCodes::INVENTORY);
if (!$salesRevenue || !$cashAccount) { if (!$salesRevenue || !$cashAccount) {
return; return;
...@@ -317,11 +258,11 @@ final class AccountingIntegrationService ...@@ -317,11 +258,11 @@ final class AccountingIntegrationService
$erInsurance = $componentMap['social_insurance_employer'] ?? '0.00'; $erInsurance = $componentMap['social_insurance_employer'] ?? '0.00';
$totalInsurance = bcadd($empInsurance, $erInsurance, 2); $totalInsurance = bcadd($empInsurance, $erInsurance, 2);
$salaryExpense = self::getAccountByCode('5101'); $salaryExpense = self::getAccountByCode(AccountCodes::SALARY_EXPENSE);
$insuranceExpense = self::getAccountByCode('5102'); $insuranceExpense = self::getAccountByCode(AccountCodes::INSURANCE_EXPENSE);
$bankAccount = self::getAccountByCode('1102'); $bankAccount = self::getAccountByCode(AccountCodes::CASH_AT_BANK);
$insurancePayable = self::getAccountByCode('2104'); $insurancePayable = self::getAccountByCode(AccountCodes::INSURANCE_PAYABLE);
$taxPayable = self::getAccountByCode('2103'); $taxPayable = self::getAccountByCode(AccountCodes::TAX_PAYABLE);
if (!$salaryExpense || !$bankAccount) { if (!$salaryExpense || !$bankAccount) {
Logger::error("Payroll auto-post failed: core accounts not found"); Logger::error("Payroll auto-post failed: core accounts not found");
...@@ -507,8 +448,8 @@ final class AccountingIntegrationService ...@@ -507,8 +448,8 @@ final class AccountingIntegrationService
} }
// Create AR entry // Create AR entry
$arAccount = self::getAccountByCode('1103'); $arAccount = self::getAccountByCode(AccountCodes::ACCOUNTS_RECEIVABLE);
$fineRevenue = self::getAccountByCode('4104'); $fineRevenue = self::getAccountByCode(AccountCodes::FINE_REVENUE);
if ($arAccount && $fineRevenue) { if ($arAccount && $fineRevenue) {
// Create receivable journal entry // Create receivable journal entry
...@@ -580,8 +521,8 @@ final class AccountingIntegrationService ...@@ -580,8 +521,8 @@ final class AccountingIntegrationService
return; return;
} }
$arAccount = self::getAccountByCode('1103'); $arAccount = self::getAccountByCode(AccountCodes::ACCOUNTS_RECEIVABLE);
$membershipRevenue = self::getAccountByCode('4101'); $membershipRevenue = self::getAccountByCode(AccountCodes::INSTALLMENT_REVENUE);
if ($arAccount && $membershipRevenue) { if ($arAccount && $membershipRevenue) {
// Journal: Dr. AR, Cr. Membership Revenue // Journal: Dr. AR, Cr. Membership Revenue
...@@ -697,8 +638,8 @@ final class AccountingIntegrationService ...@@ -697,8 +638,8 @@ final class AccountingIntegrationService
return; return;
} }
$salesRevenue = self::getAccountByCode('4103'); $salesRevenue = self::getAccountByCode(AccountCodes::SALES_REVENUE);
$cashAccount = self::getAccountByCode('1101'); $cashAccount = self::getAccountByCode(AccountCodes::CASH_ON_HAND);
if (!$salesRevenue || !$cashAccount) { if (!$salesRevenue || !$cashAccount) {
Logger::error("Refund auto-post failed: accounts not found", ['sale_id' => $saleId]); Logger::error("Refund auto-post failed: accounts not found", ['sale_id' => $saleId]);
...@@ -768,9 +709,9 @@ final class AccountingIntegrationService ...@@ -768,9 +709,9 @@ final class AccountingIntegrationService
return; return;
} }
// Reclassify: Dr. Service Revenue (4105), Cr. Deferred Revenue / Deposits (2105) // Reclassify: Dr. Service Revenue, Cr. Deferred Revenue / Deposits
$serviceRevenue = self::getAccountByCode('4105'); $serviceRevenue = self::getAccountByCode(AccountCodes::SERVICE_REVENUE);
$deferredRevenue = self::getAccountByCode('2105'); $deferredRevenue = self::getAccountByCode(AccountCodes::DEFERRED_REVENUE);
if (!$serviceRevenue || !$deferredRevenue) { if (!$serviceRevenue || !$deferredRevenue) {
return; return;
...@@ -861,9 +802,9 @@ final class AccountingIntegrationService ...@@ -861,9 +802,9 @@ final class AccountingIntegrationService
return; return;
} }
$inventoryAccount = self::getAccountByCode('1104'); $inventoryAccount = self::getAccountByCode(AccountCodes::INVENTORY);
$taxAccount = self::getAccountByCode('2103'); $taxAccount = self::getAccountByCode(AccountCodes::TAX_PAYABLE);
$apAccount = self::getAccountByCode('2101'); $apAccount = self::getAccountByCode(AccountCodes::ACCOUNTS_PAYABLE);
if (!$inventoryAccount || !$apAccount) { if (!$inventoryAccount || !$apAccount) {
Logger::error("Vendor invoice auto-post failed: core accounts not found", [ Logger::error("Vendor invoice auto-post failed: core accounts not found", [
...@@ -980,8 +921,10 @@ final class AccountingIntegrationService ...@@ -980,8 +921,10 @@ final class AccountingIntegrationService
return; return;
} }
$apAccount = self::getAccountByCode('2101'); $apAccount = self::getAccountByCode(AccountCodes::ACCOUNTS_PAYABLE);
$cashBankCode = in_array($paymentMethod, ['bank_transfer', 'check', 'wire'], true) ? '1102' : '1101'; $cashBankCode = \in_array($paymentMethod, ['bank_transfer', 'check', 'wire'], true)
? AccountCodes::CASH_AT_BANK
: AccountCodes::CASH_ON_HAND;
$cashBankAccount = self::getAccountByCode($cashBankCode); $cashBankAccount = self::getAccountByCode($cashBankCode);
if (!$apAccount || !$cashBankAccount) { if (!$apAccount || !$cashBankAccount) {
...@@ -1130,8 +1073,8 @@ final class AccountingIntegrationService ...@@ -1130,8 +1073,8 @@ final class AccountingIntegrationService
$rtvNumber = $rtv['rtv_number'] ?? ''; $rtvNumber = $rtv['rtv_number'] ?? '';
$apAccount = self::getAccountByCode('2101'); $apAccount = self::getAccountByCode(AccountCodes::ACCOUNTS_PAYABLE);
$inventoryAccount = self::getAccountByCode('1104'); $inventoryAccount = self::getAccountByCode(AccountCodes::INVENTORY);
if (!$apAccount || !$inventoryAccount) { if (!$apAccount || !$inventoryAccount) {
Logger::error("RTV auto-post failed: accounts not found", ['rtv_id' => $rtvId]); Logger::error("RTV auto-post failed: accounts not found", ['rtv_id' => $rtvId]);
......
...@@ -5,6 +5,7 @@ namespace App\Modules\Accounting\Services; ...@@ -5,6 +5,7 @@ namespace App\Modules\Accounting\Services;
use App\Core\App; use App\Core\App;
use App\Core\Logger; use App\Core\Logger;
use App\Modules\Accounting\AccountCodes;
use App\Modules\Accounting\Models\BankReconciliation; use App\Modules\Accounting\Models\BankReconciliation;
/** /**
...@@ -188,7 +189,8 @@ final class BankReconciliationService ...@@ -188,7 +189,8 @@ final class BankReconciliationService
if ($item['item_type'] === 'bank_charge') { if ($item['item_type'] === 'bank_charge') {
// Dr. Bank Charges Expense, Cr. Bank // Dr. Bank Charges Expense, Cr. Bank
$bankChargesAccount = $db->selectOne( $bankChargesAccount = $db->selectOne(
"SELECT id FROM chart_of_accounts WHERE account_code = '5201' AND is_archived = 0" "SELECT id FROM chart_of_accounts WHERE account_code = ? AND is_archived = 0",
[AccountCodes::BANK_CHARGES]
); );
if ($bankChargesAccount) { if ($bankChargesAccount) {
$lines = [ $lines = [
...@@ -201,7 +203,8 @@ final class BankReconciliationService ...@@ -201,7 +203,8 @@ final class BankReconciliationService
} elseif ($item['item_type'] === 'bank_interest') { } elseif ($item['item_type'] === 'bank_interest') {
// Dr. Bank, Cr. Interest Income // Dr. Bank, Cr. Interest Income
$interestAccount = $db->selectOne( $interestAccount = $db->selectOne(
"SELECT id FROM chart_of_accounts WHERE account_code = '4301' AND is_archived = 0" "SELECT id FROM chart_of_accounts WHERE account_code = ? AND is_archived = 0",
[AccountCodes::BANK_INTEREST_INCOME]
); );
if ($interestAccount) { if ($interestAccount) {
$lines = [ $lines = [
......
...@@ -6,6 +6,7 @@ namespace App\Modules\Accounting\Services; ...@@ -6,6 +6,7 @@ namespace App\Modules\Accounting\Services;
use App\Core\App; use App\Core\App;
use App\Core\EventBus; use App\Core\EventBus;
use App\Core\Logger; use App\Core\Logger;
use App\Modules\Accounting\AccountCodes;
use App\Modules\Accounting\Models\FiscalYear; use App\Modules\Accounting\Models\FiscalYear;
use App\Modules\Accounting\Models\PeriodClosing; use App\Modules\Accounting\Models\PeriodClosing;
...@@ -207,12 +208,13 @@ final class PeriodClosingService ...@@ -207,12 +208,13 @@ final class PeriodClosingService
$netIncome = $incomeStatement['net_income']; $netIncome = $incomeStatement['net_income'];
// Retained earnings account (3102) // Retained earnings account
$retainedEarnings = $db->selectOne( $retainedEarnings = $db->selectOne(
"SELECT id FROM chart_of_accounts WHERE account_code = '3102' AND is_archived = 0" "SELECT id FROM chart_of_accounts WHERE account_code = ? AND is_archived = 0",
[AccountCodes::RETAINED_EARNINGS]
); );
if (!$retainedEarnings) { if (!$retainedEarnings) {
return ['success' => false, 'error' => 'حساب الأرباح المحتجزة (3102) غير موجود']; return ['success' => false, 'error' => 'حساب الأرباح المحتجزة (' . AccountCodes::RETAINED_EARNINGS . ') غير موجود'];
} }
$lines = []; $lines = [];
......
<?php
declare(strict_types=1);
return [
'up' => "ALTER TABLE `chart_of_accounts` ADD COLUMN `level_name` VARCHAR(20) NULL AFTER `level`",
'down' => "ALTER TABLE `chart_of_accounts` DROP COLUMN `level_name`",
];
<?php
declare(strict_types=1);
use App\Core\Database;
/**
* Egyptian Standard Chart of Accounts — Full Implementation.
*
* Replaces the simplified 4-digit chart with proper 8-digit Egyptian standard codes.
* Revenue section (4) is customized for club/sports facility operations.
*
* Strategy:
* 1. Deactivate ALL old 4-digit accounts (preserves FK integrity for journal entries)
* 2. Insert complete new chart following Egyptian standard numbering
* 3. Idempotent: checks account_code existence before insert
*/
return function (Database $db): void {
$now = date('Y-m-d H:i:s');
// ─────────────────────────────────────────────────────────────
// Step 1: Deactivate old 4-digit accounts
// ─────────────────────────────────────────────────────────────
$db->execute(
"UPDATE chart_of_accounts SET is_active = 0, updated_at = ? WHERE LENGTH(account_code) <= 4 AND is_active = 1",
[$now]
);
// ─────────────────────────────────────────────────────────────
// Step 2: Full Egyptian Standard Chart
// ─────────────────────────────────────────────────────────────
$accounts = [
// ══════════════════════════════════════════════════════════════════
// 1 — الأصول (ASSETS)
// ══════════════════════════════════════════════════════════════════
['account_code' => '1', 'name_ar' => 'الأصول', 'name_en' => 'Assets', 'account_type' => 'asset', 'account_nature' => 'debit', 'parent_code' => null, 'level' => 1, 'is_header' => 1, 'is_system' => 1],
// 11 — الأصول الثابتة
['account_code' => '11', 'name_ar' => 'الأصول الثابتة', 'name_en' => 'Fixed Assets', 'account_type' => 'asset', 'account_nature' => 'debit', 'parent_code' => '1', 'level' => 2, 'is_header' => 1, 'is_system' => 1],
['account_code' => '1101', 'name_ar' => 'أصول ثابتة ملموسة', 'name_en' => 'Tangible Fixed Assets', 'account_type' => 'asset', 'account_nature' => 'debit', 'parent_code' => '11', 'level' => 3, 'is_header' => 1, 'is_system' => 0],
['account_code' => '110101', 'name_ar' => 'أراضي', 'name_en' => 'Land', 'account_type' => 'asset', 'account_nature' => 'debit', 'parent_code' => '1101', 'level' => 4, 'is_header' => 0, 'is_system' => 0],
['account_code' => '110102', 'name_ar' => 'مباني ومنشآت', 'name_en' => 'Buildings', 'account_type' => 'asset', 'account_nature' => 'debit', 'parent_code' => '1101', 'level' => 4, 'is_header' => 0, 'is_system' => 0],
['account_code' => '110103', 'name_ar' => 'أثاث وتجهيزات', 'name_en' => 'Furniture & Fixtures', 'account_type' => 'asset', 'account_nature' => 'debit', 'parent_code' => '1101', 'level' => 4, 'is_header' => 0, 'is_system' => 0],
['account_code' => '110104', 'name_ar' => 'معدات وأجهزة', 'name_en' => 'Equipment', 'account_type' => 'asset', 'account_nature' => 'debit', 'parent_code' => '1101', 'level' => 4, 'is_header' => 0, 'is_system' => 0],
['account_code' => '110105', 'name_ar' => 'سيارات ووسائل نقل', 'name_en' => 'Vehicles', 'account_type' => 'asset', 'account_nature' => 'debit', 'parent_code' => '1101', 'level' => 4, 'is_header' => 0, 'is_system' => 0],
['account_code' => '110106', 'name_ar' => 'أجهزة حاسب آلي', 'name_en' => 'Computer Equipment', 'account_type' => 'asset', 'account_nature' => 'debit', 'parent_code' => '1101', 'level' => 4, 'is_header' => 0, 'is_system' => 0],
['account_code' => '1102', 'name_ar' => 'مجمع الإهلاك', 'name_en' => 'Accumulated Depreciation', 'account_type' => 'asset', 'account_nature' => 'credit', 'parent_code' => '11', 'level' => 3, 'is_header' => 0, 'is_system' => 1],
// 12 — الأصول المتداولة
['account_code' => '12', 'name_ar' => 'الأصول المتداولة', 'name_en' => 'Current Assets', 'account_type' => 'asset', 'account_nature' => 'debit', 'parent_code' => '1', 'level' => 2, 'is_header' => 1, 'is_system' => 1],
['account_code' => '1201', 'name_ar' => 'النقدية وما في حكمها', 'name_en' => 'Cash & Equivalents', 'account_type' => 'asset', 'account_nature' => 'debit', 'parent_code' => '12', 'level' => 3, 'is_header' => 1, 'is_system' => 1],
['account_code' => '120101', 'name_ar' => 'نقدية بالصندوق', 'name_en' => 'Cash on Hand', 'account_type' => 'asset', 'account_nature' => 'debit', 'parent_code' => '1201', 'level' => 4, 'is_header' => 1, 'is_system' => 1],
['account_code' => '12010101', 'name_ar' => 'الصندوق الرئيسي', 'name_en' => 'Main Cash Box', 'account_type' => 'asset', 'account_nature' => 'debit', 'parent_code' => '120101', 'level' => 5, 'is_header' => 0, 'is_system' => 1],
['account_code' => '120102', 'name_ar' => 'نقدية بالبنوك', 'name_en' => 'Cash at Banks', 'account_type' => 'asset', 'account_nature' => 'debit', 'parent_code' => '1201', 'level' => 4, 'is_header' => 1, 'is_system' => 1],
['account_code' => '12010201', 'name_ar' => 'البنك الرئيسي', 'name_en' => 'Main Bank Account', 'account_type' => 'asset', 'account_nature' => 'debit', 'parent_code' => '120102', 'level' => 5, 'is_header' => 0, 'is_system' => 1],
['account_code' => '120103', 'name_ar' => 'حسابات مدينة (مدينون)', 'name_en' => 'Accounts Receivable', 'account_type' => 'asset', 'account_nature' => 'debit', 'parent_code' => '1201', 'level' => 4, 'is_header' => 0, 'is_system' => 1],
['account_code' => '120104', 'name_ar' => 'شيكات تحت التحصيل', 'name_en' => 'Checks Under Collection', 'account_type' => 'asset', 'account_nature' => 'debit', 'parent_code' => '1201', 'level' => 4, 'is_header' => 0, 'is_system' => 0],
['account_code' => '120105', 'name_ar' => 'مخزون', 'name_en' => 'Inventory', 'account_type' => 'asset', 'account_nature' => 'debit', 'parent_code' => '1201', 'level' => 4, 'is_header' => 0, 'is_system' => 1],
['account_code' => '120106', 'name_ar' => 'مصروفات مقدمة', 'name_en' => 'Prepaid Expenses', 'account_type' => 'asset', 'account_nature' => 'debit', 'parent_code' => '1201', 'level' => 4, 'is_header' => 0, 'is_system' => 0],
['account_code' => '120107', 'name_ar' => 'سلف وقروض موظفين', 'name_en' => 'Employee Loans & Advances', 'account_type' => 'asset', 'account_nature' => 'debit', 'parent_code' => '1201', 'level' => 4, 'is_header' => 0, 'is_system' => 0],
['account_code' => '120108', 'name_ar' => 'ضريبة مدخلات (مشتريات)', 'name_en' => 'Input Tax (Purchases)', 'account_type' => 'asset', 'account_nature' => 'debit', 'parent_code' => '1201', 'level' => 4, 'is_header' => 0, 'is_system' => 1],
['account_code' => '120109', 'name_ar' => 'أوراق قبض', 'name_en' => 'Notes Receivable', 'account_type' => 'asset', 'account_nature' => 'debit', 'parent_code' => '1201', 'level' => 4, 'is_header' => 0, 'is_system' => 0],
// ══════════════════════════════════════════════════════════════════
// 2 — حقوق الملكية والإلتزامات (EQUITY & LIABILITIES)
// ══════════════════════════════════════════════════════════════════
['account_code' => '2', 'name_ar' => 'حقوق الملكية والإلتزامات', 'name_en' => 'Equity & Liabilities', 'account_type' => 'liability', 'account_nature' => 'credit', 'parent_code' => null, 'level' => 1, 'is_header' => 1, 'is_system' => 1],
// 21 — الإلتزامات (Liabilities)
['account_code' => '21', 'name_ar' => 'الإلتزامات', 'name_en' => 'Liabilities', 'account_type' => 'liability', 'account_nature' => 'credit', 'parent_code' => '2', 'level' => 2, 'is_header' => 1, 'is_system' => 1],
['account_code' => '2101', 'name_ar' => 'إلتزامات متداولة', 'name_en' => 'Current Liabilities', 'account_type' => 'liability', 'account_nature' => 'credit', 'parent_code' => '21', 'level' => 3, 'is_header' => 1, 'is_system' => 1],
['account_code' => '210101', 'name_ar' => 'حسابات دائنة (دائنون)', 'name_en' => 'Accounts Payable', 'account_type' => 'liability', 'account_nature' => 'credit', 'parent_code' => '2101', 'level' => 4, 'is_header' => 0, 'is_system' => 1],
['account_code' => '210102', 'name_ar' => 'مصروفات مستحقة', 'name_en' => 'Accrued Expenses', 'account_type' => 'liability', 'account_nature' => 'credit', 'parent_code' => '2101', 'level' => 4, 'is_header' => 0, 'is_system' => 0],
['account_code' => '210103', 'name_ar' => 'ضرائب مستحقة', 'name_en' => 'Tax Payable', 'account_type' => 'liability', 'account_nature' => 'credit', 'parent_code' => '2101', 'level' => 4, 'is_header' => 0, 'is_system' => 1],
['account_code' => '210104', 'name_ar' => 'تأمينات اجتماعية مستحقة', 'name_en' => 'Social Insurance Payable', 'account_type' => 'liability', 'account_nature' => 'credit', 'parent_code' => '2101', 'level' => 4, 'is_header' => 0, 'is_system' => 1],
['account_code' => '210105', 'name_ar' => 'إيرادات مؤجلة', 'name_en' => 'Deferred Revenue', 'account_type' => 'liability', 'account_nature' => 'credit', 'parent_code' => '2101', 'level' => 4, 'is_header' => 0, 'is_system' => 1],
['account_code' => '210106', 'name_ar' => 'تأمينات عضويات مستحقة', 'name_en' => 'Membership Deposits', 'account_type' => 'liability', 'account_nature' => 'credit', 'parent_code' => '2101', 'level' => 4, 'is_header' => 0, 'is_system' => 0],
['account_code' => '210107', 'name_ar' => 'تأمينات إيجارات مستحقة', 'name_en' => 'Rental Deposits Liability', 'account_type' => 'liability', 'account_nature' => 'credit', 'parent_code' => '2101', 'level' => 4, 'is_header' => 0, 'is_system' => 1],
['account_code' => '210108', 'name_ar' => 'مخصص مكافأة نهاية خدمة', 'name_en' => 'End of Service Provision', 'account_type' => 'liability', 'account_nature' => 'credit', 'parent_code' => '2101', 'level' => 4, 'is_header' => 0, 'is_system' => 0],
['account_code' => '210109', 'name_ar' => 'أوراق دفع', 'name_en' => 'Notes Payable', 'account_type' => 'liability', 'account_nature' => 'credit', 'parent_code' => '2101', 'level' => 4, 'is_header' => 0, 'is_system' => 0],
['account_code' => '2102', 'name_ar' => 'إلتزامات طويلة الأجل', 'name_en' => 'Long-term Liabilities', 'account_type' => 'liability', 'account_nature' => 'credit', 'parent_code' => '21', 'level' => 3, 'is_header' => 1, 'is_system' => 0],
['account_code' => '210201', 'name_ar' => 'قروض طويلة الأجل', 'name_en' => 'Long-term Loans', 'account_type' => 'liability', 'account_nature' => 'credit', 'parent_code' => '2102', 'level' => 4, 'is_header' => 0, 'is_system' => 0],
// 22 — حقوق الملكية (Equity)
['account_code' => '22', 'name_ar' => 'حقوق الملكية', 'name_en' => 'Equity', 'account_type' => 'equity', 'account_nature' => 'credit', 'parent_code' => '2', 'level' => 2, 'is_header' => 1, 'is_system' => 1],
['account_code' => '2201', 'name_ar' => 'رأس المال والاحتياطيات', 'name_en' => 'Capital & Reserves', 'account_type' => 'equity', 'account_nature' => 'credit', 'parent_code' => '22', 'level' => 3, 'is_header' => 1, 'is_system' => 1],
['account_code' => '220101', 'name_ar' => 'رأس المال', 'name_en' => 'Capital', 'account_type' => 'equity', 'account_nature' => 'credit', 'parent_code' => '2201', 'level' => 4, 'is_header' => 0, 'is_system' => 1],
['account_code' => '220102', 'name_ar' => 'أرباح محتجزة', 'name_en' => 'Retained Earnings', 'account_type' => 'equity', 'account_nature' => 'credit', 'parent_code' => '2201', 'level' => 4, 'is_header' => 0, 'is_system' => 1],
['account_code' => '220103', 'name_ar' => 'احتياطي قانوني', 'name_en' => 'Legal Reserve', 'account_type' => 'equity', 'account_nature' => 'credit', 'parent_code' => '2201', 'level' => 4, 'is_header' => 0, 'is_system' => 0],
['account_code' => '220104', 'name_ar' => 'احتياطي عام', 'name_en' => 'General Reserve', 'account_type' => 'equity', 'account_nature' => 'credit', 'parent_code' => '2201', 'level' => 4, 'is_header' => 0, 'is_system' => 0],
// ══════════════════════════════════════════════════════════════════
// 3 — التكاليف والمصروفات (EXPENSES)
// ══════════════════════════════════════════════════════════════════
['account_code' => '3', 'name_ar' => 'التكاليف والمصروفات', 'name_en' => 'Costs & Expenses', 'account_type' => 'expense', 'account_nature' => 'debit', 'parent_code' => null, 'level' => 1, 'is_header' => 1, 'is_system' => 1],
// 31 — مصروفات النشاط
['account_code' => '31', 'name_ar' => 'مصروفات النشاط', 'name_en' => 'Operating Expenses', 'account_type' => 'expense', 'account_nature' => 'debit', 'parent_code' => '3', 'level' => 2, 'is_header' => 1, 'is_system' => 1],
['account_code' => '3101', 'name_ar' => 'مصروفات الموظفين', 'name_en' => 'Personnel Expenses', 'account_type' => 'expense', 'account_nature' => 'debit', 'parent_code' => '31', 'level' => 3, 'is_header' => 1, 'is_system' => 1],
['account_code' => '310101', 'name_ar' => 'مصروفات رواتب وأجور', 'name_en' => 'Salaries & Wages', 'account_type' => 'expense', 'account_nature' => 'debit', 'parent_code' => '3101', 'level' => 4, 'is_header' => 0, 'is_system' => 1],
['account_code' => '310102', 'name_ar' => 'حصة صاحب العمل تأمينات', 'name_en' => 'Employer Social Insurance', 'account_type' => 'expense', 'account_nature' => 'debit', 'parent_code' => '3101', 'level' => 4, 'is_header' => 0, 'is_system' => 1],
['account_code' => '310103', 'name_ar' => 'بدلات وحوافز', 'name_en' => 'Allowances & Bonuses', 'account_type' => 'expense', 'account_nature' => 'debit', 'parent_code' => '3101', 'level' => 4, 'is_header' => 0, 'is_system' => 0],
['account_code' => '310104', 'name_ar' => 'مصروفات تدريب', 'name_en' => 'Training Expenses', 'account_type' => 'expense', 'account_nature' => 'debit', 'parent_code' => '3101', 'level' => 4, 'is_header' => 0, 'is_system' => 0],
['account_code' => '310105', 'name_ar' => 'مكافأة نهاية خدمة', 'name_en' => 'End of Service Benefits', 'account_type' => 'expense', 'account_nature' => 'debit', 'parent_code' => '3101', 'level' => 4, 'is_header' => 0, 'is_system' => 0],
// COGS
['account_code' => '3102', 'name_ar' => 'تكلفة البضاعة المباعة', 'name_en' => 'Cost of Goods Sold', 'account_type' => 'expense', 'account_nature' => 'debit', 'parent_code' => '31', 'level' => 3, 'is_header' => 0, 'is_system' => 1],
// Operating Expenses
['account_code' => '3103', 'name_ar' => 'مصروفات تشغيلية', 'name_en' => 'Operating Expenses', 'account_type' => 'expense', 'account_nature' => 'debit', 'parent_code' => '31', 'level' => 3, 'is_header' => 1, 'is_system' => 1],
['account_code' => '310301', 'name_ar' => 'مصاريف بنكية', 'name_en' => 'Bank Charges', 'account_type' => 'expense', 'account_nature' => 'debit', 'parent_code' => '3103', 'level' => 4, 'is_header' => 0, 'is_system' => 1],
['account_code' => '310302', 'name_ar' => 'مصروفات إيجار', 'name_en' => 'Rent Expense', 'account_type' => 'expense', 'account_nature' => 'debit', 'parent_code' => '3103', 'level' => 4, 'is_header' => 0, 'is_system' => 0],
['account_code' => '310303', 'name_ar' => 'مصروفات مرافق (كهرباء/مياه/غاز)', 'name_en' => 'Utilities', 'account_type' => 'expense', 'account_nature' => 'debit', 'parent_code' => '3103', 'level' => 4, 'is_header' => 0, 'is_system' => 0],
['account_code' => '310304', 'name_ar' => 'مصروفات صيانة', 'name_en' => 'Maintenance Expense', 'account_type' => 'expense', 'account_nature' => 'debit', 'parent_code' => '3103', 'level' => 4, 'is_header' => 0, 'is_system' => 0],
['account_code' => '310305', 'name_ar' => 'مصروفات إهلاك', 'name_en' => 'Depreciation Expense', 'account_type' => 'expense', 'account_nature' => 'debit', 'parent_code' => '3103', 'level' => 4, 'is_header' => 0, 'is_system' => 1],
['account_code' => '310306', 'name_ar' => 'مصروفات نظافة', 'name_en' => 'Cleaning Expense', 'account_type' => 'expense', 'account_nature' => 'debit', 'parent_code' => '3103', 'level' => 4, 'is_header' => 0, 'is_system' => 0],
['account_code' => '310307', 'name_ar' => 'مصروفات أمن وحراسة', 'name_en' => 'Security Expense', 'account_type' => 'expense', 'account_nature' => 'debit', 'parent_code' => '3103', 'level' => 4, 'is_header' => 0, 'is_system' => 0],
['account_code' => '310308', 'name_ar' => 'مصروفات تأمين (ممتلكات)', 'name_en' => 'Property Insurance', 'account_type' => 'expense', 'account_nature' => 'debit', 'parent_code' => '3103', 'level' => 4, 'is_header' => 0, 'is_system' => 0],
['account_code' => '310309', 'name_ar' => 'مصروفات اتصالات وإنترنت', 'name_en' => 'Communications', 'account_type' => 'expense', 'account_nature' => 'debit', 'parent_code' => '3103', 'level' => 4, 'is_header' => 0, 'is_system' => 0],
['account_code' => '310310', 'name_ar' => 'مصروفات مطبوعات وقرطاسية', 'name_en' => 'Printing & Stationery', 'account_type' => 'expense', 'account_nature' => 'debit', 'parent_code' => '3103', 'level' => 4, 'is_header' => 0, 'is_system' => 0],
['account_code' => '310311', 'name_ar' => 'مصروفات ضيافة', 'name_en' => 'Hospitality', 'account_type' => 'expense', 'account_nature' => 'debit', 'parent_code' => '3103', 'level' => 4, 'is_header' => 0, 'is_system' => 0],
['account_code' => '310312', 'name_ar' => 'مصروفات نقل ومواصلات', 'name_en' => 'Transportation', 'account_type' => 'expense', 'account_nature' => 'debit', 'parent_code' => '3103', 'level' => 4, 'is_header' => 0, 'is_system' => 0],
['account_code' => '310313', 'name_ar' => 'مصروفات إعلان وتسويق', 'name_en' => 'Marketing & Advertising', 'account_type' => 'expense', 'account_nature' => 'debit', 'parent_code' => '3103', 'level' => 4, 'is_header' => 0, 'is_system' => 0],
['account_code' => '310314', 'name_ar' => 'مصروفات رسوم حكومية', 'name_en' => 'Government Fees', 'account_type' => 'expense', 'account_nature' => 'debit', 'parent_code' => '3103', 'level' => 4, 'is_header' => 0, 'is_system' => 0],
['account_code' => '310315', 'name_ar' => 'مصروفات استشارات قانونية', 'name_en' => 'Legal & Professional Fees', 'account_type' => 'expense', 'account_nature' => 'debit', 'parent_code' => '3103', 'level' => 4, 'is_header' => 0, 'is_system' => 0],
['account_code' => '310316', 'name_ar' => 'مصروفات شحن ونقل مشتريات', 'name_en' => 'Shipping & Freight', 'account_type' => 'expense', 'account_nature' => 'debit', 'parent_code' => '3103', 'level' => 4, 'is_header' => 0, 'is_system' => 0],
['account_code' => '310399', 'name_ar' => 'مصروفات متنوعة', 'name_en' => 'Miscellaneous Expenses', 'account_type' => 'expense', 'account_nature' => 'debit', 'parent_code' => '3103', 'level' => 4, 'is_header' => 0, 'is_system' => 0],
// Sports & Activities Expenses
['account_code' => '3104', 'name_ar' => 'مصروفات أنشطة ورياضة', 'name_en' => 'Sports & Activities Expenses', 'account_type' => 'expense', 'account_nature' => 'debit', 'parent_code' => '31', 'level' => 3, 'is_header' => 1, 'is_system' => 0],
['account_code' => '310401', 'name_ar' => 'مصروفات أكاديميات رياضية', 'name_en' => 'Sports Academy Expenses', 'account_type' => 'expense', 'account_nature' => 'debit', 'parent_code' => '3104', 'level' => 4, 'is_header' => 0, 'is_system' => 0],
['account_code' => '310402', 'name_ar' => 'مصروفات مرافق ومعدات رياضية', 'name_en' => 'Sports Facilities Expenses', 'account_type' => 'expense', 'account_nature' => 'debit', 'parent_code' => '3104', 'level' => 4, 'is_header' => 0, 'is_system' => 0],
['account_code' => '310403', 'name_ar' => 'مصروفات فعاليات وبطولات', 'name_en' => 'Events & Tournaments', 'account_type' => 'expense', 'account_nature' => 'debit', 'parent_code' => '3104', 'level' => 4, 'is_header' => 0, 'is_system' => 0],
// ══════════════════════════════════════════════════════════════════
// 4 — الإيرادات (REVENUE) — CUSTOMIZED FOR CLUB
// ══════════════════════════════════════════════════════════════════
['account_code' => '4', 'name_ar' => 'الإيرادات', 'name_en' => 'Revenue', 'account_type' => 'revenue', 'account_nature' => 'credit', 'parent_code' => null, 'level' => 1, 'is_header' => 1, 'is_system' => 1],
// 41 — إيرادات النشاط
['account_code' => '41', 'name_ar' => 'إيرادات النشاط', 'name_en' => 'Operating Revenue', 'account_type' => 'revenue', 'account_nature' => 'credit', 'parent_code' => '4', 'level' => 2, 'is_header' => 1, 'is_system' => 1],
// 4101 — إيرادات العضويات
['account_code' => '4101', 'name_ar' => 'إيرادات العضويات', 'name_en' => 'Membership Revenue', 'account_type' => 'revenue', 'account_nature' => 'credit', 'parent_code' => '41', 'level' => 3, 'is_header' => 1, 'is_system' => 1],
['account_code' => '410101', 'name_ar' => 'رسوم استمارات', 'name_en' => 'Form Fee Revenue', 'account_type' => 'revenue', 'account_nature' => 'credit', 'parent_code' => '4101', 'level' => 4, 'is_header' => 0, 'is_system' => 1],
['account_code' => '410102', 'name_ar' => 'قيمة عضوية', 'name_en' => 'Membership Value Revenue', 'account_type' => 'revenue', 'account_nature' => 'credit', 'parent_code' => '4101', 'level' => 4, 'is_header' => 0, 'is_system' => 1],
['account_code' => '410103', 'name_ar' => 'رسوم إضافة ملحقين', 'name_en' => 'Dependent Addition Revenue', 'account_type' => 'revenue', 'account_nature' => 'credit', 'parent_code' => '4101', 'level' => 4, 'is_header' => 0, 'is_system' => 1],
// 4102 — إيرادات الاشتراكات
['account_code' => '4102', 'name_ar' => 'إيرادات الاشتراكات', 'name_en' => 'Subscription Revenue', 'account_type' => 'revenue', 'account_nature' => 'credit', 'parent_code' => '41', 'level' => 3, 'is_header' => 1, 'is_system' => 1],
['account_code' => '410201', 'name_ar' => 'اشتراك سنوي', 'name_en' => 'Annual Subscription', 'account_type' => 'revenue', 'account_nature' => 'credit', 'parent_code' => '4102', 'level' => 4, 'is_header' => 0, 'is_system' => 1],
['account_code' => '410202', 'name_ar' => 'رسوم تنمية', 'name_en' => 'Development Fee Revenue', 'account_type' => 'revenue', 'account_nature' => 'credit', 'parent_code' => '4102', 'level' => 4, 'is_header' => 0, 'is_system' => 1],
// 4103 — إيرادات التحويلات والحالات
['account_code' => '4103', 'name_ar' => 'إيرادات التحويلات والحالات', 'name_en' => 'Transfer & Cases Revenue', 'account_type' => 'revenue', 'account_nature' => 'credit', 'parent_code' => '41', 'level' => 3, 'is_header' => 1, 'is_system' => 1],
['account_code' => '410301', 'name_ar' => 'رسوم فصل', 'name_en' => 'Separation Fee Revenue', 'account_type' => 'revenue', 'account_nature' => 'credit', 'parent_code' => '4103', 'level' => 4, 'is_header' => 0, 'is_system' => 1],
['account_code' => '410302', 'name_ar' => 'رسوم طلاق', 'name_en' => 'Divorce Fee Revenue', 'account_type' => 'revenue', 'account_nature' => 'credit', 'parent_code' => '4103', 'level' => 4, 'is_header' => 0, 'is_system' => 1],
['account_code' => '410303', 'name_ar' => 'رسوم نقل وفاة', 'name_en' => 'Death Transfer Fee Revenue', 'account_type' => 'revenue', 'account_nature' => 'credit', 'parent_code' => '4103', 'level' => 4, 'is_header' => 0, 'is_system' => 1],
['account_code' => '410304', 'name_ar' => 'رسوم تنازل', 'name_en' => 'Waiver Fee Revenue', 'account_type' => 'revenue', 'account_nature' => 'credit', 'parent_code' => '4103', 'level' => 4, 'is_header' => 0, 'is_system' => 1],
['account_code' => '410305', 'name_ar' => 'تحويل رياضي', 'name_en' => 'Sports Conversion Revenue', 'account_type' => 'revenue', 'account_nature' => 'credit', 'parent_code' => '4103', 'level' => 4, 'is_header' => 0, 'is_system' => 1],
// 4104 — إيرادات عضويات خاصة
['account_code' => '4104', 'name_ar' => 'إيرادات عضويات خاصة', 'name_en' => 'Special Memberships Revenue', 'account_type' => 'revenue', 'account_nature' => 'credit', 'parent_code' => '41', 'level' => 3, 'is_header' => 1, 'is_system' => 1],
['account_code' => '410401', 'name_ar' => 'عضوية موسمية', 'name_en' => 'Seasonal Membership Revenue', 'account_type' => 'revenue', 'account_nature' => 'credit', 'parent_code' => '4104', 'level' => 4, 'is_header' => 0, 'is_system' => 1],
['account_code' => '410402', 'name_ar' => 'بدل فاقد كارنيه', 'name_en' => 'Carnet Replacement Revenue', 'account_type' => 'revenue', 'account_nature' => 'credit', 'parent_code' => '4104', 'level' => 4, 'is_header' => 0, 'is_system' => 1],
['account_code' => '410403', 'name_ar' => 'عضوية أجنبية', 'name_en' => 'Foreign Membership Revenue', 'account_type' => 'revenue', 'account_nature' => 'credit', 'parent_code' => '4104', 'level' => 4, 'is_header' => 0, 'is_system' => 0],
// 4105 — إيرادات الأنشطة والرياضة
['account_code' => '4105', 'name_ar' => 'إيرادات الأنشطة والرياضة', 'name_en' => 'Activities & Sports Revenue', 'account_type' => 'revenue', 'account_nature' => 'credit', 'parent_code' => '41', 'level' => 3, 'is_header' => 1, 'is_system' => 1],
['account_code' => '410501', 'name_ar' => 'اشتراكات أنشطة', 'name_en' => 'Activity Subscription Revenue','account_type' => 'revenue', 'account_nature' => 'credit', 'parent_code' => '4105', 'level' => 4, 'is_header' => 0, 'is_system' => 1],
['account_code' => '410502', 'name_ar' => 'أكاديميات رياضية', 'name_en' => 'Sports Academy Revenue', 'account_type' => 'revenue', 'account_nature' => 'credit', 'parent_code' => '4105', 'level' => 4, 'is_header' => 0, 'is_system' => 1],
// 4106 — إيرادات الغرامات
['account_code' => '4106', 'name_ar' => 'إيرادات الغرامات', 'name_en' => 'Fine Revenue', 'account_type' => 'revenue', 'account_nature' => 'credit', 'parent_code' => '41', 'level' => 3, 'is_header' => 0, 'is_system' => 1],
// 4107 — إيرادات المبيعات
['account_code' => '4107', 'name_ar' => 'إيرادات المبيعات', 'name_en' => 'Sales Revenue', 'account_type' => 'revenue', 'account_nature' => 'credit', 'parent_code' => '41', 'level' => 3, 'is_header' => 0, 'is_system' => 1],
// 4108 — إيرادات الإيجارات
['account_code' => '4108', 'name_ar' => 'إيرادات الإيجارات', 'name_en' => 'Rental Revenue', 'account_type' => 'revenue', 'account_nature' => 'credit', 'parent_code' => '41', 'level' => 3, 'is_header' => 0, 'is_system' => 0],
// 4109 — إيرادات الأقساط
['account_code' => '4109', 'name_ar' => 'إيرادات الأقساط', 'name_en' => 'Installment Revenue', 'account_type' => 'revenue', 'account_nature' => 'credit', 'parent_code' => '41', 'level' => 3, 'is_header' => 1, 'is_system' => 1],
['account_code' => '410901', 'name_ar' => 'مقدمات تقسيط', 'name_en' => 'Down Payment Revenue', 'account_type' => 'revenue', 'account_nature' => 'credit', 'parent_code' => '4109', 'level' => 4, 'is_header' => 0, 'is_system' => 0],
['account_code' => '410902', 'name_ar' => 'أقساط شهرية', 'name_en' => 'Monthly Installment Revenue', 'account_type' => 'revenue', 'account_nature' => 'credit', 'parent_code' => '4109', 'level' => 4, 'is_header' => 0, 'is_system' => 0],
// 4110 — إيرادات خدمات (catch-all)
['account_code' => '4110', 'name_ar' => 'إيرادات خدمات', 'name_en' => 'Service Revenue', 'account_type' => 'revenue', 'account_nature' => 'credit', 'parent_code' => '41', 'level' => 3, 'is_header' => 0, 'is_system' => 1],
// 42 — إيرادات أخرى
['account_code' => '42', 'name_ar' => 'إيرادات أخرى', 'name_en' => 'Other Revenue', 'account_type' => 'revenue', 'account_nature' => 'credit', 'parent_code' => '4', 'level' => 2, 'is_header' => 1, 'is_system' => 0],
['account_code' => '4201', 'name_ar' => 'فوائد بنكية دائنة', 'name_en' => 'Bank Interest Income', 'account_type' => 'revenue', 'account_nature' => 'credit', 'parent_code' => '42', 'level' => 3, 'is_header' => 0, 'is_system' => 1],
['account_code' => '4202', 'name_ar' => 'إيرادات متنوعة', 'name_en' => 'Miscellaneous Income', 'account_type' => 'revenue', 'account_nature' => 'credit', 'parent_code' => '42', 'level' => 3, 'is_header' => 0, 'is_system' => 0],
];
// ─────────────────────────────────────────────────────────────
// Step 3: Insert accounts with parent resolution
// ─────────────────────────────────────────────────────────────
$codeToId = [];
foreach ($accounts as $acct) {
$existing = $db->selectOne(
"SELECT id FROM chart_of_accounts WHERE account_code = ?",
[$acct['account_code']]
);
if ($existing) {
$codeToId[$acct['account_code']] = (int) $existing['id'];
// Ensure it's active
$db->execute(
"UPDATE chart_of_accounts SET is_active = 1, updated_at = ? WHERE id = ? AND is_active = 0",
[$now, (int) $existing['id']]
);
continue;
}
$parentId = null;
$parentCode = $acct['parent_code'] ?? null;
if ($parentCode !== null && isset($codeToId[$parentCode])) {
$parentId = $codeToId[$parentCode];
}
unset($acct['parent_code']);
$insertId = $db->insert('chart_of_accounts', array_merge($acct, [
'parent_id' => $parentId,
'opening_balance' => '0.00',
'current_balance' => '0.00',
'is_active' => 1,
'created_at' => $now,
'updated_at' => $now,
]));
$codeToId[$acct['account_code']] = $insertId;
}
};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment