feat: Add PurchaseSeeder to generate purchase records with associated items and users

This commit is contained in:
Yoga Pangestu 2026-04-24 13:22:57 +07:00
parent 76753fc304
commit bfef057e6f
2 changed files with 112 additions and 0 deletions

View File

@ -52,6 +52,7 @@ public function run(): void
TestimonialSeeder::class, TestimonialSeeder::class,
ArticleSeeder::class, ArticleSeeder::class,
OrderSeeder::class, OrderSeeder::class,
PurchaseSeeder::class,
ExpenseSeeder::class, ExpenseSeeder::class,
PayrollSeeder::class, PayrollSeeder::class,
]); ]);

View File

@ -0,0 +1,111 @@
<?php
namespace Database\Seeders;
use App\Models\Perfume;
use App\Models\Product;
use App\Models\Purchase;
use App\Models\PurchaseItem;
use App\Models\User;
use App\Models\Warehouse;
use Illuminate\Database\Seeder;
use Illuminate\Support\Collection;
class PurchaseSeeder extends Seeder
{
public function run(): void
{
$warehouses = Warehouse::all();
if ($warehouses->isEmpty()) {
$warehouses = Warehouse::factory(3)->create();
}
$users = User::all();
if ($users->isEmpty()) {
$users = User::factory(5)->create();
}
$perfumes = Perfume::all();
$products = Product::all();
if ($perfumes->isEmpty() && $products->isEmpty()) {
$perfumes = Perfume::factory(10)->create();
}
$purchasableItems = collect();
if ($perfumes->isNotEmpty()) {
$purchasableItems = $purchasableItems->merge($perfumes);
}
if ($products->isNotEmpty()) {
$purchasableItems = $purchasableItems->merge($products);
}
$startDate = now()->subMonths(6)->startOfMonth();
$endDate = now();
$purchaseCount = 0;
// Iterate through each month
for ($date = $startDate->copy(); $date->lte($endDate); $date->addMonth()) {
// Purchases twice a month (e.g., 5th and 20th)
$purchaseDates = [
$date->copy()->day(5),
$date->copy()->day(20),
];
foreach ($purchaseDates as $purchaseDate) {
if ($purchaseDate->gt($endDate)) {
continue; // Skip if date is in the future
}
$purchaseCount++;
$warehouse = $warehouses->random();
$purchaseTime = $purchaseDate->copy()->addHours(rand(9, 16))->addMinutes(rand(0, 59));
$purchase = Purchase::create([
'warehouse_id' => $warehouse->id,
'invoice_number' => 'PO'.$purchaseTime->format('Ymd').str_pad($purchaseCount, 4, '0', STR_PAD_LEFT),
'purchase_date' => $purchaseTime->toDateString(),
'total' => 0,
'note' => 'Restock '.$purchaseTime->format('F Y'),
'created_at' => $purchaseTime,
'updated_at' => $purchaseTime,
]);
$this->createPurchaseItems($purchase, $users->random(), $purchasableItems);
}
}
}
private function createPurchaseItems(Purchase $purchase, User $user, Collection $purchasables): void
{
$itemCount = rand(5, 15);
$totalPurchase = 0;
for ($j = 0; $j < $itemCount; $j++) {
$item = $purchasables->random();
$qty = rand(50, 500);
$unitPrice = $item->cost_price ?? (int) (($item->sale_price ?? rand(50000, 150000)) * 0.4);
$totalPrice = $unitPrice * $qty;
PurchaseItem::create([
'purchase_id' => $purchase->id,
'user_id' => $user->id,
'purchasable_type' => $item->getMorphClass(),
'purchasable_id' => $item->id,
'quantity' => $qty,
'unit_price' => $unitPrice,
'total_price' => $totalPrice,
'created_at' => $purchase->created_at,
'updated_at' => $purchase->created_at,
]);
$totalPurchase += $totalPrice;
}
$purchase->update([
'total' => $totalPurchase,
]);
}
}