From 7899ed75ea0787ab6171e174160c12559a92eb43 Mon Sep 17 00:00:00 2001 From: Jp Date: Wed, 18 Feb 2026 21:40:39 +0800 Subject: [PATCH] feat(sales): add discount support with ledger accounting - Add discount_type column to transactions table via migration - Update Sale model to use fillable instead of guarded for better security - Implement discount account ledger creation when discount is applied - Fix net amount calculation to include discount in CreateSaleAction - Remove unused "Exempt" column from sale transaction table - Make discount_type required when discount is enabled in form - Update form data mutation to properly handle discount calculations --- .devdbrc | 11 +++++++ app/Actions/Sales/CreateSaleAction.php | 1 - .../Transactions/CreateTransactionAction.php | 32 ++++++++++++++++++- app/Filament/Resources/SaleResource.php | 11 ++++--- .../SaleResource/Pages/CreateSale.php | 7 ++-- app/Models/Sale.php | 9 +++++- ...add_discount_type_on_transaction_table.php | 28 ++++++++++++++++ 7 files changed, 88 insertions(+), 11 deletions(-) create mode 100644 .devdbrc create mode 100644 database/migrations/2026_02_17_175416_add_discount_type_on_transaction_table.php diff --git a/.devdbrc b/.devdbrc new file mode 100644 index 0000000..51824bd --- /dev/null +++ b/.devdbrc @@ -0,0 +1,11 @@ +[ + { + "name": "My test MySQL database", + "type": "mysql", + "host": "192.168.100.105", + "port": "3306", + "username": "root", + "password": "root", + "database": "mkm_admin" + } +] \ No newline at end of file diff --git a/app/Actions/Sales/CreateSaleAction.php b/app/Actions/Sales/CreateSaleAction.php index 77ccf50..c8dafea 100644 --- a/app/Actions/Sales/CreateSaleAction.php +++ b/app/Actions/Sales/CreateSaleAction.php @@ -24,7 +24,6 @@ class CreateSaleAction try { DB::beginTransaction(); - //create transactions for the sale app(CreateRecordTransactionsAction::class)($record, $transactions); diff --git a/app/Actions/Transactions/CreateTransactionAction.php b/app/Actions/Transactions/CreateTransactionAction.php index a51ac32..227d3d2 100644 --- a/app/Actions/Transactions/CreateTransactionAction.php +++ b/app/Actions/Transactions/CreateTransactionAction.php @@ -24,6 +24,10 @@ class CreateTransactionAction extends BaseAction $this->cashAccountLedger($payload); + if ($payload->transaction->discount !== 0) { + $this->discountAccountLedger($payload); + } + return $next($payload); } @@ -33,11 +37,13 @@ class CreateTransactionAction extends BaseAction $isExpense = $payload->transactionable instanceof \App\Models\Expense; $type = $isExpense ? 'debit' : 'credit'; + $discount = $payload->transaction->discount ?? 0.00; + if ($branch->isClientVatable) { //create transaction account ledger $ledgerPayload = new CreateLedgerDTO( branch_id: $payload->transactionable->branch_id, - amount: $payload->transaction->net_amount ?? 0.00, + amount: $payload->transaction->net_amount + $discount ?? 0.00, transaction: $payload->transaction, account: $payload->transaction->account, type: $type, @@ -144,4 +150,28 @@ class CreateTransactionAction extends BaseAction $this->ledgerPipe($ledgerPayload); } } + + public function discountAccountLedger($payload): void + { + $isExpense = $payload->transactionable instanceof \App\Models\Expense; + $type = $isExpense ? 'credit' : 'debit'; + $amount = $payload->transaction->discount ?? 0.00; + $clientId = $payload->transactionable->branch->client_id; + + $discountAccount = Account::query() + ->where('account', 'Sales Discount') + ->where('client_id', $clientId) + ->first(); + + if ($discountAccount && $amount > 0) { + $ledgerPayload = new CreateLedgerDTO( + branch_id: $payload->transactionable->branch_id, + amount: $amount, + transaction: $payload->transaction, + account: $discountAccount, + type: $type, + ); + $this->ledgerPipe($ledgerPayload); + } + } } diff --git a/app/Filament/Resources/SaleResource.php b/app/Filament/Resources/SaleResource.php index 4eeddec..2c043ac 100644 --- a/app/Filament/Resources/SaleResource.php +++ b/app/Filament/Resources/SaleResource.php @@ -96,7 +96,7 @@ class SaleResource extends Resource Header::make('Charge Account'), Header::make('Description'), Header::make('Gross Amount'), - Header::make('Exempt'), + // Header::make('Exempt'), Header::make('Vatable Amount'), Header::make('Output Tax'), Header::make('Withholding Tax'), @@ -110,7 +110,7 @@ class SaleResource extends Resource Header::make('Charge Account'), Header::make('Description'), Header::make('Gross Amount'), - Header::make('Exempt'), + // Header::make('Exempt'), Header::make('Vatable Amount'), Header::make('Output Tax'), Header::make('Withholding Tax'), @@ -133,6 +133,7 @@ class SaleResource extends Resource TextInput::make('exempt') ->numeric() ->live() + ->hidden() ->afterStateUpdated(function (Get $get, Set $set, ?string $old, ?string $state) { static::setDefaultFormValues($get, $set, $old, $state); })->default(0), @@ -155,16 +156,16 @@ class SaleResource extends Resource ->numeric() ->live() ->afterStateUpdated(function (Get $get, Set $set, ?string $old, ?string $state) { - static::setDefaultFormValues($get, $set, $old, $state); })->default(0), TextInput::make('discount') ->numeric() - ->readOnly() + // ->readOnly() ->visible(fn (Get $get) => $get('../../with_discount')) ->live(), Select::make('discount_type') ->options(fn (Get $get) => static::getDiscountOptions($get)) + ->required(fn (Get $get) => $get('../../with_discount')) ->visible(fn (Get $get) => $get('../../with_discount')), TextInput::make('net_amount')->numeric()->default(0), ]; @@ -225,7 +226,7 @@ class SaleResource extends Resource } $set('output_tax', number_format($outputTax, 2, '.', '')); - $set('discount', number_format($discount, 2, '.', '')); + // $set('discount', number_format($discount, 2, '.', '')); $set('vatable_amount', number_format($vatableAmount, 2, '.', '')); $set('net_amount', number_format($netAmount, 2, '.', '')); } diff --git a/app/Filament/Resources/SaleResource/Pages/CreateSale.php b/app/Filament/Resources/SaleResource/Pages/CreateSale.php index ec4fcb7..9af55f7 100644 --- a/app/Filament/Resources/SaleResource/Pages/CreateSale.php +++ b/app/Filament/Resources/SaleResource/Pages/CreateSale.php @@ -76,10 +76,11 @@ class CreateSale extends CreateRecord $data['vatable_amount'] = collect($transactions)->sum(fn (array $transaction) => (float) ($transaction['vatable_amount'] ?? 0)); $data['output_tax'] = collect($transactions)->sum(fn (array $transaction) => (float) ($transaction['output_tax'] ?? 0)); $data['payable_withholding_tax'] = collect($transactions)->sum(fn (array $transaction) => (float) ($transaction['payable_withholding_tax'] ?? 0)); - $data['discount'] = collect($transactions)->sum(fn (array $transaction) => (float) ($transaction['discount'] ?? 0)); - $data['net_amount'] = collect($transactions)->sum(fn (array $transaction) => (float) ($transaction['net_amount'] ?? 0)); + $discount = collect($transactions)->sum(fn (array $transaction) => (float) ($transaction['discount'] ?? 0)); + $data['discount'] = $discount; + $data['net_amount'] = collect($transactions)->sum(fn (array $transaction) => (float) ($transaction['net_amount'] ?? 0)) + $discount; - return Arr::except($data, ['client', 'transactions', 'with_discount']); + return Arr::except($data, ['client', 'transactions']); } public function processCreate(array $data, array $transactions): Model diff --git a/app/Models/Sale.php b/app/Models/Sale.php index b83bed0..54d5983 100644 --- a/app/Models/Sale.php +++ b/app/Models/Sale.php @@ -12,7 +12,14 @@ class Sale extends Model { use HasFactory; - protected $guarded = []; + protected $fillable = [ + 'branch_id', + 'user_id', + 'client_id', + 'happened_on', + 'reference_number', + 'buyer' + ]; protected $casts = [ 'happened_on' => 'date:Y-m-d', diff --git a/database/migrations/2026_02_17_175416_add_discount_type_on_transaction_table.php b/database/migrations/2026_02_17_175416_add_discount_type_on_transaction_table.php new file mode 100644 index 0000000..9d15eec --- /dev/null +++ b/database/migrations/2026_02_17_175416_add_discount_type_on_transaction_table.php @@ -0,0 +1,28 @@ +string('discount_type')->after('with_discount')->nullable(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('transactions', function (Blueprint $table) { + $table->dropColumn('discount_type'); + }); + } +};