1) use trait in model 
 use HasInvoiceNumber, Accountable, DraftOrderAccounting;
2) use boot in model as like
 protected static function boot()
    {
        parent::boot();
        // static::creating(function ($draftOrder) {
        //     info('creating_invoice');
        //     $draftOrder->invoice_number = $draftOrder->generateInvoiceNumber('do');

        
        static::creating(function ($model) {
            $model->invoice_number = $model->generateInvoiceNumber('do');
        });
    }

    protected static function booted()
    {
        parent::booted();

        static::created(function ($model) {
            $model->handleAccountingEntries('create', $model);
        });

        static::updated(function ($model) {
                // $model->handleAccountingEntries('update');
        });

        static::deleted(function ($model) {
            // $model->handleAccountingEntries('delete');
        });
    }

3) in DraftOrderAccounting trait use like 
 a)
    /*-----*/
    <?php

    namespace App\Traits;

    use App\Services\AccountService;
    use App\Models\DraftOrder;
    use Illuminate\Support\Facades\App;
    use Illuminate\Support\Facades\DB;
    use App\Models\Voucher;
    use App\Models\Invoice;
    use App\Models\AutoEntry;
    use App\Models\VoucherEntry;

    trait DraftOrderAccounting
    {

        protected $AccServcreditAccountId;
        protected $AccServdebitAccountId;
        protected $AccServamount;
        protected $AccServvoucherType;
        protected $AccServvoucherDescription;
        protected $AccServinvoiceable_type;
        protected $AccServinvoiceable_id;
        protected $AccServvoucherInvoiceNo;
        protected $AccServvoucherDate;
        protected $AccServAccountService;
        protected $AccServsourceType;


        public function initModel($model = null)
        {
            $this->AccServcreditAccountId = config('account_heads.draft-order.purchase_account_id');
            $this->AccServdebitAccountId = config('account_heads.draft-order.ap_account_id');
            $this->AccServamount = $model->grand_total;
            $this->AccServvoucherType = 'debit';
            $this->AccServvoucherDescription = 'Do Created for ' . $this->supplier_id. "Challan No: " . $model->challan_no. "Invoice No: 
            " . $this->invoice_number;
            $this->AccServinvoiceable_type = get_class($this);
            $this->AccServinvoiceable_id = $model->id;
            $this->AccServvoucherInvoiceNo = $model->invoice_number;
            $this->AccServvoucherDate = $model->date;
            $this->AccServsourceType = 'purchase';
            $this->AccServAccountService = new AccountService();
        }

        public function handleAccountingEntries(string $action, $model = null)
        {
            $this->initModel($model);
            info("Handling accounting entries for action: $action", ['draft_order_id' => $this->id]);
                switch ($action) {
                    case 'create':
                        info("Creating accounting entries for draft order: $this->id");
                        $this->createAccountingEntries();
                        break;
                    // case 'update':
                    //     info("Updating accounting entries for draft order: $this->id");
                    //     $this->updateAccountingEntries();
                    //     break;
                    // case 'delete':
                    //     info("Deleting accounting entries for draft order: $this->id");
                    //     $this->deleteAccountingEntries();
                    //     break;
                    default:
                        info("Invalid action: $action");
                        break;
                }
        }

        protected function createAccountingEntries()
        {

            DB::beginTransaction();
            try {
                
                $voucher = $this->AccServAccountService->createVoucherAndEntries([
                                'voucher_no' => $this->AccServvoucherInvoiceNo,
                                'type' => $this->AccServvoucherType,
                                'date' => $this->AccServvoucherDate,
                                'description' => $this->AccServvoucherDescription,
                                'entries' => [
                                    [
                                        'account_head_id' => $this->AccServdebitAccountId,
                                        'amount' => $this->AccServamount,
                                        'entry_type' => 'debit',
                                        'note' => $this->AccServvoucherDescription ?? null,
                                        'accountable_type' => $this->AccServinvoiceable_type,
                                        'accountable_id' => $this->AccServinvoiceable_id
                                    ],
                                    [
                                        'account_head_id' => $this->AccServcreditAccountId,   
                                        'amount' => $this->AccServamount,
                                        'entry_type' => 'credit',
                                        'note' => $this->AccServvoucherDescription ?? null,
                                        'accountable_type' => $this->AccServinvoiceable_type,
                                        'accountable_id' => $this->AccServinvoiceable_id
                                    ]
                                ]
                            ]);
                            
                
                $invoice = $this->AccServAccountService->createInvoice([
                    'invoice_no' => $this->AccServvoucherInvoiceNo,
                    'account_head_id' => $this->AccServdebitAccountId,
                    'voucher_id' => $voucher->id,
                    'amount' => $this->AccServamount,
                    'date' => $this->AccServvoucherDate,
                    'description' => $this->AccServvoucherDescription ?? null,
                    'invoiceable_type' => $this->AccServinvoiceable_type,
                    'invoiceable_id' => $this->AccServinvoiceable_id
                ]);

                $autoEntry = $this->AccServAccountService->createAutoEntry([
                    'source_type' => $this->AccServsourceType,
                    'source_id' => $this->AccServinvoiceable_id,
                    'voucher_id' => $voucher->id,
                    'autoentryable_type' => $this->AccServinvoiceable_type,
                    'autoentryable_id' => $this->AccServinvoiceable_id,
                ]);            
                DB::commit();
            } catch (\Exception $e) {
                DB::rollBack();
            info('Error creating accounting entries: ' . $e->getMessage());
                throw $e;
            }
        }
    }

    /*-----*/
 b)


     /*-----*/
    <?php

    namespace App\Traits;

    use App\Services\AccountService;
    use App\Models\DraftOrder;
    use Illuminate\Support\Facades\App;
    use Illuminate\Support\Facades\DB;
    use App\Models\Voucher;
    use App\Models\Invoice;
    use App\Models\AutoEntry;
    use App\Models\VoucherEntry;

    trait DraftOrderAccounting
    {

        protected $AccServcreditAccountId;
        protected $AccServdebitAccountId;
        protected $AccServamount;
        protected $AccServvoucherType;
        protected $AccServvoucherDescription;
        protected $AccServinvoiceable_type;
        protected $AccServinvoiceable_id;
        protected $AccServvoucherInvoiceNo;
        protected $AccServvoucherDate;
        protected $AccServAccountService;
        protected $AccServsourceType;


        public function initModel($model = null)
        {
            $this->AccServcreditAccountId = config('account_heads.draft-order.purchase_account_id');
            $this->AccServdebitAccountId = config('account_heads.draft-order.ap_account_id');
            $this->AccServamount = $model->grand_total;
            $this->AccServvoucherType = 'debit';
            $this->AccServvoucherDescription = 'Do Created for ' . $this->supplier_id. "Challan No: " . $model->challan_no. "Invoice No: 
            " . $this->invoice_number;
            $this->AccServinvoiceable_type = get_class($this);
            $this->AccServinvoiceable_id = $model->id;
            $this->AccServvoucherInvoiceNo = $model->invoice_number;
            $this->AccServvoucherDate = $model->date;
            $this->AccServsourceType = 'purchase';
            $this->AccServAccountService = new AccountService();
        }

        public function handleAccountingEntries(string $action, $model = null)
        {
            $this->initModel($model);
            info("Handling accounting entries for action: $action", ['draft_order_id' => $this->id]);
                switch ($action) {
                    case 'create':
                        info("Creating accounting entries for draft order: $this->id");
                        $this->createAccountingEntries();
                        break;
                    // case 'update':
                    //     info("Updating accounting entries for draft order: $this->id");
                    //     $this->updateAccountingEntries();
                    //     break;
                    // case 'delete':
                    //     info("Deleting accounting entries for draft order: $this->id");
                    //     $this->deleteAccountingEntries();
                    //     break;
                    default:
                        info("Invalid action: $action");
                        break;
                }
        }

        protected function createAccountingEntries()
        {

            DB::beginTransaction();
            try {
                
            $voucher = $this->AccServAccountService->createVoucher([
                 'voucher_no' => $this->AccServvoucherInvoiceNo,
                 'type' => 'debit',
                 'date' => $this->AccServvoucherDate,
                 'description' => 'Do Created for ',
             ]);
            // Create voucher entries
             $voucherEntry1 = $this->createVoucherEntry([
                 'account_head_id' => $this->AccServcreditAccountId,
                 'amount' => $this->AccServamount,
                 'voucher_id' => $voucher->id,   
                 'entry_type' => $this->AccServvoucherType,
                 'note' => $this->AccServvoucherDescription ?? null,
             ]);

             $voucherEntry2 = $this->createVoucherEntry([
                 'account_head_id' => $this->AccServdebitAccountId,
                 'voucher_id' => $voucher->id,
                 'amount' => $this->AccServamount,
                 'entry_type' => $this->AccServvoucherType,
                 'note' => $this->AccServvoucherDescription ?? null,
             ]);

             Create invoice
             $this->createInvoice([
                 'invoice_no' => $this->AccServvoucherInvoiceNo,
                 'account_head_id' => $this->AccServdebitAccountId,
                 'voucher_id' => $voucher->id,
                 'amount' => $this->AccServamount,
                 'date' => $this->AccServvoucherDate,
                 'description' => $this->AccServvoucherDescription ?? null,
                 'invoiceable_type' => $this->AccServinvoiceable_type,
                 'invoiceable_id' => $this->AccServinvoiceable_id
             ]);

             Create auto entry
             $this->createAutoEntry([
                 'source_type' => $this->AccServsourceType,
                 'source_id' => $this->AccServinvoiceable_id,
                 'voucher_id' => $voucher->id
             ]);

            DB::commit();
            } catch (\Exception $e) {
                DB::rollBack();
            info('Error creating accounting entries: ' . $e->getMessage());
                throw $e;
            }
        }
    }

    /*-----*/

4) AccountService

<?php

namespace App\Services;

use App\Models\Voucher;
use App\Models\VoucherEntry;
use App\Models\Invoice;
use App\Models\AutoEntry;
use App\Models\AccountHead;
use Illuminate\Support\Facades\DB;

class AccountService
{
    public function createVoucher(array $data): Voucher
    {
        return DB::transaction(function () use ($data) {
            $voucher = Voucher::create([
                'voucher_no' => $data['voucher_no'],
                'type' => $data['type'],
                'date' => $data['date'],
                'description' => $data['description'] ?? null,
            ]);


            return $voucher;
        });
    }

    public function createVoucherEntry(array $data): VoucherEntry
    {
        return DB::transaction(function () use ($data) {
            $voucherEntry = VoucherEntry::create([
                    'account_head_id' => $data['account_head_id'],
                    'voucher_id' => $data['voucher_id'],
                    'amount' => $data['amount'],
                    'entry_type' => $data['entry_type'],
                    'note' => $data['note'] ?? null,
                    'accountable_type' => $data['accountable_type'] ?? null,
                    'accountable_id' => $data['accountable_id'] ?? null,
            ]);
            return $voucherEntry;
        });
    }

    public function createVoucherAndEntries(array $data): Voucher
    {
        return DB::transaction(function () use ($data) {
            $voucher = Voucher::create([
                'voucher_no' => $data['voucher_no'],
                'type' => $data['type'],
                'date' => $data['date'],
                'description' => $data['description'] ?? null,
            ]);

            foreach ($data['entries'] as $entry) {
                $voucher->entries()->create([
                    'account_head_id' => $entry['account_head_id'],
                    'amount' => $entry['amount'],
                    'entry_type' => $entry['entry_type'],
                    'note' => $entry['note'] ?? null,
                    'accountable_type' => $entry['accountable_type'] ?? null,
                    'accountable_id' => $entry['accountable_id'] ?? null,
                ]);
            }


            return $voucher;
        });
    }


    public function createInvoice(array $data): Invoice
    {
        return DB::transaction(function () use ($data) {
            $invoice = Invoice::create([
                'invoice_no' => $data['invoice_no'],
                'account_head_id' => $data['account_head_id'],
                'voucher_id' => $data['voucher_id'],
                'amount' => $data['amount'],
                'date' => $data['date'],
                'description' => $data['description'] ?? null,
                'invoiceable_type' => $data['invoiceable_type'] ?? null,
                'invoiceable_id' => $data['invoiceable_id'] ?? null,
            ]);

            return $invoice;
        });
    }

    public function createAutoEntry(array $data): AutoEntry
    {
        return DB::transaction(function () use ($data) {
            $autoEntry = AutoEntry::create([
                'source_type' => $data['source_type'],
                'source_id' => $data['source_id'],
                'voucher_id' => $data['voucher_id'],
                'autoentryable_type' => $data['autoentryable_type'] ?? null,
                'autoentryable_id' => $data['autoentryable_id'] ?? null,
            ]);

            return $autoEntry;
        });
    }

    public function getAccountBalance(AccountHead $accountHead, ?string $startDate = null, ?string $endDate = null): float
    {
        $query = $accountHead->voucherEntries();

        if ($startDate) {
            $query->whereHas('voucher', function ($q) use ($startDate) {
                $q->where('date', '>=', $startDate);
            });
        }

        if ($endDate) {
            $query->whereHas('voucher', function ($q) use ($endDate) {
                $q->where('date', '<=', $endDate);
            });
        }

        $debit = $query->where('entry_type', 'debit')->sum('amount');
        $credit = $query->where('entry_type', 'credit')->sum('amount');

        return $debit - $credit;
    }

    // public function createDraftOrderVoucher(array $data): Voucher
    // {
    //     return DB::transaction(function () use ($data) {
    //         // Create voucher
    //         $voucher = Voucher::create([
    //             'voucher_no' => $data['voucher_no'],
    //             'type' => 'purchase',
    //             'date' => $data['date'],
    //             'description' => $data['description'] ?? 'Draft Order Purchase',
    //         ]);

    //         // Create voucher entries
    //         // Purchase Dr
    //         $voucher->entries()->create([
    //             'account_head_id' => $data['purchase_account_id'],
    //             'amount' => $data['amount'],
    //             'entry_type' => 'debit',
    //             'note' => $data['description'] ?? null,
    //         ]);

    //         // AP Cr
    //         $voucher->entries()->create([
    //             'account_head_id' => $data['ap_account_id'],
    //             'amount' => $data['amount'],
    //             'entry_type' => 'credit',
    //             'note' => $data['description'] ?? null,
    //         ]);

    //         // Create auto entry
    //         $voucher->autoEntries()->create([
    //             'source_type' => 'draft_order',
    //             'source_id' => $data['draft_order_id'],
    //         ]);

    //         // Create invoice
    //         $voucher->invoices()->create([
    //             'invoice_no' => $data['invoice_no'],
    //             'account_head_id' => $data['ap_account_id'],
    //             'amount' => $data['amount'],
    //             'date' => $data['date'],
    //             'description' => $data['description'] ?? null,
    //             'invoiceable_type' => 'supplier',
    //             'invoiceable_id' => $data['supplier_id'],
    //         ]);

    //         return $voucher;
    //     });
    // }
} 

5) trait Accountable

<?php

namespace App\Traits;

use App\Models\VoucherEntry;
use App\Models\Invoice;
use App\Models\AutoEntry;
use Illuminate\Database\Eloquent\Relations\MorphMany;
use App\Services\AccountService;

trait Accountable
{

    public function voucherEntries(): MorphMany
    {
        return $this->morphMany(VoucherEntry::class, 'accountable');
    }

    public function invoices(): MorphMany
    {
        return $this->morphMany(Invoice::class, 'invoiceable');
    }

    public function autoEntries(): MorphMany
    {
        return $this->morphMany(AutoEntry::class, 'autoentryable');
    }

    public function createVoucherEntry(array $data): VoucherEntry
    {
        return $this->voucherEntries()->create($data);
    }

    public function createInvoice(array $data): Invoice
    {
        return $this->invoices()->create($data);
    }

    public function createAutoEntry(array $data): AutoEntry
    {
        return $this->autoEntries()->create($data);
    }
} 
