gruene-seele/database/factories/StockEntryFactory.php

208 lines
6.6 KiB
PHP

<?php
namespace Database\Factories;
use App\Models\Ingredient;
use App\Models\Location;
use App\Models\MaterialQuality;
use App\Models\PackagingItem;
use App\Models\StockEntry;
use App\Models\Supplier;
use App\User;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @extends Factory<StockEntry>
*/
class StockEntryFactory extends Factory
{
protected $model = StockEntry::class;
/**
* @return array<string, mixed>
*/
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 label(): static
{
return $this->state(function () {
$supplier = Supplier::factory()->create();
$item = PackagingItem::factory()->create([
'supplier_id' => $supplier->id,
'category' => 'label',
]);
return [
'entry_type' => 'label',
'ingredient_id' => null,
'packaging_item_id' => $item->id,
'supplier_id' => $supplier->id,
'unit' => 'piece',
'price_per_kg' => null,
'price_total' => $this->faker->randomFloat(4, 5, 800),
];
});
}
public function shippingOffice(): static
{
return $this->state(function () {
$supplier = Supplier::factory()->create();
$item = PackagingItem::factory()->create([
'supplier_id' => $supplier->id,
'category' => 'shipping_office',
]);
return [
'entry_type' => 'shipping_office',
'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,
]);
}
}