schema([ Select::make('branch_id') ->label('Branch') ->options(fn () => Branch::where('client_id', $this->getOwnerRecord()->id)->pluck('name', 'id')) ->required() ->default(fn () => Branch::where('client_id', $this->getOwnerRecord()->id)->first()?->id), DatePicker::make('happened_on') ->label('Date') ->required() ->default(now()), TextInput::make('series') ->label('Reference/Series #') ->required(), Textarea::make('description') ->label('Description') ->columnSpanFull(), TableRepeater::make('ledgers') ->relationship('ledgers') ->headers([ Header::make('Account'), Header::make('Description'), Header::make('Debit'), Header::make('Credit'), ]) ->schema([ Select::make('account_id') ->relationship('account', 'account', fn (Builder $query) => $query->where('client_id', $this->getOwnerRecord()->id)) ->searchable() ->preload() ->required(), TextInput::make('description'), TextInput::make('debit_amount') ->numeric() ->default(0), TextInput::make('credit_amount') ->numeric() ->default(0), ]) ->columnSpanFull() ->minItems(2) ->live() ->rules([ fn (): \Closure => function (string $attribute, $value, \Closure $fail) { $debit = collect($value)->sum('debit_amount'); $credit = collect($value)->sum('credit_amount'); if (abs($debit - $credit) > 0.01) { $fail("Total Debit (" . number_format($debit, 2) . ") must equal Total Credit (" . number_format($credit, 2) . ")."); } }, ]) ->afterStateUpdated(function ($state, $component) { // Optional: Validation logic }), ]); } public function table(Table $table): Table { return $table ->recordTitleAttribute('description') ->columns([ Tables\Columns\TextColumn::make('happened_on') ->date() ->sortable(), Tables\Columns\TextColumn::make('series') ->searchable(), Tables\Columns\TextColumn::make('description') ->limit(50), Tables\Columns\TextColumn::make('total_debit') ->label('Total Debit') ->state(fn (Journal $record) => $record->ledgers->sum('debit_amount')) ->money('PHP'), Tables\Columns\TextColumn::make('total_credit') ->label('Total Credit') ->state(fn (Journal $record) => $record->ledgers->sum('credit_amount')) ->money('PHP'), ]) ->filters([ // ]) ->headerActions([ Tables\Actions\CreateAction::make() ->label('Add Adjustment Entry') ->using(function (array $data, string $model) { return DB::transaction(function () use ($data, $model) { $ledgersData = $data['ledgers'] ?? []; $journalData = Arr::except($data, ['ledgers']); $journalData['client_id'] = $this->getOwnerRecord()->id; $journal = $model::create($journalData); foreach ($ledgersData as $ledger) { $ledgerPayload = new CreateLedgerDTO( branch_id: $journal->branch_id, amount: ($ledger['debit_amount'] > 0) ? $ledger['debit_amount'] : $ledger['credit_amount'], ledger: null, // Will be created transaction: null, // No transaction journal: $journal, account: \App\Models\Account::find($ledger['account_id']), type: ($ledger['debit_amount'] > 0) ? 'debit' : 'credit' ); Pipeline::send(passable: $ledgerPayload)->through( [ CreateLedgerAction::class, ] )->thenReturn(); } return $journal; }); }), ]) ->actions([ Tables\Actions\EditAction::make(), Tables\Actions\DeleteAction::make(), ]) ->bulkActions([ Tables\Actions\BulkActionGroup::make([ Tables\Actions\DeleteBulkAction::make(), ]), ]); } }