Files
nnterp-react-admin/database/seeders/DemoPurchaseInvoiceSeeder.php
2026-03-13 20:49:46 +08:00

109 lines
4.9 KiB
PHP

<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use App\Models\PurchaseInvoice;
use App\Models\PurchaseInvoiceItem;
use Workdo\ProductService\Models\ProductServiceItem;
use Workdo\ProductService\Models\WarehouseStock;
use Carbon\Carbon;
class DemoPurchaseInvoiceSeeder extends Seeder
{
public function run(DemoContext $ctx): void
{
if (PurchaseInvoice::where('created_by', $ctx->userId)->exists()) {
return;
}
if (empty($ctx->vendorIds) || empty($ctx->productIds)) {
return;
}
$invoices = [
['days_ago' => 170, 'vendor_idx' => 0, 'status' => 'paid', 'items' => 3, 'notes' => 'Initial stock purchase - electronics & peripherals'],
['days_ago' => 155, 'vendor_idx' => 1, 'status' => 'paid', 'items' => 2, 'notes' => 'Office supplies and equipment'],
['days_ago' => 140, 'vendor_idx' => 2, 'status' => 'paid', 'items' => 4, 'notes' => 'Bulk order - Q3 inventory replenishment'],
['days_ago' => 120, 'vendor_idx' => 0, 'status' => 'posted', 'items' => 2, 'notes' => 'Technical equipment for new project'],
['days_ago' => 100, 'vendor_idx' => 3, 'status' => 'posted', 'items' => 3, 'notes' => 'Raw materials purchase'],
['days_ago' => 80, 'vendor_idx' => 1, 'status' => 'partial', 'items' => 2, 'notes' => 'Partial payment on software licenses'],
['days_ago' => 55, 'vendor_idx' => 4, 'status' => 'posted', 'items' => 3, 'notes' => 'Warehouse restocking order'],
['days_ago' => 35, 'vendor_idx' => 2, 'status' => 'partial', 'items' => 2, 'notes' => 'Monthly supply order - partial delivery'],
['days_ago' => 15, 'vendor_idx' => 3, 'status' => 'draft', 'items' => 3, 'notes' => 'Pending approval - new vendor items'],
['days_ago' => 5, 'vendor_idx' => 0, 'status' => 'draft', 'items' => 2, 'notes' => 'Urgent restock request'],
];
foreach ($invoices as $index => $inv) {
$date = Carbon::now()->subDays($inv['days_ago']);
$vendorId = $ctx->vendorIds[$inv['vendor_idx'] % count($ctx->vendorIds)];
$warehouseId = $ctx->warehouseIds[$index % count($ctx->warehouseIds)];
$invoiceNumber = 'PI-' . $date->format('Y') . '-' . $date->format('m') . '-' . str_pad($index + 1, 3, '0', STR_PAD_LEFT);
$invoice = PurchaseInvoice::create([
'invoice_number' => $invoiceNumber,
'invoice_date' => $date->toDateString(),
'due_date' => $date->copy()->addDays(30)->toDateString(),
'vendor_id' => $vendorId,
'warehouse_id' => $warehouseId,
'status' => $inv['status'],
'payment_terms' => 'Net 30',
'notes' => $inv['notes'],
'creator_id' => $ctx->userId,
'created_by' => $ctx->userId,
'created_at' => $date,
'updated_at' => $date,
]);
$selectedProducts = $ctx->randomProducts(min($inv['items'], count($ctx->productIds)));
$subtotal = 0;
$taxTotal = 0;
foreach ($selectedProducts as $productId) {
$product = ProductServiceItem::find($productId);
if (!$product) continue;
$quantity = rand(5, 50);
$unitPrice = $product->purchase_price > 0 ? $product->purchase_price : rand(100, 5000);
$item = PurchaseInvoiceItem::create([
'invoice_id' => $invoice->id,
'product_id' => $productId,
'quantity' => $quantity,
'unit_price' => $unitPrice,
'discount_percentage' => rand(0, 5),
'tax_percentage' => 12,
]);
$subtotal += $item->total_amount;
$taxTotal += $item->tax_amount;
// Update warehouse stock
$stock = WarehouseStock::firstOrCreate(
['product_id' => $productId, 'warehouse_id' => $warehouseId],
['quantity' => 0]
);
$stock->increment('quantity', $quantity);
}
$totalAmount = $subtotal;
$paidAmount = match ($inv['status']) {
'paid' => $totalAmount,
'partial' => round($totalAmount * 0.5, 2),
default => 0,
};
$invoice->update([
'subtotal' => $subtotal - $taxTotal,
'tax_amount' => $taxTotal,
'total_amount' => $totalAmount,
'paid_amount' => $paidAmount,
'balance_amount' => $totalAmount - $paidAmount,
]);
$ctx->purchaseInvoiceIds[] = $invoice->id;
}
}
}