faker->numberBetween(50000, 1000000); $discount = $this->faker->numberBetween(0, (int) ($subtotal * 0.3)); // Max 30% discount $total = $subtotal - $discount; $cogs = (int) ($subtotal * 0.4); // COGS is typically 40% of subtotal // Generate invoice number: INV + YYYYMMDD + 4 digit sequence // For testing, use random sequence to ensure uniqueness $sequence = $this->faker->numberBetween(1, 9999); $invoiceNumber = 'INV'.now()->format('Ymd').str_pad($sequence, 4, '0', STR_PAD_LEFT); return [ 'outlet_id' => Outlet::factory(), 'user_id' => User::factory(), 'customer_id' => null, 'voucher_id' => null, 'invoice_number' => $invoiceNumber, 'cogs' => $cogs, 'subtotal' => $subtotal, 'discount' => $discount, 'total' => $total, 'channel' => fake()->randomElement(OrderChannel::cases()), 'status' => fake()->randomElement(OrderStatus::cases()), 'ordered_at' => $this->faker->dateTimeBetween('-1 year', 'now'), ]; } /* |-------------------------------------------------------------------------- | Status States |-------------------------------------------------------------------------- */ public function draft(): Factory { return $this->state(function (array $attributes) { return [ 'status' => OrderStatus::DRAFT, ]; }); } public function pending(): Factory { return $this->state(function (array $attributes) { return [ 'status' => OrderStatus::PENDING, ]; }); } public function partial(): Factory { return $this->state(function (array $attributes) { return [ 'status' => OrderStatus::PARTIAL, ]; }); } public function paid(): Factory { return $this->state(function (array $attributes) { return [ 'status' => OrderStatus::PAID, ]; }); } public function overdue(): Factory { return $this->state(function (array $attributes) { return [ 'status' => OrderStatus::OVERDUE, ]; }); } public function canceled(): Factory { return $this->state(function (array $attributes) { return [ 'status' => OrderStatus::CANCELED, ]; }); } /* |-------------------------------------------------------------------------- | Channel States |-------------------------------------------------------------------------- */ public function outlet(): Factory { return $this->state(function (array $attributes) { return [ 'channel' => OrderChannel::OUTLET, ]; }); } public function shopee(): Factory { return $this->state(function (array $attributes) { return [ 'channel' => OrderChannel::SHOPEE, ]; }); } public function tokopedia(): Factory { return $this->state(function (array $attributes) { return [ 'channel' => OrderChannel::TOKOPEDIA, ]; }); } public function website(): Factory { return $this->state(function (array $attributes) { return [ 'channel' => OrderChannel::WEBSITE, ]; }); } public function instagram(): Factory { return $this->state(function (array $attributes) { return [ 'channel' => OrderChannel::INSTAGRAM, ]; }); } public function whatsapp(): Factory { return $this->state(function (array $attributes) { return [ 'channel' => OrderChannel::WHATSAPP, ]; }); } public function other(): Factory { return $this->state(function (array $attributes) { return [ 'channel' => OrderChannel::OTHER, ]; }); } /* |-------------------------------------------------------------------------- | Relationship States |-------------------------------------------------------------------------- */ public function withCustomer(?Customer $customer = null): Factory { return $this->state(function (array $attributes) use ($customer) { return [ 'customer_id' => $customer?->id ?? Customer::factory(), ]; }); } public function withVoucher(?Voucher $voucher = null): Factory { return $this->state(function (array $attributes) use ($voucher) { return [ 'voucher_id' => $voucher?->id ?? Voucher::factory(), ]; }); } public function withOutlet(?Outlet $outlet = null): Factory { return $this->state(function (array $attributes) use ($outlet) { return [ 'outlet_id' => $outlet?->id ?? Outlet::factory(), ]; }); } public function withUser(?User $user = null): Factory { return $this->state(function (array $attributes) use ($user) { return [ 'user_id' => $user?->id ?? User::factory(), ]; }); } /* |-------------------------------------------------------------------------- | Financial States |-------------------------------------------------------------------------- */ public function withAmounts(int $subtotal, ?int $discount = null, ?int $cogs = null): Factory { return $this->state(function (array $attributes) use ($subtotal, $discount, $cogs) { $discount = $discount ?? $this->faker->numberBetween(0, (int) ($subtotal * 0.3)); $total = $subtotal - $discount; $cogs = $cogs ?? (int) ($subtotal * 0.4); return [ 'subtotal' => $subtotal, 'discount' => $discount, 'total' => $total, 'cogs' => $cogs, ]; }); } public function withDiscount(int $discount): Factory { return $this->state(function (array $attributes) use ($discount) { $subtotal = $attributes['subtotal'] ?? $this->faker->numberBetween(50000, 1000000); $total = $subtotal - $discount; return [ 'discount' => $discount, 'total' => max(0, $total), // Ensure total is not negative ]; }); } public function withoutDiscount(): Factory { return $this->state(function (array $attributes) { $subtotal = $attributes['subtotal'] ?? $this->faker->numberBetween(50000, 1000000); return [ 'discount' => 0, 'total' => $subtotal, ]; }); } /* |-------------------------------------------------------------------------- | Date States |-------------------------------------------------------------------------- */ public function today(): Factory { return $this->state(function (array $attributes) { return [ 'ordered_at' => now(), 'created_at' => now(), ]; }); } public function yesterday(): Factory { return $this->state(function (array $attributes) { $yesterday = now()->subDay(); return [ 'ordered_at' => $yesterday, 'created_at' => $yesterday, ]; }); } public function thisWeek(): Factory { return $this->state(function (array $attributes) { return [ 'ordered_at' => $this->faker->dateTimeBetween('-7 days', 'now'), ]; }); } public function thisMonth(): Factory { return $this->state(function (array $attributes) { return [ 'ordered_at' => $this->faker->dateTimeBetween('-30 days', 'now'), ]; }); } public function lastMonth(): Factory { return $this->state(function (array $attributes) { return [ 'ordered_at' => $this->faker->dateTimeBetween('-60 days', '-30 days'), ]; }); } }