diff --git a/.gitignore b/.gitignore index 169466d..d45aa27 100644 --- a/.gitignore +++ b/.gitignore @@ -106,3 +106,4 @@ fabric.properties .directory .directory .directory +public diff --git a/app/Filament/Admin/Resources/QuoteResource.php b/app/Filament/Admin/Resources/QuoteResource.php index 331fed4..8257f71 100644 --- a/app/Filament/Admin/Resources/QuoteResource.php +++ b/app/Filament/Admin/Resources/QuoteResource.php @@ -6,6 +6,9 @@ use App\Models\Customer; use App\Models\Quote; use Filament\Forms\Components\DatePicker; +use Filament\Forms\Components\Grid; +use Filament\Forms\Components\Placeholder; +use Filament\Forms\Components\Repeater; use Filament\Forms\Components\Section; use Filament\Forms\Components\Select; use Filament\Forms\Components\Textarea; @@ -31,22 +34,44 @@ public static function form(Form $form): Form { return $form ->schema([ - Section::make([ - Select::make('customer_id') - ->required() - ->label('Customer') - ->options(Customer::all()->pluck('company_name', 'id')) - ->reactive() - ->searchable() - ->columnSpan(1), + Grid::make(3) + ->schema([ + Section::make([ + Select::make('customer_id') + ->required() + ->label('Customer') + ->options(Customer::all()->pluck('company_name', 'id')) + ->reactive() + ->searchable() + ->columnSpan(1), - DatePicker::make('date') - ->required(), + DatePicker::make('date') + ->default(today()) + ->required(), - TextArea::make('notes') - ->columnSpan(2), - ]) - ->columns(2), + TextArea::make('notes') + ->rows(3) + ->columnSpan(2), + ]) + ->columns(2) + ->columnSpan(2), + + Section::make() + ->schema([ + Placeholder::make('Id') + ->label('ID') + ->content(fn (Quote $record): ?string => $record->id), + + Placeholder::make('created_at') + ->content(fn (Quote $record): ?string => $record->created_at?->diffForHumans().' at '.$record->created_at->format('Y-m-d')), + + Placeholder::make('updated_at') + ->content(fn (Quote $record): ?string => $record->updated_at?->diffForHumans().' at '.$record->updated_at->format('Y-m-d')), + + ]) + ->columnSpan(1) + ->hidden(fn (?Quote $record) => $record === null), + ]), TableRepeater::make('embroideryEntries') ->relationship('embroideryEntries') @@ -65,10 +90,47 @@ public static function form(Form $form): Form ->prefix('$'), TextInput::make('run_charge') ->prefix('$'), - ]), + ]) + ->addActionLabel('Add Embroidery Entry') + ->defaultItems(0), - TableRepeater::make('screenPrintEntries') + Repeater::make('screenPrintEntries') ->relationship('screenPrintEntries') + ->schema([ + Grid::make(8) + ->schema([ + TextInput::make('logo') + ->label('Logo name') + ->columnSpan(2), + TextInput::make('quantity') + ->prefix('#'), + TextInput::make('width') + ->suffix('"'), + TextInput::make('height') + ->suffix('"'), + TextInput::make('setup_number') + ->prefix('#'), + TextInput::make('color_amount') + ->prefix('#'), + TextInput::make('color_match') + ->prefix('$'), + TextInput::make('flash') + ->prefix('$'), + TextInput::make('fleece') + ->prefix('$'), + TextInput::make('poly_ink') + ->prefix('$'), + TextInput::make('run_charge') + ->prefix('$'), + TextInput::make('other_charges') + ->prefix('$'), + ]), + ]) + ->addActionLabel('Add Screen Print Entry') + ->defaultItems(0), + + TableRepeater::make('heatTransferEntries') + ->relationship('heatTransferEntries') ->schema([ TextInput::make('logo') ->label('Logo name'), @@ -78,32 +140,11 @@ public static function form(Form $form): Form ->suffix('"'), TextInput::make('height') ->suffix('"'), - TextInput::make('color_amount'), - TextInput::make('color_match') - ->prefix('$'), - TextInput::make('flash') - ->prefix('$'), - TextInput::make('fleece') - ->prefix('$'), - TextInput::make('poly_ink') - ->prefix('$'), - TextInput::make('other_charges'), - ]), - - TableRepeater::make('heatTransferEntries') - ->relationship('heatTransferEntries') - ->schema([ - TextInput::make('logo') - ->label('Logo name'), - TextInput::make('quantity') - ->prefix('#'), - TextInput::make('Width') - ->suffix('"'), - TextInput::make('Height') - ->suffix('"'), TextInput::make('price') ->prefix('$'), - ]), + ]) + ->addActionLabel('Add Heat Transfer Entry') + ->defaultItems(0), ])->columns(1); } @@ -111,6 +152,10 @@ public static function table(Table $table): Table { return $table ->columns([ + TextColumn::make('id') + ->color('primary') + ->searchable(), + TextColumn::make('date') ->date('Y-m-d') ->sortable() diff --git a/app/Filament/Admin/Resources/QuoteResource/Pages/EditQuote.php b/app/Filament/Admin/Resources/QuoteResource/Pages/EditQuote.php index fd9dbd6..63842b1 100644 --- a/app/Filament/Admin/Resources/QuoteResource/Pages/EditQuote.php +++ b/app/Filament/Admin/Resources/QuoteResource/Pages/EditQuote.php @@ -3,7 +3,9 @@ namespace App\Filament\Admin\Resources\QuoteResource\Pages; use App\Filament\Admin\Resources\QuoteResource; +use App\Models\Quote; use Filament\Actions; +use Filament\Actions\Action; use Filament\Resources\Pages\EditRecord; class EditQuote extends EditRecord @@ -13,6 +15,16 @@ class EditQuote extends EditRecord protected function getHeaderActions(): array { return [ + Action::make('save') + ->label('Save changes') + ->action('save') + ->icon('lucide-save'), + + Action::make('print') + ->icon('lucide-printer') + ->url(fn (Quote $record) => route('pdf.quote', $record)) + ->openUrlInNewTab(), + Actions\DeleteAction::make(), ]; } diff --git a/app/Http/Controllers/PdfController.php b/app/Http/Controllers/PdfController.php index af9ec13..cfd448e 100644 --- a/app/Http/Controllers/PdfController.php +++ b/app/Http/Controllers/PdfController.php @@ -3,6 +3,7 @@ namespace App\Http\Controllers; use App\Models\InvoiceReport; +use App\Models\Quote; use Spatie\Browsershot\Browsershot; use Spatie\LaravelPdf\Facades\Pdf; @@ -23,4 +24,22 @@ public function invoiceReport(int $id) return redirect($url); } + + public function quote(int $id) + { + $quote = Quote::find($id); + $company_name = $quote->customer->company_name ?? ''; + + $url = strtolower('TN-quote-'.$quote->id.'.pdf'); + + Pdf::view('pdf.quote', ['quote' => $quote]) + ->withBrowsershot(function (Browsershot $browsershot) { + $browsershot->noSandbox(); + }) + ->margins(8, 8, 15, 8) + ->footerView('pdf.quote-footer', ['quote' => $quote]) + ->save($url); + + return redirect($url); + } } diff --git a/app/Models/EmbroideryEntry.php b/app/Models/EmbroideryEntry.php index 52ea268..e2f14ea 100644 --- a/app/Models/EmbroideryEntry.php +++ b/app/Models/EmbroideryEntry.php @@ -14,7 +14,7 @@ class EmbroideryEntry extends Model 'width', 'height', 'placement', - 'stitches', + 'stitch_count', 'digitizing_cost', 'run_charge', ]; diff --git a/app/Models/Quote.php b/app/Models/Quote.php index 7671739..d15fc4b 100644 --- a/app/Models/Quote.php +++ b/app/Models/Quote.php @@ -17,6 +17,10 @@ class Quote extends Model 'notes', ]; + protected $casts = [ + 'date' => 'date', + ]; + public function customer(): BelongsTo { return $this->belongsTo(Customer::class); diff --git a/database/migrations/020_create_embroidery_entries_table.php b/database/migrations/020_create_embroidery_entries_table.php index ec7f424..d7ce890 100644 --- a/database/migrations/020_create_embroidery_entries_table.php +++ b/database/migrations/020_create_embroidery_entries_table.php @@ -21,7 +21,7 @@ public function up(): void $table->decimal('width', 6, 2)->nullable(); $table->decimal('height', 6, 2)->nullable(); $table->string('placement')->nullable(); - $table->string('stitches')->nullable(); + $table->string('stitch_count')->nullable(); $table->string('digitizing_cost')->nullable(); $table->string('run_charge')->nullable(); $table->text('notes')->nullable(); diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index 8bd5966..3c3f748 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -26,7 +26,7 @@ public function run(): void ServiceTypeSeeder::class, ProductServiceSeeder::class, ServiceFileSeeder::class, - QuoteSeeder::class, + // QuoteSeeder::class, InvoiceSeeder::class, InvoiceReportSeeder::class, ]); diff --git a/resources/views/pdf/quote-footer.blade.php b/resources/views/pdf/quote-footer.blade.php new file mode 100644 index 0000000..1943f3f --- /dev/null +++ b/resources/views/pdf/quote-footer.blade.php @@ -0,0 +1,10 @@ + + +' \ No newline at end of file diff --git a/resources/views/pdf/quote.blade.php b/resources/views/pdf/quote.blade.php new file mode 100644 index 0000000..fa82614 --- /dev/null +++ b/resources/views/pdf/quote.blade.php @@ -0,0 +1,138 @@ +@extends('layouts.pdf') + + + +
+
+ TOP NOTCH EMBROIDERY & DIGITIZING LTD. +
+
+ 108-618 EAST KENT AVE. SOUTH
+ VANCOUVER BC
+ (604) 871-9991
+ info@sewtopnotch.com
+ GST# 846025062RT0001
+
+ +
+ QUOTE +
+ +
+ +
+
+ DATE +
+
+ {{ $quote->date->format('Y-m-d') }} +
+
+ +
+
+ CUSTOMER +
+
+ {{ $quote->customer->company_name ?? '' }} +
+
+ +
+
+ NOTES +
+
+ {{ $quote->notes ?? '' }} +
+
+
+ +
+ + @if($quote->embroideryEntries()->count() != 0)

Embroidery

@endif + + + + + + + + + + + + + + @foreach($quote->embroideryEntries as $entry) + + + + + + + + + + + @endforeach +
LogoPlacementQuantityWidthHeightStitch countDigitizingRun charge
+ {{ $entry->logo }} + + {{ $entry->placement }} + + {{ $entry->quantity }} + + {{$entry->width}}" + + {{$entry->height}}" + + {{$entry->stitch_count}} + + {{$entry->digitizing_cost}} + + {{$entry->run_charge}} +
+ + @if($quote->screenPrintEntries()->count() != 0)

Screen Printing

@endif + + + + + + + + + + + + +
LogoQuantityWidthHeight# of ColorsColor MatchFlashFleecePoly InkOther charges
+ +{{--
--}} + +{{--
--}} +{{--
${{number_format($invoice->subtotal, 2)}}
--}} +{{--
${{number_format($invoice->gst_amount, 2)}}
--}} +{{--
${{number_format($invoice->pst_amount, 2)}}
--}} +{{--
${{number_format($invoice->total, 2)}}
--}} +{{--
--}} +{{--
${{number_format($invoice->total, 2)}}
--}} +{{--
--}} + +{{--
--}} +{{--
Subtotal
--}} +{{--
GST @ {{$invoice->gst_rate}}%
--}} +{{--
PST (BC) @ {{$invoice->pst_rate}}%
--}} +{{--
TOTAL
--}} +{{--
--}} +{{--
BALANCE DUE
--}} +{{--
--}} +
+ +
+ diff --git a/resources/views/vendor/filament-table-repeater/table-repeater.blade.php b/resources/views/vendor/filament-table-repeater/table-repeater.blade.php index 125147e..2f90438 100644 --- a/resources/views/vendor/filament-table-repeater/table-repeater.blade.php +++ b/resources/views/vendor/filament-table-repeater/table-repeater.blade.php @@ -37,7 +37,7 @@ {{ $attributes ->merge($getExtraAttributes(), escape: false) - ->class(['bg-white border border-gray-150 rounded-xl relative dark:bg-gray-900 dark:border-gray-800']) + ->class(['bg-white border border-gray-150 rounded-xl relative dark:bg-gray-900 dark:border-gray-700']) }} > diff --git a/routes/web.php b/routes/web.php index 5d91c56..2b7c0b4 100644 --- a/routes/web.php +++ b/routes/web.php @@ -19,6 +19,8 @@ // Auth::routes(); Route::get('/pdf/invoicereport/{id}', [PdfController::class, 'invoiceReport'])->name('pdf.invoice-report'); +Route::get('/pdf/quote/{id}', [PdfController::class, 'quote'])->name('pdf.quote'); + Route::get('orders/{order}/pdf', [OrderController::class, 'pdf'])->name('orders.pdf'); Route::get('invoices/{invoice}/pdf', [InvoiceController::class, 'pdf'])->name('invoice.pdf'); Route::get('customers/{customer}/pdf', [CustomerController::class, 'pdf'])->name('customer.pdf');