- Increased icon sizes in service items, service orders, users, and technician management for better visibility. - Added custom loading indicators with appropriate icons in search fields for vehicles, work orders, and technicians. - Introduced invoice management routes for better organization and access control. - Created a new test for the estimate PDF functionality to ensure proper rendering and data integrity.
112 lines
4.4 KiB
PHP
112 lines
4.4 KiB
PHP
<?php
|
|
|
|
namespace Database\Seeders;
|
|
|
|
use App\Models\Branch;
|
|
use App\Models\Customer;
|
|
use App\Models\Invoice;
|
|
use App\Models\InvoiceLineItem;
|
|
use App\Models\Part;
|
|
use App\Models\User;
|
|
use Illuminate\Database\Seeder;
|
|
|
|
class InvoiceSeeder extends Seeder
|
|
{
|
|
/**
|
|
* Run the database seeder.
|
|
*/
|
|
public function run(): void
|
|
{
|
|
// Get necessary data
|
|
$customers = Customer::take(10)->get();
|
|
$branch = Branch::first();
|
|
$user = User::first();
|
|
$parts = Part::take(5)->get();
|
|
|
|
if ($customers->isEmpty() || ! $branch || ! $user) {
|
|
$this->command->warn('Skipping invoice seeder - missing required data (customers, branch, or user)');
|
|
|
|
return;
|
|
}
|
|
|
|
// Create sample invoices
|
|
foreach ($customers as $index => $customer) {
|
|
$invoice = Invoice::create([
|
|
'invoice_number' => Invoice::generateInvoiceNumber($branch->code),
|
|
'status' => collect(['draft', 'sent', 'paid', 'overdue'])->random(),
|
|
'customer_id' => $customer->id,
|
|
'branch_id' => $branch->id,
|
|
'created_by' => $user->id,
|
|
'invoice_date' => now()->subDays(rand(0, 30)),
|
|
'due_date' => now()->addDays(rand(15, 45)),
|
|
'description' => 'Vehicle maintenance and repair services',
|
|
'notes' => $index % 3 === 0 ? 'Customer requested expedited service. All work completed as specified.' : null,
|
|
'terms_and_conditions' => 'Payment due within 30 days. Late payments subject to 1.5% monthly service charge.',
|
|
'tax_rate' => 8.50,
|
|
'discount_amount' => $index % 4 === 0 ? rand(10, 50) : 0,
|
|
]);
|
|
|
|
// Add line items
|
|
$numItems = rand(2, 5);
|
|
for ($i = 0; $i < $numItems; $i++) {
|
|
$type = collect(['labour', 'parts', 'miscellaneous'])->random();
|
|
$quantity = rand(1, 3);
|
|
$unitPrice = match ($type) {
|
|
'labour' => rand(75, 150),
|
|
'parts' => rand(25, 300),
|
|
'miscellaneous' => rand(10, 75),
|
|
};
|
|
|
|
$part = $parts->random();
|
|
|
|
InvoiceLineItem::create([
|
|
'invoice_id' => $invoice->id,
|
|
'type' => $type,
|
|
'description' => match ($type) {
|
|
'labour' => collect([
|
|
'Brake system inspection and repair',
|
|
'Engine diagnostic and tune-up',
|
|
'Transmission service and fluid change',
|
|
'Air conditioning system service',
|
|
'Tire rotation and alignment',
|
|
'Oil change and filter replacement',
|
|
])->random(),
|
|
'parts' => $part->name ?? 'Replacement part',
|
|
'miscellaneous' => collect([
|
|
'Shop supplies and consumables',
|
|
'Environmental disposal fee',
|
|
'Vehicle inspection fee',
|
|
'Diagnostic software fee',
|
|
])->random(),
|
|
},
|
|
'quantity' => $quantity,
|
|
'unit_price' => $unitPrice,
|
|
'total_amount' => $quantity * $unitPrice,
|
|
'part_id' => $type === 'parts' ? $part->id : null,
|
|
'part_number' => $type === 'parts' ? $part->part_number : null,
|
|
'technical_notes' => $type === 'labour' && $i === 0 ? 'Required specialized diagnostic equipment' : null,
|
|
]);
|
|
}
|
|
|
|
// Recalculate totals
|
|
$invoice->recalculateTotals();
|
|
|
|
// Mark some invoices as paid
|
|
if ($invoice->status === 'paid') {
|
|
$invoice->markAsPaid(
|
|
collect(['cash', 'card', 'check', 'bank_transfer'])->random(),
|
|
'REF-'.strtoupper(\Illuminate\Support\Str::random(6)),
|
|
'Payment processed successfully'
|
|
);
|
|
}
|
|
|
|
// Mark some invoices as sent
|
|
if (in_array($invoice->status, ['sent', 'paid', 'overdue'])) {
|
|
$invoice->markAsSent('email', $customer->email);
|
|
}
|
|
}
|
|
|
|
$this->command->info('Created '.$customers->count().' sample invoices with line items');
|
|
}
|
|
}
|