diff --git a/app/Actions/Sales/CreateSaleAction.php b/app/Actions/Sales/CreateSaleAction.php new file mode 100644 index 0000000..77ccf50 --- /dev/null +++ b/app/Actions/Sales/CreateSaleAction.php @@ -0,0 +1,55 @@ +createSaleCommand->execute($data); + + try { + DB::beginTransaction(); + + //create transactions for the sale + app(CreateRecordTransactionsAction::class)($record, $transactions); + + $accountIds = collect($transactions) + ->pluck('account_id') + ->filter() + ->unique() + ->values() + ->all(); + + //sync accounts to sale + app(SyncAccountsAction::class)($record, $accountIds); + + //increment current_series + $this->createSeriesCommand->execute([ + 'branch_id' => $record->branch_id, + 'series' => $record->reference_number, + ]); + + DB::commit(); + } catch (\Exception $exception) { + DB::rollBack(); + throw new \Exception('Failed to save transactions : '.$exception->getMessage()); + } + + return $record; + } +} diff --git a/app/Actions/Sales/SyncAccountsAction.php b/app/Actions/Sales/SyncAccountsAction.php new file mode 100644 index 0000000..95277bc --- /dev/null +++ b/app/Actions/Sales/SyncAccountsAction.php @@ -0,0 +1,16 @@ +accounts()->sync($accounts); + }, attempts: 2); + } +} diff --git a/app/Actions/Transactions/CreateRecordTransactionsAction.php b/app/Actions/Transactions/CreateRecordTransactionsAction.php new file mode 100644 index 0000000..f855086 --- /dev/null +++ b/app/Actions/Transactions/CreateRecordTransactionsAction.php @@ -0,0 +1,30 @@ + $record->branch_id, + 'happened_on' => $record->happened_on, + ...$transaction, + ]; + + $payload = new CreateTransactionDTO(data: $tData, transactionable: $record); + + Pipeline::send(passable: $payload)->through( + [ + CreateTransactionAction::class, + ] + )->thenReturn(); + } + } +} + diff --git a/app/Commands/Clients/GenerateBaseAccountCommand.php b/app/Commands/Clients/GenerateBaseAccountCommand.php new file mode 100644 index 0000000..f688412 --- /dev/null +++ b/app/Commands/Clients/GenerateBaseAccountCommand.php @@ -0,0 +1,64 @@ +accounts()->createMany([ + [ + 'account_type_id' => 1, + 'account' => 'Cash', + 'normal_balance' => 'debit', + ], + [ + 'account_type_id' => 1, + 'account' => 'Input Tax', + 'normal_balance' => 'debit', + ], + [ + 'account_type_id' => 1, + 'account' => 'Creditable Withholding Tax', + 'normal_balance' => 'debit', + ], + [ + 'account_type_id' => 2, + 'account' => 'Output Tax', + 'normal_balance' => 'credit', + ], + [ + 'account_type_id' => 2, + 'account' => 'Payable Withholding Tax', + 'normal_balance' => 'credit', + ], + [ + 'account_type_id' => 5, + 'account' => 'Vat Exempt Revenue', + 'normal_balance' => 'credit', + ], + [ + 'account_type_id' => 4, + 'account' => 'Sales Discount', + 'normal_balance' => 'debit', + ], + ]); + }); + } + +} diff --git a/app/Commands/Sales/CreateSaleCommand.php b/app/Commands/Sales/CreateSaleCommand.php new file mode 100644 index 0000000..e8f0719 --- /dev/null +++ b/app/Commands/Sales/CreateSaleCommand.php @@ -0,0 +1,27 @@ +id, + ); + + return Sale::create($tData->toArray()); + }); + + } +} diff --git a/app/Filament/Resources/ClientResource/RelationManagers/AccountsRelationManager.php b/app/Filament/Resources/ClientResource/RelationManagers/AccountsRelationManager.php index 548121d..a34a448 100644 --- a/app/Filament/Resources/ClientResource/RelationManagers/AccountsRelationManager.php +++ b/app/Filament/Resources/ClientResource/RelationManagers/AccountsRelationManager.php @@ -2,6 +2,7 @@ namespace App\Filament\Resources\ClientResource\RelationManagers; +use App\Commands\Clients\GenerateBaseAccountCommand; use App\Filament\Exports\ClientAccountsExporter; use App\Models\Account; use Filament\Actions\Exports\Enums\ExportFormat; @@ -43,6 +44,20 @@ class AccountsRelationManager extends RelationManager // ]) ->headerActions([ + Tables\Actions\Action::make('generate-base-accounts') + ->requiresConfirmation() + ->label('Generate Base Accounts') + ->action(function () { + $client = $this->getOwnerRecord(); + if (! $client ) { + return; + } + + if($client->accounts()->count() > 0) { + return; + } + app(GenerateBaseAccountCommand::class)->execute($client); + }), Tables\Actions\ExportAction::make('Export Accounts')->exporter(ClientAccountsExporter::class)->formats([ExportFormat::Csv]), Tables\Actions\CreateAction::make()->label('New Account')->icon('heroicon-o-plus')->slideOver(), ]) diff --git a/app/Filament/Resources/ExpenseResource/Pages/CreateExpense.php b/app/Filament/Resources/ExpenseResource/Pages/CreateExpense.php index 8e0acc6..e133af8 100644 --- a/app/Filament/Resources/ExpenseResource/Pages/CreateExpense.php +++ b/app/Filament/Resources/ExpenseResource/Pages/CreateExpense.php @@ -2,15 +2,13 @@ namespace App\Filament\Resources\ExpenseResource\Pages; -use App\Actions\Transactions\CreateTransactionAction; -use App\DataObjects\CreateTransactionDTO; +use App\Actions\Transactions\CreateRecordTransactionsAction; use App\Filament\Resources\ClientResource; use App\Filament\Resources\ExpenseResource; use App\Models\Client; use Exception; use Filament\Resources\Pages\CreateRecord; use Illuminate\Support\Arr; -use Illuminate\Support\Facades\Pipeline; use Symfony\Component\Console\Exception\LogicException; class CreateExpense extends CreateRecord @@ -76,24 +74,7 @@ class CreateExpense extends CreateRecord $transactions = $this->form->getState()['transactions'] ?? []; try { - $branch = $this->getRecord()->branch; - - foreach ($transactions as $transaction) { - - $data = [ - 'branch_id' => $branch->id, - 'happened_on' => $this->getRecord()->happened_on, - ...$transaction, - ]; - - $payload = new CreateTransactionDTO(data: $data, transactionable: $this->getRecord()); - - Pipeline::send(passable: $payload)->through( - [ - CreateTransactionAction::class, - ] - )->thenReturn(); - } + app(CreateRecordTransactionsAction::class)($this->getRecord(), $transactions); $accountIds = collect($transactions) ->pluck('account_id') diff --git a/app/Filament/Resources/SaleResource/Pages/CreateSale.php b/app/Filament/Resources/SaleResource/Pages/CreateSale.php index 2278109..b6f063f 100644 --- a/app/Filament/Resources/SaleResource/Pages/CreateSale.php +++ b/app/Filament/Resources/SaleResource/Pages/CreateSale.php @@ -2,19 +2,22 @@ namespace App\Filament\Resources\SaleResource\Pages; -use App\Actions\Transactions\CreateTransactionAction; -use App\DataObjects\CreateTransactionDTO; +use App\Actions\Sales\CreateSaleAction; +use App\Actions\Sales\SyncAccountsAction; +use App\Actions\Transactions\CreateRecordTransactionsAction; +use App\Commands\Clients\GenerateBaseAccountCommand; use App\Filament\Resources\ClientResource; use App\Filament\Resources\SaleResource; use App\Models\Branch; use App\Models\Client; use App\Models\Sale; use App\Services\Sales\SaleService; +use Filament\Actions\Action; +use Filament\Forms\Components\Actions; use Filament\Resources\Pages\CreateRecord; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Arr; use Illuminate\Support\Facades\DB; -use Illuminate\Support\Facades\Pipeline; class CreateSale extends CreateRecord { @@ -81,41 +84,7 @@ class CreateSale extends CreateRecord public function processCreate(array $data, array $transactions): Model { - try { - DB::beginTransaction(); - $record = app(SaleService::class)->create($this->getFormDataMutation($data)); - $branch = $record->branch; - - foreach ($transactions as $transaction) { - $tData = [ - 'branch_id' => $branch->id, - 'happened_on' => $record->happened_on, - ...$transaction, - ]; - - $payload = new CreateTransactionDTO(data: $tData, transactionable: $record); - - Pipeline::send(passable: $payload)->through( - [ - CreateTransactionAction::class, - ] - )->thenReturn(); - } - - $accountIds = collect($transactions) - ->pluck('account_id') - ->filter() - ->unique() - ->values() - ->all(); - - $record->accounts()->sync($accountIds); - - DB::commit(); - } catch (\Exception $exception) { - DB::rollBack(); - throw new \Exception('Failed to save transactions : '.$exception->getMessage()); - } + $record = app(CreateSaleAction::class)($this->getFormDataMutation($data), $transactions); return $record; } diff --git a/app/Observers/ClientObserver.php b/app/Observers/ClientObserver.php index 19678c2..7db967a 100644 --- a/app/Observers/ClientObserver.php +++ b/app/Observers/ClientObserver.php @@ -2,6 +2,7 @@ namespace App\Observers; +use App\Commands\Clients\GenerateBaseAccountCommand; use App\Models\Client; use Illuminate\Support\Facades\DB; @@ -12,45 +13,7 @@ class ClientObserver */ public function created(Client $client): void { - DB::transaction(function () use ($client) { - $client->accounts()->createMany([ - [ - 'account_type_id' => 1, - 'account' => 'Cash', - 'normal_balance' => 'debit', - ], - [ - 'account_type_id' => 1, - 'account' => 'Input Tax', - 'normal_balance' => 'debit', - ], - [ - 'account_type_id' => 1, - 'account' => 'Creditable Withholding Tax', - 'normal_balance' => 'debit', - ], - [ - 'account_type_id' => 2, - 'account' => 'Output Tax', - 'normal_balance' => 'credit', - ], - [ - 'account_type_id' => 2, - 'account' => 'Payable Withholding Tax', - 'normal_balance' => 'credit', - ], - [ - 'account_type_id' => 5, - 'account' => 'Vat Exempt Revenue', - 'normal_balance' => 'credit', - ], - [ - 'account_type_id' => 4, - 'account' => 'Sales Discount', - 'normal_balance' => 'debit', - ], - ]); - }); + app(GenerateBaseAccountCommand::class)->execute($client); } /** diff --git a/app/Services/Sales/SaleService.php b/app/Services/Sales/SaleService.php deleted file mode 100644 index 0f51c61..0000000 --- a/app/Services/Sales/SaleService.php +++ /dev/null @@ -1,31 +0,0 @@ -id, - ); - return Sale::create($tData->toArray()); - } -}