Work work

This commit is contained in:
Nisse Lommerde 2024-12-10 15:28:14 -08:00
parent 90ef3c9c29
commit f122f2925a
114 changed files with 1762 additions and 771 deletions

View File

@ -0,0 +1,48 @@
<?php
namespace App\Filament\Admin\Pages;
use Filament\Forms\Components\Component;
use Filament\Forms\Components\TextInput;
use Filament\Pages\Auth\Login;
use Illuminate\Contracts\Support\Htmlable;
use Illuminate\Validation\ValidationException;
class UsernameLogin extends Login
{
protected function getEmailFormComponent(): Component
{
return TextInput::make('username')
->label('Username')
->required()
->autofocus()
->extraInputAttributes(['tabindex' => 1])
->autocomplete();
}
protected function getCredentialsFromFormData(array $data): array
{
return [
'username' => $data['username'],
'password' => $data['password'],
];
}
protected function throwFailureValidationException(): never
{
throw ValidationException::withMessages([
'data.username' => __('filament-panels::pages/auth/login.messages.failed'),
]);
}
public function getTitle(): Htmlable|string
{
return __('Login');
}
public function getHeading(): Htmlable|string
{
return __('Login');
}
}

View File

@ -1,6 +1,6 @@
<?php
namespace App\Filament\Resources\ContactResource\Pages;
namespace App\Filament\Admin\Resources\ContactResource\Pages;
use App\Filament\Resources\ContactResource;
use Filament\Resources\Pages\CreateRecord;

View File

@ -1,6 +1,6 @@
<?php
namespace App\Filament\Resources\ContactResource\Pages;
namespace App\Filament\Admin\Resources\ContactResource\Pages;
use App\Filament\Resources\ContactResource;
use Filament\Actions;

View File

@ -1,6 +1,6 @@
<?php
namespace App\Filament\Resources\ContactResource\Pages;
namespace App\Filament\Admin\Resources\ContactResource\Pages;
use App\Filament\Resources\ContactResource;
use Filament\Actions;

View File

@ -1,8 +1,7 @@
<?php
namespace App\Filament\Resources;
namespace App\Filament\Admin\Resources;
use App\Filament\Resources\CustomerReportResource\Pages;
use App\Models\Customer;
use Filament\Forms\Components\DatePicker;
use Filament\Forms\Form;
@ -42,7 +41,7 @@ public static function table(Table $table): Table
->extraHeaderAttributes(['class' => 'w-full']),
Tables\Columns\TextColumn::make('subtotal')
->money('usd')
->money()
->alignRight()
->getStateUsing(function (Table $table, Model $record) {
return $record->getSubtotalAttribute(
@ -53,7 +52,7 @@ public static function table(Table $table): Table
Tables\Columns\TextColumn::make('gst')
->label('GST')
->money('usd')
->money()
->alignRight()
->getStateUsing(function (Table $table, Model $record) {
return $record->getGstAttribute(
@ -64,7 +63,7 @@ public static function table(Table $table): Table
Tables\Columns\TextColumn::make('pst')
->label('PST')
->money('usd')
->money()
->alignRight()
->getStateUsing(function (Table $table, Model $record) {
return $record->getPstAttribute(
@ -74,7 +73,7 @@ public static function table(Table $table): Table
}),
Tables\Columns\TextColumn::make('total')
->money('usd')
->money()
->weight('bold')
->alignRight()
->getStateUsing(function (Table $table, Model $record) {
@ -113,7 +112,7 @@ public static function getRelations(): array
public static function getPages(): array
{
return [
'index' => Pages\ListCustomerReports::route('/'),
'index' => \App\Filament\Admin\Resources\CustomerReportResource\Pages\ListCustomerReports::route('/'),
];
}
}

View File

@ -1,8 +1,8 @@
<?php
namespace App\Filament\Resources\CustomerReportResource\Pages;
namespace App\Filament\Admin\Resources\CustomerReportResource\Pages;
use App\Filament\Resources\CustomerReportResource;
use App\Filament\Admin\Resources\CustomerReportResource;
use Filament\Resources\Pages\CreateRecord;
class CreateCustomerReport extends CreateRecord

View File

@ -1,8 +1,8 @@
<?php
namespace App\Filament\Resources\CustomerReportResource\Pages;
namespace App\Filament\Admin\Resources\CustomerReportResource\Pages;
use App\Filament\Resources\CustomerReportResource;
use App\Filament\Admin\Resources\CustomerReportResource;
use Filament\Actions;
use Filament\Resources\Pages\EditRecord;

View File

@ -1,8 +1,8 @@
<?php
namespace App\Filament\Resources\CustomerReportResource\Pages;
namespace App\Filament\Admin\Resources\CustomerReportResource\Pages;
use App\Filament\Resources\CustomerReportResource;
use App\Filament\Admin\Resources\CustomerReportResource;
use Filament\Resources\Pages\ListRecords;
class ListCustomerReports extends ListRecords

View File

@ -1,10 +1,9 @@
<?php
namespace App\Filament\Resources;
namespace App\Filament\Admin\Resources;
use App\Filament\Resources\CustomerResource\Pages;
use App\Filament\Resources\CustomerResource\RelationManagers\ContactsRelationManager;
use App\Filament\Resources\CustomerResource\RelationManagers\ShippingEntriesRelationManager;
use App\Filament\Admin\Resources\CustomerResource\RelationManagers\ContactsRelationManager;
use App\Filament\Admin\Resources\CustomerResource\RelationManagers\ShippingEntriesRelationManager;
use App\Models\Customer;
use Filament\Forms\Components\Section;
use Filament\Forms\Components\TextInput;
@ -75,9 +74,9 @@ public static function getRelations(): array
public static function getPages(): array
{
return [
'index' => Pages\ListCustomers::route('/'),
'create' => Pages\CreateCustomer::route('/create'),
'edit' => Pages\EditCustomer::route('/{record}/edit'),
'index' => \App\Filament\Admin\Resources\CustomerResource\Pages\ListCustomers::route('/'),
'create' => \App\Filament\Admin\Resources\CustomerResource\Pages\CreateCustomer::route('/create'),
'edit' => \App\Filament\Admin\Resources\CustomerResource\Pages\EditCustomer::route('/{record}/edit'),
];
}
}

View File

@ -1,8 +1,8 @@
<?php
namespace App\Filament\Resources\CustomerResource\Pages;
namespace App\Filament\Admin\Resources\CustomerResource\Pages;
use App\Filament\Resources\CustomerResource;
use App\Filament\Admin\Resources\CustomerResource;
use Filament\Resources\Pages\CreateRecord;
class CreateCustomer extends CreateRecord

View File

@ -1,8 +1,8 @@
<?php
namespace App\Filament\Resources\CustomerResource\Pages;
namespace App\Filament\Admin\Resources\CustomerResource\Pages;
use App\Filament\Resources\CustomerResource;
use App\Filament\Admin\Resources\CustomerResource;
use Filament\Actions;
use Filament\Resources\Pages\EditRecord;

View File

@ -1,8 +1,8 @@
<?php
namespace App\Filament\Resources\CustomerResource\Pages;
namespace App\Filament\Admin\Resources\CustomerResource\Pages;
use App\Filament\Resources\CustomerResource;
use App\Filament\Admin\Resources\CustomerResource;
use Filament\Actions;
use Filament\Resources\Pages\ListRecords;

View File

@ -1,6 +1,6 @@
<?php
namespace App\Filament\Resources\CustomerResource\RelationManagers;
namespace App\Filament\Admin\Resources\CustomerResource\RelationManagers;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Form;

View File

@ -1,6 +1,6 @@
<?php
namespace App\Filament\Resources\CustomerResource\RelationManagers;
namespace App\Filament\Admin\Resources\CustomerResource\RelationManagers;
use Filament\Forms;
use Filament\Forms\Form;

View File

@ -1,9 +1,8 @@
<?php
namespace App\Filament\Resources;
namespace App\Filament\Admin\Resources;
use App\Filament\Resources\InvoiceReportResource\Pages;
use App\Filament\Resources\InvoiceReportResource\RelationManagers\InvoicesRelationManager;
use App\Filament\Admin\Resources\InvoiceReportResource\RelationManagers\InvoicesRelationManager;
use Filament\Forms\Components\DatePicker;
use Filament\Forms\Components\Section;
use Filament\Forms\Components\Select;
@ -11,6 +10,7 @@
use Filament\Forms\Form;
use Filament\Resources\Resource;
use Filament\Support\Enums\FontFamily;
use Filament\Support\Enums\FontWeight;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
@ -72,24 +72,15 @@ public static function table(Table $table): Table
->label('End Date')
->date('Y-m-d'),
TextColumn::make('total')
->label('Balance Due')
->weight(FontWeight::Bold)
->money(),
])
->defaultSort('created_at', 'desc')
->defaultSort('id', 'desc')
->filters([
])
->actions([]);
// ->defaultGroup(
// Group::make('date')
// ->getKeyFromRecordUsing(fn (Order $record): string => $record->invoice->date->format('Y-m-0'))
// ->getTitleFromRecordUsing(fn (Order $record): string => $record->invoice->date->format('F Y'))
// ->orderQueryUsing(function (Builder $query) {
//
// return $query->join('invoices', 'orders.invoice_id', '=', 'invoices.id')
// ->orderBy('invoices.date', 'desc');
// })
// ->titlePrefixedWithLabel(false),
// );
}
public static function getRelations(): array
@ -102,9 +93,9 @@ public static function getRelations(): array
public static function getPages(): array
{
return [
'index' => Pages\ListInvoiceReports::route('/'),
'edit' => Pages\EditInvoiceReport::route('/{record}/edit'),
'create' => Pages\CreateInvoiceReport::route('/create'),
'index' => \App\Filament\Admin\Resources\InvoiceReportResource\Pages\ListInvoiceReports::route('/'),
'create' => \App\Filament\Admin\Resources\InvoiceReportResource\Pages\CreateInvoiceReport::route('/create'),
'view' => \App\Filament\Admin\Resources\InvoiceReportResource\Pages\ViewInvoiceReport::route('/{record}'),
];
}
}

View File

@ -1,8 +1,8 @@
<?php
namespace App\Filament\Resources\InvoiceReportResource\Pages;
namespace App\Filament\Admin\Resources\InvoiceReportResource\Pages;
use App\Filament\Resources\InvoiceReportResource;
use App\Filament\Admin\Resources\InvoiceReportResource;
use Filament\Resources\Pages\CreateRecord;
class CreateInvoiceReport extends CreateRecord

View File

@ -1,8 +1,8 @@
<?php
namespace App\Filament\Resources\InvoiceReportResource\Pages;
namespace App\Filament\Admin\Resources\InvoiceReportResource\Pages;
use App\Filament\Resources\InvoiceReportResource;
use App\Filament\Admin\Resources\InvoiceReportResource;
use Filament\Actions;
use Filament\Resources\Pages\EditRecord;

View File

@ -1,8 +1,8 @@
<?php
namespace App\Filament\Resources\InvoiceReportResource\Pages;
namespace App\Filament\Admin\Resources\InvoiceReportResource\Pages;
use App\Filament\Resources\InvoiceReportResource;
use App\Filament\Admin\Resources\InvoiceReportResource;
use Filament\Actions;
use Filament\Resources\Pages\ListRecords;

View File

@ -0,0 +1,25 @@
<?php
namespace App\Filament\Admin\Resources\InvoiceReportResource\Pages;
use App\Filament\Admin\Resources\InvoiceReportResource;
use App\Models\InvoiceReport;
use Filament\Actions\Action;
use Filament\Resources\Pages\ViewRecord;
class ViewInvoiceReport extends ViewRecord
{
protected static string $resource = InvoiceReportResource::class;
protected static ?string $title = 'View Invoice Report';
protected function getHeaderActions(): array
{
return [
Action::make('print')
->icon('lucide-printer')
->url(fn (InvoiceReport $record) => route('pdf.invoice-report', $record))
->openUrlInNewTab(),
];
}
}

View File

@ -0,0 +1,71 @@
<?php
namespace App\Filament\Admin\Resources\InvoiceReportResource\RelationManagers;
use App\Filament\Admin\Resources\InvoiceResource;
use Filament\Forms;
use Filament\Forms\Form;
use Filament\Resources\RelationManagers\RelationManager;
use Filament\Support\Enums\FontWeight;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
class InvoicesRelationManager extends RelationManager
{
protected static string $relationship = 'invoices';
public function form(Form $form): Form
{
return $form
->schema([
Forms\Components\TextInput::make('id')
->required()
->maxLength(255),
]);
}
public function table(Table $table): Table
{
return $table
->recordTitleAttribute('internal_id')
->recordUrl(fn ($record) => InvoiceResource::getUrl('edit', ['record' => $record->id]))
->columns([
TextColumn::make('internal_id')
->label('ID')
->extraHeaderAttributes(['class' => 'w-full'])
->color('primary'),
TextColumn::make('date')
->label('Created')
->date(),
TextColumn::make('subtotal')
->alignRight()
->money(),
TextColumn::make('gst_amount')
->label('GST')
->alignRight()
->money(),
TextColumn::make('pst_amount')
->label('PST')
->alignRight()
->formatStateUsing(function ($state) {
return $state == 0.00 ? '-' : '$'.$state;
}),
TextColumn::make('total')
->label('Balance Due')
->alignRight()
->money()
->weight(FontWeight::Bold),
TextColumn::make('status'),
])
->filters([
//
])
->headerActions([
])
->defaultSort('invoices.id')
->actions([
])
->bulkActions([
]);
}
}

View File

@ -1,15 +1,16 @@
<?php
namespace App\Filament\Resources;
namespace App\Filament\Admin\Resources;
use App\Enums\InvoiceStatus;
use App\Filament\Resources\InvoiceResource\Pages;
use App\Filament\Resources\InvoiceResource\RelationManagers\OrdersRelationManager;
use App\Filament\Resources\InvoiceResource\RelationManagers\ProductServicesRelationManager;
use App\Filament\Admin\Resources\InvoiceResource\RelationManagers\OrdersRelationManager;
use App\Filament\Admin\Resources\InvoiceResource\RelationManagers\ProductServicesRelationManager;
use App\Models\Customer;
use App\Models\Invoice;
use Filament\Forms\Components\DatePicker;
use Filament\Forms\Components\Grid;
use Filament\Forms\Components\Group;
use Filament\Forms\Components\Placeholder;
use Filament\Forms\Components\Section;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\Split;
@ -35,6 +36,8 @@ class InvoiceResource extends Resource
public static function form(Form $form): Form
{
return $form
->schema([
Group::make()
->schema([
Section::make([
Grid::make(2)
@ -55,11 +58,18 @@ public static function form(Form $form): Form
DatePicker::make('due_date'),
])
->columnSpan(2),
Select::make('status')
ToggleButtons::make('status')
->options(InvoiceStatus::class)
->searchable()
->required()
->default(InvoiceStatus::UNPAID),
->inline()
->default(InvoiceStatus::UNPAID)
->columnSpan(2),
// Select::make('status')
// ->options(InvoiceStatus::class)
// ->searchable()
// ->required()
// ->default(InvoiceStatus::UNPAID),
])->columnSpan(2),
Grid::make(1)
@ -84,8 +94,26 @@ public static function form(Form $form): Form
])->columnSpan(1),
])
->columns(3)
->columnSpan(3),
])->columns(3);
->columnSpan(2),
Section::make()
->schema([
Placeholder::make('created_at')
->label('Created at')
->content(fn (Invoice $record): ?string => $record->created_at?->diffForHumans()),
Placeholder::make('updated_at')
->label('Last modified at')
->content(fn (Invoice $record): ?string => $record->updated_at?->diffForHumans()),
])
->columnSpan(1)
->hidden(fn (?Invoice $record) => $record === null),
])
->columns(3)
->columnSpan(2),
])->columns(2);
}
public static function table(Table $table): Table
@ -97,22 +125,33 @@ public static function table(Table $table): Table
->fontFamily('mono')
->color('primary')
->sortable()
->searchable(),
->searchable(query: function (Builder $query, $search) {
return $query->where('internal_id', 'like', "%{$search}%")
->orWhereHas('orders', function (Builder $query) use ($search) {
return $query->where('customer_po', 'like', "%{$search}%")
->orWhere('internal_po', 'like', "%{$search}%");
});
}),
Tables\Columns\TextColumn::make('customer.company_name')
->sortable()
->extraHeaderAttributes(['class' => 'w-full'])
->searchable(),
Tables\Columns\TextColumn::make('created_at')
->label('Created')
->date()
->sortable(),
Tables\Columns\TextColumn::make('subtotal')
->money('USD')
->money()
->alignRight(),
Tables\Columns\TextColumn::make('gst_amount')
->label('GST')
->money('USD')
->money()
->alignRight(),
Tables\Columns\TextColumn::make('pst_amount')
->label('PST')
->formatStateUsing(function ($state) {
@ -120,7 +159,8 @@ public static function table(Table $table): Table
})
->alignRight(),
Tables\Columns\TextColumn::make('total')
->money('USD')
->label('Balance')
->money()
->weight('bold')
->alignRight(),
Tables\Columns\TextColumn::make('status')
@ -157,11 +197,10 @@ public static function table(Table $table): Table
'status',
])
->defaultSort('created_at', 'desc')
->defaultSort('id', 'desc')
->actions([
Tables\Actions\EditAction::make(),
//todo: generate report pdf
])
->bulkActions([
@ -205,9 +244,14 @@ public static function getRelations(): array
public static function getPages(): array
{
return [
'index' => Pages\ListInvoices::route('/'),
'create' => Pages\CreateInvoice::route('/create'),
'edit' => Pages\EditInvoice::route('/{record}/edit'),
'index' => \App\Filament\Admin\Resources\InvoiceResource\Pages\ListInvoices::route('/'),
'create' => \App\Filament\Admin\Resources\InvoiceResource\Pages\CreateInvoice::route('/create'),
'edit' => \App\Filament\Admin\Resources\InvoiceResource\Pages\EditInvoice::route('/{record}/edit'),
];
}
public static function canAccess(): bool
{
return parent::canAccess(); // TODO: Change the autogenerated stub
}
}

View File

@ -1,8 +1,8 @@
<?php
namespace App\Filament\Resources\InvoiceResource\Pages;
namespace App\Filament\Admin\Resources\InvoiceResource\Pages;
use App\Filament\Resources\InvoiceResource;
use App\Filament\Admin\Resources\InvoiceResource;
use App\Models\Invoice;
use Filament\Resources\Pages\CreateRecord;
use Illuminate\Database\Eloquent\Model;

View File

@ -1,8 +1,8 @@
<?php
namespace App\Filament\Resources\InvoiceResource\Pages;
namespace App\Filament\Admin\Resources\InvoiceResource\Pages;
use App\Filament\Resources\InvoiceResource;
use App\Filament\Admin\Resources\InvoiceResource;
use App\Models\Invoice;
use Filament\Actions;
use Filament\Actions\Action;
@ -23,4 +23,15 @@ protected function getHeaderActions(): array
->icon('lucide-trash-2'),
];
}
// protected function after(array $data): array
// {
// $invoice = Invoice::findOrFail($data['id']);
//
// if ($invoice->invoiceReports()->count() > 0) {
// foreach ($invoice->invoiceReports as $report) {
// $report->updateTotalBalance();
// }
// }
// }
}

View File

@ -1,8 +1,8 @@
<?php
namespace App\Filament\Resources\InvoiceResource\Pages;
namespace App\Filament\Admin\Resources\InvoiceResource\Pages;
use App\Filament\Resources\InvoiceResource;
use App\Filament\Admin\Resources\InvoiceResource;
use Filament\Actions;
use Filament\Resources\Pages\ListRecords;

View File

@ -1,10 +1,12 @@
<?php
namespace App\Filament\Resources\InvoiceResource\RelationManagers;
namespace App\Filament\Admin\Resources\InvoiceResource\RelationManagers;
use App\Filament\Admin\Resources\OrderResource;
use Filament\Forms;
use Filament\Forms\Form;
use Filament\Resources\RelationManagers\RelationManager;
use Filament\Support\Enums\FontFamily;
use Filament\Tables;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
@ -27,18 +29,27 @@ public function table(Table $table): Table
{
return $table
->recordTitleAttribute('customer_po')
->recordUrl(fn ($record) => OrderResource::getUrl('edit', ['record' => $record->id]))
->columns([
Tables\Columns\TextColumn::make('internal_po')
->label('Internal PO')
->color('primary')
->fontFamily(FontFamily::Mono),
Tables\Columns\TextColumn::make('customer_po')
->label('Customer PO')
->color('code')
->weight('bold')
->extraHeaderAttributes(['class' => 'w-full']),
Tables\Columns\TextColumn::make('total_product_quantity')
->label('Total QTY')
->alignRight(),
Tables\Columns\TextColumn::make('total_service_price')
->alignRight()
->label('Total price')
->money('usd'),
->money(),
])
->filters([
//

View File

@ -1,6 +1,6 @@
<?php
namespace App\Filament\Resources\InvoiceResource\RelationManagers;
namespace App\Filament\Admin\Resources\InvoiceResource\RelationManagers;
use Filament\Forms;
use Filament\Forms\Form;

View File

@ -0,0 +1,374 @@
<?php
namespace App\Filament\Admin\Resources;
use App\Enums\OrderAttributes;
use App\Enums\OrderStatus;
use App\Enums\OrderType;
use App\Models\Contact;
use App\Models\Customer;
use App\Models\Order;
use App\Models\OrderProduct;
use App\Models\ProductService;
use App\Models\ServiceFile;
use App\Models\ServiceType;
use Filament\Forms\Components\DatePicker;
use Filament\Forms\Components\Grid;
use Filament\Forms\Components\Group;
use Filament\Forms\Components\Placeholder;
use Filament\Forms\Components\Repeater;
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\Notifications\Notification;
use Filament\Resources\Resource;
use Filament\Support\Enums\MaxWidth;
use Filament\Tables;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
use Guava\FilamentClusters\Forms\Cluster;
use Icetalker\FilamentTableRepeater\Forms\Components\TableRepeater;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
class OrderResource extends Resource
{
protected static ?string $model = Order::class;
protected static ?string $navigationIcon = 'lucide-shopping-cart';
protected static ?string $navigationGroup = 'Production';
public static function form(Form $form): Form
{
return $form->schema([
Group::make()
->schema([
Section::make([
Grid::make(1)
->schema([
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')),
]),
Textarea::make('notes')
->rows(3),
])->columnSpan(1),
Grid::make(1)
->schema([
ToggleButtons::make('status')
->required()
->default(OrderStatus::DRAFT->value)
->options(OrderStatus::class)
->inline(),
ToggleButtons::make('order_attributes')
->options(OrderAttributes::class)
->multiple()
->inline(),
ToggleButtons::make('printed')
->boolean()
->default(false)
->inline(),
ToggleButtons::make('pre_production')
->label('Pre-production')
->default(false)
->boolean()
->inline()
->colors([
'true' => 'info',
'false' => 'info',
]),
])->columnSpan(1),
])->columns(2)
->columnSpan(fn (?Order $record) => $record === null ? 4 : 3),
Section::make()
->schema([
Placeholder::make('created_at')
->label('Created')
->content(fn (Order $record): ?string => $record->created_at?->diffForHumans()),
Placeholder::make('updated_at')
->label('Last modified')
->content(fn (Order $record): ?string => $record->updated_at?->diffForHumans()),
])
->columnSpan(1)
->hidden(fn (?Order $record) => $record === null),
])
->columns(4)
->columnSpan(2),
TableRepeater::make('order_products')
->label('Garments')
->schema([
TextInput::make('sku')
->datalist(OrderProduct::all()->unique('sku')->pluck('sku')->toArray()),
TextInput::make('product_name')
->datalist(OrderProduct::all()->unique('product_name')->pluck('product_name')->toArray())
->required(),
TextInput::make('color')
->datalist(OrderProduct::all()->unique('color')->pluck('color')->toArray()),
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'),
])
->reorderable()
->cloneable(),
Repeater::make('services')
->label('Product Services')
->schema([
Grid::make(19)
->schema([
Select::make('serviceType')
->options(ServiceType::all()->pluck('value', 'id'))
->columnSpan(4)
->placeholder('Select...')
->searchable()
->createOptionForm([
TextInput::make('name')
->label('Code')
->placeholder('Abbreviation here (example: \'Emb\'')
->required(),
TextInput::make('value')
->placeholder('Full name here (example: \'Embroidery\'')
->required(),
])
->createOptionUsing(function (array $data): int {
return ServiceType::create($data)->getKey();
}),
TextInput::make('placement')
->datalist(ProductService::all()->unique('placement')->pluck('placement')->toArray())
->columnSpan(3),
TextInput::make('serviceFileName')
->datalist(ServiceFile::all()->unique('name')->pluck('name')->toArray())
->columnSpan(3)
->label('Logo Name'),
TextInput::make('serviceFileSetupNumber')
->label('Setup')
->columnSpan(1),
Cluster::make([
TextInput::make('serviceFileWidth')
->prefix('w'),
TextInput::make('serviceFileHeight')
->prefix('h'),
])
->label('Dimensions (inches)')
->columnSpan(4),
TextInput::make('amount')
->label('Quantity')
->live()
->prefix('#')
->columnSpan(2),
TextInput::make('amount_price')
->label('Amount')
->prefix('$')
->columnSpan(2),
]),
Grid::make(9)
->schema([
TextInput::make('serviceFileCode')
->label('Code')
->datalist(ServiceFile::all()->unique('code')->pluck('code')->toArray())
->columnSpan(1)
->placeholder('A1234'),
Textarea::make('notes')
->placeholder('Thread colors...')
->columnSpan(8),
]),
])
->reorderable()
->cloneable()
->columns(4)
->columnSpan(2),
]);
}
public static function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\IconColumn::make('alert')
->getStateUsing(fn ($record) => $record->is_alert_danger || $record->is_alert_warning)
->label('')
->color(fn ($record) => $record->is_alert_danger ? 'danger' : 'warning')
->icon(function ($record) {
return $record->is_alert_danger
? 'lucide-calendar-clock' : ($record->rush
? OrderAttributes::rush->getIcon() : null);
})
->size(Tables\Columns\IconColumn\IconColumnSize::Medium),
TextColumn::make('internal_po')
->label('Internal PO')
->fontFamily('mono')
->color('info')
->searchable(query: function (Builder $query, $search) {
return $query
->where('internal_po', 'like', "%{$search}%")
->orWhereHas('productServices', function (Builder $query) use ($search) {
return $query->where('placement', 'like', "%{$search}%")
->orWhereHas('serviceFile', function (Builder $query) use ($search) {
return $query->where('code', 'like', "%{$search}%")
->orWhere('name', 'like', "%{$search}%");
});
});
})
->sortable(),
TextColumn::make('customer.company_name')
->searchable()
->sortable(),
TextColumn::make('customer_po')
->label('PO')
->wrap()
->weight('bold')
->color('code')
->searchable()
->sortable()
->extraHeaderAttributes([
'class' => 'w-full',
]),
TextColumn::make('order_date')
->searchable()
->sortable(),
TextColumn::make('due_date')
->searchable()
->sortable(),
TextColumn::make('status')
->badge()
->searchable()
->sortable(),
])
->defaultSort('order_date', 'desc')
->filters([
Tables\Filters\Filter::make('order_date')
->form([
DatePicker::make('created_from'),
DatePicker::make('created_until'),
])
->query(function (Builder $query, array $data): Builder {
return $query
->when(
$data['created_from'],
fn (Builder $query, $date): Builder => $query->whereDate('order_date', '>=', $date),
)
->when(
$data['created_until'],
fn (Builder $query, $date): Builder => $query->whereDate('order_date', '<=', $date),
);
}),
], )
->actions([
Tables\Actions\EditAction::make(),
])
->bulkActions([
Tables\Actions\BulkAction::make('updateStatus')
->form([
Select::make('status')
->options(OrderStatus::class),
])
->modalHeading('Change selected orders status')
->modalWidth(MaxWidth::Medium)
->action(function (array $data, Collection $records): void {
foreach ($records as $record) {
$record->status = $data['status'];
$record->save();
}
Notification::make()
->title(count($records).' item(s) updated successfully')
->success()
->send();
})
->icon('lucide-pen')
->color('info')
->deselectRecordsAfterCompletion(),
Tables\Actions\BulkActionGroup::make([
Tables\Actions\DeleteBulkAction::make(),
]),
]);
}
public static function getRelations(): array
{
return [
];
}
public static function getPages(): array
{
return [
'index' => \App\Filament\Admin\Resources\OrderResource\Pages\ListOrders::route('/'),
'create' => \App\Filament\Admin\Resources\OrderResource\Pages\CreateOrder::route('/create'),
'edit' => \App\Filament\Admin\Resources\OrderResource\Pages\EditOrder::route('/{record}/edit'),
];
}
}

View File

@ -1,9 +1,9 @@
<?php
namespace App\Filament\Resources\OrderResource\Pages;
namespace App\Filament\Admin\Resources\OrderResource\Pages;
use App\Enums\OrderAttributes;
use App\Filament\Resources\OrderResource;
use App\Filament\Admin\Resources\OrderResource;
use App\Models\Order;
use App\Models\OrderProduct;
use App\Models\ProductService;

View File

@ -1,9 +1,9 @@
<?php
namespace App\Filament\Resources\OrderResource\Pages;
namespace App\Filament\Admin\Resources\OrderResource\Pages;
use App\Enums\OrderAttributes;
use App\Filament\Resources\OrderResource;
use App\Filament\Admin\Resources\OrderResource;
use App\Models\Order;
use App\Models\OrderProduct;
use App\Models\ProductService;
@ -148,6 +148,9 @@ protected function getHeaderActions(): array
->label('Save changes')
->action('save')
->icon('lucide-save'),
Actions\ReplicateAction::make()
->icon('lucide-copy')
->color('info'),
Action::make('print')
->icon('lucide-printer')
->url(fn (Order $record) => route('orders.pdf', $record))
@ -156,4 +159,9 @@ protected function getHeaderActions(): array
->icon('lucide-trash-2'),
];
}
// protected function getRedirectUrl(): string
// {
// return $this->previousUrl ?? $this->getResource()::getUrl('index');
// }
}

View File

@ -1,10 +1,10 @@
<?php
namespace App\Filament\Resources\OrderResource\Pages;
namespace App\Filament\Admin\Resources\OrderResource\Pages;
use App\Enums\OrderAttributes;
use App\Enums\OrderStatus;
use App\Filament\Resources\OrderResource;
use App\Filament\Admin\Resources\OrderResource;
use App\Models\Order;
use Filament\Actions;
use Filament\Resources\Components\Tab;
@ -36,6 +36,19 @@ public function getTabs(): array
->whereNot('status', OrderStatus::INVOICED)
->count();
}),
'unprinted' => Tab::make()
->query(function ($query) {
return $query->where('printed', false);
})
->icon('lucide-printer')
->badge(function () {
$count = Order::where('printed', false)->count();
return $count > 0 ? $count : null;
})
->badgeColor('success'),
'overdue' => Tab::make()
->query(function ($query) {
return $query->whereDate('due_date', '<=', today())
@ -70,28 +83,8 @@ public function getTabs(): array
})
->badgeColor('warning'),
null => Tab::make('All')
'all' => Tab::make('All')
->icon('lucide-layout-grid'),
// 'draft' => Tab::make()
// ->query(fn ($query) => $query->where('status', OrderStatus::DRAFT->value))
// ->icon(OrderStatus::DRAFT->getIcon()),
//
// 'approved' => Tab::make()
// ->query(fn ($query) => $query->where('status', OrderStatus::APPROVED->value))
// ->icon(OrderStatus::APPROVED->getIcon()),
//
// 'production' => Tab::make()
// ->query(fn ($query) => $query->where('status', OrderStatus::PRODUCTION->value))
// ->icon(OrderStatus::PRODUCTION->getIcon()),
//
// 'shipped' => Tab::make()
// ->query(fn ($query) => $query->where('status', OrderStatus::SHIPPED->value))
// ->icon(OrderStatus::SHIPPED->getIcon()),
//
// 'invoiced' => Tab::make()
// ->query(fn ($query) => $query->where('status', OrderStatus::INVOICED->value))
// ->icon(OrderStatus::INVOICED->getIcon()),
];
}
}

View File

@ -1,8 +1,8 @@
<?php
namespace App\Filament\Resources\OrderResource\Pages;
namespace App\Filament\Admin\Resources\OrderResource\Pages;
use App\Filament\Resources\OrderResource;
use App\Filament\Admin\Resources\OrderResource;
use Filament\Resources\Pages\ViewRecord;
class ViewOrder extends ViewRecord

View File

@ -1,6 +1,6 @@
<?php
namespace App\Filament\Resources\OrderResource\RelationManagers;
namespace App\Filament\Admin\Resources\OrderResource\RelationManagers;
use Filament\Forms;
use Filament\Forms\Form;

View File

@ -1,12 +1,12 @@
<?php
namespace App\Filament\Resources;
namespace App\Filament\Admin\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\Section;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
@ -30,19 +30,29 @@ public static function form(Form $form): Form
{
return $form
->schema([
DatePicker::make('date_received'),
TextInput::make('amount'),
Section::make([
DatePicker::make('date_received')
->default(today())
->required(),
// TextInput::make('amount')
// ->label('Quantity')
// ->required(),
Select::make('customer_id')
->label('Customer')
->options(Customer::all()->pluck('company_name', 'id'))
->reactive()
->searchable(),
Select::make('order_id')
->label('Order')
->required()
->options(fn ($get): array => Order::where('customer_id', $get('customer_id') ?? null)
->get()
->pluck('customer_po', 'id')
->toArray())
->searchable(),
TextArea::make('contents'),
])
->columns(2),
]);
}
@ -58,8 +68,10 @@ public static function table(Table $table): Table
->color('code')
->sortable()
->searchable(),
TextColumn::make('contents'),
TextColumn::make('amount'),
TextColumn::make('contents')
->extraHeaderAttributes(['class' => 'w-full']),
// TextColumn::make('amount')
// ->label('Quantity'),
TextColumn::make('order.customer.company_name')
->sortable()
->searchable(),
@ -88,9 +100,9 @@ public static function getRelations(): array
public static function getPages(): array
{
return [
'index' => Pages\ListPackingSlips::route('/'),
'create' => Pages\CreatePackingSlip::route('/create'),
'edit' => Pages\EditPackingSlip::route('/{record}/edit'),
'index' => \App\Filament\Admin\Resources\PackingSlipResource\Pages\ListPackingSlips::route('/'),
'create' => \App\Filament\Admin\Resources\PackingSlipResource\Pages\CreatePackingSlip::route('/create'),
'edit' => \App\Filament\Admin\Resources\PackingSlipResource\Pages\EditPackingSlip::route('/{record}/edit'),
];
}
}

View File

@ -1,8 +1,8 @@
<?php
namespace App\Filament\Resources\PackingSlipResource\Pages;
namespace App\Filament\Admin\Resources\PackingSlipResource\Pages;
use App\Filament\Resources\PackingSlipResource;
use App\Filament\Admin\Resources\PackingSlipResource;
use Filament\Resources\Pages\CreateRecord;
class CreatePackingSlip extends CreateRecord

View File

@ -1,8 +1,8 @@
<?php
namespace App\Filament\Resources\PackingSlipResource\Pages;
namespace App\Filament\Admin\Resources\PackingSlipResource\Pages;
use App\Filament\Resources\PackingSlipResource;
use App\Filament\Admin\Resources\PackingSlipResource;
use Filament\Actions;
use Filament\Resources\Pages\EditRecord;

View File

@ -1,8 +1,8 @@
<?php
namespace App\Filament\Resources\PackingSlipResource\Pages;
namespace App\Filament\Admin\Resources\PackingSlipResource\Pages;
use App\Filament\Resources\PackingSlipResource;
use App\Filament\Admin\Resources\PackingSlipResource;
use Filament\Actions;
use Filament\Resources\Pages\ListRecords;

View File

@ -1,15 +1,14 @@
<?php
namespace App\Filament\Resources;
namespace App\Filament\Admin\Resources;
use App\Filament\Resources\QuoteResource\Pages;
use App\Models\Customer;
use App\Models\Order;
use App\Models\Quote;
use Filament\Forms\Components\RichEditor;
use Filament\Forms\Components\Section;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\Split;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Form;
use Filament\Resources\Resource;
use Filament\Tables;
@ -47,9 +46,9 @@ public static function form(Form $form): Form
->searchable(),
])->columnSpan(2),
Textarea::make('body')
->columnSpan(2)
->rows(8),
RichEditor::make('body')
->columnSpan(2),
// ->rows(8),
]),
])->columns(3);
}
@ -94,9 +93,9 @@ public static function getRelations(): array
public static function getPages(): array
{
return [
'index' => Pages\ListQuotes::route('/'),
'create' => Pages\CreateQuote::route('/create'),
'edit' => Pages\EditQuote::route('/{record}/edit'),
'index' => \App\Filament\Admin\Resources\QuoteResource\Pages\ListQuotes::route('/'),
'create' => \App\Filament\Admin\Resources\QuoteResource\Pages\CreateQuote::route('/create'),
'edit' => \App\Filament\Admin\Resources\QuoteResource\Pages\EditQuote::route('/{record}/edit'),
];
}
}

View File

@ -1,8 +1,8 @@
<?php
namespace App\Filament\Resources\QuoteResource\Pages;
namespace App\Filament\Admin\Resources\QuoteResource\Pages;
use App\Filament\Resources\QuoteResource;
use App\Filament\Admin\Resources\QuoteResource;
use Filament\Resources\Pages\CreateRecord;
class CreateQuote extends CreateRecord

View File

@ -1,8 +1,8 @@
<?php
namespace App\Filament\Resources\QuoteResource\Pages;
namespace App\Filament\Admin\Resources\QuoteResource\Pages;
use App\Filament\Resources\QuoteResource;
use App\Filament\Admin\Resources\QuoteResource;
use Filament\Actions;
use Filament\Resources\Pages\EditRecord;

View File

@ -1,8 +1,8 @@
<?php
namespace App\Filament\Resources\QuoteResource\Pages;
namespace App\Filament\Admin\Resources\QuoteResource\Pages;
use App\Filament\Resources\QuoteResource;
use App\Filament\Admin\Resources\QuoteResource;
use Filament\Actions;
use Filament\Resources\Pages\ListRecords;

View File

@ -1,9 +1,8 @@
<?php
namespace App\Filament\Resources;
namespace App\Filament\Admin\Resources;
use App\Filament\Resources\ServiceTypeResource\Pages;
use App\Filament\Resources\ServiceTypeResource\Widgets\ServiceTypeOverview;
use App\Filament\Admin\Resources\ServiceTypeResource\Widgets\ServiceTypeOverview;
use App\Models\ServiceType;
use Filament\Forms\Components\DatePicker;
use Filament\Forms\Form;
@ -119,8 +118,8 @@ public static function getRelations(): array
public static function getPages(): array
{
return [
'index' => Pages\ListServiceTypes::route('/'),
'create' => Pages\CreateServiceType::route('/create'),
'index' => \App\Filament\Admin\Resources\ServiceTypeResource\Pages\ListServiceTypes::route('/'),
'create' => \App\Filament\Admin\Resources\ServiceTypeResource\Pages\CreateServiceType::route('/create'),
];
}
}

View File

@ -1,8 +1,8 @@
<?php
namespace App\Filament\Resources\ServiceTypeResource\Pages;
namespace App\Filament\Admin\Resources\ServiceTypeResource\Pages;
use App\Filament\Resources\ServiceTypeResource;
use App\Filament\Admin\Resources\ServiceTypeResource;
use Filament\Resources\Pages\CreateRecord;
class CreateServiceType extends CreateRecord

View File

@ -1,8 +1,8 @@
<?php
namespace App\Filament\Resources\ServiceTypeResource\Pages;
namespace App\Filament\Admin\Resources\ServiceTypeResource\Pages;
use App\Filament\Resources\ServiceTypeResource;
use App\Filament\Admin\Resources\ServiceTypeResource;
use Filament\Actions;
use Filament\Resources\Pages\EditRecord;

View File

@ -1,8 +1,8 @@
<?php
namespace App\Filament\Resources\ServiceTypeResource\Pages;
namespace App\Filament\Admin\Resources\ServiceTypeResource\Pages;
use App\Filament\Resources\ServiceTypeResource;
use App\Filament\Admin\Resources\ServiceTypeResource;
use Filament\Resources\Pages\ListRecords;
class ListServiceTypes extends ListRecords

View File

@ -1,6 +1,6 @@
<?php
namespace App\Filament\Resources\ServiceTypeResource\Widgets;
namespace App\Filament\Admin\Resources\ServiceTypeResource\Widgets;
use Filament\Widgets\ChartWidget;

View File

@ -1,9 +1,8 @@
<?php
namespace App\Filament\Resources;
namespace App\Filament\Admin\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;
@ -147,9 +146,9 @@ public static function getRelations(): array
public static function getPages(): array
{
return [
'index' => Pages\ListShippingEntries::route('/'),
'create' => Pages\CreateShippingEntry::route('/create'),
'edit' => Pages\EditShippingEntry::route('/{record}/edit'),
'index' => \App\Filament\Admin\Resources\ShippingEntryResource\Pages\ListShippingEntries::route('/'),
'create' => \App\Filament\Admin\Resources\ShippingEntryResource\Pages\CreateShippingEntry::route('/create'),
'edit' => \App\Filament\Admin\Resources\ShippingEntryResource\Pages\EditShippingEntry::route('/{record}/edit'),
];
}
}

View File

@ -1,8 +1,8 @@
<?php
namespace App\Filament\Resources\ShippingEntryResource\Pages;
namespace App\Filament\Admin\Resources\ShippingEntryResource\Pages;
use App\Filament\Resources\ShippingEntryResource;
use App\Filament\Admin\Resources\ShippingEntryResource;
use Filament\Resources\Pages\CreateRecord;
class CreateShippingEntry extends CreateRecord

View File

@ -1,8 +1,8 @@
<?php
namespace App\Filament\Resources\ShippingEntryResource\Pages;
namespace App\Filament\Admin\Resources\ShippingEntryResource\Pages;
use App\Filament\Resources\ShippingEntryResource;
use App\Filament\Admin\Resources\ShippingEntryResource;
use Filament\Actions;
use Filament\Resources\Pages\EditRecord;

View File

@ -1,8 +1,8 @@
<?php
namespace App\Filament\Resources\ShippingEntryResource\Pages;
namespace App\Filament\Admin\Resources\ShippingEntryResource\Pages;
use App\Filament\Resources\ShippingEntryResource;
use App\Filament\Admin\Resources\ShippingEntryResource;
use Filament\Actions;
use Filament\Resources\Pages\ListRecords;

View File

@ -0,0 +1,69 @@
<?php
namespace App\Filament\Admin\Resources;
use App\Models\User;
use Filament\Forms\Form;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
class UserResource extends Resource
{
protected static ?int $navigationSort = 10;
protected static ?string $model = User::class;
protected static ?string $navigationIcon = 'lucide-users';
protected static ?string $navigationGroup = 'Settings';
public static function form(Form $form): Form
{
return $form
->schema([
//
]);
}
public static function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\IconColumn::make('is_admin')
->label('Admin')
->boolean()
->alignRight(),
TextColumn::make('username')
->extraHeaderAttributes(['class' => 'w-full']),
])
->filters([
//
])
->actions([
Tables\Actions\EditAction::make(),
])
->bulkActions([
Tables\Actions\BulkActionGroup::make([
Tables\Actions\DeleteBulkAction::make(),
]),
]);
}
public static function getRelations(): array
{
return [
//
];
}
public static function getPages(): array
{
return [
'index' => \App\Filament\Admin\Resources\UserResource\Pages\ListUsers::route('/'),
'create' => \App\Filament\Admin\Resources\UserResource\Pages\CreateUser::route('/create'),
'edit' => \App\Filament\Admin\Resources\UserResource\Pages\EditUser::route('/{record}/edit'),
];
}
}

View File

@ -0,0 +1,11 @@
<?php
namespace App\Filament\Admin\Resources\UserResource\Pages;
use App\Filament\Admin\Resources\UserResource;
use Filament\Resources\Pages\CreateRecord;
class CreateUser extends CreateRecord
{
protected static string $resource = UserResource::class;
}

View File

@ -0,0 +1,19 @@
<?php
namespace App\Filament\Admin\Resources\UserResource\Pages;
use App\Filament\Admin\Resources\UserResource;
use Filament\Actions;
use Filament\Resources\Pages\EditRecord;
class EditUser extends EditRecord
{
protected static string $resource = UserResource::class;
protected function getHeaderActions(): array
{
return [
Actions\DeleteAction::make(),
];
}
}

View File

@ -0,0 +1,19 @@
<?php
namespace App\Filament\Admin\Resources\UserResource\Pages;
use App\Filament\Admin\Resources\UserResource;
use Filament\Actions;
use Filament\Resources\Pages\ListRecords;
class ListUsers extends ListRecords
{
protected static string $resource = UserResource::class;
protected function getHeaderActions(): array
{
return [
Actions\CreateAction::make(),
];
}
}

View File

@ -1,6 +1,6 @@
<?php
namespace App\Filament\Widgets;
namespace App\Filament\Admin\Widgets;
use App\Enums\OrderStatus;
use App\Models\Order;

View File

@ -1,6 +1,6 @@
<?php
namespace App\Filament\Widgets;
namespace App\Filament\Admin\Widgets;
use App\Enums\OrderStatus;
use App\Models\Order;

View File

@ -1,6 +1,6 @@
<?php
namespace App\Filament\Widgets;
namespace App\Filament\Admin\Widgets;
use App\Enums\OrderStatus;
use App\Models\Order;

View File

@ -0,0 +1,67 @@
<?php
namespace App\Filament\Customer\Resources;
use App\Filament\Customer\Resources\OrderResource\Pages;
use App\Models\Order;
use Filament\Forms\Form;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
class OrderResource extends Resource
{
protected static ?string $model = Order::class;
protected static ?string $navigationIcon = 'lucide-shopping-cart';
public static function form(Form $form): Form
{
return $form
->schema([
//
]);
}
public static function table(Table $table): Table
{
return \App\Filament\Admin\Resources\OrderResource::table($table)
->modifyQueryUsing(function (Builder $query) {
return $query->where('customer_id', 1);
})
->actions([])
->bulKActions([]);
// $table
// ->columns([
// //
// ])
// ->filters([
// //
// ])
// ->actions([
// Tables\Actions\EditAction::make(),
// ])
// ->bulkActions([
// Tables\Actions\BulkActionGroup::make([
// Tables\Actions\DeleteBulkAction::make(),
// ]),
// ]);
}
public static function getRelations(): array
{
return [
//
];
}
public static function getPages(): array
{
return [
'index' => Pages\ListOrders::route('/'),
// 'create' => Pages\CreateOrder::route('/create'),
// 'edit' => Pages\EditOrder::route('/{record}/edit'),
];
}
}

View File

@ -0,0 +1,11 @@
<?php
namespace App\Filament\Customer\Resources\OrderResource\Pages;
use App\Filament\Customer\Resources\OrderResource;
use Filament\Resources\Pages\CreateRecord;
class CreateOrder extends CreateRecord
{
protected static string $resource = OrderResource::class;
}

View File

@ -0,0 +1,19 @@
<?php
namespace App\Filament\Customer\Resources\OrderResource\Pages;
use App\Filament\Customer\Resources\OrderResource;
use Filament\Actions;
use Filament\Resources\Pages\EditRecord;
class EditOrder extends EditRecord
{
protected static string $resource = OrderResource::class;
protected function getHeaderActions(): array
{
return [
Actions\DeleteAction::make(),
];
}
}

View File

@ -0,0 +1,19 @@
<?php
namespace App\Filament\Customer\Resources\OrderResource\Pages;
use App\Filament\Customer\Resources\OrderResource;
use Filament\Actions;
use Filament\Resources\Pages\ListRecords;
class ListOrders extends ListRecords
{
protected static string $resource = OrderResource::class;
protected function getHeaderActions(): array
{
return [
Actions\CreateAction::make(),
];
}
}

View File

@ -0,0 +1,46 @@
<?php
namespace App\Filament\Guest\Pages;
use Filament\Forms\Components\Placeholder;
use Filament\Forms\Components\Section;
use Filament\Pages\Page;
use Illuminate\Support\HtmlString;
class ContactUs extends Page
{
protected static ?string $navigationIcon = 'lucide-contact';
protected static ?int $navigationSort = 2;
protected static string $view = 'filament.guest.pages.contact-us';
protected function getFormSchema(): array
{
return [
Section::make()
->schema([
Placeholder::make('digitizingContent')
->hiddenLabel()
->content(new HtmlString('<p class="w-3/4">
<b>Address</b>
<br>
<ul class="list-none list-inside">
<li>108 - 618 East Kent Ave. South,</li>
<li> Vancouver BC, V5X 0B1</li>
</ul>
<br>
<b>Contact Numbers</b>
<br>
<ul class="list-none list-inside">
<li>Tel: (604)871-9991</li>
<li>Fax: (604)871-9980</li>
<li>E-mail: info@sewtopnotch.com</li>
</ul>
</p>')),
])
->columns(2)
->columnSpan(1),
];
}
}

View File

@ -0,0 +1,43 @@
<?php
namespace App\Filament\Guest\Pages;
use Filament\Forms\Components\Placeholder;
use Filament\Forms\Components\Section;
use Filament\Pages\Page;
use Illuminate\Support\HtmlString;
class Digitizing extends Page
{
protected static ?string $navigationIcon = 'heroicon-o-document-text';
protected static ?int $navigationSort = -1;
protected static string $view = 'filament.guest.pages.digitizing';
protected function getFormSchema(): array
{
return [
Section::make()
->schema([
Placeholder::make('digitizingContent')
->hiddenLabel()
->content(new HtmlString('<p class="w-3/4">
<b>Overview</b>
<br>
<ul class="list-disc">
<li>Digitizing is the process of converting an artwork/picture into instructions an embroidery machine can understand.</li>
<br>
<li>The quality of digitizing plays a very important role in the final embroidery quality.</li>
<br>
<li>We have our own digitizing expert working in the shop, so digitizing files can be adjusted according to fabric, placement, and colors.</li>
<br>
<li>We always digitize by ourselves.</li>
</ul>
</p>')),
])
->columns(2)
->columnSpan(1),
];
}
}

View File

@ -0,0 +1,51 @@
<?php
namespace App\Filament\Guest\Pages;
use Filament\Forms\Components\Placeholder;
use Filament\Forms\Components\Section;
use Filament\Pages\Page;
use Illuminate\Support\HtmlString;
class Embroidery extends Page
{
protected static ?string $navigationIcon = 'heroicon-o-document-text';
protected static ?int $navigationSort = 0;
protected static string $view = 'filament.guest.pages.embroidery';
protected function getFormSchema(): array
{
return [
Section::make()
->schema([
Placeholder::make('embContent')
->hiddenLabel()
->content(new HtmlString('<p class="w-3/4">
<b>Overview</b>
<br>
<ul class="list-disc list-inside">
<li>We can do regular embroidery, appliqué, patches, puff (3D). They can apply on apparels, hats, bags, towels, blankets, etc. </li>
<br>
<li> Comparing with screen printing, embroidery means high end. To make sure it is really high end, we strictly apply 3 steps: </li>
</ul>
<br>
<ul class="list-inside list-decimal">
<li>1. Good digitizing</li>
<li>2. Best quality materials (such as threads and backings)</li>
<li>3. Detailed QC (Quality Control) procedures</li>
</ul>
<br>
<ul class="list-disc list-inside">
<li>As for the material, there are every kind of threads, backings, and other materials that embroidery needs to use. We always use the best quality.</li>
<br>
<li>QC is the last step before our embroidery products leave the shop. We consider QC as important as digitizing and embroidery. The time we spent on QC is twice as others.</li>
</ul>
</p>')),
])
->columns(2)
->columnSpan(1),
];
}
}

View File

@ -0,0 +1,42 @@
<?php
namespace App\Filament\Guest\Pages;
use Filament\Forms\Components\Placeholder;
use Filament\Forms\Components\Section;
use Filament\Pages\Page;
use Illuminate\Support\HtmlString;
class Home extends Page
{
protected static ?string $navigationIcon = 'lucide-house';
protected static ?int $navigationSort = -2;
protected static string $view = 'filament.guest.pages.home';
protected function getFormSchema(): array
{
return [
Section::make()
->schema([
Placeholder::make('homeContent')
->hiddenLabel()
->content(new HtmlString('<p class="w-3/4">
<b>Welcome to Top-Notch Embroidery and Digitizing Ltd.</b>
<br>
<ul class="list-disc list-inside">
<li>We specialize in digitizing, embroidery, vinyl and screen printing.</li>
<br>
<li>Our digitizing is done by our experienced digitizer right in our shop.</li>
<br>
<li>We can embellish on jackets, shirts, pants, sweaters, hoodies, sports jerseys,
team wears, bags, towels, hats, blankets, wedding gawns, gloves, head bands, wrist bands, etc.</li>
</ul>
</p>')),
])
->columns(2)
->columnSpan(1),
];
}
}

View File

@ -0,0 +1,38 @@
<?php
namespace App\Filament\Guest\Pages;
use Filament\Forms\Components\Placeholder;
use Filament\Forms\Components\Section;
use Filament\Pages\Page;
use Illuminate\Support\HtmlString;
class Vinyl extends Page
{
protected static ?string $navigationIcon = 'heroicon-o-document-text';
protected static ?int $navigationSort = 1;
protected static string $view = 'filament.guest.pages.vinyl';
protected function getFormSchema(): array
{
return [
Section::make()
->schema([
Placeholder::make('digitizingContent')
->hiddenLabel()
->content(new HtmlString('<p class="w-3/4">
<b>Overview</b>
<br>
<ul class="list-disc">
<li>Vinyl is widely used in jerseys and other apparels. </li>
<li>We mostly use 3M material.</li>
</ul>
</p>')),
])
->columns(2)
->columnSpan(1),
];
}
}

View File

@ -1,19 +0,0 @@
<?php
namespace App\Filament\Resources\InvoiceReportResource\Pages;
use App\Filament\Resources\InvoiceReportResource;
use Filament\Resources\Pages\ViewRecord;
class ViewInvoiceReport extends ViewRecord
{
protected static string $resource = InvoiceReportResource::class;
protected static ?string $title = 'View Invoice Report';
protected function getHeaderActions(): array
{
return [
];
}
}

View File

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

View File

@ -1,48 +0,0 @@
<?php
namespace App\Filament\Resources\InvoiceReportResource\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(),
]),
]);
}
}

View File

@ -1,322 +0,0 @@
<?php
namespace App\Filament\Resources;
use App\Enums\OrderAttributes;
use App\Enums\OrderStatus;
use App\Enums\OrderType;
use App\Filament\Resources\OrderResource\Pages;
use App\Models\Contact;
use App\Models\Customer;
use App\Models\Order;
use App\Models\ServiceType;
use Filament\Forms\Components\DatePicker;
use Filament\Forms\Components\Grid;
use Filament\Forms\Components\Repeater;
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\Forms\Get;
use Filament\Forms\Set;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
use Guava\FilamentClusters\Forms\Cluster;
use Icetalker\FilamentTableRepeater\Forms\Components\TableRepeater;
use Illuminate\Database\Eloquent\Builder;
class OrderResource extends Resource
{
protected static ?string $model = Order::class;
protected static ?string $navigationIcon = 'lucide-shopping-cart';
protected static ?string $navigationGroup = 'Production';
public static function form(Form $form): Form
{
return $form->schema([
Section::make([
Grid::make(1)
->schema([
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')),
]),
Textarea::make('notes')
->rows(3),
])->columnSpan(1),
Grid::make(1)
->schema([
ToggleButtons::make('status')
->required()
->default(OrderStatus::DRAFT->value)
->options(OrderStatus::class)
->inline(),
ToggleButtons::make('order_attributes')
->options(OrderAttributes::class)
->multiple()
->inline(),
ToggleButtons::make('printed')
->boolean()
->default(false)
->inline(),
ToggleButtons::make('pre_production')
->label('Pre-production')
->default(false)
->boolean()
->inline()
->colors([
'true' => 'info',
'false' => 'info',
]),
])->columnSpan(1),
])->columns(2),
TableRepeater::make('order_products')
->label('Garments')
->schema([
TextInput::make('sku'),
TextInput::make('product_name')
->required(),
TextInput::make('color'),
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'),
])
->reorderable()
->cloneable(),
Repeater::make('services')
->label('Product Services')
->schema([
Grid::make(19)
->schema([
Select::make('serviceType')
->options(ServiceType::all()->pluck('name', 'id'))
->columnSpan(2)
->placeholder('Select...')
->searchable(),
TextInput::make('placement')
->columnSpan(3),
TextInput::make('serviceFileName')
->columnSpan(3)
->label('Logo Name'),
TextInput::make('serviceFileSetupNumber')
->label('Setup')
->columnSpan(1),
Cluster::make([
TextInput::make('serviceFileWidth')
->prefix('w'),
TextInput::make('serviceFileHeight')
->prefix('h'),
])
->label('Dimensions')
->columnSpan(4),
TextInput::make('amount')
->label('Quantity')
->live()
->reactive()
->afterStateUpdated(function ($state, Get $get, Set $set) {
$set('total_price', ($get('amount_price') * $state ?? 0));
})
->afterStateHydrated(function ($state, Get $get, Set $set) {
$set('total_price', ($get('amount_price') * $state ?? 0));
})
->prefix('#')
->columnSpan(2),
TextInput::make('amount_price')
->prefix('$')
->reactive()
->afterStateUpdated(function ($state, Get $get, Set $set) {
$set('total_price', ($get('amount') * $state ?? 0));
})
->afterStateHydrated(function ($state, Get $get, Set $set) {
$set('total_price', ($get('amount') * $state ?? 0));
})
->columnSpan(2),
TextInput::make('total_price')
->prefix('$')
->readOnly()
->columnSpan(2),
]),
Grid::make(9)
->schema([
TextInput::make('serviceFileCode')
->label('Code')
->columnSpan(1)
->placeholder('A1234'),
Textarea::make('notes')
->placeholder('Thread colors...')
->columnSpan(8),
]),
])
->reorderable()
->cloneable()
->columns(4)
->columnSpan(2),
]);
}
public static function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\IconColumn::make('alert')
->getStateUsing(fn ($record) => $record->is_alert_danger || $record->is_alert_warning)
->label('')
->color(fn ($record) => $record->is_alert_danger ? 'danger' : 'warning')
->icon(function ($record) {
return $record->is_alert_danger
? 'lucide-calendar-clock' : ($record->rush
? OrderAttributes::rush->getIcon() : null);
})
->size(Tables\Columns\IconColumn\IconColumnSize::Medium),
TextColumn::make('internal_po')
->label('Internal PO')
->fontFamily('mono')
->color('info')
->searchable()
->sortable(),
TextColumn::make('customer.company_name')
->searchable()
->sortable(),
TextColumn::make('customer_po')
->label('PO')
->wrap()
->weight('bold')
->color('code')
->searchable()
->sortable()
->extraHeaderAttributes([
'class' => 'w-full',
]),
TextColumn::make('order_date')
->searchable()
->sortable(),
TextColumn::make('due_date')
->searchable()
->sortable(),
TextColumn::make('status')
->badge()
->searchable()
->sortable(),
])
->defaultSort('order_date', 'desc')
->filters([
Tables\Filters\Filter::make('order_date')
->form([
DatePicker::make('created_from'),
DatePicker::make('created_until'),
])
->query(function (Builder $query, array $data): Builder {
return $query
->when(
$data['created_from'],
fn (Builder $query, $date): Builder => $query->whereDate('order_date', '>=', $date),
)
->when(
$data['created_until'],
fn (Builder $query, $date): Builder => $query->whereDate('order_date', '<=', $date),
);
}),
], )
->actions([
Tables\Actions\EditAction::make(),
])
->bulkActions([
Tables\Actions\BulkActionGroup::make([
Tables\Actions\DeleteBulkAction::make(),
]),
]);
}
public static function getRelations(): array
{
return [
];
}
public static function getPages(): array
{
return [
'index' => Pages\ListOrders::route('/'),
'create' => Pages\CreateOrder::route('/create'),
'edit' => Pages\EditOrder::route('/{record}/edit'),
];
}
}

View File

@ -0,0 +1,26 @@
<?php
namespace App\Http\Controllers;
use App\Models\InvoiceReport;
use Spatie\Browsershot\Browsershot;
use Spatie\LaravelPdf\Facades\Pdf;
class PdfController extends Controller
{
public function invoiceReport(int $id)
{
$invoiceReport = InvoiceReport::find($id);
$url = strtolower('invoicereport-'.$invoiceReport->internal_id.'.pdf');
Pdf::view('pdf.invoice-report', ['invoiceReport' => $invoiceReport])
->withBrowsershot(function (Browsershot $browsershot) {
$browsershot->noSandbox();
})
->margins(8, 8, 15, 8)
->footerView('pdf.invoice-report-footer', ['invoiceReport' => $invoiceReport])
->save($url);
return redirect($url);
}
}

View File

@ -8,10 +8,11 @@
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
use Illuminate\Database\Eloquent\SoftDeletes;
class Invoice extends Model
{
use HasFactory;
use HasFactory, SoftDeletes;
protected $fillable = [
'customer_id',
@ -41,7 +42,7 @@ public static function boot(): void
parent::boot();
static::created(function ($model) {
$model->attributes['internal_id'] = $model->generateInternalId($model->id);
$model->attributes['internal_id'] = 'TN4'.str_pad($model->id, 4, '0', STR_PAD_LEFT);
$model->save();
});
}
@ -54,13 +55,13 @@ public function setStatus(InvoiceStatus $status)
}
}
public function generateInternalId(int $id): string
{
$po = str_pad(strval($id), 4, '0', STR_PAD_LEFT);
$year = date('y');
return 'TN-IN-'.$year.'-'.$po;
}
// public function generateInternalId(int $id): string
// {
// $po = str_pad(strval($id), 4, '0', STR_PAD_LEFT);
// $year = date('y');
//
// return 'TN-IN-'.$year.'-'.$po;
// }
public function calculateTotals(): void
{

View File

@ -2,11 +2,11 @@
namespace App\Models;
use App\Enums\InvoiceStatus;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
class InvoiceReport extends Model
{
@ -21,19 +21,46 @@ class InvoiceReport extends Model
'subtotal',
'pst',
'gst',
];
protected $appends = [
'total',
];
protected $casts = [
'date_start' => 'date',
'date_end' => 'date',
];
public static function boot(): void
{
parent::boot();
static::created(function ($model) {
$model->attributes['internal_id'] = 'TN-INR-'.$model->id;
static::created(function (InvoiceReport $model) {
// Set ID after creation
$model->attributes['internal_id'] = 'TNR'.str_pad($model->id, 4, '0', STR_PAD_LEFT);
// Associate all relevant invoices
$invoices = Invoice::whereBetween('date', [$model->date_start, $model->date_end])
->where('customer_id', $model->customer_id)
->when($model->filter_paid, function ($query) {
$query->whereNot('status', InvoiceStatus::PAID);
});
$model->invoices()->sync($invoices->pluck('id')->toArray());
// $model->total = $model->invoices()->where('status', 'UNPAID')->sum('total');
// Finally, save
$model->save();
});
}
public function getTotalAttribute()
{
return $this->invoices()->sum('total');
}
public function customer(): BelongsTo
{
return $this->belongsTo(Customer::class);
@ -44,8 +71,8 @@ public function invoices(): BelongsToMany
return $this->BelongsToMany(Invoice::class);
}
public function orders(): HasManyThrough
public function orders()
{
return $this->hasManyThrough(Order::class, Invoice::class);
return $this->invoices()->with('orders')->get()->pluck('orders')->flatten()->unique('id');
}
}

View File

@ -29,11 +29,6 @@ class ProductService extends Model
'price',
];
// public function getServiceType(): string
// {
// return $this->serviceType->name ?? '';
// }
public function getPriceAttribute(): float
{
return number_format($this->amount * $this->amount_price, 2);

View File

@ -4,11 +4,12 @@
// use Illuminate\Contracts\Auth\MustVerifyEmail;
use Database\Factories\UserFactory;
use Filament\Models\Contracts\HasName;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class User extends Authenticatable
class User extends Authenticatable implements HasName
{
/** @use HasFactory<UserFactory> */
use HasFactory, Notifiable;
@ -19,8 +20,8 @@ class User extends Authenticatable
* @var array<int, string>
*/
protected $fillable = [
'name',
'email',
'username',
'is_admin',
'password',
];
@ -42,8 +43,12 @@ class User extends Authenticatable
protected function casts(): array
{
return [
'email_verified_at' => 'datetime',
'password' => 'hashed',
];
}
public function getFilamentName(): string
{
return $this->username;
}
}

View File

@ -0,0 +1,49 @@
<?php
namespace App\Observers;
use App\Models\Invoice;
use Illuminate\Support\Facades\Log;
class InvoiceObserver
{
/**
* Handle the Invoice "created" event.
*/
public function created(Invoice $invoice): void
{
Log::debug('Invoice created');
}
/**
* Handle the Invoice "updated" event.
*/
public function updated(Invoice $invoice): void
{
\Log::debug('Invoice updated!');
}
/**
* Handle the Invoice "deleted" event.
*/
public function deleted(Invoice $invoice): void
{
//
}
/**
* Handle the Invoice "restored" event.
*/
public function restored(Invoice $invoice): void
{
//
}
/**
* Handle the Invoice "force deleted" event.
*/
public function forceDeleted(Invoice $invoice): void
{
//
}
}

View File

@ -2,6 +2,7 @@
namespace App\Providers\Filament;
use App\Filament\Admin\Pages\UsernameLogin;
use Filament\Http\Middleware\Authenticate;
use Filament\Http\Middleware\DisableBladeIconComponents;
use Filament\Http\Middleware\DispatchServingFilamentEvent;
@ -25,18 +26,18 @@ public function panel(Panel $panel): Panel
->default()
->id('admin')
->path('admin')
->login()
->login(UsernameLogin::class)
->colors([
'primary' => Color::Blue,
'code' => Color::hex('#d63384'),
'invoiced' => Color::hex('#900090'),
])
->discoverResources(in: app_path('Filament/Resources'), for: 'App\\Filament\\Resources')
->discoverPages(in: app_path('Filament/Pages'), for: 'App\\Filament\\Pages')
->discoverResources(in: app_path('Filament/Admin/Resources/'), for: 'App\\Filament\\Admin\\Resources')
->discoverPages(in: app_path('Filament/Admin/Pages'), for: 'App\\Filament\\Admin\\Pages')
->pages([
Pages\Dashboard::class,
])
->discoverWidgets(in: app_path('Filament/Widgets'), for: 'App\\Filament\\Widgets')
->discoverWidgets(in: app_path('Filament/Admin/Widgets'), for: 'App\\Filament\\Admin\\Widgets')
->widgets([])
->middleware([
EncryptCookies::class,

View File

@ -0,0 +1,58 @@
<?php
namespace App\Providers\Filament;
use Filament\Http\Middleware\Authenticate;
use Filament\Http\Middleware\DisableBladeIconComponents;
use Filament\Http\Middleware\DispatchServingFilamentEvent;
use Filament\Pages;
use Filament\Panel;
use Filament\PanelProvider;
use Filament\Support\Colors\Color;
use Filament\Widgets;
use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
use Illuminate\Cookie\Middleware\EncryptCookies;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
use Illuminate\Routing\Middleware\SubstituteBindings;
use Illuminate\Session\Middleware\AuthenticateSession;
use Illuminate\Session\Middleware\StartSession;
use Illuminate\View\Middleware\ShareErrorsFromSession;
class CustomerPanelProvider extends PanelProvider
{
public function panel(Panel $panel): Panel
{
return $panel
->id('customer')
->path('customer')
->colors([
'primary' => Color::Blue,
'code' => Color::hex('#d63384'),
'invoiced' => Color::hex('#900090'),
])
->discoverResources(in: app_path('Filament/Customer/Resources'), for: 'App\\Filament\\Customer\\Resources')
->discoverPages(in: app_path('Filament/Customer/Pages'), for: 'App\\Filament\\Customer\\Pages')
->pages([
Pages\Dashboard::class,
])
->discoverWidgets(in: app_path('Filament/Customer/Widgets'), for: 'App\\Filament\\Customer\\Widgets')
->widgets([
Widgets\AccountWidget::class,
Widgets\FilamentInfoWidget::class,
])
->middleware([
EncryptCookies::class,
AddQueuedCookiesToResponse::class,
StartSession::class,
AuthenticateSession::class,
ShareErrorsFromSession::class,
VerifyCsrfToken::class,
SubstituteBindings::class,
DisableBladeIconComponents::class,
DispatchServingFilamentEvent::class,
])
->authMiddleware([
Authenticate::class,
]);
}
}

View File

@ -0,0 +1,56 @@
<?php
namespace App\Providers\Filament;
use Filament\Http\Middleware\Authenticate;
use Filament\Http\Middleware\DisableBladeIconComponents;
use Filament\Http\Middleware\DispatchServingFilamentEvent;
use Filament\Pages;
use Filament\Panel;
use Filament\PanelProvider;
use Filament\Support\Colors\Color;
use Filament\Widgets;
use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
use Illuminate\Cookie\Middleware\EncryptCookies;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
use Illuminate\Routing\Middleware\SubstituteBindings;
use Illuminate\Session\Middleware\AuthenticateSession;
use Illuminate\Session\Middleware\StartSession;
use Illuminate\View\Middleware\ShareErrorsFromSession;
class GuestPanelProvider extends PanelProvider
{
public function panel(Panel $panel): Panel
{
return $panel
->id('guest')
->path('')
->colors([
'primary' => Color::Blue,
])
->discoverResources(in: app_path('Filament/Guest/Resources'), for: 'App\\Filament\\Guest\\Resources')
->discoverPages(in: app_path('Filament/Guest/Pages'), for: 'App\\Filament\\Guest\\Pages')
->pages([
// Pages\Dashboard::class,
])
->discoverWidgets(in: app_path('Filament/Guest/Widgets'), for: 'App\\Filament\\Guest\\Widgets')
->widgets([
// Widgets\AccountWidget::class,
// Widgets\FilamentInfoWidget::class,
])
->middleware([
EncryptCookies::class,
AddQueuedCookiesToResponse::class,
StartSession::class,
AuthenticateSession::class,
ShareErrorsFromSession::class,
VerifyCsrfToken::class,
SubstituteBindings::class,
DisableBladeIconComponents::class,
DispatchServingFilamentEvent::class,
])
->authMiddleware([
// Authenticate::class,
]);
}
}

View File

@ -3,4 +3,6 @@
return [
App\Providers\AppServiceProvider::class,
App\Providers\Filament\AdminPanelProvider::class,
App\Providers\Filament\CustomerPanelProvider::class,
App\Providers\Filament\GuestPanelProvider::class,
];

View File

@ -17,11 +17,7 @@ public function definition(): array
'customer_id' => Customer::all()->shuffle()->first()->id,
'date_start' => Carbon::now()->subYear(),
'date_end' => Carbon::now(),
'filter_paid' => $this->faker->boolean(90),
/* 'subtotal' => $this->faker->randomFloat(),
'pst' => $this->faker->randomFloat(),
'gst' => $this->faker->randomFloat(),
'total' => $this->faker->randomFloat(),*/
'filter_paid' => $this->faker->boolean(40),
'created_at' => Carbon::now(),
'updated_at' => Carbon::now(),
];

View File

@ -24,21 +24,9 @@ class UserFactory extends Factory
public function definition(): array
{
return [
'name' => fake()->name(),
'email' => fake()->unique()->safeEmail(),
'email_verified_at' => now(),
'username' => $this->faker->userName(),
'password' => Hash::make('password'),
'remember_token' => Str::random(10),
];
}
/**
* Indicate that the model's email address should be unverified.
*/
public function unverified(): static
{
return $this->state(fn (array $attributes) => [
'email_verified_at' => null,
]);
}
}

View File

@ -13,10 +13,9 @@ public function up(): void
{
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('username')->unique();
$table->string('password');
$table->boolean('is_admin')->default(0);
$table->rememberToken();
$table->timestamps();
});

View File

@ -25,6 +25,7 @@ public function up(): void
$table->date('date')->default(today());
$table->date('due_date')->nullable();
$table->softDeletes();
$table->timestamps();
});
}

View File

@ -20,7 +20,7 @@ public function up(): void
$table->float('subtotal', 2)->default(0);
$table->float('pst', 2)->default(0);
$table->float('gst', 2)->default(0);
$table->float('total', 2)->default(0);
// $table->float('total', 2)->default(0);
$table->timestamps();
});

View File

@ -30,8 +30,8 @@ public function run(): void
]);
User::factory()->create([
'name' => 'Test User',
'email' => 'test@example.com',
'username' => 'admin',
'is_admin' => true,
]);
}
}

View File

@ -26,7 +26,5 @@ public function run(): void
$invoice->calculateTotals();
}
\Log::debug(Invoice::all());
}
}

Binary file not shown.

BIN
public/invoice-tn40003.pdf Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
public/order-tn24-0029.pdf Normal file

Binary file not shown.

BIN
public/order-tn24-0093.pdf Normal file

Binary file not shown.

BIN
public/order-tn24-0132.pdf Normal file

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More