From 9b2866ed0e3ace71ea7dd743d54c4095ec4d4d09 Mon Sep 17 00:00:00 2001 From: Yoga Pangestu Date: Tue, 17 Feb 2026 20:29:50 +0700 Subject: [PATCH] refactor: Add HasFactory trait to Chicken, Feed, FeedPurchase, and Unit models for improved factory support --- app/Models/Chicken.php | 3 +- app/Models/Feed.php | 3 +- app/Models/FeedPurchase.php | 3 +- app/Models/Unit.php | 3 +- database/factories/ChickenFactory.php | 39 +++++++++++++ database/factories/FeedFactory.php | 31 ++++++++++ database/factories/FeedPurchaseFactory.php | 66 ++++++++++++++++++++++ database/factories/UnitFactory.php | 22 ++++++++ database/seeders/ChickenSeeder.php | 17 ++++++ database/seeders/DatabaseSeeder.php | 4 ++ database/seeders/FeedPurchaseSeeder.php | 17 ++++++ database/seeders/FeedSeeder.php | 17 ++++++ database/seeders/UnitSeeder.php | 34 +++++++++++ 13 files changed, 255 insertions(+), 4 deletions(-) create mode 100644 database/factories/ChickenFactory.php create mode 100644 database/factories/FeedFactory.php create mode 100644 database/factories/FeedPurchaseFactory.php create mode 100644 database/factories/UnitFactory.php create mode 100644 database/seeders/ChickenSeeder.php create mode 100644 database/seeders/FeedPurchaseSeeder.php create mode 100644 database/seeders/FeedSeeder.php create mode 100644 database/seeders/UnitSeeder.php diff --git a/app/Models/Chicken.php b/app/Models/Chicken.php index d8f7c28..e658bfc 100644 --- a/app/Models/Chicken.php +++ b/app/Models/Chicken.php @@ -3,12 +3,13 @@ namespace App\Models; use App\Enums\ChickenStatus; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\SoftDeletes; class Chicken extends Model { - use SoftDeletes; + use HasFactory, SoftDeletes; protected $guarded = ['id']; diff --git a/app/Models/Feed.php b/app/Models/Feed.php index 6612a76..86c0b4f 100644 --- a/app/Models/Feed.php +++ b/app/Models/Feed.php @@ -3,6 +3,7 @@ namespace App\Models; use Illuminate\Database\Eloquent\Casts\Attribute; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\HasMany; @@ -12,7 +13,7 @@ class Feed extends Model implements HasMedia { - use InteractsWithMedia, SoftDeletes; + use HasFactory, InteractsWithMedia, SoftDeletes; protected $guarded = ['id']; diff --git a/app/Models/FeedPurchase.php b/app/Models/FeedPurchase.php index e8795c0..df6150d 100644 --- a/app/Models/FeedPurchase.php +++ b/app/Models/FeedPurchase.php @@ -2,13 +2,14 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\SoftDeletes; class FeedPurchase extends Model { - use SoftDeletes; + use HasFactory, SoftDeletes; protected $guarded = ['id']; diff --git a/app/Models/Unit.php b/app/Models/Unit.php index b357b44..a24273e 100644 --- a/app/Models/Unit.php +++ b/app/Models/Unit.php @@ -2,12 +2,13 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\SoftDeletes; class Unit extends Model { - use SoftDeletes; + use HasFactory, SoftDeletes; protected $guarded = ['id']; } diff --git a/database/factories/ChickenFactory.php b/database/factories/ChickenFactory.php new file mode 100644 index 0000000..85f28db --- /dev/null +++ b/database/factories/ChickenFactory.php @@ -0,0 +1,39 @@ + + */ +class ChickenFactory extends Factory +{ + protected $model = Chicken::class; + + public function definition(): array + { + $arrivalDate = $this->faker->dateTimeBetween('-6 months', 'now'); + $hatchDate = $this->faker->boolean(70) + ? $this->faker->dateTimeBetween( + (clone $arrivalDate)->modify('-2 months'), + $arrivalDate + ) + : null; + + $status = $this->faker->randomElement(ChickenStatus::cases()); + $exitDate = $status === ChickenStatus::DEAD + ? $this->faker->dateTimeBetween($arrivalDate, 'now') + : null; + + return [ + 'tag_code' => strtoupper($this->faker->bothify('CHK-###??')), + 'hatch_date' => $hatchDate, + 'arrival_date' => $arrivalDate, + 'exit_date' => $exitDate, + 'status' => $status, + ]; + } +} diff --git a/database/factories/FeedFactory.php b/database/factories/FeedFactory.php new file mode 100644 index 0000000..0a1f0e5 --- /dev/null +++ b/database/factories/FeedFactory.php @@ -0,0 +1,31 @@ + + */ +class FeedFactory extends Factory +{ + protected $model = Feed::class; + + public function definition(): array + { + return [ + 'name' => $this->faker->randomElement([ + 'Pakan Starter', + 'Pakan Grower', + 'Pakan Layer', + 'Konsentrat Ayam', + 'Jagung Giling', + ]), + 'unit_id' => Unit::inRandomOrder()->value('id') ?? Unit::factory(), + 'stock' => $this->faker->numberBetween(0, 500), + 'price' => $this->faker->numberBetween(10000, 150000), + ]; + } +} diff --git a/database/factories/FeedPurchaseFactory.php b/database/factories/FeedPurchaseFactory.php new file mode 100644 index 0000000..ef0b804 --- /dev/null +++ b/database/factories/FeedPurchaseFactory.php @@ -0,0 +1,66 @@ + + */ +class FeedPurchaseFactory extends Factory +{ + protected $model = FeedPurchase::class; + + public function definition(): array + { + $date = $this->faker->dateTimeBetween('-3 months', 'now'); + + return [ + 'reference_number' => $this->faker->unique()->numerify('PO-#####'), + 'purchase_date' => $date, + 'total_price' => 0, // akan dihitung ulang setelah items dibuat + 'notes' => $this->faker->optional(0.4)->sentence(), + ]; + } + + public function configure() + { + return $this->afterCreating(function (FeedPurchase $purchase) { + $feeds = Feed::inRandomOrder()->take(5)->get(); + + if ($feeds->isEmpty()) { + $feeds = Feed::factory()->count(5)->create(); + } + + $itemCount = $this->faker->numberBetween(1, min(5, $feeds->count())); + $selectedFeeds = $feeds->shuffle()->take($itemCount); + + $total = 0; + + foreach ($selectedFeeds as $feed) { + $quantity = $this->faker->numberBetween(1, 50); + $unitPrice = $feed->price ?? $this->faker->numberBetween(10000, 150000); + $subtotal = $quantity * $unitPrice; + + FeedPurchaseItem::create([ + 'feed_purchase_id' => $purchase->id, + 'feed_id' => $feed->id, + 'quantity' => $quantity, + 'unit_price' => $unitPrice, + 'subtotal' => $subtotal, + ]); + + $total += $subtotal; + } + + $purchase->update(['total_price' => $total]); + + // update stok feed sesuai logic di model + $purchase->refresh(); + $purchase->updateFeedStock(); + }); + } +} diff --git a/database/factories/UnitFactory.php b/database/factories/UnitFactory.php new file mode 100644 index 0000000..fb353f7 --- /dev/null +++ b/database/factories/UnitFactory.php @@ -0,0 +1,22 @@ + + */ +class UnitFactory extends Factory +{ + protected $model = Unit::class; + + public function definition(): array + { + return [ + 'name' => $this->faker->randomElement(['Kilogram', 'Gram', 'Sak', 'Karung', 'Liter']), + 'alias' => $this->faker->unique()->randomElement(['kg', 'g', 'sak', 'karung', 'ltr']), + ]; + } +} diff --git a/database/seeders/ChickenSeeder.php b/database/seeders/ChickenSeeder.php new file mode 100644 index 0000000..a3b4548 --- /dev/null +++ b/database/seeders/ChickenSeeder.php @@ -0,0 +1,17 @@ +count(50)->create(); + } +} diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index 6b43e93..722b8f0 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -17,6 +17,10 @@ public function run(): void $this->call([ ShieldSeeder::class, UserSeeder::class, + UnitSeeder::class, + ChickenSeeder::class, + FeedSeeder::class, + FeedPurchaseSeeder::class, ]); } } diff --git a/database/seeders/FeedPurchaseSeeder.php b/database/seeders/FeedPurchaseSeeder.php new file mode 100644 index 0000000..6540b17 --- /dev/null +++ b/database/seeders/FeedPurchaseSeeder.php @@ -0,0 +1,17 @@ +count(20)->create(); + } +} diff --git a/database/seeders/FeedSeeder.php b/database/seeders/FeedSeeder.php new file mode 100644 index 0000000..84aba11 --- /dev/null +++ b/database/seeders/FeedSeeder.php @@ -0,0 +1,17 @@ +count(20)->create(); + } +} diff --git a/database/seeders/UnitSeeder.php b/database/seeders/UnitSeeder.php new file mode 100644 index 0000000..b34175c --- /dev/null +++ b/database/seeders/UnitSeeder.php @@ -0,0 +1,34 @@ + 'Kilogram', 'alias' => 'kg'], + ['name' => 'Gram', 'alias' => 'g'], + ['name' => 'Sak', 'alias' => 'sak'], + ['name' => 'Karung', 'alias' => 'karung'], + ['name' => 'Liter', 'alias' => 'ltr'], + ]; + + foreach ($defaults as $data) { + Unit::firstOrCreate( + ['alias' => $data['alias']], + ['name' => $data['name']] + ); + } + + // Tambah beberapa unit random jika diperlukan + Unit::factory()->count(5)->create(); + } +}