---
description: توثيق ربط الخزائن بالحسابات في شجرة الحسابات
alwaysApply: true
---

# ربط الخزائن بالحسابات في شجرة الحسابات

## المشكلة

يجب أن تكون كل خزينة في النظام مرتبطة بحساب فرعي في شجرة الحسابات بنفس اسم الخزينة. هذا الربط ضروري لضمان التكامل بين نظام الخزائن ونظام المحاسبة، حيث يتم تسجيل جميع معاملات الخزينة تلقائياً في الحساب المرتبط بها.

## الحل المطلوب

1. **التحقق من وجود حساب لكل خزينة**: يجب التأكد من أن كل خزينة لها حساب فرعي مقابل في شجرة الحسابات بنفس اسم الخزينة.
2. **إنشاء حسابات للخزائن الجديدة**: عند إنشاء خزينة جديدة، يجب إنشاء حساب فرعي لها تلقائياً في شجرة الحسابات.
3. **ربط الخزائن بالحسابات**: يجب ربط كل خزينة بالحساب المقابل لها في جدول `cash_register_accounts`.

## هيكل البيانات

### جدول الخزائن (cash_registers)

يحتوي على معلومات الخزائن في النظام:

```php
protected $fillable = [
    'name',
    'code',
    'description',
    'company_id',
    'branch_id',
    'responsible_user_id',
    'initial_balance',
    'current_balance',
    'currency',
    'is_active',
    'is_main'
];
```

### جدول شجرة الحسابات (chart_of_accounts)

يحتوي على معلومات الحسابات في النظام:

```php
protected $fillable = [
    'company_id',
    'account_code',
    'name',
    'name_en',
    'account_type',
    'sub_type',
    'parent_id',
    'description',
    'is_active',
    'is_system',
    'opening_balance',
    'current_balance',
    'currency',
    'balance_type',
    'is_cash_account',
    'is_bank_account',
    'level'
];
```

### جدول ربط الخزائن بالحسابات (cash_register_accounts)

جدول وسيط يربط بين الخزائن والحسابات:

```php
Schema::create('cash_register_accounts', function (Blueprint $table) {
    $table->id();
    $table->foreignId('cash_register_id')->constrained()->onDelete('cascade');
    $table->foreignId('account_id')->constrained('chart_of_accounts')->onDelete('cascade');
    $table->timestamps();
    $table->unique(['cash_register_id', 'account_id']);
});
```

## آلية الربط

### 1. إنشاء حساب للخزينة

عند إنشاء خزينة جديدة، يجب إنشاء حساب فرعي لها في شجرة الحسابات:

```php
// إنشاء حساب للخزينة
$parentAccount = ChartOfAccount::where('company_id', $companyId)
    ->where('account_type', 'asset')
    ->where('is_cash_account', true)
    ->where('parent_id', null)
    ->first();

if ($parentAccount) {
    $account = ChartOfAccount::create([
        'company_id' => $companyId,
        'account_code' => 'CASH-' . $cashRegister->id,
        'name' => $cashRegister->name,
        'name_en' => $cashRegister->name,
        'account_type' => 'asset',
        'sub_type' => 'cash',
        'parent_id' => $parentAccount->id,
        'description' => 'حساب الخزينة: ' . $cashRegister->name,
        'is_active' => true,
        'is_system' => false,
        'opening_balance' => $cashRegister->initial_balance,
        'current_balance' => $cashRegister->current_balance,
        'currency' => $cashRegister->currency,
        'balance_type' => 'debit',
        'is_cash_account' => true,
        'is_bank_account' => false,
        'level' => $parentAccount->level + 1
    ]);
}
```

### 2. ربط الخزينة بالحساب

بعد إنشاء الحساب، يجب ربط الخزينة بالحساب في جدول `cash_register_accounts`:

```php
// ربط الخزينة بالحساب
DB::table('cash_register_accounts')->insert([
    'cash_register_id' => $cashRegister->id,
    'account_id' => $account->id,
    'created_at' => now(),
    'updated_at' => now()
]);
```

### 3. تحديث الحساب عند تحديث الخزينة

عند تحديث اسم الخزينة أو معلوماتها، يجب تحديث الحساب المرتبط بها:

```php
// تحديث الحساب المرتبط بالخزينة
$accountId = DB::table('cash_register_accounts')
    ->where('cash_register_id', $cashRegister->id)
    ->value('account_id');

if ($accountId) {
    ChartOfAccount::where('id', $accountId)->update([
        'name' => $cashRegister->name,
        'name_en' => $cashRegister->name,
        'description' => 'حساب الخزينة: ' . $cashRegister->name,
        'is_active' => $cashRegister->is_active,
        'currency' => $cashRegister->currency
    ]);
}
```

## التنفيذ المقترح

### 1. تعديل CashRegisterController

يجب تعديل وحدة التحكم `CashRegisterController` لإضافة وظائف إنشاء وربط الحسابات:

```php
/**
 * إنشاء حساب للخزينة وربطه بها
 */
private function createAndLinkAccount(CashRegister $cashRegister)
{
    // البحث عن حساب الأصول النقدية الرئيسي
    $parentAccount = ChartOfAccount::where('company_id', $cashRegister->company_id)
        ->where('account_type', 'asset')
        ->where('is_cash_account', true)
        ->where('parent_id', null)
        ->first();

    if (!$parentAccount) {
        // إنشاء حساب الأصول النقدية الرئيسي إذا لم يكن موجوداً
        $parentAccount = ChartOfAccount::create([
            'company_id' => $cashRegister->company_id,
            'account_code' => 'CASH',
            'name' => 'النقدية',
            'name_en' => 'Cash',
            'account_type' => 'asset',
            'sub_type' => 'cash',
            'parent_id' => null,
            'description' => 'حساب النقدية الرئيسي',
            'is_active' => true,
            'is_system' => true,
            'opening_balance' => 0,
            'current_balance' => 0,
            'currency' => $cashRegister->currency,
            'balance_type' => 'debit',
            'is_cash_account' => true,
            'is_bank_account' => false,
            'level' => 1
        ]);
    }

    // إنشاء حساب للخزينة
    $account = ChartOfAccount::create([
        'company_id' => $cashRegister->company_id,
        'account_code' => 'CASH-' . $cashRegister->id,
        'name' => $cashRegister->name,
        'name_en' => $cashRegister->name,
        'account_type' => 'asset',
        'sub_type' => 'cash',
        'parent_id' => $parentAccount->id,
        'description' => 'حساب الخزينة: ' . $cashRegister->name,
        'is_active' => $cashRegister->is_active,
        'is_system' => false,
        'opening_balance' => $cashRegister->initial_balance,
        'current_balance' => $cashRegister->current_balance,
        'currency' => $cashRegister->currency,
        'balance_type' => 'debit',
        'is_cash_account' => true,
        'is_bank_account' => false,
        'level' => $parentAccount->level + 1
    ]);

    // ربط الخزينة بالحساب
    DB::table('cash_register_accounts')->insert([
        'cash_register_id' => $cashRegister->id,
        'account_id' => $account->id,
        'created_at' => now(),
        'updated_at' => now()
    ]);

    return $account;
}
```

### 2. تعديل طريقة store في CashRegisterController

```php
public function store(Request $request)
{
    // التحقق من البيانات وإنشاء الخزينة
    // ...

    $cashRegister = CashRegister::create($data);

    // إنشاء حساب للخزينة وربطه بها
    $this->createAndLinkAccount($cashRegister);

    return redirect()->route('cash-registers.index')
        ->with('success', 'تم إنشاء الخزينة بنجاح');
}
```

### 3. تعديل طريقة update في CashRegisterController

```php
public function update(Request $request, $id)
{
    // التحقق من البيانات وتحديث الخزينة
    // ...

    $cashRegister->update($data);

    // تحديث الحساب المرتبط بالخزينة
    $accountId = DB::table('cash_register_accounts')
        ->where('cash_register_id', $cashRegister->id)
        ->value('account_id');

    if ($accountId) {
        ChartOfAccount::where('id', $accountId)->update([
            'name' => $cashRegister->name,
            'name_en' => $cashRegister->name,
            'description' => 'حساب الخزينة: ' . $cashRegister->name,
            'is_active' => $cashRegister->is_active,
            'currency' => $cashRegister->currency
        ]);
    } else {
        // إنشاء حساب للخزينة وربطه بها إذا لم يكن موجوداً
        $this->createAndLinkAccount($cashRegister);
    }

    return redirect()->route('cash-registers.index')
        ->with('success', 'تم تحديث الخزينة بنجاح');
}
```

## سكريبت لإصلاح الخزائن الحالية

يمكن استخدام السكريبت التالي لإصلاح الخزائن الحالية التي ليس لها حسابات مرتبطة:

```php
<?php

use App\Models\CashRegister;
use App\Models\ChartOfAccount;
use Illuminate\Support\Facades\DB;

// الحصول على جميع الخزائن
$cashRegisters = CashRegister::all();

foreach ($cashRegisters as $cashRegister) {
    // التحقق مما إذا كانت الخزينة مرتبطة بحساب
    $hasAccount = DB::table('cash_register_accounts')
        ->where('cash_register_id', $cashRegister->id)
        ->exists();

    if (!$hasAccount) {
        // البحث عن حساب الأصول النقدية الرئيسي
        $parentAccount = ChartOfAccount::where('company_id', $cashRegister->company_id)
            ->where('account_type', 'asset')
            ->where('is_cash_account', true)
            ->where('parent_id', null)
            ->first();

        if (!$parentAccount) {
            // إنشاء حساب الأصول النقدية الرئيسي إذا لم يكن موجوداً
            $parentAccount = ChartOfAccount::create([
                'company_id' => $cashRegister->company_id,
                'account_code' => 'CASH',
                'name' => 'النقدية',
                'name_en' => 'Cash',
                'account_type' => 'asset',
                'sub_type' => 'cash',
                'parent_id' => null,
                'description' => 'حساب النقدية الرئيسي',
                'is_active' => true,
                'is_system' => true,
                'opening_balance' => 0,
                'current_balance' => 0,
                'currency' => $cashRegister->currency,
                'balance_type' => 'debit',
                'is_cash_account' => true,
                'is_bank_account' => false,
                'level' => 1
            ]);
        }

        // إنشاء حساب للخزينة
        $account = ChartOfAccount::create([
            'company_id' => $cashRegister->company_id,
            'account_code' => 'CASH-' . $cashRegister->id,
            'name' => $cashRegister->name,
            'name_en' => $cashRegister->name,
            'account_type' => 'asset',
            'sub_type' => 'cash',
            'parent_id' => $parentAccount->id,
            'description' => 'حساب الخزينة: ' . $cashRegister->name,
            'is_active' => $cashRegister->is_active,
            'is_system' => false,
            'opening_balance' => $cashRegister->initial_balance,
            'current_balance' => $cashRegister->current_balance,
            'currency' => $cashRegister->currency,
            'balance_type' => 'debit',
            'is_cash_account' => true,
            'is_bank_account' => false,
            'level' => $parentAccount->level + 1
        ]);

        // ربط الخزينة بالحساب
        DB::table('cash_register_accounts')->insert([
            'cash_register_id' => $cashRegister->id,
            'account_id' => $account->id,
            'created_at' => now(),
            'updated_at' => now()
        ]);

        echo "تم إنشاء وربط حساب للخزينة: {$cashRegister->name}\n";
    } else {
        echo "الخزينة {$cashRegister->name} مرتبطة بالفعل بحساب\n";
    }
}

echo "تم الانتهاء من إصلاح جميع الخزائن\n";
```

## ملاحظات هامة

1. يجب التأكد من أن كل خزينة مرتبطة بحساب واحد فقط في شجرة الحسابات.
2. يجب أن يكون اسم الحساب مطابقاً لاسم الخزينة.
3. عند تغيير اسم الخزينة، يجب تحديث اسم الحساب المرتبط بها.
4. عند حذف الخزينة، يجب حذف الحساب المرتبط بها (يتم ذلك تلقائياً بفضل قيد `onDelete('cascade')` في جدول `cash_register_accounts`).
5. يجب أن تكون جميع حسابات الخزائن من نوع `asset` وتحت نوع `cash` وتحت حساب الأصول النقدية الرئيسي.