Work work
This commit is contained in:
parent
90ef3c9c29
commit
fc3c2421ca
67
app/Filament/Customer/Resources/OrderResource.php
Normal file
67
app/Filament/Customer/Resources/OrderResource.php
Normal 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\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'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
@ -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(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
@ -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(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
46
app/Filament/Guest/Pages/ContactUs.php
Normal file
46
app/Filament/Guest/Pages/ContactUs.php
Normal 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),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
43
app/Filament/Guest/Pages/Digitizing.php
Normal file
43
app/Filament/Guest/Pages/Digitizing.php
Normal 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),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
51
app/Filament/Guest/Pages/Embroidery.php
Normal file
51
app/Filament/Guest/Pages/Embroidery.php
Normal 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),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
42
app/Filament/Guest/Pages/Home.php
Normal file
42
app/Filament/Guest/Pages/Home.php
Normal 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),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
38
app/Filament/Guest/Pages/Vinyl.php
Normal file
38
app/Filament/Guest/Pages/Vinyl.php
Normal 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),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
@ -42,7 +42,7 @@ public static function table(Table $table): Table
|
|||||||
->extraHeaderAttributes(['class' => 'w-full']),
|
->extraHeaderAttributes(['class' => 'w-full']),
|
||||||
|
|
||||||
Tables\Columns\TextColumn::make('subtotal')
|
Tables\Columns\TextColumn::make('subtotal')
|
||||||
->money('usd')
|
->money()
|
||||||
->alignRight()
|
->alignRight()
|
||||||
->getStateUsing(function (Table $table, Model $record) {
|
->getStateUsing(function (Table $table, Model $record) {
|
||||||
return $record->getSubtotalAttribute(
|
return $record->getSubtotalAttribute(
|
||||||
@ -53,7 +53,7 @@ public static function table(Table $table): Table
|
|||||||
|
|
||||||
Tables\Columns\TextColumn::make('gst')
|
Tables\Columns\TextColumn::make('gst')
|
||||||
->label('GST')
|
->label('GST')
|
||||||
->money('usd')
|
->money()
|
||||||
->alignRight()
|
->alignRight()
|
||||||
->getStateUsing(function (Table $table, Model $record) {
|
->getStateUsing(function (Table $table, Model $record) {
|
||||||
return $record->getGstAttribute(
|
return $record->getGstAttribute(
|
||||||
@ -64,7 +64,7 @@ public static function table(Table $table): Table
|
|||||||
|
|
||||||
Tables\Columns\TextColumn::make('pst')
|
Tables\Columns\TextColumn::make('pst')
|
||||||
->label('PST')
|
->label('PST')
|
||||||
->money('usd')
|
->money()
|
||||||
->alignRight()
|
->alignRight()
|
||||||
->getStateUsing(function (Table $table, Model $record) {
|
->getStateUsing(function (Table $table, Model $record) {
|
||||||
return $record->getPstAttribute(
|
return $record->getPstAttribute(
|
||||||
@ -74,7 +74,7 @@ public static function table(Table $table): Table
|
|||||||
}),
|
}),
|
||||||
|
|
||||||
Tables\Columns\TextColumn::make('total')
|
Tables\Columns\TextColumn::make('total')
|
||||||
->money('usd')
|
->money()
|
||||||
->weight('bold')
|
->weight('bold')
|
||||||
->alignRight()
|
->alignRight()
|
||||||
->getStateUsing(function (Table $table, Model $record) {
|
->getStateUsing(function (Table $table, Model $record) {
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
use Filament\Forms\Form;
|
use Filament\Forms\Form;
|
||||||
use Filament\Resources\Resource;
|
use Filament\Resources\Resource;
|
||||||
use Filament\Support\Enums\FontFamily;
|
use Filament\Support\Enums\FontFamily;
|
||||||
|
use Filament\Support\Enums\FontWeight;
|
||||||
use Filament\Tables\Columns\TextColumn;
|
use Filament\Tables\Columns\TextColumn;
|
||||||
use Filament\Tables\Table;
|
use Filament\Tables\Table;
|
||||||
|
|
||||||
@ -72,24 +73,15 @@ public static function table(Table $table): Table
|
|||||||
->label('End Date')
|
->label('End Date')
|
||||||
->date('Y-m-d'),
|
->date('Y-m-d'),
|
||||||
TextColumn::make('total')
|
TextColumn::make('total')
|
||||||
|
->label('Balance Due')
|
||||||
|
->weight(FontWeight::Bold)
|
||||||
->money(),
|
->money(),
|
||||||
])
|
])
|
||||||
->defaultSort('created_at', 'desc')
|
->defaultSort('id', 'desc')
|
||||||
|
|
||||||
->filters([
|
->filters([
|
||||||
])
|
])
|
||||||
->actions([]);
|
->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
|
public static function getRelations(): array
|
||||||
@ -103,8 +95,8 @@ public static function getPages(): array
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'index' => Pages\ListInvoiceReports::route('/'),
|
'index' => Pages\ListInvoiceReports::route('/'),
|
||||||
'edit' => Pages\EditInvoiceReport::route('/{record}/edit'),
|
|
||||||
'create' => Pages\CreateInvoiceReport::route('/create'),
|
'create' => Pages\CreateInvoiceReport::route('/create'),
|
||||||
|
'view' => Pages\ViewInvoiceReport::route('/{record}'),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
namespace App\Filament\Resources\InvoiceReportResource\Pages;
|
namespace App\Filament\Resources\InvoiceReportResource\Pages;
|
||||||
|
|
||||||
use App\Filament\Resources\InvoiceReportResource;
|
use App\Filament\Resources\InvoiceReportResource;
|
||||||
|
use App\Models\InvoiceReport;
|
||||||
|
use Filament\Actions\Action;
|
||||||
use Filament\Resources\Pages\ViewRecord;
|
use Filament\Resources\Pages\ViewRecord;
|
||||||
|
|
||||||
class ViewInvoiceReport extends ViewRecord
|
class ViewInvoiceReport extends ViewRecord
|
||||||
@ -14,6 +16,10 @@ class ViewInvoiceReport extends ViewRecord
|
|||||||
protected function getHeaderActions(): array
|
protected function getHeaderActions(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
|
Action::make('print')
|
||||||
|
->icon('lucide-printer')
|
||||||
|
->url(fn (InvoiceReport $record) => route('pdf.invoice-report', $record))
|
||||||
|
->openUrlInNewTab(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,10 +2,12 @@
|
|||||||
|
|
||||||
namespace App\Filament\Resources\InvoiceReportResource\RelationManagers;
|
namespace App\Filament\Resources\InvoiceReportResource\RelationManagers;
|
||||||
|
|
||||||
|
use App\Filament\Resources\InvoiceResource;
|
||||||
use Filament\Forms;
|
use Filament\Forms;
|
||||||
use Filament\Forms\Form;
|
use Filament\Forms\Form;
|
||||||
use Filament\Resources\RelationManagers\RelationManager;
|
use Filament\Resources\RelationManagers\RelationManager;
|
||||||
use Filament\Tables;
|
use Filament\Support\Enums\FontWeight;
|
||||||
|
use Filament\Tables\Columns\TextColumn;
|
||||||
use Filament\Tables\Table;
|
use Filament\Tables\Table;
|
||||||
|
|
||||||
class InvoicesRelationManager extends RelationManager
|
class InvoicesRelationManager extends RelationManager
|
||||||
@ -26,25 +28,44 @@ public function table(Table $table): Table
|
|||||||
{
|
{
|
||||||
return $table
|
return $table
|
||||||
->recordTitleAttribute('internal_id')
|
->recordTitleAttribute('internal_id')
|
||||||
|
->recordUrl(fn ($record) => InvoiceResource::getUrl('edit', ['record' => $record->id]))
|
||||||
->columns([
|
->columns([
|
||||||
Tables\Columns\TextColumn::make('internal_id'),
|
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([
|
->filters([
|
||||||
//
|
//
|
||||||
])
|
])
|
||||||
->headerActions([
|
->headerActions([
|
||||||
// Tables\Actions\CreateAction::make(),
|
|
||||||
Tables\Actions\AssociateAction::make(),
|
|
||||||
])
|
])
|
||||||
|
->defaultSort('invoices.id')
|
||||||
->actions([
|
->actions([
|
||||||
Tables\Actions\DissociateAction::make(),
|
|
||||||
// Tables\Actions\EditAction::make(),
|
|
||||||
// Tables\Actions\DeleteAction::make(),
|
|
||||||
])
|
])
|
||||||
->bulkActions([
|
->bulkActions([
|
||||||
// Tables\Actions\BulkActionGroup::make([
|
|
||||||
// Tables\Actions\DeleteBulkAction::make(),
|
|
||||||
// ]),
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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(),
|
|
||||||
]),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
@ -10,6 +10,8 @@
|
|||||||
use App\Models\Invoice;
|
use App\Models\Invoice;
|
||||||
use Filament\Forms\Components\DatePicker;
|
use Filament\Forms\Components\DatePicker;
|
||||||
use Filament\Forms\Components\Grid;
|
use Filament\Forms\Components\Grid;
|
||||||
|
use Filament\Forms\Components\Group;
|
||||||
|
use Filament\Forms\Components\Placeholder;
|
||||||
use Filament\Forms\Components\Section;
|
use Filament\Forms\Components\Section;
|
||||||
use Filament\Forms\Components\Select;
|
use Filament\Forms\Components\Select;
|
||||||
use Filament\Forms\Components\Split;
|
use Filament\Forms\Components\Split;
|
||||||
@ -35,6 +37,8 @@ class InvoiceResource extends Resource
|
|||||||
public static function form(Form $form): Form
|
public static function form(Form $form): Form
|
||||||
{
|
{
|
||||||
return $form
|
return $form
|
||||||
|
->schema([
|
||||||
|
Group::make()
|
||||||
->schema([
|
->schema([
|
||||||
Section::make([
|
Section::make([
|
||||||
Grid::make(2)
|
Grid::make(2)
|
||||||
@ -55,11 +59,18 @@ public static function form(Form $form): Form
|
|||||||
DatePicker::make('due_date'),
|
DatePicker::make('due_date'),
|
||||||
])
|
])
|
||||||
->columnSpan(2),
|
->columnSpan(2),
|
||||||
Select::make('status')
|
|
||||||
|
ToggleButtons::make('status')
|
||||||
->options(InvoiceStatus::class)
|
->options(InvoiceStatus::class)
|
||||||
->searchable()
|
|
||||||
->required()
|
->required()
|
||||||
->default(InvoiceStatus::UNPAID),
|
->inline()
|
||||||
|
->default(InvoiceStatus::UNPAID)
|
||||||
|
->columnSpan(2),
|
||||||
|
// Select::make('status')
|
||||||
|
// ->options(InvoiceStatus::class)
|
||||||
|
// ->searchable()
|
||||||
|
// ->required()
|
||||||
|
// ->default(InvoiceStatus::UNPAID),
|
||||||
])->columnSpan(2),
|
])->columnSpan(2),
|
||||||
|
|
||||||
Grid::make(1)
|
Grid::make(1)
|
||||||
@ -84,8 +95,26 @@ public static function form(Form $form): Form
|
|||||||
])->columnSpan(1),
|
])->columnSpan(1),
|
||||||
])
|
])
|
||||||
->columns(3)
|
->columns(3)
|
||||||
->columnSpan(3),
|
->columnSpan(2),
|
||||||
])->columns(3);
|
|
||||||
|
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
|
public static function table(Table $table): Table
|
||||||
@ -97,22 +126,33 @@ public static function table(Table $table): Table
|
|||||||
->fontFamily('mono')
|
->fontFamily('mono')
|
||||||
->color('primary')
|
->color('primary')
|
||||||
->sortable()
|
->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')
|
Tables\Columns\TextColumn::make('customer.company_name')
|
||||||
->sortable()
|
->sortable()
|
||||||
->extraHeaderAttributes(['class' => 'w-full'])
|
->extraHeaderAttributes(['class' => 'w-full'])
|
||||||
->searchable(),
|
->searchable(),
|
||||||
|
|
||||||
Tables\Columns\TextColumn::make('created_at')
|
Tables\Columns\TextColumn::make('created_at')
|
||||||
->label('Created')
|
->label('Created')
|
||||||
->date()
|
->date()
|
||||||
->sortable(),
|
->sortable(),
|
||||||
|
|
||||||
Tables\Columns\TextColumn::make('subtotal')
|
Tables\Columns\TextColumn::make('subtotal')
|
||||||
->money('USD')
|
->money()
|
||||||
->alignRight(),
|
->alignRight(),
|
||||||
|
|
||||||
Tables\Columns\TextColumn::make('gst_amount')
|
Tables\Columns\TextColumn::make('gst_amount')
|
||||||
->label('GST')
|
->label('GST')
|
||||||
->money('USD')
|
->money()
|
||||||
->alignRight(),
|
->alignRight(),
|
||||||
|
|
||||||
Tables\Columns\TextColumn::make('pst_amount')
|
Tables\Columns\TextColumn::make('pst_amount')
|
||||||
->label('PST')
|
->label('PST')
|
||||||
->formatStateUsing(function ($state) {
|
->formatStateUsing(function ($state) {
|
||||||
@ -120,7 +160,8 @@ public static function table(Table $table): Table
|
|||||||
})
|
})
|
||||||
->alignRight(),
|
->alignRight(),
|
||||||
Tables\Columns\TextColumn::make('total')
|
Tables\Columns\TextColumn::make('total')
|
||||||
->money('USD')
|
->label('Balance')
|
||||||
|
->money()
|
||||||
->weight('bold')
|
->weight('bold')
|
||||||
->alignRight(),
|
->alignRight(),
|
||||||
Tables\Columns\TextColumn::make('status')
|
Tables\Columns\TextColumn::make('status')
|
||||||
@ -157,11 +198,10 @@ public static function table(Table $table): Table
|
|||||||
'status',
|
'status',
|
||||||
])
|
])
|
||||||
|
|
||||||
->defaultSort('created_at', 'desc')
|
->defaultSort('id', 'desc')
|
||||||
|
|
||||||
->actions([
|
->actions([
|
||||||
Tables\Actions\EditAction::make(),
|
Tables\Actions\EditAction::make(),
|
||||||
//todo: generate report pdf
|
|
||||||
])
|
])
|
||||||
|
|
||||||
->bulkActions([
|
->bulkActions([
|
||||||
|
@ -23,4 +23,15 @@ protected function getHeaderActions(): array
|
|||||||
->icon('lucide-trash-2'),
|
->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();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,11 @@
|
|||||||
|
|
||||||
namespace App\Filament\Resources\InvoiceResource\RelationManagers;
|
namespace App\Filament\Resources\InvoiceResource\RelationManagers;
|
||||||
|
|
||||||
|
use App\Filament\Resources\OrderResource;
|
||||||
use Filament\Forms;
|
use Filament\Forms;
|
||||||
use Filament\Forms\Form;
|
use Filament\Forms\Form;
|
||||||
use Filament\Resources\RelationManagers\RelationManager;
|
use Filament\Resources\RelationManagers\RelationManager;
|
||||||
|
use Filament\Support\Enums\FontFamily;
|
||||||
use Filament\Tables;
|
use Filament\Tables;
|
||||||
use Filament\Tables\Table;
|
use Filament\Tables\Table;
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
@ -27,18 +29,27 @@ public function table(Table $table): Table
|
|||||||
{
|
{
|
||||||
return $table
|
return $table
|
||||||
->recordTitleAttribute('customer_po')
|
->recordTitleAttribute('customer_po')
|
||||||
|
->recordUrl(fn ($record) => OrderResource::getUrl('edit', ['record' => $record->id]))
|
||||||
->columns([
|
->columns([
|
||||||
|
Tables\Columns\TextColumn::make('internal_po')
|
||||||
|
->label('Internal PO')
|
||||||
|
->color('primary')
|
||||||
|
->fontFamily(FontFamily::Mono),
|
||||||
|
|
||||||
Tables\Columns\TextColumn::make('customer_po')
|
Tables\Columns\TextColumn::make('customer_po')
|
||||||
|
->label('Customer PO')
|
||||||
->color('code')
|
->color('code')
|
||||||
->weight('bold')
|
->weight('bold')
|
||||||
->extraHeaderAttributes(['class' => 'w-full']),
|
->extraHeaderAttributes(['class' => 'w-full']),
|
||||||
|
|
||||||
Tables\Columns\TextColumn::make('total_product_quantity')
|
Tables\Columns\TextColumn::make('total_product_quantity')
|
||||||
->label('Total QTY')
|
->label('Total QTY')
|
||||||
->alignRight(),
|
->alignRight(),
|
||||||
|
|
||||||
Tables\Columns\TextColumn::make('total_service_price')
|
Tables\Columns\TextColumn::make('total_service_price')
|
||||||
->alignRight()
|
->alignRight()
|
||||||
->label('Total price')
|
->label('Total price')
|
||||||
->money('usd'),
|
->money(),
|
||||||
])
|
])
|
||||||
->filters([
|
->filters([
|
||||||
//
|
//
|
||||||
|
@ -9,9 +9,14 @@
|
|||||||
use App\Models\Contact;
|
use App\Models\Contact;
|
||||||
use App\Models\Customer;
|
use App\Models\Customer;
|
||||||
use App\Models\Order;
|
use App\Models\Order;
|
||||||
|
use App\Models\OrderProduct;
|
||||||
|
use App\Models\ProductService;
|
||||||
|
use App\Models\ServiceFile;
|
||||||
use App\Models\ServiceType;
|
use App\Models\ServiceType;
|
||||||
use Filament\Forms\Components\DatePicker;
|
use Filament\Forms\Components\DatePicker;
|
||||||
use Filament\Forms\Components\Grid;
|
use Filament\Forms\Components\Grid;
|
||||||
|
use Filament\Forms\Components\Group;
|
||||||
|
use Filament\Forms\Components\Placeholder;
|
||||||
use Filament\Forms\Components\Repeater;
|
use Filament\Forms\Components\Repeater;
|
||||||
use Filament\Forms\Components\Section;
|
use Filament\Forms\Components\Section;
|
||||||
use Filament\Forms\Components\Select;
|
use Filament\Forms\Components\Select;
|
||||||
@ -20,15 +25,16 @@
|
|||||||
use Filament\Forms\Components\TextInput;
|
use Filament\Forms\Components\TextInput;
|
||||||
use Filament\Forms\Components\ToggleButtons;
|
use Filament\Forms\Components\ToggleButtons;
|
||||||
use Filament\Forms\Form;
|
use Filament\Forms\Form;
|
||||||
use Filament\Forms\Get;
|
use Filament\Notifications\Notification;
|
||||||
use Filament\Forms\Set;
|
|
||||||
use Filament\Resources\Resource;
|
use Filament\Resources\Resource;
|
||||||
|
use Filament\Support\Enums\MaxWidth;
|
||||||
use Filament\Tables;
|
use Filament\Tables;
|
||||||
use Filament\Tables\Columns\TextColumn;
|
use Filament\Tables\Columns\TextColumn;
|
||||||
use Filament\Tables\Table;
|
use Filament\Tables\Table;
|
||||||
use Guava\FilamentClusters\Forms\Cluster;
|
use Guava\FilamentClusters\Forms\Cluster;
|
||||||
use Icetalker\FilamentTableRepeater\Forms\Components\TableRepeater;
|
use Icetalker\FilamentTableRepeater\Forms\Components\TableRepeater;
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
|
use Illuminate\Database\Eloquent\Collection;
|
||||||
|
|
||||||
class OrderResource extends Resource
|
class OrderResource extends Resource
|
||||||
{
|
{
|
||||||
@ -41,8 +47,9 @@ class OrderResource extends Resource
|
|||||||
public static function form(Form $form): Form
|
public static function form(Form $form): Form
|
||||||
{
|
{
|
||||||
return $form->schema([
|
return $form->schema([
|
||||||
|
Group::make()
|
||||||
|
->schema([
|
||||||
Section::make([
|
Section::make([
|
||||||
|
|
||||||
Grid::make(1)
|
Grid::make(1)
|
||||||
->schema([
|
->schema([
|
||||||
Select::make('order_type')
|
Select::make('order_type')
|
||||||
@ -50,22 +57,22 @@ public static function form(Form $form): Form
|
|||||||
->options(OrderType::class)
|
->options(OrderType::class)
|
||||||
->searchable(),
|
->searchable(),
|
||||||
|
|
||||||
Split::make([
|
// Split::make([
|
||||||
Select::make('customer_id')
|
Select::make('customer_id')
|
||||||
->required()
|
->required()
|
||||||
->label('Customer')
|
->label('Customer')
|
||||||
->options(Customer::all()->pluck('company_name', 'id'))
|
->options(Customer::all()->pluck('company_name', 'id'))
|
||||||
->reactive()
|
// ->reactive()
|
||||||
->searchable(),
|
->searchable(),
|
||||||
|
|
||||||
Select::make('contact_id')
|
// Select::make('contact_id')
|
||||||
->label('Contact')
|
// ->label('Contact')
|
||||||
->options(fn ($get): array => Contact::where('customer_id', $get('customer_id') ?? null)
|
// ->options(fn ($get): array => Contact::where('customer_id', $get('customer_id') ?? null)
|
||||||
->get()
|
// ->get()
|
||||||
->pluck('full_name', 'id')
|
// ->pluck('full_name', 'id')
|
||||||
->toArray())
|
// ->toArray())
|
||||||
->searchable(),
|
// ->searchable(),
|
||||||
]),
|
// ]),
|
||||||
|
|
||||||
TextInput::make('customer_po')
|
TextInput::make('customer_po')
|
||||||
->required()
|
->required()
|
||||||
@ -113,15 +120,35 @@ public static function form(Form $form): Form
|
|||||||
]),
|
]),
|
||||||
|
|
||||||
])->columnSpan(1),
|
])->columnSpan(1),
|
||||||
])->columns(2),
|
])->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')
|
TableRepeater::make('order_products')
|
||||||
->label('Garments')
|
->label('Garments')
|
||||||
->schema([
|
->schema([
|
||||||
TextInput::make('sku'),
|
TextInput::make('sku')
|
||||||
|
->datalist(OrderProduct::all()->unique('sku')->pluck('sku')->toArray()),
|
||||||
TextInput::make('product_name')
|
TextInput::make('product_name')
|
||||||
|
->datalist(OrderProduct::all()->unique('product_name')->pluck('product_name')->toArray())
|
||||||
->required(),
|
->required(),
|
||||||
TextInput::make('color'),
|
TextInput::make('color')
|
||||||
|
->datalist(OrderProduct::all()->unique('color')->pluck('color')->toArray()),
|
||||||
Cluster::make([
|
Cluster::make([
|
||||||
TextInput::make('xs')
|
TextInput::make('xs')
|
||||||
->placeholder('xs'),
|
->placeholder('xs'),
|
||||||
@ -151,13 +178,27 @@ public static function form(Form $form): Form
|
|||||||
Grid::make(19)
|
Grid::make(19)
|
||||||
->schema([
|
->schema([
|
||||||
Select::make('serviceType')
|
Select::make('serviceType')
|
||||||
->options(ServiceType::all()->pluck('name', 'id'))
|
->options(ServiceType::all()->pluck('value', 'id'))
|
||||||
->columnSpan(2)
|
->columnSpan(4)
|
||||||
->placeholder('Select...')
|
->placeholder('Select...')
|
||||||
->searchable(),
|
->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')
|
TextInput::make('placement')
|
||||||
|
->datalist(ProductService::all()->unique('placement')->pluck('placement')->toArray())
|
||||||
->columnSpan(3),
|
->columnSpan(3),
|
||||||
TextInput::make('serviceFileName')
|
TextInput::make('serviceFileName')
|
||||||
|
->datalist(ServiceFile::all()->unique('name')->pluck('name')->toArray())
|
||||||
->columnSpan(3)
|
->columnSpan(3)
|
||||||
->label('Logo Name'),
|
->label('Logo Name'),
|
||||||
TextInput::make('serviceFileSetupNumber')
|
TextInput::make('serviceFileSetupNumber')
|
||||||
@ -170,36 +211,18 @@ public static function form(Form $form): Form
|
|||||||
TextInput::make('serviceFileHeight')
|
TextInput::make('serviceFileHeight')
|
||||||
->prefix('h'),
|
->prefix('h'),
|
||||||
])
|
])
|
||||||
->label('Dimensions')
|
->label('Dimensions (inches)')
|
||||||
->columnSpan(4),
|
->columnSpan(4),
|
||||||
|
|
||||||
TextInput::make('amount')
|
TextInput::make('amount')
|
||||||
->label('Quantity')
|
->label('Quantity')
|
||||||
->live()
|
->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('#')
|
->prefix('#')
|
||||||
->columnSpan(2),
|
->columnSpan(2),
|
||||||
|
|
||||||
TextInput::make('amount_price')
|
TextInput::make('amount_price')
|
||||||
|
->label('Amount')
|
||||||
->prefix('$')
|
->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),
|
->columnSpan(2),
|
||||||
]),
|
]),
|
||||||
|
|
||||||
@ -207,6 +230,7 @@ public static function form(Form $form): Form
|
|||||||
->schema([
|
->schema([
|
||||||
TextInput::make('serviceFileCode')
|
TextInput::make('serviceFileCode')
|
||||||
->label('Code')
|
->label('Code')
|
||||||
|
->datalist(ServiceFile::all()->unique('code')->pluck('code')->toArray())
|
||||||
->columnSpan(1)
|
->columnSpan(1)
|
||||||
->placeholder('A1234'),
|
->placeholder('A1234'),
|
||||||
|
|
||||||
@ -241,7 +265,17 @@ public static function table(Table $table): Table
|
|||||||
->label('Internal PO')
|
->label('Internal PO')
|
||||||
->fontFamily('mono')
|
->fontFamily('mono')
|
||||||
->color('info')
|
->color('info')
|
||||||
->searchable()
|
->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(),
|
->sortable(),
|
||||||
|
|
||||||
TextColumn::make('customer.company_name')
|
TextColumn::make('customer.company_name')
|
||||||
@ -272,9 +306,7 @@ public static function table(Table $table): Table
|
|||||||
->searchable()
|
->searchable()
|
||||||
->sortable(),
|
->sortable(),
|
||||||
])
|
])
|
||||||
|
|
||||||
->defaultSort('order_date', 'desc')
|
->defaultSort('order_date', 'desc')
|
||||||
|
|
||||||
->filters([
|
->filters([
|
||||||
Tables\Filters\Filter::make('order_date')
|
Tables\Filters\Filter::make('order_date')
|
||||||
->form([
|
->form([
|
||||||
@ -293,12 +325,33 @@ public static function table(Table $table): Table
|
|||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
], )
|
], )
|
||||||
|
|
||||||
->actions([
|
->actions([
|
||||||
Tables\Actions\EditAction::make(),
|
Tables\Actions\EditAction::make(),
|
||||||
])
|
])
|
||||||
|
|
||||||
->bulkActions([
|
->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\BulkActionGroup::make([
|
||||||
Tables\Actions\DeleteBulkAction::make(),
|
Tables\Actions\DeleteBulkAction::make(),
|
||||||
]),
|
]),
|
||||||
|
@ -148,6 +148,9 @@ protected function getHeaderActions(): array
|
|||||||
->label('Save changes')
|
->label('Save changes')
|
||||||
->action('save')
|
->action('save')
|
||||||
->icon('lucide-save'),
|
->icon('lucide-save'),
|
||||||
|
Actions\ReplicateAction::make()
|
||||||
|
->icon('lucide-copy')
|
||||||
|
->color('info'),
|
||||||
Action::make('print')
|
Action::make('print')
|
||||||
->icon('lucide-printer')
|
->icon('lucide-printer')
|
||||||
->url(fn (Order $record) => route('orders.pdf', $record))
|
->url(fn (Order $record) => route('orders.pdf', $record))
|
||||||
@ -156,4 +159,9 @@ protected function getHeaderActions(): array
|
|||||||
->icon('lucide-trash-2'),
|
->icon('lucide-trash-2'),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// protected function getRedirectUrl(): string
|
||||||
|
// {
|
||||||
|
// return $this->previousUrl ?? $this->getResource()::getUrl('index');
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,19 @@ public function getTabs(): array
|
|||||||
->whereNot('status', OrderStatus::INVOICED)
|
->whereNot('status', OrderStatus::INVOICED)
|
||||||
->count();
|
->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()
|
'overdue' => Tab::make()
|
||||||
->query(function ($query) {
|
->query(function ($query) {
|
||||||
return $query->whereDate('due_date', '<=', today())
|
return $query->whereDate('due_date', '<=', today())
|
||||||
@ -70,28 +83,8 @@ public function getTabs(): array
|
|||||||
})
|
})
|
||||||
->badgeColor('warning'),
|
->badgeColor('warning'),
|
||||||
|
|
||||||
null => Tab::make('All')
|
'all' => Tab::make('All')
|
||||||
->icon('lucide-layout-grid'),
|
->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()),
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
use App\Models\Order;
|
use App\Models\Order;
|
||||||
use App\Models\PackingSlip;
|
use App\Models\PackingSlip;
|
||||||
use Filament\Forms\Components\DatePicker;
|
use Filament\Forms\Components\DatePicker;
|
||||||
|
use Filament\Forms\Components\Section;
|
||||||
use Filament\Forms\Components\Select;
|
use Filament\Forms\Components\Select;
|
||||||
use Filament\Forms\Components\Textarea;
|
use Filament\Forms\Components\Textarea;
|
||||||
use Filament\Forms\Components\TextInput;
|
use Filament\Forms\Components\TextInput;
|
||||||
@ -30,19 +31,29 @@ public static function form(Form $form): Form
|
|||||||
{
|
{
|
||||||
return $form
|
return $form
|
||||||
->schema([
|
->schema([
|
||||||
DatePicker::make('date_received'),
|
Section::make([
|
||||||
TextInput::make('amount'),
|
DatePicker::make('date_received')
|
||||||
|
->default(today())
|
||||||
|
->required(),
|
||||||
|
// TextInput::make('amount')
|
||||||
|
// ->label('Quantity')
|
||||||
|
// ->required(),
|
||||||
Select::make('customer_id')
|
Select::make('customer_id')
|
||||||
|
->label('Customer')
|
||||||
->options(Customer::all()->pluck('company_name', 'id'))
|
->options(Customer::all()->pluck('company_name', 'id'))
|
||||||
->reactive()
|
->reactive()
|
||||||
->searchable(),
|
->searchable(),
|
||||||
Select::make('order_id')
|
Select::make('order_id')
|
||||||
|
->label('Order')
|
||||||
|
->required()
|
||||||
->options(fn ($get): array => Order::where('customer_id', $get('customer_id') ?? null)
|
->options(fn ($get): array => Order::where('customer_id', $get('customer_id') ?? null)
|
||||||
->get()
|
->get()
|
||||||
->pluck('customer_po', 'id')
|
->pluck('customer_po', 'id')
|
||||||
->toArray())
|
->toArray())
|
||||||
->searchable(),
|
->searchable(),
|
||||||
TextArea::make('contents'),
|
TextArea::make('contents'),
|
||||||
|
])
|
||||||
|
->columns(2),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,8 +69,10 @@ public static function table(Table $table): Table
|
|||||||
->color('code')
|
->color('code')
|
||||||
->sortable()
|
->sortable()
|
||||||
->searchable(),
|
->searchable(),
|
||||||
TextColumn::make('contents'),
|
TextColumn::make('contents')
|
||||||
TextColumn::make('amount'),
|
->extraHeaderAttributes(['class' => 'w-full']),
|
||||||
|
// TextColumn::make('amount')
|
||||||
|
// ->label('Quantity'),
|
||||||
TextColumn::make('order.customer.company_name')
|
TextColumn::make('order.customer.company_name')
|
||||||
->sortable()
|
->sortable()
|
||||||
->searchable(),
|
->searchable(),
|
||||||
|
@ -6,10 +6,10 @@
|
|||||||
use App\Models\Customer;
|
use App\Models\Customer;
|
||||||
use App\Models\Order;
|
use App\Models\Order;
|
||||||
use App\Models\Quote;
|
use App\Models\Quote;
|
||||||
|
use Filament\Forms\Components\RichEditor;
|
||||||
use Filament\Forms\Components\Section;
|
use Filament\Forms\Components\Section;
|
||||||
use Filament\Forms\Components\Select;
|
use Filament\Forms\Components\Select;
|
||||||
use Filament\Forms\Components\Split;
|
use Filament\Forms\Components\Split;
|
||||||
use Filament\Forms\Components\Textarea;
|
|
||||||
use Filament\Forms\Form;
|
use Filament\Forms\Form;
|
||||||
use Filament\Resources\Resource;
|
use Filament\Resources\Resource;
|
||||||
use Filament\Tables;
|
use Filament\Tables;
|
||||||
@ -47,9 +47,9 @@ public static function form(Form $form): Form
|
|||||||
->searchable(),
|
->searchable(),
|
||||||
|
|
||||||
])->columnSpan(2),
|
])->columnSpan(2),
|
||||||
Textarea::make('body')
|
RichEditor::make('body')
|
||||||
->columnSpan(2)
|
->columnSpan(2),
|
||||||
->rows(8),
|
// ->rows(8),
|
||||||
]),
|
]),
|
||||||
])->columns(3);
|
])->columns(3);
|
||||||
}
|
}
|
||||||
|
26
app/Http/Controllers/PdfController.php
Normal file
26
app/Http/Controllers/PdfController.php
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
@ -8,10 +8,11 @@
|
|||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
|
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
class Invoice extends Model
|
class Invoice extends Model
|
||||||
{
|
{
|
||||||
use HasFactory;
|
use HasFactory, SoftDeletes;
|
||||||
|
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
'customer_id',
|
'customer_id',
|
||||||
@ -41,7 +42,7 @@ public static function boot(): void
|
|||||||
parent::boot();
|
parent::boot();
|
||||||
|
|
||||||
static::created(function ($model) {
|
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();
|
$model->save();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -54,13 +55,13 @@ public function setStatus(InvoiceStatus $status)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function generateInternalId(int $id): string
|
// public function generateInternalId(int $id): string
|
||||||
{
|
// {
|
||||||
$po = str_pad(strval($id), 4, '0', STR_PAD_LEFT);
|
// $po = str_pad(strval($id), 4, '0', STR_PAD_LEFT);
|
||||||
$year = date('y');
|
// $year = date('y');
|
||||||
|
//
|
||||||
return 'TN-IN-'.$year.'-'.$po;
|
// return 'TN-IN-'.$year.'-'.$po;
|
||||||
}
|
// }
|
||||||
|
|
||||||
public function calculateTotals(): void
|
public function calculateTotals(): void
|
||||||
{
|
{
|
||||||
|
@ -2,11 +2,11 @@
|
|||||||
|
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
|
use App\Enums\InvoiceStatus;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
|
|
||||||
|
|
||||||
class InvoiceReport extends Model
|
class InvoiceReport extends Model
|
||||||
{
|
{
|
||||||
@ -21,19 +21,46 @@ class InvoiceReport extends Model
|
|||||||
'subtotal',
|
'subtotal',
|
||||||
'pst',
|
'pst',
|
||||||
'gst',
|
'gst',
|
||||||
|
];
|
||||||
|
|
||||||
|
protected $appends = [
|
||||||
'total',
|
'total',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
protected $casts = [
|
||||||
|
'date_start' => 'date',
|
||||||
|
'date_end' => 'date',
|
||||||
|
];
|
||||||
|
|
||||||
public static function boot(): void
|
public static function boot(): void
|
||||||
{
|
{
|
||||||
parent::boot();
|
parent::boot();
|
||||||
|
|
||||||
static::created(function ($model) {
|
static::created(function (InvoiceReport $model) {
|
||||||
$model->attributes['internal_id'] = 'TN-INR-'.$model->id;
|
|
||||||
|
// 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();
|
$model->save();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getTotalAttribute()
|
||||||
|
{
|
||||||
|
return $this->invoices()->sum('total');
|
||||||
|
}
|
||||||
|
|
||||||
public function customer(): BelongsTo
|
public function customer(): BelongsTo
|
||||||
{
|
{
|
||||||
return $this->belongsTo(Customer::class);
|
return $this->belongsTo(Customer::class);
|
||||||
@ -44,8 +71,8 @@ public function invoices(): BelongsToMany
|
|||||||
return $this->BelongsToMany(Invoice::class);
|
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');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,11 +29,6 @@ class ProductService extends Model
|
|||||||
'price',
|
'price',
|
||||||
];
|
];
|
||||||
|
|
||||||
// public function getServiceType(): string
|
|
||||||
// {
|
|
||||||
// return $this->serviceType->name ?? '';
|
|
||||||
// }
|
|
||||||
|
|
||||||
public function getPriceAttribute(): float
|
public function getPriceAttribute(): float
|
||||||
{
|
{
|
||||||
return number_format($this->amount * $this->amount_price, 2);
|
return number_format($this->amount * $this->amount_price, 2);
|
||||||
|
49
app/Observers/InvoiceObserver.php
Normal file
49
app/Observers/InvoiceObserver.php
Normal 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
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
58
app/Providers/Filament/CustomerPanelProvider.php
Normal file
58
app/Providers/Filament/CustomerPanelProvider.php
Normal 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,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
56
app/Providers/Filament/GuestPanelProvider.php
Normal file
56
app/Providers/Filament/GuestPanelProvider.php
Normal 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,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
@ -3,4 +3,6 @@
|
|||||||
return [
|
return [
|
||||||
App\Providers\AppServiceProvider::class,
|
App\Providers\AppServiceProvider::class,
|
||||||
App\Providers\Filament\AdminPanelProvider::class,
|
App\Providers\Filament\AdminPanelProvider::class,
|
||||||
|
App\Providers\Filament\CustomerPanelProvider::class,
|
||||||
|
App\Providers\Filament\GuestPanelProvider::class,
|
||||||
];
|
];
|
||||||
|
@ -17,11 +17,7 @@ public function definition(): array
|
|||||||
'customer_id' => Customer::all()->shuffle()->first()->id,
|
'customer_id' => Customer::all()->shuffle()->first()->id,
|
||||||
'date_start' => Carbon::now()->subYear(),
|
'date_start' => Carbon::now()->subYear(),
|
||||||
'date_end' => Carbon::now(),
|
'date_end' => Carbon::now(),
|
||||||
'filter_paid' => $this->faker->boolean(90),
|
'filter_paid' => $this->faker->boolean(40),
|
||||||
/* 'subtotal' => $this->faker->randomFloat(),
|
|
||||||
'pst' => $this->faker->randomFloat(),
|
|
||||||
'gst' => $this->faker->randomFloat(),
|
|
||||||
'total' => $this->faker->randomFloat(),*/
|
|
||||||
'created_at' => Carbon::now(),
|
'created_at' => Carbon::now(),
|
||||||
'updated_at' => Carbon::now(),
|
'updated_at' => Carbon::now(),
|
||||||
];
|
];
|
||||||
|
@ -25,6 +25,7 @@ public function up(): void
|
|||||||
$table->date('date')->default(today());
|
$table->date('date')->default(today());
|
||||||
$table->date('due_date')->nullable();
|
$table->date('due_date')->nullable();
|
||||||
|
|
||||||
|
$table->softDeletes();
|
||||||
$table->timestamps();
|
$table->timestamps();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ public function up(): void
|
|||||||
$table->float('subtotal', 2)->default(0);
|
$table->float('subtotal', 2)->default(0);
|
||||||
$table->float('pst', 2)->default(0);
|
$table->float('pst', 2)->default(0);
|
||||||
$table->float('gst', 2)->default(0);
|
$table->float('gst', 2)->default(0);
|
||||||
$table->float('total', 2)->default(0);
|
// $table->float('total', 2)->default(0);
|
||||||
|
|
||||||
$table->timestamps();
|
$table->timestamps();
|
||||||
});
|
});
|
||||||
|
@ -26,7 +26,5 @@ public function run(): void
|
|||||||
|
|
||||||
$invoice->calculateTotals();
|
$invoice->calculateTotals();
|
||||||
}
|
}
|
||||||
|
|
||||||
\Log::debug(Invoice::all());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
BIN
public/invoice-tn-in-24-0017.pdf
Normal file
BIN
public/invoice-tn-in-24-0017.pdf
Normal file
Binary file not shown.
BIN
public/invoice-tn40003.pdf
Normal file
BIN
public/invoice-tn40003.pdf
Normal file
Binary file not shown.
BIN
public/invoicereport-tn-inr-1.pdf
Normal file
BIN
public/invoicereport-tn-inr-1.pdf
Normal file
Binary file not shown.
BIN
public/invoicereport-tn-inr-3.pdf
Normal file
BIN
public/invoicereport-tn-inr-3.pdf
Normal file
Binary file not shown.
BIN
public/invoicereport-tn-inr-6.pdf
Normal file
BIN
public/invoicereport-tn-inr-6.pdf
Normal file
Binary file not shown.
BIN
public/invoicereport-tn40006.pdf
Normal file
BIN
public/invoicereport-tn40006.pdf
Normal file
Binary file not shown.
BIN
public/invoicereport-tnr0002.pdf
Normal file
BIN
public/invoicereport-tnr0002.pdf
Normal file
Binary file not shown.
BIN
public/invoicereport-tnr0005.pdf
Normal file
BIN
public/invoicereport-tnr0005.pdf
Normal file
Binary file not shown.
BIN
public/invoicereport-tnr0006.pdf
Normal file
BIN
public/invoicereport-tnr0006.pdf
Normal file
Binary file not shown.
BIN
public/invoicereport-tnr0007.pdf
Normal file
BIN
public/invoicereport-tnr0007.pdf
Normal file
Binary file not shown.
BIN
public/invoicereport-tnr0008.pdf
Normal file
BIN
public/invoicereport-tnr0008.pdf
Normal file
Binary file not shown.
BIN
public/order-tn24-0029.pdf
Normal file
BIN
public/order-tn24-0029.pdf
Normal file
Binary file not shown.
BIN
public/order-tn24-0093.pdf
Normal file
BIN
public/order-tn24-0093.pdf
Normal file
Binary file not shown.
BIN
public/order-tn24-0132.pdf
Normal file
BIN
public/order-tn24-0132.pdf
Normal file
Binary file not shown.
BIN
public/order-tn24-0179.pdf
Normal file
BIN
public/order-tn24-0179.pdf
Normal file
Binary file not shown.
BIN
public/order-tn24-0202.pdf
Normal file
BIN
public/order-tn24-0202.pdf
Normal file
Binary file not shown.
@ -0,0 +1,5 @@
|
|||||||
|
<x-filament-panels::page>
|
||||||
|
|
||||||
|
{{ $this->form }}
|
||||||
|
|
||||||
|
</x-filament-panels::page>
|
@ -0,0 +1,3 @@
|
|||||||
|
<x-filament-panels::page>
|
||||||
|
{{ $this->form }}
|
||||||
|
</x-filament-panels::page>
|
@ -0,0 +1,3 @@
|
|||||||
|
<x-filament-panels::page>
|
||||||
|
{{ $this->form }}
|
||||||
|
</x-filament-panels::page>
|
3
resources/views/filament/guest/pages/home.blade.php
Normal file
3
resources/views/filament/guest/pages/home.blade.php
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<x-filament-panels::page>
|
||||||
|
{{ $this->form }}
|
||||||
|
</x-filament-panels::page>
|
3
resources/views/filament/guest/pages/vinyl.blade.php
Normal file
3
resources/views/filament/guest/pages/vinyl.blade.php
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<x-filament-panels::page>
|
||||||
|
{{ $this->form }}
|
||||||
|
</x-filament-panels::page>
|
10
resources/views/pdf/invoice-report-footer.blade.php
Normal file
10
resources/views/pdf/invoice-report-footer.blade.php
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<style>
|
||||||
|
* {
|
||||||
|
font-size: 12px;
|
||||||
|
margin: 10px 5px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<footer>
|
||||||
|
{{$invoiceReport->internal_id}}, page @pageNumber of @totalPages
|
||||||
|
</footer>'
|
106
resources/views/pdf/invoice-report.blade.php
Normal file
106
resources/views/pdf/invoice-report.blade.php
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
@extends('layouts.pdf')
|
||||||
|
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="container-fluid pt-4 font-serif" style="">
|
||||||
|
|
||||||
|
<div class="fw-bold">
|
||||||
|
TOP NOTCH EMBROIDERY & DIGITIZING LTD.
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
108-618 EAST KENT AVE. SOUTH <br>
|
||||||
|
VANCOUVER BC <br>
|
||||||
|
(604) 871-9991 <br>
|
||||||
|
info@sewtopnotch.com <br>
|
||||||
|
GST# 846025062RT0001 <br>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="fs-3 fw-bold text-primary mt-2">
|
||||||
|
INVOICE STATEMENT
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="d-flex flex-row">
|
||||||
|
<div class="me-auto">
|
||||||
|
<div class="fw-bold">
|
||||||
|
BILL TO
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{{$invoiceReport->customer->company_name}} <br>
|
||||||
|
{{$invoiceReport->customer->billing_address_line_1}} <br>
|
||||||
|
{{$invoiceReport->customer->billing_address_line_2}} <br>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="text-end pe-2">
|
||||||
|
<div class="fw-bold">
|
||||||
|
INVOICE REPORT #
|
||||||
|
</div>
|
||||||
|
<div class="fw-bold">
|
||||||
|
DATE
|
||||||
|
</div>
|
||||||
|
<div class="fw-bold">
|
||||||
|
DATE FROM
|
||||||
|
</div>
|
||||||
|
<div class="fw-bold">
|
||||||
|
DATE TO
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
<div class="fw-bold">
|
||||||
|
TOTAL BALANCE DUE
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<div>
|
||||||
|
{{$invoiceReport->internal_id}}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{{Date::make($invoiceReport->created_at)->format('Y-m-d')}}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{{$invoiceReport->date_start->format('Y-m-d')}}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{{$invoiceReport->date_end->format('Y-m-d')}}
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
<div>
|
||||||
|
${{number_format($invoiceReport->total, 2)}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
|
||||||
|
<table class="table table-sm table-striped">
|
||||||
|
<tr>
|
||||||
|
<th>Date</th>
|
||||||
|
<th>Invoice</th>
|
||||||
|
<th class="text-end">Subtotal</th>
|
||||||
|
<th class="text-end">GST</th>
|
||||||
|
<th class="text-end">PST</th>
|
||||||
|
<th class="text-end">Balance</th>
|
||||||
|
<th class="text-end">Status</th>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
@foreach($invoiceReport->invoices->sortBy('id') as $invoice)
|
||||||
|
<tr>
|
||||||
|
<td>{{Date::make($invoice->created_at)->format('Y-m-d')}}</td>
|
||||||
|
<td>{{$invoice->internal_id}}</td>
|
||||||
|
<td class="text-end">${{$invoice->subtotal}}</td>
|
||||||
|
<td class="text-end">${{number_format($invoice->gst_amount, 2)}}</td>
|
||||||
|
<td class="text-end">{{!$invoice->pst_amount ? '-' : '$'.number_format($invoice->pst_amount, 2)}}</td>
|
||||||
|
<td class="text-end">${{$invoice->total}}</td>
|
||||||
|
<td class="text-end">{{$invoice->status->value}}</td>
|
||||||
|
</tr>
|
||||||
|
@endforeach
|
||||||
|
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
@ -70,10 +70,11 @@
|
|||||||
<th>RATE</th>
|
<th>RATE</th>
|
||||||
<th>AMOUNT</th>
|
<th>AMOUNT</th>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
@foreach($invoice->productServices as $service)
|
@foreach($invoice->productServices as $service)
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td class="text-nowrap">
|
||||||
<span style="font-size: 0.9rem">
|
<span style="font-size: 0.8rem">
|
||||||
{{$service->order->internal_po}}
|
{{$service->order->internal_po}}
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
|
@ -108,8 +108,9 @@
|
|||||||
<div class="fs-6">
|
<div class="fs-6">
|
||||||
PO#
|
PO#
|
||||||
</div>
|
</div>
|
||||||
<div class="fs-6 text-info">
|
<div class="fs-6 text-primary">
|
||||||
{{$order->customer_po}}
|
{{$order->customer_po}}
|
||||||
|
@if($order->pre_production)<span class="text-danger"> (pre-pro)</span>@endif()
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -118,7 +119,7 @@
|
|||||||
<div class="d-inline-flex gap-2">
|
<div class="d-inline-flex gap-2">
|
||||||
<div class="h-auto">
|
<div class="h-auto">
|
||||||
<div class="border border-1 border-opacity-50 mt-1">
|
<div class="border border-1 border-opacity-50 mt-1">
|
||||||
<div class="@if(!$order->purchased_garments) opacity-0 @endif">
|
<div class="@if(!$order->garments) opacity-0 @endif">
|
||||||
<x-bi-check/>
|
<x-bi-check/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -170,14 +171,16 @@
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mt-3 text-end" style="font-size: 11px">
|
<div class="row mt-3 text-end" style="font-size: 12px">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
TOTAL QUANTITY: {{$order->totalProductQuantity}}
|
TOTAL QUANTITY: {{$order->totalProductQuantity}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
<!-- Services Table -->
|
<!-- Services Table -->
|
||||||
<div class="row mt-3">
|
<div class="row mt-2">
|
||||||
<table class="table table-striped" style="font-size: 11px;">
|
<table class="table table-striped" style="font-size: 11px;">
|
||||||
<thead class="opacity-50 fw-normal">
|
<thead class="opacity-50 fw-normal">
|
||||||
<th>Placement & Service</th>
|
<th>Placement & Service</th>
|
||||||
@ -227,6 +230,8 @@
|
|||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
<div class="row mt-3">
|
<div class="row mt-3">
|
||||||
{{$order->notes}}
|
{{$order->notes}}
|
||||||
</div>
|
</div>
|
||||||
|
@ -8,33 +8,26 @@
|
|||||||
use App\Http\Controllers\OrderController;
|
use App\Http\Controllers\OrderController;
|
||||||
use App\Http\Controllers\OrderProductController;
|
use App\Http\Controllers\OrderProductController;
|
||||||
use App\Http\Controllers\PackingSlipController;
|
use App\Http\Controllers\PackingSlipController;
|
||||||
|
use App\Http\Controllers\PdfController;
|
||||||
use App\Http\Controllers\ShippingEntryController;
|
use App\Http\Controllers\ShippingEntryController;
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
|
|
||||||
Route::get('/', function () {
|
//Route::get('/', function () {
|
||||||
return redirect()->route('dashboard');
|
// return redirect()->route('dashboard');
|
||||||
});
|
//});
|
||||||
|
//
|
||||||
|
//Auth::routes();
|
||||||
|
|
||||||
Auth::routes();
|
Route::get('/pdf/invoicereport/{id}', [PdfController::class, 'invoiceReport'])->name('pdf.invoice-report');
|
||||||
|
|
||||||
Route::get('/dashboard', [DashboardController::class, 'index'])->name('dashboard');
|
|
||||||
|
|
||||||
Route::get('/management/{tab?}', [ManagementController::class, 'index'])->name('management.index');
|
|
||||||
|
|
||||||
// OrderProducts
|
|
||||||
Route::resource('order-products', OrderProductController::class);
|
|
||||||
|
|
||||||
// Contacts
|
|
||||||
Route::resource('contacts', ContactController::class);
|
|
||||||
Route::post('/contacts/request-destroy', [ContactController::class, 'requestDestroy'])->name('contacts.requestDestroy');
|
|
||||||
|
|
||||||
Route::resource('packing-slips', PackingSlipController::class);
|
|
||||||
|
|
||||||
Route::resource('shipping-entries', ShippingEntryController::class);
|
|
||||||
|
|
||||||
Route::resource('orders', OrderController::class);
|
|
||||||
Route::get('orders/{order}/pdf', [OrderController::class, 'pdf'])->name('orders.pdf');
|
Route::get('orders/{order}/pdf', [OrderController::class, 'pdf'])->name('orders.pdf');
|
||||||
|
|
||||||
Route::get('invoices/{invoice}/pdf', [InvoiceController::class, 'pdf'])->name('invoice.pdf');
|
Route::get('invoices/{invoice}/pdf', [InvoiceController::class, 'pdf'])->name('invoice.pdf');
|
||||||
|
|
||||||
Route::get('customers/{customer}/pdf', [CustomerController::class, 'pdf'])->name('customer.pdf');
|
Route::get('customers/{customer}/pdf', [CustomerController::class, 'pdf'])->name('customer.pdf');
|
||||||
|
|
||||||
|
//Route::get('/dashboard', [DashboardController::class, 'index'])->name('dashboard');
|
||||||
|
//Route::get('/management/{tab?}', [ManagementController::class, 'index'])->name('management.index');
|
||||||
|
//Route::resource('order-products', OrderProductController::class);
|
||||||
|
//Route::resource('contacts', ContactController::class);
|
||||||
|
//Route::post('/contacts/request-destroy', [ContactController::class, 'requestDestroy'])->name('contacts.requestDestroy');
|
||||||
|
//Route::resource('packing-slips', PackingSlipController::class);
|
||||||
|
//Route::resource('shipping-entries', ShippingEntryController::class);
|
||||||
|
//Route::resource('orders', OrderController::class);
|
||||||
|
107
todos
107
todos
@ -1,40 +1,99 @@
|
|||||||
todo
|
todo
|
||||||
Invoice Report
|
|
||||||
--------------
|
Customer panel
|
||||||
Model ?customer > table
|
-----------
|
||||||
|
Make login stuff
|
||||||
|
Set query to use logged in customer
|
||||||
|
Disable edit
|
||||||
|
Make view page
|
||||||
|
|
||||||
|
Orders
|
||||||
|
-------
|
||||||
|
- Validation
|
||||||
|
- Tabs for quotes, invoices, packingSlips?
|
||||||
|
- Duplicate in order?
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Quotes
|
Quotes
|
||||||
------
|
------
|
||||||
- Add date?
|
- Add date?
|
||||||
|
|
||||||
Orders
|
Customer report
|
||||||
-------
|
----------------
|
||||||
- Fix service type
|
- Save to PDF
|
||||||
- PDF pre-pro property
|
|
||||||
- Change order status from table > do thru checkboxes?
|
|
||||||
- Tabs for quotes, invoices, packingSlips?
|
|
||||||
- Fix total order price
|
|
||||||
- Duplicate to new order
|
|
||||||
|
|
||||||
Shipping Entries
|
Invoices
|
||||||
-----------------
|
--------
|
||||||
- Clickable URL in title
|
Due date doesn't update?
|
||||||
|
Total doesn't update after dis/enabling pst or gst
|
||||||
|
|
||||||
Others
|
Others
|
||||||
-------
|
-------
|
||||||
- ServiceFile findOrCreate
|
- Change price calculations to round to two
|
||||||
- Way to set GST and PST
|
|
||||||
- Remove service_type from ProductService?
|
|
||||||
- order pdfs checkboxes don't tick no more
|
|
||||||
- duplicate order button (edit page header)
|
|
||||||
- badge for invoices
|
|
||||||
|
|
||||||
|
|
||||||
- finish invoice styling
|
|
||||||
- add to invoice button on order page
|
|
||||||
- customer name to invoice title / filename
|
- customer name to invoice title / filename
|
||||||
|
- ability to change PST / GST amounts
|
||||||
|
- ability to change office address (see below)
|
||||||
|
- dynamically get office address in invoice / invoice reports (add top notch as customer?)
|
||||||
|
|
||||||
|
Potentials
|
||||||
|
-----------
|
||||||
|
- ServiceFile findOrCreate?
|
||||||
|
- add to invoice button on order page?
|
||||||
|
- Save and close buttons at header (orders)
|
||||||
|
|
||||||
|
|
||||||
renamings:
|
renamings:
|
||||||
- order->total_service_price => subtotal
|
- order->total_service_price => subtotal
|
||||||
- amount > quantity
|
- amount > quantity
|
||||||
- amount_price > amount
|
- amount_price > amount
|
||||||
|
|
||||||
|
|
||||||
|
Discuss w/ James
|
||||||
|
-----------------
|
||||||
|
- Customer address system improvement (multiple addresses per customer instead of customer entry per address?)
|
||||||
|
- Global search?
|
||||||
|
- GST / PST edits? > yes, set global amount
|
||||||
|
- Advanced shipping match system
|
||||||
|
- Automatic BeUltimate orders
|
||||||
|
|
||||||
|
Oplevering
|
||||||
|
-----------
|
||||||
|
orders:
|
||||||
|
- Remove customer name from print form
|
||||||
|
- Go to new order when click replicate
|
||||||
|
- Add order to invoice
|
||||||
|
-
|
||||||
|
|
||||||
|
Invoices:
|
||||||
|
- Admin permissions
|
||||||
|
-
|
||||||
|
|
||||||
|
Invoice
|
||||||
|
- Enter payment amount & link to invoice(s)
|
||||||
|
- Calculate total of all selected invoices
|
||||||
|
- Invoices partial payment
|
||||||
|
- Balance due (what they need to pay)
|
||||||
|
- Balance (per customer)
|
||||||
|
- Partially paid invoice = not paid, registered in balance instead
|
||||||
|
- Filter paid should only show "not paid"
|
||||||
|
|
||||||
|
Customer Reports
|
||||||
|
-----------------
|
||||||
|
Subtotal/totals for all customers combined
|
||||||
|
|
||||||
|
Quote
|
||||||
|
-----
|
||||||
|
- Logo, quantity, run charge, emb / digitizing, screen printing
|
||||||
|
|
||||||
|
Packing slips
|
||||||
|
--------------
|
||||||
|
Amount default value
|
||||||
|
|
||||||
|
|
||||||
|
Customer Site
|
||||||
|
--------------
|
||||||
|
Get rid of New order button
|
||||||
|
|
||||||
|
Public site
|
||||||
|
-----------
|
||||||
|
Loading…
x
Reference in New Issue
Block a user