Work on invoices

orders
Nisse Lommerde 3 weeks ago
parent d950955371
commit a12e0b29d3

@ -3,7 +3,15 @@
namespace App\Filament\Resources;
use App\Filament\Resources\InvoiceResource\Pages;
use App\Models\Customer;
use App\Models\Invoice;
use App\Models\Order;
use Filament\Forms\Components\DatePicker;
use Filament\Forms\Components\Grid;
use Filament\Forms\Components\Section;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\Split;
use Filament\Forms\Components\ToggleButtons;
use Filament\Forms\Form;
use Filament\Resources\Resource;
use Filament\Tables;
@ -23,19 +31,78 @@ class InvoiceResource extends Resource
{
return $form
->schema([
//
]);
Section::make([
Grid::make(2)
->schema([
Select::make('customer_id')
->required()
->label('Customer')
->options(Customer::all()->pluck('company_name', 'id'))
->reactive()
->searchable()
->columnSpan(2),
Select::make('orders')
->options(fn ($get): array => Order::where('customer_id', $get('customer_id') ?? null)
->get()
->pluck('customer_po', 'id')
->toArray())
->multiple()
->searchable()
->columnSpan(2),
Split::make([
DatePicker::make('date')
->required()
->default(today()),
DatePicker::make('due_date'),
])
->columnSpan(2),
])->columnSpan(2),
Grid::make(1)
->schema([
ToggleButtons::make('gst')
->boolean()
->default(true)
->inline()
->colors([
'true' => 'info',
'false' => 'info',
]),
ToggleButtons::make('pst')
->boolean()
->default(false)
->inline()
->colors([
'true' => 'info',
'false' => 'info',
]),
])->columnSpan(1),
])
->columns(3)
->columnSpan(3),
])->columns(3);
}
public static function table(Table $table): Table
{
return $table
->columns([
//
Tables\Columns\TextColumn::make('internal_id')
->label('ID')
->color('primary'),
Tables\Columns\TextColumn::make('created_at')
->date(),
Tables\Columns\TextColumn::make('order.total_service_price')
->label('Price')
->prefix('$'),
])
->filters([
//
])
->defaultSort('created_at', 'desc')
->actions([
Tables\Actions\EditAction::make(),
])
@ -49,7 +116,7 @@ class InvoiceResource extends Resource
public static function getRelations(): array
{
return [
//
// OrdersRelationManager::class,
];
}

@ -3,13 +3,36 @@
namespace App\Filament\Resources\InvoiceResource\Pages;
use App\Filament\Resources\InvoiceResource;
use App\Models\Invoice;
use App\Models\Order;
use Filament\Actions;
use Filament\Resources\Pages\EditRecord;
use Illuminate\Database\Eloquent\Model;
class EditInvoice extends EditRecord
{
protected static string $resource = InvoiceResource::class;
protected function mutateFormDataBeforeFill(array $data): array
{
$invoice = Invoice::findOrFail($data['id']);
foreach ($invoice->orders as $order) {
$data['orders'][] = $order->id;
}
return $data;
}
protected function handleRecordUpdate(Model $record, array $data): Model
{
$record->orders()->delete();
$record->orders()->saveMany(Order::findMany($data['orders']));
return $record;
}
protected function getHeaderActions(): array
{
return [

@ -0,0 +1,48 @@
<?php
namespace App\Filament\Resources\InvoiceResource\RelationManagers;
use Filament\Forms;
use Filament\Forms\Form;
use Filament\Resources\RelationManagers\RelationManager;
use Filament\Tables;
use Filament\Tables\Table;
class OrdersRelationManager extends RelationManager
{
protected static string $relationship = 'orders';
public function form(Form $form): Form
{
return $form
->schema([
Forms\Components\TextInput::make('customer_po')
->required()
->maxLength(255),
]);
}
public function table(Table $table): Table
{
return $table
->recordTitleAttribute('customer_po')
->columns([
Tables\Columns\TextColumn::make('customer_po'),
])
->filters([
//
])
->headerActions([
Tables\Actions\CreateAction::make(),
])
->actions([
Tables\Actions\EditAction::make(),
Tables\Actions\DeleteAction::make(),
])
->bulkActions([
Tables\Actions\BulkActionGroup::make([
Tables\Actions\DeleteBulkAction::make(),
]),
]);
}
}

@ -255,6 +255,13 @@ class OrderResource extends Resource
->searchable()
->sortable(),
])
->recordClasses(function (Order $order) {
if ($order->rush) {
return 'bg-green-100';
}
return '';
})
->defaultSort('order_date', 'desc')
->groups([
'status',

@ -6,6 +6,7 @@ use App\Filament\Resources\QuoteResource\Pages;
use App\Models\Customer;
use App\Models\Order;
use App\Models\Quote;
use Filament\Forms\Components\Section;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\Split;
use Filament\Forms\Components\Textarea;
@ -28,6 +29,7 @@ class QuoteResource extends Resource
{
return $form
->schema([
Section::make([
Split::make([
Select::make('customer_id')
->required()
@ -43,10 +45,12 @@ class QuoteResource extends Resource
->pluck('customer_po', 'id')
->toArray())
->searchable(),
])->columnSpan(2),
Textarea::make('body')
->columnSpan(2)
->rows(8),
]),
])->columns(3);
}

@ -52,4 +52,9 @@ class Customer extends Model
{
return $this->hasMany(Order::class);
}
public function invoices(): HasMany
{
return $this->hasMany(invoice::class);
}
}

@ -4,8 +4,41 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
class Invoice extends Model
{
use HasFactory;
protected $fillable = [
'customer_id',
'subtotal',
'total',
'gst',
'pst',
'date',
];
protected $appends = [
'internal_id',
];
public function getInternalIdAttribute(): string
{
$po = str_pad(strval($this->id), 4, '0', STR_PAD_LEFT);
$year = date('y');
return 'TN-IN-'.$year.'-'.$po;
}
public function orders(): HasMany
{
return $this->HasMany(Order::class);
}
public function customer(): BelongsTo
{
return $this->belongsTo(Customer::class);
}
}

@ -42,9 +42,12 @@ class Order extends Model
'pre_production',
];
protected $appends = [
'total_service_price',
];
protected $casts = [
'status' => OrderStatus::class,
// 'order_attributes' => 'array',
];
public static function boot(): void
@ -86,7 +89,7 @@ class Order extends Model
return $total;
}
public function totalServicePrice(): string
public function getTotalServicePriceAttribute(): string
{
$total = 0;
@ -200,6 +203,11 @@ class Order extends Model
return $this->hasOne(Quote::class);
}
public function invoice(): BelongsTo
{
return $this->belongsTo(Invoice::class);
}
protected function serializeDate(DateTimeInterface $date): string
{
return $date->format('Y-m-d');

@ -18,7 +18,7 @@ class ProductServiceFactory extends Factory
'service_type' => $this->faker->randomElement(['emb', 'scp', 'dtg', 'vinyl']),
'placement' => $this->faker->randomElement(['l/c', 'c/f', 'f/b', 'r/c']),
'amount' => $this->faker->randomNumber(1),
'amount_price' => 0,
'amount_price' => random_int(1, 15),
'notes' => $this->faker->randomElement(['1) 1149 2) grey 3) white', '1) white', '1) black 2) white']),
];
}

@ -11,10 +11,17 @@ return new class extends Migration
Schema::create('invoices', function (Blueprint $table) {
$table->id();
$table->foreignId('order_id')->nullable();
$table->foreignId('customer_id')->constrained()->nullable();
$table->float('subtotal')->default(0.00);
$table->float('total')->default(0.00);
$table->boolean('gst')->default(0);
$table->boolean('pst')->default(0);
$table->date('date')->default(today());
$table->date('due_date')->nullable();
$table->timestamps();
});
}

@ -10,8 +10,11 @@ return new class extends Migration
{
Schema::create('orders', function (Blueprint $table) {
$table->id();
$table->foreignId('customer_id')->constrained();
$table->foreignId('contact_id')->nullable()->constrained();
$table->foreignId('invoice_id')->nullable()->constrained();
$table->string('internal_po')->nullable();
$table->string('customer_po');
$table->string('order_type');

@ -2,9 +2,6 @@
namespace Database\Seeders;
use App\Enums\OrderStatus;
use App\Models\Invoice;
use App\Models\Order;
use Illuminate\Database\Seeder;
class InvoiceSeeder extends Seeder
@ -14,8 +11,8 @@ class InvoiceSeeder extends Seeder
*/
public function run(): void
{
foreach (Order::where('status', OrderStatus::INVOICED) as $order) {
Invoice::factory()->for($order)->create();
}
// foreach (Order::where('status', OrderStatus::INVOICED->value)->get() as $order) {
// Invoice::factory()->for($order)->create();
// }
}
}

@ -2,7 +2,8 @@
export default {
content: [
"./resources/**/*.blade.php",
"./app/Filament/**/*.blade.php"
"./app/Filament/**/*.php",
"./vendor/filament/**/*.php"
],
theme: {
extend: {},

Loading…
Cancel
Save