|
@@ -2,12 +2,15 @@
|
2
|
2
|
|
3
|
3
|
namespace App\Filament\Company\Resources\Sales;
|
4
|
4
|
|
|
5
|
+use App\Enums\Accounting\InvoiceStatus;
|
5
|
6
|
use App\Filament\Company\Resources\Sales\InvoiceResource\Pages;
|
6
|
7
|
use App\Models\Accounting\Adjustment;
|
7
|
8
|
use App\Models\Accounting\DocumentLineItem;
|
8
|
9
|
use App\Models\Accounting\Invoice;
|
|
10
|
+use App\Models\Banking\BankAccount;
|
9
|
11
|
use App\Models\Common\Offering;
|
10
|
12
|
use App\Utilities\Currency\CurrencyAccessor;
|
|
13
|
+use App\Utilities\Currency\CurrencyConverter;
|
11
|
14
|
use Awcodes\TableRepeater\Components\TableRepeater;
|
12
|
15
|
use Awcodes\TableRepeater\Header;
|
13
|
16
|
use Carbon\CarbonInterface;
|
|
@@ -439,8 +442,133 @@ class InvoiceResource extends Resource
|
439
|
442
|
//
|
440
|
443
|
])
|
441
|
444
|
->actions([
|
442
|
|
- Tables\Actions\EditAction::make(),
|
443
|
|
- Tables\Actions\ViewAction::make(),
|
|
445
|
+ Tables\Actions\ActionGroup::make([
|
|
446
|
+ Tables\Actions\EditAction::make(),
|
|
447
|
+ Tables\Actions\ViewAction::make(),
|
|
448
|
+ Tables\Actions\DeleteAction::make(),
|
|
449
|
+ Tables\Actions\ReplicateAction::make()
|
|
450
|
+ ->label('Duplicate')
|
|
451
|
+ ->excludeAttributes(['status', 'amount_paid', 'amount_due', 'created_by', 'updated_by', 'created_at', 'updated_at', 'invoice_number', 'date', 'due_date'])
|
|
452
|
+ ->modal(false)
|
|
453
|
+ ->beforeReplicaSaved(function (Invoice $original, Invoice $replica) {
|
|
454
|
+ $replica->status = InvoiceStatus::Draft;
|
|
455
|
+ $replica->invoice_number = Invoice::getNextDocumentNumber();
|
|
456
|
+ $replica->date = now();
|
|
457
|
+ $replica->due_date = now()->addDays($original->company->defaultInvoice->payment_terms->getDays());
|
|
458
|
+ })
|
|
459
|
+ ->after(function (Invoice $original, Invoice $replica) {
|
|
460
|
+ $original->lineItems->each(function (DocumentLineItem $lineItem) use ($replica) {
|
|
461
|
+ $replicaLineItem = $lineItem->replicate([
|
|
462
|
+ 'documentable_id',
|
|
463
|
+ 'documentable_type',
|
|
464
|
+ 'subtotal',
|
|
465
|
+ 'total',
|
|
466
|
+ 'created_by',
|
|
467
|
+ 'updated_by',
|
|
468
|
+ 'created_at',
|
|
469
|
+ 'updated_at',
|
|
470
|
+ ]);
|
|
471
|
+
|
|
472
|
+ $replicaLineItem->documentable_id = $replica->id;
|
|
473
|
+ $replicaLineItem->documentable_type = $replica->getMorphClass();
|
|
474
|
+
|
|
475
|
+ $replicaLineItem->save();
|
|
476
|
+
|
|
477
|
+ $replicaLineItem->adjustments()->sync($lineItem->adjustments->pluck('id'));
|
|
478
|
+ });
|
|
479
|
+ })
|
|
480
|
+ ->successRedirectUrl(function (Invoice $replica) {
|
|
481
|
+ return InvoiceResource::getUrl('edit', ['record' => $replica]);
|
|
482
|
+ }),
|
|
483
|
+ Tables\Actions\Action::make('approveDraft')
|
|
484
|
+ ->label('Approve')
|
|
485
|
+ ->icon('heroicon-o-check-circle')
|
|
486
|
+ ->visible(function (Invoice $record) {
|
|
487
|
+ return $record->isDraft();
|
|
488
|
+ })
|
|
489
|
+ ->action(function (Invoice $record) {
|
|
490
|
+ $record->updateQuietly([
|
|
491
|
+ 'status' => InvoiceStatus::Unsent,
|
|
492
|
+ ]);
|
|
493
|
+ }),
|
|
494
|
+ Tables\Actions\Action::make('markAsSent')
|
|
495
|
+ ->label('Mark as Sent')
|
|
496
|
+ ->icon('heroicon-o-paper-airplane')
|
|
497
|
+ ->visible(function (Invoice $record) {
|
|
498
|
+ return $record->status === InvoiceStatus::Unsent;
|
|
499
|
+ })
|
|
500
|
+ ->action(function (Invoice $record) {
|
|
501
|
+ $record->updateQuietly([
|
|
502
|
+ 'status' => InvoiceStatus::Sent,
|
|
503
|
+ ]);
|
|
504
|
+ }),
|
|
505
|
+ Tables\Actions\Action::make('recordPayment')
|
|
506
|
+ ->label('Record Payment')
|
|
507
|
+ ->modalWidth(MaxWidth::TwoExtraLarge)
|
|
508
|
+ ->icon('heroicon-o-credit-card')
|
|
509
|
+ ->visible(function (Invoice $record) {
|
|
510
|
+ return $record->canRecordPayment();
|
|
511
|
+ })
|
|
512
|
+ ->mountUsing(function (Invoice $record, Form $form) {
|
|
513
|
+ $form->fill([
|
|
514
|
+ 'date' => now(),
|
|
515
|
+ 'amount' => $record->amount_due,
|
|
516
|
+ ]);
|
|
517
|
+ })
|
|
518
|
+ ->form([
|
|
519
|
+ Forms\Components\DatePicker::make('date')
|
|
520
|
+ ->label('Payment Date'),
|
|
521
|
+ Forms\Components\TextInput::make('amount')
|
|
522
|
+ ->label('Amount')
|
|
523
|
+ ->required()
|
|
524
|
+ ->money(),
|
|
525
|
+ Forms\Components\Select::make('payment_method')
|
|
526
|
+ ->label('Payment Method')
|
|
527
|
+ ->options([
|
|
528
|
+ 'bank_payment' => 'Bank Payment',
|
|
529
|
+ 'cash' => 'Cash',
|
|
530
|
+ 'check' => 'Check',
|
|
531
|
+ 'credit_card' => 'Credit Card',
|
|
532
|
+ 'paypal' => 'PayPal',
|
|
533
|
+ 'other' => 'Other',
|
|
534
|
+ ]),
|
|
535
|
+ Forms\Components\Select::make('bank_account_id')
|
|
536
|
+ ->label('Account')
|
|
537
|
+ ->options(BankAccount::query()
|
|
538
|
+ ->get()
|
|
539
|
+ ->pluck('account.name', 'id'))
|
|
540
|
+ ->searchable(),
|
|
541
|
+ Forms\Components\Textarea::make('notes')
|
|
542
|
+ ->label('Notes'),
|
|
543
|
+ ])
|
|
544
|
+ ->action(function (Invoice $record, array $data) {
|
|
545
|
+ $payment = $record->payments()->create([
|
|
546
|
+ 'date' => $data['date'],
|
|
547
|
+ 'amount' => $data['amount'],
|
|
548
|
+ 'payment_method' => $data['payment_method'],
|
|
549
|
+ 'bank_account_id' => $data['bank_account_id'],
|
|
550
|
+ 'notes' => $data['notes'],
|
|
551
|
+ ]);
|
|
552
|
+
|
|
553
|
+ $amountPaid = $record->getRawOriginal('amount_paid');
|
|
554
|
+ $paymentAmount = $payment->getRawOriginal('amount');
|
|
555
|
+ $totalAmount = $record->getRawOriginal('total');
|
|
556
|
+
|
|
557
|
+ $newAmountPaid = $amountPaid + $paymentAmount;
|
|
558
|
+
|
|
559
|
+ $record->amount_paid = CurrencyConverter::convertCentsToFloat($newAmountPaid);
|
|
560
|
+
|
|
561
|
+ if ($newAmountPaid > $totalAmount) {
|
|
562
|
+ $record->status = InvoiceStatus::Overpaid;
|
|
563
|
+ } elseif ($newAmountPaid === $totalAmount) {
|
|
564
|
+ $record->status = InvoiceStatus::Paid;
|
|
565
|
+ } else {
|
|
566
|
+ $record->status = InvoiceStatus::Partial;
|
|
567
|
+ }
|
|
568
|
+
|
|
569
|
+ $record->save();
|
|
570
|
+ }),
|
|
571
|
+ ]),
|
444
|
572
|
])
|
445
|
573
|
->bulkActions([
|
446
|
574
|
Tables\Actions\BulkActionGroup::make([
|