*/ class StockEntryFactory extends Factory { protected $model = StockEntry::class; /** * @return array */ public function definition(): array { $orderedAt = Carbon::instance($this->faker->dateTimeBetween('-3 months', 'now')); return [ 'entry_type' => 'ingredient', 'ingredient_id' => fn () => $this->makeIngredient()->id, 'packaging_item_id' => null, 'supplier_id' => Supplier::factory(), 'location_id' => Location::factory(), 'unit' => 'gram', 'ordered_by' => fn () => $this->makeOrderUser()->id, 'ordered_at' => $orderedAt->format('Y-m-d'), 'ordered_quantity' => $this->faker->randomFloat(2, 250, 50_000), 'price_per_kg' => $this->faker->randomFloat(4, 2, 120), 'price_total' => null, 'received_by' => null, 'received_at' => null, 'received_quantity' => null, 'batch_number' => null, 'best_before' => null, 'quality_id' => null, 'status' => 'pending', ]; } public function ingredient(): static { return $this->state(fn () => [ 'entry_type' => 'ingredient', 'ingredient_id' => fn () => $this->makeIngredient()->id, 'packaging_item_id' => null, 'unit' => 'gram', 'price_per_kg' => $this->faker->randomFloat(4, 2, 120), 'price_total' => null, ]); } public function packaging(): static { return $this->state(function () { $supplier = Supplier::factory()->create(); $item = PackagingItem::factory()->create([ 'supplier_id' => $supplier->id, 'category' => 'packaging', ]); return [ 'entry_type' => 'packaging', 'ingredient_id' => null, 'packaging_item_id' => $item->id, 'supplier_id' => $supplier->id, 'unit' => 'piece', 'price_per_kg' => null, 'price_total' => $this->faker->randomFloat(4, 15, 2500), ]; }); } public function shipping(): static { return $this->shippingOffice(); } public function shippingOffice(): static { return $this->state(function () { $supplier = Supplier::factory()->create(); $item = PackagingItem::factory()->create([ 'supplier_id' => $supplier->id, 'category' => 'shipping', ]); return [ 'entry_type' => 'shipping', 'ingredient_id' => null, 'packaging_item_id' => $item->id, 'supplier_id' => $supplier->id, 'unit' => 'piece', 'price_per_kg' => null, 'price_total' => $this->faker->randomFloat(4, 8, 1500), ]; }); } public function pending(): static { return $this->state(fn () => [ 'status' => 'pending', 'received_by' => null, 'received_at' => null, 'received_quantity' => null, 'batch_number' => null, 'best_before' => null, 'quality_id' => null, ]); } public function received(): static { return $this->state(function (array $attributes) { $receiver = $this->makeOrderUser(); $orderedAt = $attributes['ordered_at'] ?? now()->format('Y-m-d'); $orderedCarbon = Carbon::parse($orderedAt); $receivedCarbon = (clone $orderedCarbon)->addDays($this->faker->numberBetween(1, 21)); if ($receivedCarbon->isFuture()) { $receivedCarbon = Carbon::now(); } $qty = $attributes['ordered_quantity'] ?? 1000; $entryType = $attributes['entry_type'] ?? 'ingredient'; $extra = [ 'status' => 'received', 'received_by' => $receiver->id, 'received_at' => $receivedCarbon->format('Y-m-d'), 'received_quantity' => round((float) $qty, 2), ]; if ($entryType === 'ingredient') { $extra['batch_number'] = $this->faker->bothify('CH-####-??'); $extra['best_before'] = $this->faker->dateTimeBetween('+2 months', '+24 months')->format('Y-m-d'); $extra['quality_id'] = MaterialQuality::query()->inRandomOrder()->value('id'); } else { $extra['batch_number'] = null; $extra['best_before'] = null; $extra['quality_id'] = null; } return $extra; }); } private function makeIngredient(): Ingredient { $name = $this->faker->randomElement([ 'Shea Butter', 'Kokosöl raffiniert', 'Mandelöl süß', 'Jojobaöl', 'Distillat Rosenhydrolat', ]).' '.$this->faker->unique()->numerify('###'); return Ingredient::query()->create([ 'name' => $name, 'trans_name' => '', 'inci' => $this->faker->optional(0.7)->words(3, true) ?? '', 'trans_inci' => '', 'effect' => '', 'trans_effect' => '', 'active' => true, 'pos' => 0, ]); } private function makeOrderUser(): User { return User::query()->create([ 'email' => 'sf_u_'.str_replace('.', '', uniqid('', true)).'@factory.test', 'password' => bcrypt('password'), 'admin' => 7, 'confirmed' => true, 'active' => true, 'wizard' => 100, 'blocked' => false, ]); } }