diff --git a/app/Filament/Resources/OrderResource.php b/app/Filament/Resources/OrderResource.php index d7dbfcc..330da8e 100644 --- a/app/Filament/Resources/OrderResource.php +++ b/app/Filament/Resources/OrderResource.php @@ -17,15 +17,13 @@ use Filament\Forms\Components\Split; use Filament\Forms\Components\Textarea; use Filament\Forms\Components\TextInput; use Filament\Forms\Components\ToggleButtons; -use Filament\Forms\Components\Wizard; use Filament\Forms\Form; use Filament\Resources\Resource; use Filament\Tables; use Filament\Tables\Columns\TextColumn; use Filament\Tables\Table; use Guava\FilamentClusters\Forms\Cluster; -use Illuminate\Support\Facades\Blade; -use Illuminate\Support\HtmlString; +use Icetalker\FilamentTableRepeater\Forms\Components\TableRepeater; class OrderResource extends Resource { @@ -38,25 +36,144 @@ class OrderResource extends Resource public static function form(Form $form): Form { return $form->schema([ - Wizard::make([ - Wizard\Step::make('Order Details') - ->schema(self::getOrderDetails()) - ->columns(2), - Wizard\Step::make('Garment Details') - ->schema(self::getGarmentDetails()), - Wizard\Step::make('Production Details') - ->schema(self::getProductionDetails()), - ]) - ->skippable() - ->submitAction(new HtmlString(Blade::render(<<<'BLADE' - - Submit - - BLADE))), - ])->columns(1); + // Wizard::make([ + // Wizard\Step::make('Order Details') + // ->schema(self::getOrderDetails()) + // ->columns(2), + // Wizard\Step::make('Garment Details') + // ->schema(self::getGarmentDetails()), + // Wizard\Step::make('Production Details') + // ->schema(self::getProductionDetails()), + // ]) + // ->skippable() + // ->submitAction(new HtmlString(Blade::render(<<<'BLADE' + // + // Submit + // + // BLADE))), + Section::make([ + + Section::make([ + Select::make('order_type') + ->required() + ->options(OrderType::class) + ->searchable(), + + Split::make([ + Select::make('customer_id') + ->required() + ->label('Customer') + ->options(Customer::all()->pluck('company_name', 'id')) + ->reactive() + ->searchable(), + + Select::make('contact_id') + ->label('Contact') + ->options(fn ($get): array => Contact::where('customer_id', $get('customer_id') ?? null)->get()->pluck('full_name', 'id')->toArray()) + ->searchable(), + ]), + + TextInput::make('customer_po') + ->required() + ->label('Customer PO'), + + Split::make([ + DatePicker::make('order_date') + ->required() + ->default(today()), + DatePicker::make('due_date') + ->required() + ->default(today()->add('10 days')), + ]), + ])->columnSpan(1), + + Section::make([ + ToggleButtons::make('status') + ->required() + ->options(OrderStatus::class) + ->inline(), + + ToggleButtons::make('order_attributes') + ->options(OrderAttributes::class) + ->multiple() + ->inline(), + + Textarea::make('notes') + ->rows(3), + + ])->columnSpan(1), + ])->columns(2), + + TableRepeater::make('Order Products') + ->relationship('orderProducts') + ->label('Garments') + ->schema([ + TextInput::make('sku') + ->columnSpan(1), + TextInput::make('product_name') + ->columnSpan(2), + TextInput::make('color') + ->columnSpan(1), + Cluster::make([ + TextInput::make('xs') + ->placeholder('xs'), + TextInput::make('s') + ->placeholder('s'), + TextInput::make('m') + ->placeholder('m'), + TextInput::make('l') + ->placeholder('l'), + TextInput::make('xl') + ->placeholder('xl'), + TextInput::make('2xl') + ->placeholder('2xl'), + TextInput::make('3xl') + ->placeholder('3xl'), + TextInput::make('osfa') + ->placeholder('osfa'), + ]) + ->label('Sizes') + ->columnSpan(5), + ]) + ->reorderable() + ->cloneable(), + + Repeater::make('Services') + ->relationship('productServices') + ->label('Production Details') + ->schema([ + TextInput::make('service_type') + ->datalist([ + 'Embroidery', + 'Screen Printing', + 'Vinyl', + 'Editing', + 'Digitizing', + ]) + ->grow(false), + TextInput::make('placement'), + TextInput::make('serviceFile.name') + ->label('Logo Name'), + + TextInput::make('serviceFile.code'), + TextInput::make('serviceFile.setup_number'), + TextInput::make('serviceFile.width'), + TextInput::make('serviceFile.height'), + TextInput::make('amount') + ->label('Quantity'), + TextInput::make('amount_price'), + + Textarea::make('notes') + ->placeholder('Thread colors...'), + ]) + ->reorderable() + ->cloneable() + ->columns(4) + ->columnSpan(2), + ]); } public static function table(Table $table): Table @@ -65,7 +182,6 @@ class OrderResource extends Resource ->columns([ TextColumn::make('internal_po') ->label('Internal PO') - ->copyable() ->fontFamily('mono') ->color('info') ->searchable() @@ -76,7 +192,6 @@ class OrderResource extends Resource TextColumn::make('customer_po') ->label('PO') ->wrap() - ->copyable() ->weight('bold') ->color('code') ->searchable() @@ -114,7 +229,7 @@ class OrderResource extends Resource public static function getRelations(): array { return [ - // + // OrderProductsRelationManager::class, ]; } @@ -185,33 +300,35 @@ class OrderResource extends Resource private static function getGarmentDetails(): array { return [ - Repeater::make('Garments')->schema([ - Split::make([ - TextInput::make('sku')->grow(true), - TextInput::make('name')->grow(false), - TextInput::make('color')->grow(true), - ]), - Split::make([ - Cluster::make([ - TextInput::make('xs') - ->placeholder('xs'), - TextInput::make('s') - ->placeholder('s'), - TextInput::make('m') - ->placeholder('m'), - TextInput::make('l') - ->placeholder('l'), - TextInput::make('xl') - ->placeholder('xl'), - TextInput::make('2xl') - ->placeholder('2xl'), - TextInput::make('3xl') - ->placeholder('3xl'), - TextInput::make('osfa') - ->placeholder('osfa'), - ])->label('Sizes'), - ]), - ])->grid(2), + Repeater::make('Garments') + ->relationship('orderProducts') + ->schema([ + Split::make([ + TextInput::make('sku')->grow(true), + TextInput::make('product_name')->grow(false), + TextInput::make('color')->grow(true), + ]), + Split::make([ + Cluster::make([ + TextInput::make('xs') + ->placeholder('xs'), + TextInput::make('s') + ->placeholder('s'), + TextInput::make('m') + ->placeholder('m'), + TextInput::make('l') + ->placeholder('l'), + TextInput::make('xl') + ->placeholder('xl'), + TextInput::make('2xl') + ->placeholder('2xl'), + TextInput::make('3xl') + ->placeholder('3xl'), + TextInput::make('osfa') + ->placeholder('osfa'), + ])->label('Sizes'), + ]), + ])->grid(1), ]; } @@ -219,7 +336,37 @@ class OrderResource extends Resource { return [ Repeater::make('Production Details') - ->schema([]), + ->relationship('productServices') + ->schema([ + Split::make([ + TextInput::make('service_type') + ->datalist([ + 'Embroidery', + 'Screen Printing', + 'Vinyl', + 'Editing', + 'Digitizing', + ]) + ->grow(false), + TextInput::make('placement'), + TextInput::make('serviceFile.name') + ->label('Logo Name'), + ]), + + Split::make([ + TextInput::make('serviceFile.code'), + TextInput::make('serviceFile.setup_number'), + TextInput::make('serviceFile.width'), + TextInput::make('serviceFile.height'), + TextInput::make('amount') + ->label('Quantity'), + TextInput::make('amount_price'), + ]), + + Textarea::make('notes') + ->placeholder('Thread colors...'), + ]) + ->defaultItems(2), ]; } } diff --git a/app/Filament/Resources/OrderResource/RelationManagers/OrderProductsRelationManager.php b/app/Filament/Resources/OrderResource/RelationManagers/OrderProductsRelationManager.php new file mode 100644 index 0000000..2b35b87 --- /dev/null +++ b/app/Filament/Resources/OrderResource/RelationManagers/OrderProductsRelationManager.php @@ -0,0 +1,50 @@ +schema([ + Forms\Components\TextInput::make('id') + ->required() + ->maxLength(255), + ]); + } + + public function table(Table $table): Table + { + return $table + ->recordTitleAttribute('id') + ->columns([ + Tables\Columns\TextColumn::make('sku'), + Tables\Columns\TextColumn::make('product_name'), + Tables\Columns\TextColumn::make('color'), + ]) + ->filters([ + // + ]) + ->headerActions([ + Tables\Actions\CreateAction::make(), + ]) + ->actions([ + Tables\Actions\EditAction::make(), + Tables\Actions\DeleteAction::make(), + ]) + ->bulkActions([ + Tables\Actions\BulkActionGroup::make([ + Tables\Actions\DeleteBulkAction::make(), + ]), + ]); + } +} diff --git a/app/Filament/Resources/PackingSlipResource.php b/app/Filament/Resources/PackingSlipResource.php index 0ad32fb..812c863 100644 --- a/app/Filament/Resources/PackingSlipResource.php +++ b/app/Filament/Resources/PackingSlipResource.php @@ -3,7 +3,13 @@ namespace App\Filament\Resources; use App\Filament\Resources\PackingSlipResource\Pages; +use App\Models\Customer; +use App\Models\Order; use App\Models\PackingSlip; +use Filament\Forms\Components\DatePicker; +use Filament\Forms\Components\Select; +use Filament\Forms\Components\Textarea; +use Filament\Forms\Components\TextInput; use Filament\Forms\Form; use Filament\Resources\Resource; use Filament\Tables; @@ -22,7 +28,19 @@ class PackingSlipResource extends Resource { return $form ->schema([ - // + DatePicker::make('date_received'), + TextInput::make('amount'), + Select::make('customer_id') + ->options(Customer::all()->pluck('company_name', 'id')) + ->reactive() + ->searchable(), + Select::make('order_id') + ->options(fn ($get): array => Order::where('customer_id', $get('customer_id') ?? null) + ->get() + ->pluck('customer_po', 'id') + ->toArray()) + ->searchable(), + TextArea::make('contents'), ]); } diff --git a/app/Models/OrderProduct.php b/app/Models/OrderProduct.php index 75ce673..7809d61 100644 --- a/app/Models/OrderProduct.php +++ b/app/Models/OrderProduct.php @@ -38,10 +38,10 @@ class OrderProduct extends Model /** * @return HasOne */ - public function serviceFile(): HasOne - { - return $this->hasOne(ServiceFile::class); - } + // public function serviceFile(): HasOne + // { + // return $this->hasOne(ServiceFile::class); + // } /** * @return HasMany diff --git a/app/Models/ServiceFile.php b/app/Models/ServiceFile.php index dd5a201..2bde33b 100644 --- a/app/Models/ServiceFile.php +++ b/app/Models/ServiceFile.php @@ -24,7 +24,7 @@ class ServiceFile extends Model /** * @return HasMany */ - public function productService(): HasMany + public function productServices(): HasMany { return $this->HasMany(ProductService::class); } diff --git a/composer.json b/composer.json index 83c857d..fb624bb 100644 --- a/composer.json +++ b/composer.json @@ -9,6 +9,7 @@ "davidhsianturi/blade-bootstrap-icons": "^1.5", "filament/filament": "^3.2", "guava/filament-clusters": "^1.4", + "icetalker/filament-table-repeater": "^1.3", "laravel/framework": "^11.9", "laravel/tinker": "^2.9", "livewire/livewire": "^3.5", diff --git a/composer.lock b/composer.lock index a639cb5..62f6bed 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "00bc993b06d741537a402ae3b7418edb", + "content-hash": "86c43bbee5882b7329eaa389aa089339", "packages": [ { "name": "anourvalar/eloquent-serialize", @@ -2098,6 +2098,87 @@ ], "time": "2023-12-03T19:50:20+00:00" }, + { + "name": "icetalker/filament-table-repeater", + "version": "v1.3.1", + "source": { + "type": "git", + "url": "https://github.com/icetalker/filament-table-repeater.git", + "reference": "2d9fa7738d6aa6939b6dfcb49d53aed44da6b8ba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/icetalker/filament-table-repeater/zipball/2d9fa7738d6aa6939b6dfcb49d53aed44da6b8ba", + "reference": "2d9fa7738d6aa6939b6dfcb49d53aed44da6b8ba", + "shasum": "" + }, + "require": { + "filament/forms": "^3.0", + "illuminate/contracts": "^8.6|^9.0|^10.0|^11.0", + "php": "^8.0", + "spatie/laravel-package-tools": "^1.9.2" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.8", + "nunomaduro/collision": "^6.0|^8.0", + "nunomaduro/larastan": "^2.0.1", + "orchestra/testbench": "^7.0|^9.0", + "pestphp/pest": "^1.21|^2.34", + "pestphp/pest-plugin-laravel": "^1.1|^2.3", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan-deprecation-rules": "^1.0", + "phpstan/phpstan-phpunit": "^1.0", + "phpunit/phpunit": "^9.5|^10.5", + "spatie/laravel-ray": "^1.26" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Icetalker\\FilamentTableRepeater\\FilamentTableRepeaterServiceProvider" + ], + "aliases": { + "FilamentTableRepeater": "Icetalker\\FilamentTableRepeater\\Facades\\FilamentTableRepeater" + } + } + }, + "autoload": { + "psr-4": { + "Icetalker\\FilamentTableRepeater\\": "src", + "Icetalker\\FilamentTableRepeater\\Database\\Factories\\": "database/factories" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Martin Hwang", + "email": "martin.hwang@outlook.com", + "role": "Developer" + } + ], + "description": "This is a package for Filament form component. Extends form Repeater, but shows in Table Layout.", + "homepage": "https://github.com/icetalker/filament-table-repeater", + "keywords": [ + "filament", + "filament-table-repeater", + "icetalker", + "laravel" + ], + "support": { + "issues": "https://github.com/icetalker/filament-table-repeater/issues", + "source": "https://github.com/icetalker/filament-table-repeater/tree/v1.3.1" + }, + "funding": [ + { + "url": "https://paypal.me/termlong", + "type": "custom" + } + ], + "time": "2024-05-07T12:46:22+00:00" + }, { "name": "kirschbaum-development/eloquent-power-joins", "version": "4.0.0",