From bfef057e6fb2fccb606da35261e7399716cd441c Mon Sep 17 00:00:00 2001 From: Yoga Pangestu Date: Fri, 24 Apr 2026 13:22:57 +0700 Subject: [PATCH] feat: Add PurchaseSeeder to generate purchase records with associated items and users --- database/seeders/DatabaseSeeder.php | 1 + database/seeders/PurchaseSeeder.php | 111 ++++++++++++++++++++++++++++ 2 files changed, 112 insertions(+) create mode 100644 database/seeders/PurchaseSeeder.php diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index c40ec9e..d2bc3eb 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -52,6 +52,7 @@ public function run(): void TestimonialSeeder::class, ArticleSeeder::class, OrderSeeder::class, + PurchaseSeeder::class, ExpenseSeeder::class, PayrollSeeder::class, ]); diff --git a/database/seeders/PurchaseSeeder.php b/database/seeders/PurchaseSeeder.php new file mode 100644 index 0000000..97ae5a0 --- /dev/null +++ b/database/seeders/PurchaseSeeder.php @@ -0,0 +1,111 @@ +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, + ]); + } +}