feat: Add OrderSeeder to generate realistic order data and integrate it into the main database seeder.
This commit is contained in:
parent
b37ae44c0d
commit
42efa0dc7a
@ -51,6 +51,7 @@ public function run(): void
|
||||
ChooseUsSeeder::class,
|
||||
TestimonialSeeder::class,
|
||||
ArticleSeeder::class,
|
||||
OrderSeeder::class,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
140
database/seeders/OrderSeeder.php
Normal file
140
database/seeders/OrderSeeder.php
Normal file
@ -0,0 +1,140 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use App\Enums\OrderChannel;
|
||||
use App\Enums\OrderStatus;
|
||||
use App\Models\Customer;
|
||||
use App\Models\Order;
|
||||
use App\Models\OrderItem;
|
||||
use App\Models\Outlet;
|
||||
use App\Models\Perfume;
|
||||
use App\Models\Product;
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Seeder;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
class OrderSeeder extends Seeder
|
||||
{
|
||||
public function run(): void
|
||||
{
|
||||
$outlets = Outlet::all();
|
||||
if ($outlets->isEmpty()) {
|
||||
$outlets = Outlet::factory(3)->create();
|
||||
}
|
||||
|
||||
$users = User::all();
|
||||
if ($users->isEmpty()) {
|
||||
$users = User::factory(5)->create();
|
||||
}
|
||||
|
||||
$customers = Customer::all();
|
||||
if ($customers->isEmpty()) {
|
||||
$customers = Customer::factory(20)->create();
|
||||
}
|
||||
|
||||
$perfumes = Perfume::all();
|
||||
$products = Product::all();
|
||||
|
||||
if ($perfumes->isEmpty() && $products->isEmpty()) {
|
||||
$perfumes = Perfume::factory(10)->create();
|
||||
}
|
||||
|
||||
$orderableItems = collect();
|
||||
if ($perfumes->isNotEmpty()) {
|
||||
$orderableItems = $orderableItems->merge($perfumes);
|
||||
}
|
||||
if ($products->isNotEmpty()) {
|
||||
$orderableItems = $orderableItems->merge($products);
|
||||
}
|
||||
|
||||
for ($i = 0; $i < 50; $i++) {
|
||||
$outlet = $outlets->random();
|
||||
$user = $users->random();
|
||||
$customer = $customers->random();
|
||||
|
||||
$status = $this->getRandomStatus();
|
||||
$orderedAt = now()->subDays(rand(0, 90));
|
||||
|
||||
$order = Order::create([
|
||||
'outlet_id' => $outlet->id,
|
||||
'user_id' => $user->id,
|
||||
'customer_id' => $customer->id,
|
||||
'voucher_id' => null,
|
||||
'invoice_number' => 'INV'.$orderedAt->format('Ymd').str_pad($i + 1, 4, '0', STR_PAD_LEFT),
|
||||
'channel' => OrderChannel::OUTLET,
|
||||
'status' => $status,
|
||||
'ordered_at' => $orderedAt,
|
||||
'created_at' => $orderedAt,
|
||||
'updated_at' => $orderedAt,
|
||||
'cogs' => 0,
|
||||
'subtotal' => 0,
|
||||
'discount' => 0,
|
||||
'voucher_discount' => 0,
|
||||
'total' => 0,
|
||||
]);
|
||||
|
||||
$this->createOrderItems($order, $user, $orderableItems);
|
||||
}
|
||||
}
|
||||
|
||||
private function getRandomStatus(): OrderStatus
|
||||
{
|
||||
$rand = rand(1, 100);
|
||||
if ($rand <= 80) {
|
||||
return OrderStatus::PAID;
|
||||
}
|
||||
if ($rand <= 90) {
|
||||
return OrderStatus::PENDING;
|
||||
}
|
||||
if ($rand <= 95) {
|
||||
return OrderStatus::CANCELED;
|
||||
}
|
||||
|
||||
return OrderStatus::DRAFT;
|
||||
}
|
||||
|
||||
private function createOrderItems(Order $order, User $user, Collection $orderables): void
|
||||
{
|
||||
$itemCount = rand(1, 5);
|
||||
$totalCogs = 0;
|
||||
$totalSubtotal = 0;
|
||||
|
||||
for ($j = 0; $j < $itemCount; $j++) {
|
||||
$item = $orderables->random();
|
||||
$qty = rand(1, 3);
|
||||
|
||||
$price = $item->sale_price ?? rand(50000, 150000);
|
||||
$cogs = $item->cost_price ?? (int) ($price * 0.4);
|
||||
|
||||
OrderItem::create([
|
||||
'order_id' => $order->id,
|
||||
'user_id' => $user->id,
|
||||
'orderable_type' => $item->getMorphClass(),
|
||||
'orderable_id' => $item->id,
|
||||
'quantity' => $qty,
|
||||
'unit_price' => $price,
|
||||
'cogs' => $cogs,
|
||||
'created_at' => $order->ordered_at,
|
||||
'updated_at' => $order->ordered_at,
|
||||
]);
|
||||
|
||||
$totalCogs += ($cogs * $qty);
|
||||
$totalSubtotal += ($price * $qty);
|
||||
}
|
||||
|
||||
$discount = rand(1, 100) > 80 ? rand(5000, 20000) : 0;
|
||||
if ($discount > $totalSubtotal) {
|
||||
$discount = 0;
|
||||
}
|
||||
|
||||
$total = $totalSubtotal - $discount;
|
||||
|
||||
$order->update([
|
||||
'cogs' => $totalCogs,
|
||||
'subtotal' => $totalSubtotal,
|
||||
'discount' => $discount,
|
||||
'total' => $total,
|
||||
]);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user