2025-02-11 14:32:10 -05:00

242 lines
9.7 KiB
PHP

<?php
namespace App\Filament\Admin\Resources\OrderResource\Pages;
use App\Enums\IconEnum;
use App\Enums\InvoiceStatus;
use App\Enums\OrderAttributes;
use App\Enums\OrderStatus;
use App\Filament\Admin\Resources\InvoiceResource;
use App\Filament\Admin\Resources\OrderResource;
use App\Models\Invoice;
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 Filament\Actions;
use Filament\Actions\Action;
use Filament\Notifications\Notification;
use Filament\Resources\Pages\EditRecord;
use Illuminate\Contracts\Support\Htmlable;
use Illuminate\Database\Eloquent\Model;
class EditOrder extends EditRecord
{
protected static string $resource = OrderResource::class;
public function getTitle(): string|Htmlable
{
return parent::getTitle().' '.$this->record->internal_po;
}
protected function mutateFormDataBeforeFill(array $data): array
{
$order = Order::findOrFail($data['id']);
// Order Products
foreach ($order->orderProducts as $key => $product) {
$data['order_products'][$key] = [
'sku' => $product->sku,
'product_name' => $product->product_name,
'color' => $product->color,
'xs' => $product->productSizes->where('size', 'xs')->first()->amount ?? null,
's' => $product->productSizes->where('size', 's')->first()->amount ?? null,
'm' => $product->productSizes->where('size', 'm')->first()->amount ?? null,
'l' => $product->productSizes->where('size', 'l')->first()->amount ?? null,
'xl' => $product->productSizes->where('size', 'xl')->first()->amount ?? null,
'2xl' => $product->productSizes->where('size', '2xl')->first()->amount ?? null,
'3xl' => $product->productSizes->where('size', '3xl')->first()->amount ?? null,
'osfa' => $product->productSizes->where('size', 'osfa')->first()->amount ?? null,
];
}
// Product Services
foreach ($order->productServices as $key => $service) {
$data['services'][$key] = [
'placement' => $service->placement ?? '',
'amount' => $service->amount ?? '',
'amount_price' => $service->amount_price ?? '',
'notes' => $service->notes ?? '',
'serviceType' => $service->serviceType->id ?? '',
'serviceFileName' => $service->serviceFile->name ?? '',
'serviceFileWidth' => $service->serviceFile->width ?? '',
'serviceFileHeight' => $service->serviceFile->height ?? '',
'serviceFileCode' => $service->serviceFile->code ?? '',
'serviceFileSetupNumber' => $service->serviceFile->setup_number ?? '',
];
}
foreach (OrderAttributes::cases() as $case) {
if ($data[$case->name]) {
$data['order_attributes'][] = $case->value ?? null;
}
}
return $data;
}
public function handleRecordUpdate(Model $record, array $data): Model
{
// Correctly set attribute booleans
foreach (OrderAttributes::cases() as $case) {
$data[$case->name] = false;
}
$data['order_attributes'] = array_filter($data['order_attributes']);
foreach ($data['order_attributes'] as $attribute) {
$data[OrderAttributes::from($attribute)->name] = true;
}
unset($data['order_attributes']);
$record->update($data);
// Delete old and create new Order Products
foreach ($record->orderProducts as $product) {
foreach ($product->productSizes as $size) {
$size->delete();
}
$product->delete();
}
foreach ($data['order_products'] as $product) {
$orderProduct = OrderProduct::create([
'sku' => $product['sku'],
'product_name' => $product['product_name'],
'color' => $product['color'],
'order_id' => $record->id,
]);
$sizes = ['xs', 's', 'm', 'l', 'xl', '2xl', '3xl', 'osfa'];
foreach ($sizes as $size) {
if ($product[$size] > 0) {
ProductSize::create([
'amount' => $product[$size],
'size' => $size,
'order_product_id' => $orderProduct->id,
]);
}
}
}
// Delete old and create new services
foreach ($record->productServices as $service) {
$service->delete();
}
foreach ($data['services'] as $service) {
$serviceFile = ServiceFile::create([
'name' => strtoupper($service['serviceFileName']) ?? '',
'code' => strtoupper($service['serviceFileCode']) ?? '',
'width' => $service['serviceFileWidth'] ?? null,
'height' => $service['serviceFileHeight'] ?? null,
'setup_number' => $service['serviceFileSetupNumber'] ?? null,
]);
ProductService::create([
'service_type_id' => ServiceType::findOrFail($service['serviceType'])->id ?? null,
'placement' => strtoupper($service['placement']) ?? null,
'notes' => strtoupper($service['notes']) ?? null,
'amount' => $service['amount'] ?? null,
'amount_price' => $service['amount_price'] ?? null,
'total_price' => $service['total_price'] ?? null,
'service_file_id' => $serviceFile->id,
'order_id' => $record->id,
]);
}
return $record;
}
protected function getHeaderActions(): array
{
return [
Action::make('save')
->label('Save changes')
->action('save')
->icon(IconEnum::SAVE->value),
Actions\ReplicateAction::make()
->label('Duplicate')
->icon(IconEnum::COPY->value)
->mutateRecordDataUsing(function (array $data): array {
$po = 'Duplicate of '.$data['customer_po'];
$data['customer_po'] = $po;
return $data;
})
->beforeReplicaSaved(function (Order $replica): void {
$replica->customer_po = 'Repeat of '.$replica->customer_po;
$replica->status = OrderStatus::DRAFT;
$replica->printed = false;
$replica->pre_production = false;
$replica->order_date = today();
$replica->due_date = today()->addDays(10);
$replica->save();
foreach ($this->record->orderProducts as $product) {
$newProduct = $product->replicate();
$newProduct->order_id = $replica->id;
$newProduct->save();
foreach ($product->productSizes as $size) {
$newSize = $size->replicate();
$newSize->order_product_id = $newProduct->id;
$newSize->save();
}
}
/** @var ProductService $service */
foreach ($this->record->productServices as $service) {
/** @var ServiceFile $newServiceFile */
$newServiceFile = $service->serviceFile->replicate();
$newService = $service->replicate();
$newService->order_id = $replica->id;
$newService->service_file_id = $newServiceFile->id;
$newService->save();
}
})
->successRedirectUrl(fn (Model $replica): string => OrderResource::getUrl('edit', [$replica])),
Action::make('invoice')
->visible(fn () => auth()->user()->is_admin)
->label(fn (Order $record) => $record->invoice()->exists() ? 'To Invoice' : 'Make Invoice')
->icon(IconEnum::INVOICE->value)
->action(function (Order $record) {
if ($record->invoice()->exists()) {
return redirect()->to(InvoiceResource::getUrl('edit', ['record' => $record->invoice->id]));
}
$invoice = Invoice::create([
'customer_id' => $record->customer_id,
'date' => today(),
'status' => InvoiceStatus::UNPAID->value,
]);
$invoice->orders()->save($record);
return Notification::make()
->title('Invoice '.$invoice->internal_id.' created successfully')
->body('Click the button again to go to the invoice')
->success()
->send();
}),
Action::make('print')
->icon(IconEnum::PRINT->value)
->url(fn (Order $record) => route('orders.pdf', $record))
->openUrlInNewTab(),
Actions\DeleteAction::make()
->icon(IconEnum::TRASH->value),
];
}
}