#102 Create 'Ready for invoicing'-status, and associated ways to create invoices from bulk orders
This commit is contained in:
parent
779d46d708
commit
dddbbb8f9b
@ -51,6 +51,7 @@ enum IconEnum: string
|
|||||||
case APPROVED = 'lucide-check-check';
|
case APPROVED = 'lucide-check-check';
|
||||||
case PRODUCTION = 'lucide-refresh-cw';
|
case PRODUCTION = 'lucide-refresh-cw';
|
||||||
case SHIPPED = 'lucide-send';
|
case SHIPPED = 'lucide-send';
|
||||||
|
case INVOICING = 'lucide-calendar';
|
||||||
case INVOICED = 'lucide-credit-card';
|
case INVOICED = 'lucide-credit-card';
|
||||||
|
|
||||||
// Shipping Types (THEY_SHIP => SHIPPING_ENTRY)
|
// Shipping Types (THEY_SHIP => SHIPPING_ENTRY)
|
||||||
|
@ -8,11 +8,12 @@
|
|||||||
|
|
||||||
enum OrderStatus: string implements HasColor, HasIcon, HasLabel
|
enum OrderStatus: string implements HasColor, HasIcon, HasLabel
|
||||||
{
|
{
|
||||||
case DRAFT = 'Draft';
|
case DRAFT = 'Draft';
|
||||||
case APPROVED = 'Approved';
|
case APPROVED = 'Approved';
|
||||||
case PRODUCTION = 'Production';
|
case PRODUCTION = 'Production';
|
||||||
case SHIPPED = 'Shipped';
|
case SHIPPED = 'Shipped';
|
||||||
case INVOICED = 'Invoiced';
|
case READY_FOR_INVOICE = 'Ready for Invoice';
|
||||||
|
case INVOICED = 'Invoiced';
|
||||||
|
|
||||||
public function getLabel(): ?string
|
public function getLabel(): ?string
|
||||||
{
|
{
|
||||||
@ -22,22 +23,24 @@ public function getLabel(): ?string
|
|||||||
public function getColor(): string|array|null
|
public function getColor(): string|array|null
|
||||||
{
|
{
|
||||||
return match ($this) {
|
return match ($this) {
|
||||||
self::DRAFT => 'gray',
|
self::DRAFT => 'gray',
|
||||||
self::APPROVED => 'success',
|
self::APPROVED => 'success',
|
||||||
self::PRODUCTION => 'primary',
|
self::PRODUCTION => 'primary',
|
||||||
self::SHIPPED => 'warning',
|
self::SHIPPED => 'warning',
|
||||||
self::INVOICED => 'invoiced',
|
self::READY_FOR_INVOICE => 'invoicing',
|
||||||
|
self::INVOICED => 'invoiced',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getIcon(): ?string
|
public function getIcon(): ?string
|
||||||
{
|
{
|
||||||
return match ($this) {
|
return match ($this) {
|
||||||
self::DRAFT => IconEnum::DRAFT->value,
|
self::DRAFT => IconEnum::DRAFT->value,
|
||||||
self::APPROVED => IconEnum::APPROVED->value,
|
self::APPROVED => IconEnum::APPROVED->value,
|
||||||
self::PRODUCTION => IconEnum::PRODUCTION->value,
|
self::PRODUCTION => IconEnum::PRODUCTION->value,
|
||||||
self::SHIPPED => IconEnum::SHIPPED->value,
|
self::SHIPPED => IconEnum::SHIPPED->value,
|
||||||
self::INVOICED => IconEnum::INVOICED->value,
|
self::READY_FOR_INVOICE => IconEnum::INVOICING->value,
|
||||||
|
self::INVOICED => IconEnum::INVOICED->value,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,10 @@ public function getTabs(): array
|
|||||||
->query(fn ($query) => $query->where('status', InvoiceStatus::UNPAID))
|
->query(fn ($query) => $query->where('status', InvoiceStatus::UNPAID))
|
||||||
->icon(InvoiceStatus::UNPAID->getIcon()),
|
->icon(InvoiceStatus::UNPAID->getIcon()),
|
||||||
|
|
||||||
|
'partially_paid' => Tab::make('Partially Paid')
|
||||||
|
->query(fn ($query) => $query->where('status', InvoiceStatus::PARTIALLY_PAID))
|
||||||
|
->icon(InvoiceStatus::PARTIALLY_PAID->getIcon()),
|
||||||
|
|
||||||
'paid' => Tab::make('Paid')
|
'paid' => Tab::make('Paid')
|
||||||
->query(fn ($query) => $query->where('status', InvoiceStatus::PAID))
|
->query(fn ($query) => $query->where('status', InvoiceStatus::PAID))
|
||||||
->icon(InvoiceStatus::PAID->getIcon()),
|
->icon(InvoiceStatus::PAID->getIcon()),
|
||||||
|
@ -3,10 +3,12 @@
|
|||||||
namespace App\Filament\Admin\Resources;
|
namespace App\Filament\Admin\Resources;
|
||||||
|
|
||||||
use App\Enums\IconEnum;
|
use App\Enums\IconEnum;
|
||||||
|
use App\Enums\InvoiceStatus;
|
||||||
use App\Enums\OrderAttributes;
|
use App\Enums\OrderAttributes;
|
||||||
use App\Enums\OrderStatus;
|
use App\Enums\OrderStatus;
|
||||||
use App\Enums\OrderType;
|
use App\Enums\OrderType;
|
||||||
use App\Models\Customer;
|
use App\Models\Customer;
|
||||||
|
use App\Models\Invoice;
|
||||||
use App\Models\Order;
|
use App\Models\Order;
|
||||||
use App\Models\OrderProduct;
|
use App\Models\OrderProduct;
|
||||||
use App\Models\ProductService;
|
use App\Models\ProductService;
|
||||||
@ -28,6 +30,8 @@
|
|||||||
use Filament\Resources\Resource;
|
use Filament\Resources\Resource;
|
||||||
use Filament\Support\Enums\MaxWidth;
|
use Filament\Support\Enums\MaxWidth;
|
||||||
use Filament\Tables;
|
use Filament\Tables;
|
||||||
|
use Filament\Tables\Actions\BulkAction;
|
||||||
|
use Filament\Tables\Actions\BulkActionGroup;
|
||||||
use Filament\Tables\Columns\IconColumn\IconColumnSize;
|
use Filament\Tables\Columns\IconColumn\IconColumnSize;
|
||||||
use Filament\Tables\Columns\TextColumn;
|
use Filament\Tables\Columns\TextColumn;
|
||||||
use Filament\Tables\Table;
|
use Filament\Tables\Table;
|
||||||
@ -202,13 +206,13 @@ public static function form(Form $form): Form
|
|||||||
->createOptionUsing(function (array $data): int {
|
->createOptionUsing(function (array $data): int {
|
||||||
return ServiceType::create($data)->getKey();
|
return ServiceType::create($data)->getKey();
|
||||||
}),
|
}),
|
||||||
TextInput::make('placement')
|
|
||||||
->datalist(ProductService::all()->unique('placement')->pluck('placement')->toArray())
|
|
||||||
->columnSpan(3),
|
|
||||||
TextInput::make('serviceFileName')
|
TextInput::make('serviceFileName')
|
||||||
->datalist(ServiceFile::all()->unique('name')->pluck('name')->toArray())
|
->datalist(ServiceFile::all()->unique('name')->pluck('name')->toArray())
|
||||||
->columnSpan(3)
|
->columnSpan(3)
|
||||||
->label('Logo Name'),
|
->label('Logo Name'),
|
||||||
|
TextInput::make('placement')
|
||||||
|
->datalist(ProductService::all()->unique('placement')->pluck('placement')->toArray())
|
||||||
|
->columnSpan(3),
|
||||||
TextInput::make('serviceFileSetupNumber')
|
TextInput::make('serviceFileSetupNumber')
|
||||||
->label('Setup')
|
->label('Setup')
|
||||||
->columnSpan(1)
|
->columnSpan(1)
|
||||||
@ -343,7 +347,6 @@ public static function table(Table $table): Table
|
|||||||
Tables\Actions\EditAction::make(),
|
Tables\Actions\EditAction::make(),
|
||||||
])
|
])
|
||||||
->bulkActions([
|
->bulkActions([
|
||||||
|
|
||||||
Tables\Actions\BulkAction::make('updateStatus')
|
Tables\Actions\BulkAction::make('updateStatus')
|
||||||
->form([
|
->form([
|
||||||
Select::make('status')
|
Select::make('status')
|
||||||
@ -366,9 +369,92 @@ public static function table(Table $table): Table
|
|||||||
->color('info')
|
->color('info')
|
||||||
->deselectRecordsAfterCompletion(),
|
->deselectRecordsAfterCompletion(),
|
||||||
|
|
||||||
Tables\Actions\BulkActionGroup::make([
|
BulkActionGroup::make([
|
||||||
|
BulkAction::make('Create individual invoices')
|
||||||
|
->icon(IconEnum::INVOICE->value)
|
||||||
|
->action(function (Collection $records): void {
|
||||||
|
[$invoiced, $toInvoice] = $records->partition(fn ($record) => $record->invoice);
|
||||||
|
|
||||||
|
$toInvoice->each(function ($record) {
|
||||||
|
$invoice = Invoice::create([
|
||||||
|
'customer_id' => $record->customer->id,
|
||||||
|
'date' => today(),
|
||||||
|
'status' => InvoiceStatus::UNPAID->value,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$invoice->orders()->save($record);
|
||||||
|
$invoice->calculateTotals();
|
||||||
|
$record->update(['status' => OrderStatus::INVOICED->value]);
|
||||||
|
});
|
||||||
|
|
||||||
|
if ($invoiced->isNotEmpty()) {
|
||||||
|
Notification::make()
|
||||||
|
->title("{$invoiced->count()} orders are already invoiced")
|
||||||
|
->warning()
|
||||||
|
->send();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($toInvoice->isNotEmpty()) {
|
||||||
|
Notification::make()
|
||||||
|
->title("Successfully created {$toInvoice->count()} invoice(s)")
|
||||||
|
->success()
|
||||||
|
->send();
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
|
||||||
|
BulkAction::make('Add all to new invoice')
|
||||||
|
->icon(IconEnum::REPEAT->value)
|
||||||
|
->action(function (Collection $records): void {
|
||||||
|
if ($records->pluck('customer_id')->unique()->count() !== 1) {
|
||||||
|
Notification::make()
|
||||||
|
->title('Invalid order combination')
|
||||||
|
->body('Make sure all orders are from the same customer')
|
||||||
|
->danger()
|
||||||
|
->send();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
[$invoiced, $validOrders] = $records->partition(fn ($record) => $record->invoice);
|
||||||
|
|
||||||
|
if ($validOrders->isNotEmpty()) {
|
||||||
|
$invoice = Invoice::create([
|
||||||
|
'customer_id' => $records->first()->customer_id,
|
||||||
|
'date' => today(),
|
||||||
|
'status' => InvoiceStatus::UNPAID->value,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$invoice->orders()->saveMany($validOrders);
|
||||||
|
$invoice->calculateTotals(); // FIXME: Investigate why this is needed.
|
||||||
|
|
||||||
|
Order::whereIn('id', $validOrders->pluck('id'))->update([
|
||||||
|
'status' => OrderStatus::INVOICED->value,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($invoiced->isNotEmpty()) {
|
||||||
|
Notification::make()
|
||||||
|
->title('Some orders are already invoiced')
|
||||||
|
->body("{$invoiced->count()} orders are already invoiced and will not be added")
|
||||||
|
->warning()
|
||||||
|
->send();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($validOrders->isNotEmpty()) {
|
||||||
|
Notification::make()
|
||||||
|
->title('Invoice created')
|
||||||
|
->body("{$validOrders->count()} orders have been added to this invoice")
|
||||||
|
->success()
|
||||||
|
->send();
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
->label('Invoicing')
|
||||||
|
->hidden(fn () => ! auth()->user()->is_admin),
|
||||||
|
|
||||||
|
BulkActionGroup::make([
|
||||||
Tables\Actions\DeleteBulkAction::make(),
|
Tables\Actions\DeleteBulkAction::make(),
|
||||||
]),
|
])->label('Other actions'),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,6 +15,25 @@ class ListOrders extends ListRecords
|
|||||||
{
|
{
|
||||||
protected static string $resource = OrderResource::class;
|
protected static string $resource = OrderResource::class;
|
||||||
|
|
||||||
|
private function excludeStatuses($query): mixed
|
||||||
|
{
|
||||||
|
return $query
|
||||||
|
->whereNot('status', OrderStatus::READY_FOR_INVOICE)
|
||||||
|
->whereNot('status', OrderStatus::INVOICED)
|
||||||
|
->whereNot('status', OrderStatus::SHIPPED);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getBadgeCount(callable $queryCallback): ?int
|
||||||
|
{
|
||||||
|
$count = Order::query()->when(true, $queryCallback)
|
||||||
|
->whereNot('status', OrderStatus::READY_FOR_INVOICE)
|
||||||
|
->whereNot('status', OrderStatus::INVOICED)
|
||||||
|
->whereNot('status', OrderStatus::SHIPPED)
|
||||||
|
->count();
|
||||||
|
|
||||||
|
return $count > 0 ? $count : null;
|
||||||
|
}
|
||||||
|
|
||||||
protected function getHeaderActions(): array
|
protected function getHeaderActions(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
@ -26,67 +45,37 @@ protected function getHeaderActions(): array
|
|||||||
public function getTabs(): array
|
public function getTabs(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
|
'all' => Tab::make('All')
|
||||||
|
->icon(IconEnum::TAB_ALL->value),
|
||||||
|
|
||||||
'active' => Tab::make()
|
'active' => Tab::make()
|
||||||
->query(function ($query) {
|
->query(fn ($query) => $this->excludeStatuses($query))
|
||||||
return $query
|
|
||||||
->whereNot('status', OrderStatus::INVOICED)
|
|
||||||
->whereNot('status', ORderStatus::SHIPPED);
|
|
||||||
})
|
|
||||||
->icon(OrderStatus::PRODUCTION->getIcon())
|
->icon(OrderStatus::PRODUCTION->getIcon())
|
||||||
->badge(function () {
|
->badge(fn () => $this->getBadgeCount(fn ($query) => $this->excludeStatuses($query))),
|
||||||
return Order::whereNot('status', OrderStatus::SHIPPED)
|
|
||||||
->whereNot('status', OrderStatus::INVOICED)
|
|
||||||
->count();
|
|
||||||
}),
|
|
||||||
|
|
||||||
'unprinted' => Tab::make()
|
'unprinted' => Tab::make()
|
||||||
->query(function ($query) {
|
->query(fn ($query) => $this->excludeStatuses($query)->where('printed', false))
|
||||||
return $query->where('printed', false);
|
|
||||||
})
|
|
||||||
->icon(IconEnum::PRINT->value)
|
->icon(IconEnum::PRINT->value)
|
||||||
->badge(function () {
|
->badge(fn () => $this->getBadgeCount(fn ($query) => $query->where('printed', false)))
|
||||||
$count = Order::where('printed', false)->count();
|
|
||||||
|
|
||||||
return $count > 0 ? $count : null;
|
|
||||||
})
|
|
||||||
->badgeColor('success'),
|
->badgeColor('success'),
|
||||||
|
|
||||||
'overdue' => Tab::make()
|
'overdue' => Tab::make()
|
||||||
->query(function ($query) {
|
->query(fn ($query) => $this->excludeStatuses($query)->whereDate('due_date', '<=', today()))
|
||||||
return $query->whereDate('due_date', '<=', today())
|
|
||||||
->whereNot('status', OrderStatus::INVOICED)
|
|
||||||
->whereNot('status', ORderStatus::SHIPPED);
|
|
||||||
})
|
|
||||||
->icon(IconEnum::TAB_OVERDUE->value)
|
->icon(IconEnum::TAB_OVERDUE->value)
|
||||||
->badge(function () {
|
->badge(fn () => $this->getBadgeCount(fn ($query) => $query->whereDate('due_date', '<=', today())))
|
||||||
$count = Order::whereDate('due_date', '<=', today())
|
|
||||||
->whereNot('status', OrderStatus::INVOICED)
|
|
||||||
->whereNot('status', ORderStatus::SHIPPED)
|
|
||||||
->count();
|
|
||||||
|
|
||||||
return $count > 0 ? $count : null;
|
|
||||||
})
|
|
||||||
->badgeColor('danger'),
|
->badgeColor('danger'),
|
||||||
|
|
||||||
'rush' => Tab::make()
|
'rush' => Tab::make()
|
||||||
->query(function ($query) {
|
->query(fn ($query) => $this->excludeStatuses($query)->where('rush', true))
|
||||||
return $query->where('rush', true)
|
|
||||||
->whereNot('status', OrderStatus::INVOICED)
|
|
||||||
->whereNot('status', OrderStatus::SHIPPED);
|
|
||||||
})
|
|
||||||
->icon(OrderAttributes::rush->getIcon())
|
->icon(OrderAttributes::rush->getIcon())
|
||||||
->badge(function () {
|
->badge(fn () => $this->getBadgeCount(fn ($query) => $query->where('rush', true)))
|
||||||
$count = Order::where('rush', true)
|
|
||||||
->whereNot('status', OrderStatus::INVOICED)
|
|
||||||
->whereNot('status', OrderStatus::SHIPPED)
|
|
||||||
->count();
|
|
||||||
|
|
||||||
return $count > 0 ? $count : null;
|
|
||||||
})
|
|
||||||
->badgeColor('warning'),
|
->badgeColor('warning'),
|
||||||
|
|
||||||
'all' => Tab::make('All')
|
'ready_for_invoice' => Tab::make()
|
||||||
->icon(IconEnum::TAB_ALL->value),
|
->query(fn ($query) => $query->where('status', OrderStatus::READY_FOR_INVOICE))
|
||||||
|
->icon(OrderStatus::READY_FOR_INVOICE->getIcon())
|
||||||
|
->badge(fn () => $this->getBadgeCount(fn ($query) => $query->where('status', OrderStatus::READY_FOR_INVOICE)))
|
||||||
|
->badgeColor(OrderStatus::READY_FOR_INVOICE->getColor()),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,8 @@ class ActiveOrdersTable extends BaseWidget
|
|||||||
{
|
{
|
||||||
protected static ?int $sort = 2;
|
protected static ?int $sort = 2;
|
||||||
|
|
||||||
|
protected string|int|array $columnSpan = 2;
|
||||||
|
|
||||||
public function table(Table $table): Table
|
public function table(Table $table): Table
|
||||||
{
|
{
|
||||||
return $table
|
return $table
|
||||||
|
@ -10,6 +10,8 @@
|
|||||||
|
|
||||||
class RushOrdersTable extends BaseWidget
|
class RushOrdersTable extends BaseWidget
|
||||||
{
|
{
|
||||||
|
protected string|int|array $columnSpan = 2;
|
||||||
|
|
||||||
public function table(Table $table): Table
|
public function table(Table $table): Table
|
||||||
{
|
{
|
||||||
return $table
|
return $table
|
||||||
|
@ -12,7 +12,7 @@ class OrderObserver
|
|||||||
*/
|
*/
|
||||||
public function created(Order $order): void
|
public function created(Order $order): void
|
||||||
{
|
{
|
||||||
if ($order->invoice()->exists()) {
|
if ($order->invoice != null) {
|
||||||
$order->invoice->calculateTotals();
|
$order->invoice->calculateTotals();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -22,7 +22,7 @@ public function created(Order $order): void
|
|||||||
*/
|
*/
|
||||||
public function updated(Order $order): void
|
public function updated(Order $order): void
|
||||||
{
|
{
|
||||||
if ($order->invoice()->exists()) {
|
if ($order->invoice != null) {
|
||||||
$order->invoice->calculateTotals();
|
$order->invoice->calculateTotals();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -33,7 +33,9 @@ public function updated(Order $order): void
|
|||||||
public function saved(Order $order): void
|
public function saved(Order $order): void
|
||||||
{
|
{
|
||||||
if ($order->isDirty(['invoice_id']) && Invoice::where('id', $order->invoice_id)->exists()) {
|
if ($order->isDirty(['invoice_id']) && Invoice::where('id', $order->invoice_id)->exists()) {
|
||||||
$order->invoice->calculateTotals();
|
if ($order->invoice != null) {
|
||||||
|
$order->invoice->calculateTotals();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,7 +44,7 @@ public function saved(Order $order): void
|
|||||||
*/
|
*/
|
||||||
public function deleted(Order $order): void
|
public function deleted(Order $order): void
|
||||||
{
|
{
|
||||||
if ($order->invoice()->exists()) {
|
if ($order->invoice != null) {
|
||||||
$order->invoice->calculateTotals();
|
$order->invoice->calculateTotals();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,9 +29,10 @@ public function panel(Panel $panel): Panel
|
|||||||
->path('admin')
|
->path('admin')
|
||||||
->login(UsernameLogin::class)
|
->login(UsernameLogin::class)
|
||||||
->colors([
|
->colors([
|
||||||
'primary' => Color::Blue,
|
'primary' => Color::Blue,
|
||||||
'code' => Color::hex('#d63384'),
|
'code' => Color::hex('#d63384'),
|
||||||
'invoiced' => Color::hex('#900090'),
|
'invoicing' => Color::hex('#DD00DD'),
|
||||||
|
'invoiced' => Color::hex('#900090'),
|
||||||
])
|
])
|
||||||
->discoverResources(in: app_path('Filament/Admin/Resources/'), for: 'App\\Filament\\Admin\\Resources')
|
->discoverResources(in: app_path('Filament/Admin/Resources/'), for: 'App\\Filament\\Admin\\Resources')
|
||||||
->discoverPages(in: app_path('Filament/Admin/Pages'), for: 'App\\Filament\\Admin\\Pages')
|
->discoverPages(in: app_path('Filament/Admin/Pages'), for: 'App\\Filament\\Admin\\Pages')
|
||||||
|
@ -17,7 +17,8 @@ class TaxRateFactory extends Factory
|
|||||||
public function definition(): array
|
public function definition(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
//
|
'name' => strtoupper($this->faker->randomLetter()).'ST',
|
||||||
|
'value' => random_int(1, 15),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,9 +29,13 @@
|
|||||||
$user = User::factory(['is_admin' => true])->create();
|
$user = User::factory(['is_admin' => true])->create();
|
||||||
$this->actingAs($user);
|
$this->actingAs($user);
|
||||||
|
|
||||||
|
TaxRate::factory(['name' => 'GST'])->create();
|
||||||
|
TaxRate::factory(['name' => 'PST'])->create();
|
||||||
|
TaxRate::factory(['name' => 'HST'])->create();
|
||||||
|
|
||||||
$customer = Customer::factory()->create(); // Generates a customer
|
$customer = Customer::factory()->create(); // Generates a customer
|
||||||
$pst_rate = TaxRate::where('name', 'PST')->value('value') ?? 0;
|
|
||||||
$gst_rate = TaxRate::where('name', 'GST')->value('value') ?? 0;
|
$gst_rate = TaxRate::where('name', 'GST')->value('value') ?? 0;
|
||||||
|
$pst_rate = TaxRate::where('name', 'PST')->value('value') ?? 0;
|
||||||
$hst_rate = TaxRate::where('name', 'HST')->value('value') ?? 0;
|
$hst_rate = TaxRate::where('name', 'HST')->value('value') ?? 0;
|
||||||
|
|
||||||
$formData = [
|
$formData = [
|
||||||
@ -39,9 +43,9 @@
|
|||||||
'date' => now()->toDateString(),
|
'date' => now()->toDateString(),
|
||||||
'due_date' => now()->addDays(7)->toDateString(),
|
'due_date' => now()->addDays(7)->toDateString(),
|
||||||
'status' => InvoiceStatus::UNPAID->value,
|
'status' => InvoiceStatus::UNPAID->value,
|
||||||
'has_gst' => true,
|
'has_gst' => 1,
|
||||||
'has_pst' => true,
|
'has_pst' => 1,
|
||||||
'has_hst' => false,
|
'has_hst' => 0,
|
||||||
];
|
];
|
||||||
|
|
||||||
$this->livewire(CreateInvoice::class)
|
$this->livewire(CreateInvoice::class)
|
||||||
@ -50,7 +54,7 @@
|
|||||||
->assertHasNoErrors();
|
->assertHasNoErrors();
|
||||||
|
|
||||||
$this->assertDatabaseHas('invoices', [
|
$this->assertDatabaseHas('invoices', [
|
||||||
'internal_id' => 'INV40001',
|
'internal_id' => 'TN40001',
|
||||||
'customer_id' => $formData['customer_id'],
|
'customer_id' => $formData['customer_id'],
|
||||||
'status' => $formData['status'],
|
'status' => $formData['status'],
|
||||||
'has_gst' => $formData['has_gst'],
|
'has_gst' => $formData['has_gst'],
|
||||||
@ -61,7 +65,7 @@
|
|||||||
'hst_rate' => $hst_rate,
|
'hst_rate' => $hst_rate,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$invoice = Invoice::where('internal_id', 'INV40001')->firstOrFail();
|
$invoice = Invoice::where('internal_id', 'TN40001')->firstOrFail();
|
||||||
|
|
||||||
$this->assertEquals($invoice->orders->isEmpty(), true);
|
$this->assertEquals($invoice->orders->isEmpty(), true);
|
||||||
});
|
});
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
uses(DatabaseMigrations::class);
|
uses(DatabaseMigrations::class);
|
||||||
|
|
||||||
it('can render the list page', function () {
|
it('can render the list page', function () {
|
||||||
|
$this->actingAs(User::factory(['is_admin' => true])->create());
|
||||||
livewire(ListOrders::class)->assertSuccessful();
|
livewire(ListOrders::class)->assertSuccessful();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -83,19 +83,19 @@
|
|||||||
|
|
||||||
'screenPrintEntries' => [
|
'screenPrintEntries' => [
|
||||||
[
|
[
|
||||||
'logo' => 'logo name',
|
'logo' => 'logo name',
|
||||||
'quantity' => 5,
|
'quantity' => 5,
|
||||||
'width' => 1.5,
|
'width' => 1.5,
|
||||||
'height' => 2.5,
|
'height' => 2.5,
|
||||||
'color_amount' => 2,
|
'color_amount' => 2,
|
||||||
'setup_amount' => 2,
|
'setup_amount' => 2,
|
||||||
'run_charge' => 10,
|
'run_charge' => 10,
|
||||||
'color_match' => true,
|
'color_match' => 5.10,
|
||||||
'color_change' => true,
|
'color_change' => 5.15,
|
||||||
'flash' => 5.20,
|
'flash' => 5.20,
|
||||||
'fleece' => 5.30,
|
'fleece' => 5.30,
|
||||||
'poly_ink' => 5.40,
|
'poly_ink' => 5.40,
|
||||||
'other_charges' => 5.50,
|
'artwork_fee' => 5.50,
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user