More work on shippingEntries
Table groupified + search working despite lack of column; create/edit form
This commit is contained in:
parent
487ea48c14
commit
548e56335f
@ -2,9 +2,28 @@
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
enum ShippingType: string
|
||||
use Filament\Support\Contracts\HasIcon;
|
||||
use Filament\Support\Contracts\HasLabel;
|
||||
|
||||
enum ShippingType: string implements HasIcon, HasLabel
|
||||
{
|
||||
case THEY_SHIP = 'They ship';
|
||||
case WE_SHIP = 'We ship';
|
||||
case PICKUP = 'Pickup';
|
||||
case OTHER = 'Other';
|
||||
|
||||
public function getLabel(): ?string
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
public function getIcon(): ?string
|
||||
{
|
||||
return match ($this) {
|
||||
self::THEY_SHIP => 'lucide-truck',
|
||||
self::WE_SHIP => 'lucide-house',
|
||||
self::PICKUP => 'lucide-handshake',
|
||||
self::OTHER => 'lucide-ellipsis'
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -2,12 +2,24 @@
|
||||
|
||||
namespace App\Filament\Resources;
|
||||
|
||||
use App\Enums\ShippingType;
|
||||
use App\Filament\Resources\ShippingEntryResource\Pages;
|
||||
use App\Models\ShippingEntry;
|
||||
use Filament\Forms\Components\Fieldset;
|
||||
use Filament\Forms\Components\Section;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Components\Split;
|
||||
use Filament\Forms\Components\Textarea;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Components\ToggleButtons;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Support\Enums\IconPosition;
|
||||
use Filament\Tables;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Grouping\Group;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class ShippingEntryResource extends Resource
|
||||
{
|
||||
@ -23,7 +35,65 @@ public static function form(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->schema([
|
||||
//
|
||||
Section::make([
|
||||
Fieldset::make('Primary information')
|
||||
->schema([
|
||||
Select::make('customer')
|
||||
->relationship('customer', 'company_name')
|
||||
->searchable()
|
||||
->required(),
|
||||
|
||||
ToggleButtons::make('shipping_type')
|
||||
->options(ShippingType::class)
|
||||
->inline()
|
||||
->required(),
|
||||
|
||||
TextInput::make('courier')
|
||||
->placeholder('UPS, Purolator...'),
|
||||
]),
|
||||
|
||||
Split::make([
|
||||
Fieldset::make('Account Details')
|
||||
->schema([
|
||||
TextInput::make('account_title')
|
||||
->label('Title')
|
||||
->prefixIcon('lucide-folder-pen')
|
||||
->placeholder('What is this account used for?')
|
||||
->columnSpan(2),
|
||||
TextInput::make('account_url')
|
||||
->label('URL')
|
||||
->prefixIcon('lucide-globe')
|
||||
->placeholder('Shipping website')
|
||||
->url()
|
||||
->columnSpan(2),
|
||||
TextInput::make('account_username')
|
||||
->label('Username')
|
||||
->prefixIcon('lucide-circle-user')
|
||||
->placeholder('...'),
|
||||
TextInput::make('account_password')
|
||||
->label('Password')
|
||||
->prefixIcon('lucide-key-round')
|
||||
->placeholder('...'),
|
||||
])->columnSpan(1),
|
||||
|
||||
Fieldset::make('Shipping Instructions')
|
||||
->schema([
|
||||
TextInput::make('info_needed')
|
||||
->label('Instructions')
|
||||
->prefixIcon('lucide-pencil')
|
||||
->placeholder('Example: put PO on box')
|
||||
->columnSpan(2),
|
||||
TextInput::make('notify')
|
||||
->placeholder('Who to email and CC?')
|
||||
->prefixIcon('lucide-users-round')
|
||||
->columnSpan(2),
|
||||
TextArea::make('notes')
|
||||
->placeholder('Any additional information...')
|
||||
->rows(2)
|
||||
->columnSpan(2),
|
||||
]),
|
||||
])->columnSpan(2),
|
||||
])->columns(2),
|
||||
]);
|
||||
}
|
||||
|
||||
@ -31,19 +101,24 @@ public static function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
Tables\Columns\TextColumn::make('customer.company_name')
|
||||
->searchable(),
|
||||
Tables\Columns\TextColumn::make('shipping_type')
|
||||
TextColumn::make('shipping_type')
|
||||
->label('Type')
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('courier'),
|
||||
// Tables\Columns\TextColumn::make('contact'),
|
||||
Tables\Columns\TextColumn::make('account_title'),
|
||||
// Tables\Columns\TextColumn::make('account_username'),
|
||||
// Tables\Columns\TextColumn::make('account_password'),
|
||||
Tables\Columns\TextColumn::make('info_needed'),
|
||||
Tables\Columns\TextColumn::make('notify'),
|
||||
TextColumn::make('courier')
|
||||
->url(fn ($record) => $record->account_url ?? null, shouldOpenInNewTab: true)
|
||||
->icon(fn ($record) => $record->account_url ? 'lucide-external-link' : null)
|
||||
->iconPosition(IconPosition::After)
|
||||
->searchable(query: function (Builder $query, $search) {
|
||||
return $query
|
||||
->where('courier', 'like', "%{$search}%")
|
||||
->orWhereHas('customer', function (Builder $query) use ($search) {
|
||||
return $query->where('company_name', 'like', "%{$search}%");
|
||||
});
|
||||
}),
|
||||
|
||||
TextColumn::make('account_title'),
|
||||
TextColumn::make('info_needed'),
|
||||
TextColumn::make('notify'),
|
||||
])
|
||||
->filters([
|
||||
//
|
||||
@ -55,11 +130,11 @@ public static function table(Table $table): Table
|
||||
// Tables\Actions\BulkActionGroup::make([
|
||||
// Tables\Actions\DeleteBulkAction::make(),
|
||||
// ]),
|
||||
]);
|
||||
// ->defaultGroup(
|
||||
// Group::make('customer.company_name')
|
||||
// ->titlePrefixedWithLabel(false)
|
||||
// );
|
||||
])
|
||||
->defaultGroup(
|
||||
Group::make('customer.company_name')
|
||||
->titlePrefixedWithLabel(false)
|
||||
);
|
||||
}
|
||||
|
||||
public static function getRelations(): array
|
||||
|
@ -24,6 +24,7 @@ class ShippingEntry extends Model
|
||||
'courier',
|
||||
'contact',
|
||||
'account_title',
|
||||
'account_url',
|
||||
'account_username',
|
||||
'account_password',
|
||||
'info_needed',
|
||||
|
@ -18,6 +18,7 @@ public function definition(): array
|
||||
'courier' => $this->faker->randomElement(['UPS', 'Purolator', 'FreightCom', 'E-Shipper', 'ACE']),
|
||||
'contact' => $this->faker->randomElement(['courier.com', '+1 604 123 4567']),
|
||||
'account_title' => $this->faker->word,
|
||||
'account_url' => 'https://www.example.com',
|
||||
'account_username' => 'username',
|
||||
'account_password' => 'password',
|
||||
'info_needed' => $this->faker->words(3, true),
|
||||
|
@ -15,6 +15,7 @@ public function up(): void
|
||||
$table->string('courier')->nullable();
|
||||
$table->string('contact')->nullable();
|
||||
$table->string('account_title')->nullable();
|
||||
$table->string('account_url')->nullable();
|
||||
$table->string('account_username')->nullable();
|
||||
$table->string('account_password')->nullable();
|
||||
$table->string('info_needed')->nullable();
|
||||
|
@ -9,17 +9,23 @@
|
||||
use App\Models\Contact;
|
||||
use App\Models\Customer;
|
||||
use App\Models\Order;
|
||||
use App\Models\OrderProduct;
|
||||
use App\Models\ProductService;
|
||||
use App\Models\ProductSize;
|
||||
use App\Models\ServiceFile;
|
||||
use App\Models\ServiceType;
|
||||
use App\Models\User;
|
||||
|
||||
use function Pest\Livewire\livewire;
|
||||
|
||||
it('can create an order and save it to the database', function () {
|
||||
it('can create an order and all associated models and save it to the database', function () {
|
||||
$type = fake()->randomElement(OrderType::cases());
|
||||
$status = fake()->randomElement(OrderStatus::cases());
|
||||
$customer = Customer::factory()->create();
|
||||
$contact = Contact::factory()->for($customer)->create();
|
||||
$attributes = array_map(fn ($case) => $case->value, OrderAttributes::cases());
|
||||
$orderDate = today();
|
||||
$dueDate = today()->addDays(10);
|
||||
|
||||
$serviceTypes = ServiceType::factory()->count(2)->create();
|
||||
|
||||
@ -31,8 +37,8 @@
|
||||
'customer_id' => $customer->id,
|
||||
'contact_id' => $contact->id,
|
||||
'customer_po' => 'Customer PO name here',
|
||||
'order_date' => today(),
|
||||
'due_date' => today()->addDays(10),
|
||||
'order_date' => $orderDate,
|
||||
'due_date' => $dueDate,
|
||||
'notes' => 'Notes go here! Here\'s the notes!',
|
||||
'pre_production' => '1',
|
||||
'printed' => '1',
|
||||
@ -102,9 +108,180 @@
|
||||
->assertHasNoErrors();
|
||||
|
||||
$order = Order::first();
|
||||
|
||||
$this->assertNotNull($order);
|
||||
$this->assertSame(
|
||||
[
|
||||
$order->id,
|
||||
$order->customer_id,
|
||||
$order->contact_id,
|
||||
$order->internal_po,
|
||||
$order->customer_po,
|
||||
$order->invoice_id,
|
||||
$order->order_date,
|
||||
$order->order_type,
|
||||
$order->status,
|
||||
$order->due_date,
|
||||
$order->notes,
|
||||
$order->rush,
|
||||
$order->repeat,
|
||||
$order->new_art,
|
||||
$order->event,
|
||||
$order->digitizing,
|
||||
$order->garments,
|
||||
$order->supplied_file,
|
||||
$order->printed,
|
||||
$order->pre_production,
|
||||
],
|
||||
[
|
||||
1,
|
||||
$customer->id,
|
||||
$contact->id,
|
||||
'TN24-0001',
|
||||
'Customer PO name here',
|
||||
null,
|
||||
$orderDate->format('Y-m-d'),
|
||||
$type,
|
||||
$status,
|
||||
$dueDate->format('Y-m-d'),
|
||||
'Notes go here! Here\'s the notes!',
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
]);
|
||||
|
||||
$this->assertSame($order->customer_id, $formData['customer_id']);
|
||||
// Order Products
|
||||
$orderProducts = OrderProduct::all();
|
||||
$this->assertNotNull($orderProducts);
|
||||
$this->assertEquals(2, $orderProducts->count());
|
||||
$this->assertEquals(
|
||||
[
|
||||
$orderProducts[0]->id,
|
||||
$orderProducts[0]->sku,
|
||||
$orderProducts[0]->product_name,
|
||||
$orderProducts[0]->color,
|
||||
$orderProducts[0]->order_id,
|
||||
|
||||
$orderProducts[1]->id,
|
||||
$orderProducts[1]->sku,
|
||||
$orderProducts[1]->product_name,
|
||||
$orderProducts[1]->color,
|
||||
$orderProducts[1]->order_id,
|
||||
],
|
||||
[
|
||||
1,
|
||||
'sku 1',
|
||||
'test',
|
||||
'black',
|
||||
'1',
|
||||
|
||||
2,
|
||||
'sku 2',
|
||||
'also test',
|
||||
'white',
|
||||
'1',
|
||||
]
|
||||
);
|
||||
|
||||
// Product Services
|
||||
$productServices = ProductService::all();
|
||||
$this->assertNotNull($productServices);
|
||||
$this->assertEquals(2, $productServices->count());
|
||||
$this->assertEquals(
|
||||
[
|
||||
$productServices[0]->id,
|
||||
$productServices[0]->order_id,
|
||||
$productServices[0]->service_file_id,
|
||||
$productServices[0]->service_type_id,
|
||||
$productServices[0]->placement,
|
||||
$productServices[0]->amount,
|
||||
$productServices[0]->amount_price,
|
||||
$productServices[0]->notes,
|
||||
|
||||
$productServices[1]->id,
|
||||
$productServices[1]->order_id,
|
||||
$productServices[1]->service_file_id,
|
||||
$productServices[1]->service_type_id,
|
||||
$productServices[1]->placement,
|
||||
$productServices[1]->amount,
|
||||
$productServices[1]->amount_price,
|
||||
$productServices[1]->notes,
|
||||
],
|
||||
[
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
$serviceTypes[0]->id,
|
||||
'C/F',
|
||||
'3',
|
||||
'4',
|
||||
'HERE\'S SOME NOTES, ALL HANDWRITTEN BY ME.',
|
||||
|
||||
2,
|
||||
1,
|
||||
2,
|
||||
$serviceTypes[1]->id,
|
||||
'F/B',
|
||||
'8',
|
||||
'9',
|
||||
'HERE\'S EVEN MORE NOTES, STILL HANDWRITTEN BY ME.',
|
||||
]
|
||||
);
|
||||
|
||||
// Service Files
|
||||
$serviceFiles = ServiceFile::all();
|
||||
$this->assertNotNull($serviceFiles);
|
||||
$this->assertEquals(2, $serviceFiles->count());
|
||||
$this->assertEquals(
|
||||
[
|
||||
$serviceFiles[0]->id,
|
||||
$serviceFiles[0]->code,
|
||||
$serviceFiles[0]->name,
|
||||
$serviceFiles[0]->width,
|
||||
$serviceFiles[0]->height,
|
||||
$serviceFiles[0]->setup_number,
|
||||
|
||||
$serviceFiles[1]->id,
|
||||
$serviceFiles[1]->code,
|
||||
$serviceFiles[1]->name,
|
||||
$serviceFiles[1]->width,
|
||||
$serviceFiles[1]->height,
|
||||
$serviceFiles[1]->setup_number,
|
||||
],
|
||||
[
|
||||
1,
|
||||
'A1234',
|
||||
'LOGO NAME 1',
|
||||
'1.00',
|
||||
'2.00',
|
||||
1,
|
||||
|
||||
2,
|
||||
'B5678',
|
||||
'LOGO NAME 2',
|
||||
'6.00',
|
||||
'7.00',
|
||||
5,
|
||||
]
|
||||
);
|
||||
|
||||
// Product Sizes
|
||||
$productSizes = ProductSize::all();
|
||||
$this->assertNotNull($productSizes);
|
||||
$this->assertEquals(16, $productSizes->count());
|
||||
|
||||
$sizes = ['xs', 's', 'm', 'l', 'xl', '2xl', '3xl', 'osfa', 'xs', 's', 'm', 'l', 'xl', '2xl', '3xl', 'osfa'];
|
||||
|
||||
for ($i = 0; $i < $productSizes->count(); $i++) {
|
||||
$this->assertSame($productSizes[$i]->id, $i + 1);
|
||||
$this->assertEquals($productSizes[$i]->order_product_id, $i > 7 ? '2' : '1');
|
||||
$this->assertEquals($productSizes[$i]->amount, $i + 1);
|
||||
$this->assertEquals($productSizes[$i]->size, $sizes[$i]);
|
||||
}
|
||||
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user