ultimatepos/Modules/Accounting/Services/IranianChartOfAccountsService.php

96 lines
5.2 KiB
PHP

<?php
namespace Modules\Accounting\Services;
use Illuminate\Support\Facades\DB;
use Modules\Accounting\Entities\AccountingAccount;
class IranianChartOfAccountsService
{
/**
* Standard Iranian-style chart skeleton (معین / کل).
*
* @return array<int, array{gl_code: string, name: string, account_primary_type: string, children?: array}>
*/
public function template(): array
{
return [
['gl_code' => '1', 'name' => 'دارایی‌ها', 'account_primary_type' => 'asset', 'children' => [
['gl_code' => '11', 'name' => 'دارایی‌های جاری', 'account_primary_type' => 'asset', 'children' => [
['gl_code' => '1101', 'name' => 'صندوق', 'account_primary_type' => 'asset'],
['gl_code' => '1102', 'name' => 'بانک', 'account_primary_type' => 'asset'],
['gl_code' => '1103', 'name' => 'حساب‌های دریافتنی', 'account_primary_type' => 'asset'],
['gl_code' => '1104', 'name' => 'اسناد دریافتنی', 'account_primary_type' => 'asset'],
['gl_code' => '1105', 'name' => 'موجودی کالا', 'account_primary_type' => 'asset'],
]],
['gl_code' => '12', 'name' => 'دارایی‌های غیرجاری', 'account_primary_type' => 'asset', 'children' => [
['gl_code' => '1201', 'name' => 'دارایی ثابت', 'account_primary_type' => 'asset'],
['gl_code' => '1202', 'name' => 'استهلاک انباشته', 'account_primary_type' => 'asset'],
]],
]],
['gl_code' => '2', 'name' => 'بدهی‌ها', 'account_primary_type' => 'liability', 'children' => [
['gl_code' => '21', 'name' => 'بدهی‌های جاری', 'account_primary_type' => 'liability', 'children' => [
['gl_code' => '2101', 'name' => 'حساب‌های پرداختنی', 'account_primary_type' => 'liability'],
['gl_code' => '2102', 'name' => 'اسناد پرداختنی', 'account_primary_type' => 'liability'],
['gl_code' => '2103', 'name' => 'مالیات پرداختنی', 'account_primary_type' => 'liability'],
['gl_code' => '2104', 'name' => 'وام‌های کوتاه‌مدت', 'account_primary_type' => 'liability'],
]],
]],
['gl_code' => '3', 'name' => 'حقوق صاحبان سهام', 'account_primary_type' => 'equity', 'children' => [
['gl_code' => '31', 'name' => 'سرمایه', 'account_primary_type' => 'equity'],
['gl_code' => '32', 'name' => 'سود (زیان) انباشته', 'account_primary_type' => 'equity'],
]],
['gl_code' => '4', 'name' => 'درآمدها', 'account_primary_type' => 'income', 'children' => [
['gl_code' => '41', 'name' => 'فروش کالا و خدمات', 'account_primary_type' => 'income'],
['gl_code' => '42', 'name' => 'درآمد متفرقه', 'account_primary_type' => 'income'],
]],
['gl_code' => '5', 'name' => 'هزینه‌ها', 'account_primary_type' => 'expenses', 'children' => [
['gl_code' => '51', 'name' => 'بهای تمام‌شده کالای فروش‌رفته', 'account_primary_type' => 'expenses'],
['gl_code' => '52', 'name' => 'هزینه‌های اداری و عمومی', 'account_primary_type' => 'expenses'],
['gl_code' => '53', 'name' => 'هزینه حقوق و دستمزد', 'account_primary_type' => 'expenses'],
['gl_code' => '54', 'name' => 'هزینه استهلاک', 'account_primary_type' => 'expenses'],
]],
];
}
public function seed(int $businessId, int $userId, bool $skipExisting = true): int
{
$created = 0;
DB::transaction(function () use ($businessId, $userId, $skipExisting, &$created) {
foreach ($this->template() as $node) {
$created += $this->createNode($businessId, $userId, $node, null, $skipExisting);
}
});
return $created;
}
protected function createNode(int $businessId, int $userId, array $node, ?int $parentId, bool $skipExisting): int
{
$created = 0;
if ($skipExisting && AccountingAccount::where('business_id', $businessId)->where('gl_code', $node['gl_code'])->exists()) {
$accountId = AccountingAccount::where('business_id', $businessId)->where('gl_code', $node['gl_code'])->value('id');
} else {
$account = AccountingAccount::create([
'name' => $node['name'],
'gl_code' => $node['gl_code'],
'business_id' => $businessId,
'account_primary_type' => $node['account_primary_type'],
'parent_account_id' => $parentId,
'status' => 'active',
'created_by' => $userId,
]);
$accountId = $account->id;
$created++;
}
foreach ($node['children'] ?? [] as $child) {
$created += $this->createNode($businessId, $userId, $child, $accountId, $skipExisting);
}
return $created;
}
}