208 lines
6.6 KiB
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,
|
|
]);
|
|
}
|
|
}
|