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,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`",
];
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