feat: membuat factory seluruh model

- menyesuaikan model jika ada yang salah seperti kurangnya trait SoftDeletes, casting yang salah, relasi yang kurang dan lainnya
- memperbaiki enum di migrasi
This commit is contained in:
Yoga Pangestu 2025-12-09 08:25:07 +07:00
parent 8dcc57673d
commit c4b90acf53
65 changed files with 1003 additions and 232 deletions

View File

@ -4,11 +4,12 @@
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
use Veelasky\LaravelHashId\Eloquent\HashableId;
class Membership extends Model
{
use HashableId;
use HashableId, SoftDeletes;
protected $guarded = ['id'];

View File

@ -6,9 +6,12 @@
use App\Enums\PaymentStatus;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
class Payment extends Model
{
use SoftDeletes;
protected $guarded = ['id'];
protected function casts(): array
@ -16,7 +19,7 @@ protected function casts(): array
return [
'method' => PaymentMethod::class,
'amount' => 'int',
'payment' => PaymentStatus::class,
'status' => PaymentStatus::class,
];
}

View File

@ -3,6 +3,7 @@
namespace App\Models;
use App\Enums\StockOpnameStatus;
use Dyrynda\Database\Support\CascadeSoftDeletes;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
@ -11,7 +12,7 @@
class StockOpname extends Model
{
use HashableId, SoftDeletes;
use CascadeSoftDeletes, HashableId, SoftDeletes;
protected $table = 'stock_opname';

View File

@ -97,6 +97,11 @@ public function payrolls(): HasMany
return $this->hasMany(Payroll::class);
}
public function expenses(): HasMany
{
return $this->hasMany(Expense::class);
}
public function orders(): HasMany
{
return $this->hasMany(Order::class);
@ -117,6 +122,11 @@ public function payments(): HasMany
return $this->hasMany(Payment::class);
}
public function salaryHistories(): HasMany
{
return $this->hasMany(SalaryHistory::class);
}
public function priceRequests(): HasMany
{
return $this->hasMany(PriceRequest::class);
@ -132,6 +142,11 @@ public function pointRecords(): HasMany
return $this->hasMany(PointRecord::class);
}
public function stockOpnameItems(): HasMany
{
return $this->hasMany(StockOpnameItem::class);
}
public function pushNotifications(): HasMany
{
return $this->hasMany(PushNotification::class);

View File

@ -8,6 +8,8 @@ class UserVoucher extends Model
{
protected $table = 'user_voucher';
protected $guarded = ['id'];
protected function casts(): array
{
return [

View File

@ -0,0 +1,40 @@
<?php
namespace Database\Factories;
use App\Enums\ArticleStatus;
use App\Models\Article;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;
class ArticleFactory extends Factory
{
protected $model = Article::class;
public function definition(): array
{
$title = $this->faker->sentence(6);
return [
'author_id' => User::factory(),
'title' => $title,
'slug' => Str::slug($title.'-'.$this->faker->unique()->randomNumber()),
'excerpt' => $this->faker->paragraph(),
'content' => $this->faker->paragraphs(3, true),
'status' => ArticleStatus::PUBLISHED,
'published_at' => $this->faker->optional()->dateTimeBetween('-10 days', 'now'),
'views' => $this->faker->numberBetween(0, 1000),
];
}
public function draft(): Factory
{
return $this->state(fn () => ['status' => ArticleStatus::DRAFT, 'published_at' => null]);
}
public function published(): Factory
{
return $this->state(fn () => ['status' => ArticleStatus::PUBLISHED, 'published_at' => now()]);
}
}

View File

@ -2,13 +2,13 @@
namespace Database\Factories;
use App\Models\Bottle;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Bottle>
*/
class BottleFactory extends Factory
{
protected $model = Bottle::class;
public function definition(): array
{
$costPrice = $this->faker->randomNumber(2);

View File

@ -0,0 +1,22 @@
<?php
namespace Database\Factories;
use App\Models\Bottle;
use App\Models\BottleOutlet;
use App\Models\Outlet;
use Illuminate\Database\Eloquent\Factories\Factory;
class BottleOutletFactory extends Factory
{
protected $model = BottleOutlet::class;
public function definition(): array
{
return [
'bottle_id' => Bottle::factory(),
'outlet_id' => Outlet::factory(),
'stock' => $this->faker->numberBetween(0, 200),
];
}
}

View File

@ -7,6 +7,8 @@
class BrandFactory extends Factory
{
protected $model = Brand::class;
public function definition(): array
{
return [

View File

@ -0,0 +1,21 @@
<?php
namespace Database\Factories;
use App\Models\Broadcast;
use App\Models\BroadcastAudience;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class BroadcastAudienceFactory extends Factory
{
protected $model = BroadcastAudience::class;
public function definition(): array
{
return [
'broadcast_id' => Broadcast::factory(),
'user_id' => User::factory(),
];
}
}

View File

@ -0,0 +1,21 @@
<?php
namespace Database\Factories;
use App\Models\Broadcast;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class BroadcastFactory extends Factory
{
protected $model = Broadcast::class;
public function definition(): array
{
return [
'user_id' => User::factory(),
'title' => $this->faker->sentence(4),
'body' => $this->faker->paragraph(),
];
}
}

View File

@ -7,6 +7,8 @@
class CategoryFactory extends Factory
{
protected $model = Category::class;
public function definition(): array
{
return [

View File

@ -0,0 +1,21 @@
<?php
namespace Database\Factories;
use App\Models\Category;
use App\Models\CategoryPerfume;
use App\Models\Perfume;
use Illuminate\Database\Eloquent\Factories\Factory;
class CategoryPerfumeFactory extends Factory
{
protected $model = CategoryPerfume::class;
public function definition(): array
{
return [
'category_id' => Category::factory(),
'perfume_id' => Perfume::factory(),
];
}
}

View File

@ -0,0 +1,20 @@
<?php
namespace Database\Factories;
use App\Models\ChooseUs;
use Illuminate\Database\Eloquent\Factories\Factory;
class ChooseUsFactory extends Factory
{
protected $model = ChooseUs::class;
public function definition(): array
{
return [
'name' => $this->faker->words(2, true),
'description' => $this->faker->paragraph(),
'sort_order' => $this->faker->numberBetween(1, 50),
];
}
}

View File

@ -3,10 +3,13 @@
namespace Database\Factories;
use App\Enums\Gender;
use App\Models\Customer;
use Illuminate\Database\Eloquent\Factories\Factory;
class CustomerFactory extends Factory
{
protected $model = Customer::class;
public function definition(): array
{
return [

View File

@ -9,6 +9,8 @@
class EmployeeFactory extends Factory
{
protected $model = Employee::class;
public function definition(): array
{
return [
@ -38,46 +40,26 @@ public function definition(): array
public function male(): Factory
{
return $this->state(function (array $attributes) {
return [
'gender' => Gender::MALE,
];
});
return $this->state(fn () => ['gender' => Gender::MALE]);
}
public function female(): Factory
{
return $this->state(function (array $attributes) {
return [
'gender' => Gender::FEMALE,
];
});
return $this->state(fn () => ['gender' => Gender::FEMALE]);
}
public function permanent(): Factory
{
return $this->state(function (array $attributes) {
return [
'status' => EmploymentStatus::PERMANENT,
];
});
return $this->state(fn () => ['status' => EmploymentStatus::PERMANENT]);
}
public function contract(): Factory
{
return $this->state(function (array $attributes) {
return [
'status' => EmploymentStatus::CONTRACT,
];
});
return $this->state(fn () => ['status' => EmploymentStatus::CONTRACT]);
}
public function intern(): Factory
{
return $this->state(function (array $attributes) {
return [
'status' => EmploymentStatus::INTERN,
];
});
return $this->state(fn () => ['status' => EmploymentStatus::INTERN]);
}
}

View File

@ -0,0 +1,40 @@
<?php
namespace Database\Factories;
use App\Enums\ExpenseType;
use App\Models\Expense;
use App\Models\Outlet;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class ExpenseFactory extends Factory
{
protected $model = Expense::class;
public function definition(): array
{
return [
'user_id' => User::factory(),
'outlet_id' => Outlet::factory(),
'amount' => $this->faker->numberBetween(10000, 200000),
'description' => $this->faker->sentence(6),
'type' => ExpenseType::OPERATIONAL,
];
}
public function operational(): Factory
{
return $this->state(fn () => ['type' => ExpenseType::OPERATIONAL]);
}
public function purchase(): Factory
{
return $this->state(fn () => ['type' => ExpenseType::PURCHASE]);
}
public function salary(): Factory
{
return $this->state(fn () => ['type' => ExpenseType::SALARY]);
}
}

View File

@ -2,10 +2,13 @@
namespace Database\Factories;
use App\Models\Facility;
use Illuminate\Database\Eloquent\Factories\Factory;
class FacilityFactory extends Factory
{
protected $model = Facility::class;
public function definition(): array
{
return [

View File

@ -0,0 +1,20 @@
<?php
namespace Database\Factories;
use App\Models\Faq;
use Illuminate\Database\Eloquent\Factories\Factory;
class FaqFactory extends Factory
{
protected $model = Faq::class;
public function definition(): array
{
return [
'question' => $this->faker->sentence(6),
'answer' => $this->faker->paragraph(),
'sort_order' => $this->faker->numberBetween(1, 50),
];
}
}

View File

@ -2,13 +2,13 @@
namespace Database\Factories;
use App\Models\Formula;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Formula>
*/
class FormulaFactory extends Factory
{
protected $model = Formula::class;
public function definition(): array
{
return [

View File

@ -0,0 +1,24 @@
<?php
namespace Database\Factories;
use App\Models\Membership;
use App\Models\Tier;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class MembershipFactory extends Factory
{
protected $model = Membership::class;
public function definition(): array
{
return [
'user_id' => User::factory(),
'tier_id' => Tier::factory(),
'tier_points' => $this->faker->numberBetween(0, 1000),
'reward_points' => $this->faker->numberBetween(0, 1000),
'last_transaction_at' => $this->faker->optional()->dateTimeBetween('-30 days', 'now'),
];
}
}

View File

@ -3,10 +3,13 @@
namespace Database\Factories;
use App\Enums\Day;
use App\Models\OpeningHour;
use Illuminate\Database\Eloquent\Factories\Factory;
class OpeningHourFactory extends Factory
{
protected $model = OpeningHour::class;
public function definition(): array
{
return [

View File

@ -5,6 +5,7 @@
use App\Enums\OrderChannel;
use App\Enums\OrderStatus;
use App\Models\Customer;
use App\Models\Order;
use App\Models\Outlet;
use App\Models\User;
use App\Models\Voucher;
@ -12,6 +13,8 @@
class OrderFactory extends Factory
{
protected $model = Order::class;
public function definition(): array
{
$subtotal = $this->faker->numberBetween(50000, 1000000);
@ -40,183 +43,91 @@ public function definition(): array
];
}
/*
|--------------------------------------------------------------------------
| Status States
|--------------------------------------------------------------------------
*/
public function draft(): Factory
{
return $this->state(function (array $attributes) {
return [
'status' => OrderStatus::DRAFT,
];
});
return $this->state(fn () => ['status' => OrderStatus::DRAFT]);
}
public function pending(): Factory
{
return $this->state(function (array $attributes) {
return [
'status' => OrderStatus::PENDING,
];
});
return $this->state(fn () => ['status' => OrderStatus::PENDING]);
}
public function partial(): Factory
{
return $this->state(function (array $attributes) {
return [
'status' => OrderStatus::PARTIAL,
];
});
return $this->state(fn () => ['status' => OrderStatus::PARTIAL]);
}
public function paid(): Factory
{
return $this->state(function (array $attributes) {
return [
'status' => OrderStatus::PAID,
];
});
return $this->state(fn () => ['status' => OrderStatus::PAID]);
}
public function overdue(): Factory
{
return $this->state(function (array $attributes) {
return [
'status' => OrderStatus::OVERDUE,
];
});
return $this->state(fn () => ['status' => OrderStatus::OVERDUE]);
}
public function canceled(): Factory
{
return $this->state(function (array $attributes) {
return [
'status' => OrderStatus::CANCELED,
];
});
return $this->state(fn () => ['status' => OrderStatus::CANCELED]);
}
/*
|--------------------------------------------------------------------------
| Channel States
|--------------------------------------------------------------------------
*/
public function outlet(): Factory
{
return $this->state(function (array $attributes) {
return [
'channel' => OrderChannel::OUTLET,
];
});
return $this->state(fn () => ['channel' => OrderChannel::OUTLET]);
}
public function shopee(): Factory
{
return $this->state(function (array $attributes) {
return [
'channel' => OrderChannel::SHOPEE,
];
});
return $this->state(fn () => ['channel' => OrderChannel::SHOPEE]);
}
public function tokopedia(): Factory
{
return $this->state(function (array $attributes) {
return [
'channel' => OrderChannel::TOKOPEDIA,
];
});
return $this->state(fn () => ['channel' => OrderChannel::TOKOPEDIA]);
}
public function website(): Factory
{
return $this->state(function (array $attributes) {
return [
'channel' => OrderChannel::WEBSITE,
];
});
return $this->state(fn () => ['channel' => OrderChannel::WEBSITE]);
}
public function instagram(): Factory
{
return $this->state(function (array $attributes) {
return [
'channel' => OrderChannel::INSTAGRAM,
];
});
return $this->state(fn () => ['channel' => OrderChannel::INSTAGRAM]);
}
public function whatsapp(): Factory
{
return $this->state(function (array $attributes) {
return [
'channel' => OrderChannel::WHATSAPP,
];
});
return $this->state(fn () => ['channel' => OrderChannel::WHATSAPP]);
}
public function other(): Factory
{
return $this->state(function (array $attributes) {
return [
'channel' => OrderChannel::OTHER,
];
});
return $this->state(fn () => ['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(),
];
});
return $this->state(fn () => ['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(),
];
});
return $this->state(fn () => ['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(),
];
});
return $this->state(fn () => ['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(),
];
});
return $this->state(fn () => ['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) {
@ -241,7 +152,7 @@ public function withDiscount(int $discount): Factory
return [
'discount' => $discount,
'total' => max(0, $total), // Ensure total is not negative
'total' => max(0, $total),
];
});
}
@ -258,58 +169,28 @@ public function withoutDiscount(): Factory
});
}
/*
|--------------------------------------------------------------------------
| Date States
|--------------------------------------------------------------------------
*/
public function today(): Factory
{
return $this->state(function (array $attributes) {
return [
'ordered_at' => now(),
'created_at' => now(),
];
});
return $this->state(fn () => ['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,
];
});
return $this->state(fn () => tap(now()->subDay(), fn ($d) => null) && ['ordered_at' => $d = now()->subDay(), 'created_at' => $d]);
}
public function thisWeek(): Factory
{
return $this->state(function (array $attributes) {
return [
'ordered_at' => $this->faker->dateTimeBetween('-7 days', 'now'),
];
});
return $this->state(fn () => ['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'),
];
});
return $this->state(fn () => ['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'),
];
});
return $this->state(fn () => ['ordered_at' => $this->faker->dateTimeBetween('-60 days', '-30 days')]);
}
}

View File

@ -0,0 +1,29 @@
<?php
namespace Database\Factories;
use App\Models\Order;
use App\Models\OrderItem;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class OrderItemFactory extends Factory
{
protected $model = OrderItem::class;
public function definition(): array
{
$unitPrice = $this->faker->numberBetween(20000, 150000);
$quantity = $this->faker->numberBetween(1, 5);
return [
'order_id' => Order::factory(),
'user_id' => User::factory(),
'orderable_type' => null,
'orderable_id' => null,
'cogs' => (int) ($unitPrice * 0.4),
'unit_price' => $unitPrice,
'quantity' => $quantity,
];
}
}

View File

@ -3,10 +3,13 @@
namespace Database\Factories;
use App\Enums\OutletStatus;
use App\Models\Outlet;
use Illuminate\Database\Eloquent\Factories\Factory;
class OutletFactory extends Factory
{
protected $model = Outlet::class;
public function definition(): array
{
return [
@ -31,28 +34,16 @@ public function definition(): array
public function operational(): Factory
{
return $this->state(function (array $attributes) {
return [
'status' => OutletStatus::OPERATIONAL,
];
});
return $this->state(fn () => ['status' => OutletStatus::OPERATIONAL]);
}
public function underConstruction(): Factory
{
return $this->state(function (array $attributes) {
return [
'status' => OutletStatus::UNDER_CONSTRUCTION,
];
});
return $this->state(fn () => ['status' => OutletStatus::UNDER_CONSTRUCTION]);
}
public function terminated(): Factory
{
return $this->state(function (array $attributes) {
return [
'status' => OutletStatus::TERMINATED,
];
});
return $this->state(fn () => ['status' => OutletStatus::TERMINATED]);
}
}

View File

@ -0,0 +1,22 @@
<?php
namespace Database\Factories;
use App\Models\Outlet;
use App\Models\OutletPerfume;
use App\Models\Perfume;
use Illuminate\Database\Eloquent\Factories\Factory;
class OutletPerfumeFactory extends Factory
{
protected $model = OutletPerfume::class;
public function definition(): array
{
return [
'outlet_id' => Outlet::factory(),
'perfume_id' => Perfume::factory(),
'stock' => $this->faker->numberBetween(0, 500),
];
}
}

View File

@ -0,0 +1,22 @@
<?php
namespace Database\Factories;
use App\Models\Outlet;
use App\Models\OutletProduct;
use App\Models\Product;
use Illuminate\Database\Eloquent\Factories\Factory;
class OutletProductFactory extends Factory
{
protected $model = OutletProduct::class;
public function definition(): array
{
return [
'outlet_id' => Outlet::factory(),
'product_id' => Product::factory(),
'stock' => $this->faker->numberBetween(0, 500),
];
}
}

View File

@ -0,0 +1,21 @@
<?php
namespace Database\Factories;
use App\Models\Outlet;
use App\Models\OutletUser;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class OutletUserFactory extends Factory
{
protected $model = OutletUser::class;
public function definition(): array
{
return [
'outlet_id' => Outlet::factory(),
'user_id' => User::factory(),
];
}
}

View File

@ -0,0 +1,21 @@
<?php
namespace Database\Factories;
use App\Models\Outlet;
use App\Models\OutletVoucher;
use App\Models\Voucher;
use Illuminate\Database\Eloquent\Factories\Factory;
class OutletVoucherFactory extends Factory
{
protected $model = OutletVoucher::class;
public function definition(): array
{
return [
'outlet_id' => Outlet::factory(),
'voucher_id' => Voucher::factory(),
];
}
}

View File

@ -0,0 +1,47 @@
<?php
namespace Database\Factories;
use App\Enums\PaymentMethod;
use App\Enums\PaymentStatus;
use App\Models\Order;
use App\Models\Payment;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class PaymentFactory extends Factory
{
protected $model = Payment::class;
public function definition(): array
{
return [
'order_id' => Order::factory(),
'user_id' => User::factory(),
'method' => PaymentMethod::CASH,
'amount' => $this->faker->numberBetween(20000, 400000),
'paid_at' => $this->faker->dateTimeBetween('-7 days', 'now'),
'status' => PaymentStatus::PENDING,
];
}
public function cash(): Factory
{
return $this->state(fn () => ['method' => PaymentMethod::CASH]);
}
public function transfer(): Factory
{
return $this->state(fn () => ['method' => PaymentMethod::TRANSFER]);
}
public function paid(): Factory
{
return $this->state(fn () => ['status' => PaymentStatus::PAID]);
}
public function pending(): Factory
{
return $this->state(fn () => ['status' => PaymentStatus::PENDING]);
}
}

View File

@ -0,0 +1,33 @@
<?php
namespace Database\Factories;
use App\Enums\SalaryAdjustmentType;
use App\Models\Payroll;
use App\Models\PayrollAdjustment;
use Illuminate\Database\Eloquent\Factories\Factory;
class PayrollAdjustmentFactory extends Factory
{
protected $model = PayrollAdjustment::class;
public function definition(): array
{
return [
'payroll_id' => Payroll::factory(),
'type' => SalaryAdjustmentType::BONUS,
'description' => $this->faker->sentence(4),
'amount' => $this->faker->numberBetween(50000, 500000),
];
}
public function deduction(): Factory
{
return $this->state(fn () => ['type' => SalaryAdjustmentType::DEDUCTION]);
}
public function bonus(): Factory
{
return $this->state(fn () => ['type' => SalaryAdjustmentType::BONUS]);
}
}

View File

@ -0,0 +1,39 @@
<?php
namespace Database\Factories;
use App\Enums\IsPaid;
use App\Models\Payroll;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class PayrollFactory extends Factory
{
protected $model = Payroll::class;
public function definition(): array
{
$base = $this->faker->numberBetween(3000000, 8000000);
$bonus = $this->faker->numberBetween(0, 2000000);
$deduction = $this->faker->numberBetween(0, 500000);
return [
'user_id' => User::factory(),
'period_month' => $this->faker->date('Y-m'),
'base_salary' => $base,
'bonus' => $bonus,
'deduction' => $deduction,
'total_salary' => $base + $bonus - $deduction,
'is_paid' => IsPaid::NOT_PAID,
'paid_at' => null,
];
}
public function paid(): Factory
{
return $this->state(fn () => [
'is_paid' => IsPaid::PAID,
'paid_at' => $this->faker->dateTimeBetween('-3 days', 'now'),
]);
}
}

View File

@ -0,0 +1,44 @@
<?php
namespace Database\Factories;
use App\Enums\Concentration;
use App\Models\Brand;
use App\Models\Perfume;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;
class PerfumeFactory extends Factory
{
protected $model = Perfume::class;
public function definition(): array
{
$name = $this->faker->unique()->words(2, true);
return [
'brand_id' => Brand::factory(),
'name' => Str::title($name),
'slug' => Str::slug($name.'-'.$this->faker->unique()->randomNumber()),
'sku' => strtoupper($this->faker->unique()->bothify('PER-#####')),
'concentration' => Concentration::EXTRAIT_DE_PERFUME,
'cost_price' => $this->faker->numberBetween(50000, 250000),
'sale_price' => $this->faker->numberBetween(80000, 400000),
'point_per_ml' => $this->faker->numberBetween(1, 30),
'base_notes' => $this->faker->optional()->words(3, true),
'middle_notes' => $this->faker->optional()->words(3, true),
'top_notes' => $this->faker->optional()->words(3, true),
'description' => $this->faker->optional()->paragraph(),
];
}
public function extrait(): Factory
{
return $this->state(fn () => ['concentration' => Concentration::EXTRAIT_DE_PERFUME]);
}
public function eauDeParfum(): Factory
{
return $this->state(fn () => ['concentration' => Concentration::EAU_DE_PERFUME]);
}
}

View File

@ -0,0 +1,20 @@
<?php
namespace Database\Factories;
use App\Models\PerfumeFeature;
use Illuminate\Database\Eloquent\Factories\Factory;
class PerfumeFeatureFactory extends Factory
{
protected $model = PerfumeFeature::class;
public function definition(): array
{
return [
'name' => $this->faker->words(2, true),
'description' => $this->faker->paragraph(),
'sort_order' => $this->faker->numberBetween(1, 50),
];
}
}

View File

@ -0,0 +1,37 @@
<?php
namespace Database\Factories;
use App\Enums\PointRecordType;
use App\Models\PointRecord;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class PointRecordFactory extends Factory
{
protected $model = PointRecord::class;
public function definition(): array
{
$change = $this->faker->numberBetween(10, 500);
$isAddition = $this->faker->boolean();
return [
'user_id' => User::factory(),
'change' => $change,
'type' => PointRecordType::REWARD,
'description' => $this->faker->sentence(4),
'is_addition' => $isAddition,
];
}
public function reward(): Factory
{
return $this->state(fn () => ['type' => PointRecordType::REWARD, 'is_addition' => true]);
}
public function redemption(): Factory
{
return $this->state(fn () => ['type' => PointRecordType::REDEMPTION, 'is_addition' => false]);
}
}

View File

@ -0,0 +1,38 @@
<?php
namespace Database\Factories;
use App\Enums\PriceRequestStatus;
use App\Models\PriceRequest;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class PriceRequestFactory extends Factory
{
protected $model = PriceRequest::class;
public function definition(): array
{
return [
'user_id' => User::factory(),
'module' => $this->faker->randomElement(['product', 'perfume', 'bottle']),
'status' => PriceRequestStatus::PENDING,
'finalized_at' => null,
];
}
public function pending(): Factory
{
return $this->state(fn () => ['status' => PriceRequestStatus::PENDING, 'finalized_at' => null]);
}
public function approved(): Factory
{
return $this->state(fn () => ['status' => PriceRequestStatus::APPROVED, 'finalized_at' => $this->faker->dateTime()]);
}
public function rejected(): Factory
{
return $this->state(fn () => ['status' => PriceRequestStatus::REJECTED, 'finalized_at' => $this->faker->dateTime()]);
}
}

View File

@ -0,0 +1,27 @@
<?php
namespace Database\Factories;
use App\Models\Product;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;
class ProductFactory extends Factory
{
protected $model = Product::class;
public function definition(): array
{
$name = $this->faker->unique()->words(2, true);
return [
'name' => Str::title($name),
'slug' => Str::slug($name.'-'.$this->faker->unique()->randomNumber()),
'sku' => strtoupper($this->faker->unique()->bothify('PRD-#####')),
'cost_price' => $this->faker->numberBetween(20000, 150000),
'sale_price' => $this->faker->numberBetween(30000, 200000),
'point_per_pcs' => $this->faker->numberBetween(1, 50),
'description' => $this->faker->optional()->paragraph(),
];
}
}

View File

@ -0,0 +1,24 @@
<?php
namespace Database\Factories;
use App\Models\Outlet;
use App\Models\Purchase;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;
class PurchaseFactory extends Factory
{
protected $model = Purchase::class;
public function definition(): array
{
return [
'outlet_id' => Outlet::factory(),
'invoice_number' => Str::upper($this->faker->bothify('PO-########')),
'purchase_date' => $this->faker->date(),
'total' => $this->faker->numberBetween(50000, 500000),
'note' => $this->faker->optional()->sentence(6),
];
}
}

View File

@ -0,0 +1,29 @@
<?php
namespace Database\Factories;
use App\Models\Purchase;
use App\Models\PurchaseItem;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class PurchaseItemFactory extends Factory
{
protected $model = PurchaseItem::class;
public function definition(): array
{
$unitPrice = $this->faker->numberBetween(10000, 100000);
$quantity = $this->faker->numberBetween(1, 10);
return [
'purchase_id' => Purchase::factory(),
'user_id' => User::factory(),
'purchasable_type' => null,
'purchasable_id' => null,
'quantity' => $quantity,
'unit_price' => $unitPrice,
'total_price' => $unitPrice * $quantity,
];
}
}

View File

@ -0,0 +1,28 @@
<?php
namespace Database\Factories;
use App\Models\PushNotification;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class PushNotificationFactory extends Factory
{
protected $model = PushNotification::class;
public function definition(): array
{
return [
'user_id' => User::factory(),
'subscriptions' => [
[
'endpoint' => $this->faker->url(),
'keys' => [
'p256dh' => $this->faker->sha256(),
'auth' => $this->faker->md5(),
],
],
],
];
}
}

View File

@ -2,13 +2,13 @@
namespace Database\Factories;
use App\Models\ReferralCode;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\ReferralCode>
*/
class ReferralCodeFactory extends Factory
{
protected $model = ReferralCode::class;
public function definition(): array
{
return [

View File

@ -0,0 +1,21 @@
<?php
namespace Database\Factories;
use App\Models\ReferralCode;
use App\Models\ReferralUsage;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class ReferralUsageFactory extends Factory
{
protected $model = ReferralUsage::class;
public function definition(): array
{
return [
'user_id' => User::factory(),
'referral_code_id' => ReferralCode::factory(),
];
}
}

View File

@ -0,0 +1,25 @@
<?php
namespace Database\Factories;
use App\Models\SalaryHistory;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class SalaryHistoryFactory extends Factory
{
protected $model = SalaryHistory::class;
public function definition(): array
{
$old = $this->faker->numberBetween(3000000, 6000000);
$new = $old + $this->faker->numberBetween(-500000, 1000000);
return [
'user_id' => User::factory(),
'old_salary' => $old,
'new_salary' => max(0, $new),
'effective_date' => $this->faker->date(),
];
}
}

View File

@ -0,0 +1,33 @@
<?php
namespace Database\Factories;
use App\Enums\StockOpnameStatus;
use App\Models\Outlet;
use App\Models\StockOpname;
use Illuminate\Database\Eloquent\Factories\Factory;
class StockOpnameFactory extends Factory
{
protected $model = StockOpname::class;
public function definition(): array
{
return [
'outlet_id' => Outlet::factory(),
'period_month' => $this->faker->date('Y-m'),
'status' => StockOpnameStatus::DRAFT,
'note' => $this->faker->optional()->sentence(8),
];
}
public function draft(): Factory
{
return $this->state(fn () => ['status' => StockOpnameStatus::DRAFT]);
}
public function finalized(): Factory
{
return $this->state(fn () => ['status' => StockOpnameStatus::FINALIZED]);
}
}

View File

@ -0,0 +1,28 @@
<?php
namespace Database\Factories;
use App\Models\StockOpname;
use App\Models\StockOpnameItem;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class StockOpnameItemFactory extends Factory
{
protected $model = StockOpnameItem::class;
public function definition(): array
{
$qtySystem = $this->faker->numberBetween(0, 200);
$qtyPhysical = $this->faker->optional()->numberBetween(0, 200);
return [
'stock_opname_id' => StockOpname::factory(),
'user_id' => User::factory(),
'itemable_type' => null,
'itemable_id' => null,
'qty_system' => $qtySystem,
'qty_physical' => $qtyPhysical,
];
}
}

View File

@ -2,10 +2,13 @@
namespace Database\Factories;
use App\Models\Tier;
use Illuminate\Database\Eloquent\Factories\Factory;
class TierFactory extends Factory
{
protected $model = Tier::class;
public function definition(): array
{
return [

View File

@ -0,0 +1,21 @@
<?php
namespace Database\Factories;
use App\Models\Tier;
use App\Models\TierReward;
use Illuminate\Database\Eloquent\Factories\Factory;
class TierRewardFactory extends Factory
{
protected $model = TierReward::class;
public function definition(): array
{
return [
'tier_id' => Tier::factory(),
'name' => $this->faker->words(2, true),
'value' => $this->faker->numberBetween(10, 500),
];
}
}

View File

@ -3,35 +3,31 @@
namespace Database\Factories;
use App\Enums\UserStatus;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Facades\Hash;
class UserFactory extends Factory
{
protected $model = User::class;
public function definition(): array
{
return [
'email' => $this->faker->unique()->safeEmail(),
'username' => fake()->unique()->regexify('[A-Za-z0-9]{8}'),
'password' => Hash::make(config('myconfig.password_default')),
'',
];
}
public function active(): Factory
{
return $this->state(function (array $attributes) {
return [
'status' => UserStatus::ACTIVE,
];
});
return $this->state(fn () => ['status' => UserStatus::ACTIVE]);
}
public function inactive(): Factory
{
return $this->state(function (array $attributes) {
return [
'status' => UserStatus::INACTIVE,
];
});
return $this->state(fn () => ['status' => UserStatus::INACTIVE]);
}
}

View File

@ -0,0 +1,22 @@
<?php
namespace Database\Factories;
use App\Models\User;
use App\Models\UserVoucher;
use App\Models\Voucher;
use Illuminate\Database\Eloquent\Factories\Factory;
class UserVoucherFactory extends Factory
{
protected $model = UserVoucher::class;
public function definition(): array
{
return [
'user_id' => User::factory(),
'voucher_id' => Voucher::factory(),
'quantity' => $this->faker->numberBetween(1, 5),
];
}
}

View File

@ -0,0 +1,21 @@
<?php
namespace Database\Factories;
use App\Models\OrderItem;
use App\Models\VolumeItem;
use Illuminate\Database\Eloquent\Factories\Factory;
class VolumeItemFactory extends Factory
{
protected $model = VolumeItem::class;
public function definition(): array
{
return [
'order_item_id' => OrderItem::factory(),
'quality' => $this->faker->randomElement(['GOOD', 'OK', 'BAD']),
'volume' => $this->faker->numberBetween(5, 200),
];
}
}

View File

@ -2,7 +2,7 @@
namespace Database\Factories;
use App\Enums\IsActive;
use App\Enums\IsShow;
use App\Enums\VoucherType;
use App\Models\Voucher;
use Illuminate\Database\Eloquent\Factories\Factory;
@ -31,15 +31,17 @@ public function definition(): array
'summary' => $this->faker->sentence(),
'start_date' => $this->faker->dateTimeBetween('tomorrow', '+1 week')->format('Y-m-d'),
'end_date' => $this->faker->optional()->dateTimeBetween('+1 day', '+2 months')?->format('Y-m-d'),
'is_show' => $this->faker->randomElement(IsShow::values()),
];
}
public function active(): Factory
public function show(): Factory
{
return $this->state(function (array $attributes) {
return [
'is_active' => IsActive::ACTIVE,
];
});
return $this->state(fn () => ['is_show' => IsShow::SHOW]);
}
public function hidden(): Factory
{
return $this->state(fn () => ['is_show' => IsShow::HIDDEN]);
}
}

View File

@ -17,7 +17,7 @@ public function up(): void
$table->string('email', 100)->unique();
$table->string('username', 20)->unique();
$table->string('password', 97);
$table->enum('status', [UserStatus::values()])->default(UserStatus::ACTIVE)->comment(UserStatus::comment());
$table->enum('status', UserStatus::values())->default(UserStatus::ACTIVE)->comment(UserStatus::comment());
$table->timestamp('email_verified_at')->nullable();
$table->timestamp('last_login_at')->nullable();
$table->timestamp('last_password_change_at')->nullable();

View File

@ -20,12 +20,12 @@ public function up(): void
$table->string('code', 20)->unique();
$table->string('phone_number', 20);
$table->unsignedInteger('base_salary')->default(0);
$table->enum('gender', [Gender::values()])->comment(Gender::comment());
$table->enum('gender', Gender::values())->comment(Gender::comment());
$table->text('address')->nullable();
$table->date('birthdate');
$table->date('hire_date');
$table->date('resign_date')->nullable();
$table->enum('status', [EmploymentStatus::values()])->default(EmploymentStatus::PERMANENT)->comment(EmploymentStatus::comment());
$table->enum('status', EmploymentStatus::values())->default(EmploymentStatus::PERMANENT)->comment(EmploymentStatus::comment());
$table->timestamp('created_at')->useCurrent();
$table->timestamp('updated_at')->nullable()->useCurrentOnUpdate();
$table->softDeletes();

View File

@ -20,7 +20,7 @@ public function up(): void
$table->text('address');
$table->string('landmark', 30)->nullable();
$table->text('maps_url')->nullable();
$table->enum('status', [OutletStatus::values()])->default(OutletStatus::OPERATIONAL)->comment(OutletStatus::comment());
$table->enum('status', OutletStatus::values())->default(OutletStatus::OPERATIONAL)->comment(OutletStatus::comment());
$table->date('opened_date');
$table->date('closed_date')->nullable();
$table->timestamp('created_at')->useCurrent();

View File

@ -17,7 +17,7 @@ public function up(): void
$table->id();
$table->string('name', 50);
$table->string('code', 20)->unique();
$table->enum('type', [VoucherType::values()])->default(VoucherType::PERCENTAGE)->comment(VoucherType::comment());
$table->enum('type', VoucherType::values())->default(VoucherType::PERCENTAGE)->comment(VoucherType::comment());
$table->string('tags', 20);
$table->string('summary', 200);
$table->unsignedInteger('discount_amount');
@ -28,7 +28,7 @@ public function up(): void
$table->unsignedInteger('limit_per_user')->nullable();
$table->date('start_date');
$table->date('end_date')->nullable();
$table->enum('is_show', [IsShow::values()])->default(IsShow::SHOW)->comment(IsShow::comment());
$table->enum('is_show', IsShow::values())->default(IsShow::SHOW)->comment(IsShow::comment());
$table->timestamp('created_at')->useCurrent();
$table->timestamp('updated_at')->nullable()->useCurrentOnUpdate();
$table->softDeletes();

View File

@ -17,7 +17,7 @@ public function up(): void
$table->foreignId('user_id')->nullable()->constrained()->cascadeOnDelete();
$table->string('name', 50);
$table->string('phone_number', 20)->nullable();
$table->enum('gender', [Gender::values()])->comment(Gender::comment());
$table->enum('gender', Gender::values())->comment(Gender::comment());
$table->timestamp('created_at')->useCurrent();
$table->timestamp('updated_at')->nullable()->useCurrentOnUpdate();
$table->softDeletes();

View File

@ -18,7 +18,7 @@ public function up(): void
$table->string('name', 50);
$table->string('slug', 70)->unique();
$table->string('sku', 20)->unique();
$table->enum('concentration', [Concentration::values()])->default(Concentration::EXTRAIT_DE_PERFUME)->comment(Concentration::comment());
$table->enum('concentration', Concentration::values())->default(Concentration::EXTRAIT_DE_PERFUME)->comment(Concentration::comment());
$table->unsignedInteger('cost_price')->default(0);
$table->unsignedInteger('sale_price')->default(0);
$table->unsignedInteger('point_per_ml');

View File

@ -19,7 +19,7 @@ public function up(): void
$table->string('slug')->unique();
$table->text('excerpt');
$table->text('content');
$table->enum('status', [ArticleStatus::values()])->default(ArticleStatus::PUBLISHED)->comment(ArticleStatus::comment());
$table->enum('status', ArticleStatus::values())->default(ArticleStatus::PUBLISHED)->comment(ArticleStatus::comment());
$table->timestamp('published_at')->nullable();
$table->unsignedInteger('views')->default(0);
$table->timestamp('created_at')->useCurrent();

View File

@ -20,7 +20,7 @@ public function up(): void
$table->unsignedInteger('bonus');
$table->unsignedInteger('deduction');
$table->unsignedInteger('total_salary');
$table->enum('is_paid', [IsPaid::values()])->default(IsPaid::NOT_PAID)->comment(IsPaid::comment());
$table->enum('is_paid', IsPaid::values())->default(IsPaid::NOT_PAID)->comment(IsPaid::comment());
$table->dateTime('paid_at')->nullable();
$table->timestamp('created_at')->useCurrent();
$table->timestamp('updated_at')->useCurrent()->useCurrentOnUpdate();

View File

@ -15,7 +15,7 @@ public function up(): void
Schema::create('payroll_adjustments', function (Blueprint $table) {
$table->id();
$table->foreignId('payroll_id')->constrained()->cascadeOnDelete();
$table->enum('type', [SalaryAdjustmentType::values()])->comment(SalaryAdjustmentType::comment());
$table->enum('type', SalaryAdjustmentType::values())->comment(SalaryAdjustmentType::comment());
$table->string('description', 100);
$table->unsignedInteger('amount');
$table->timestamp('created_at')->useCurrent();

View File

@ -24,8 +24,8 @@ public function up(): void
$table->unsignedInteger('subtotal');
$table->unsignedInteger('discount');
$table->unsignedInteger('total');
$table->enum('channel', [OrderChannel::values()])->default(OrderChannel::OUTLET)->comment(OrderChannel::comment());
$table->enum('status', [OrderStatus::values()])->default(OrderStatus::PENDING)->comment(OrderStatus::comment());
$table->enum('channel', OrderChannel::values())->default(OrderChannel::OUTLET)->comment(OrderChannel::comment());
$table->enum('status', OrderStatus::values())->default(OrderStatus::PENDING)->comment(OrderStatus::comment());
$table->dateTime('ordered_at');
$table->timestamp('created_at')->useCurrent();
$table->timestamp('updated_at')->nullable()->useCurrentOnUpdate();

View File

@ -17,10 +17,10 @@ public function up(): void
$table->id();
$table->foreignId('order_id')->constrained()->cascadeOnDelete();
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
$table->enum('method', [PaymentMethod::values()])->default(PaymentMethod::CASH)->comment(PaymentMethod::comment());
$table->enum('method', PaymentMethod::values())->default(PaymentMethod::CASH)->comment(PaymentMethod::comment());
$table->unsignedInteger('amount');
$table->timestamp('paid_at')->useCurrent();
$table->enum('status', [PaymentStatus::values()])->default(PaymentStatus::PENDING)->comment(PaymentStatus::comment());
$table->enum('status', PaymentStatus::values())->default(PaymentStatus::PENDING)->comment(PaymentStatus::comment());
$table->timestamp('created_at')->useCurrent();
$table->timestamp('updated_at')->nullable()->useCurrentOnUpdate();
$table->softDeletes();

View File

@ -16,7 +16,7 @@ public function up(): void
$table->id();
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
$table->string('module', 20);
$table->enum('status', [PriceRequestStatus::values()])->default(PriceRequestStatus::PENDING)->comment(PriceRequestStatus::comment());
$table->enum('status', PriceRequestStatus::values())->default(PriceRequestStatus::PENDING)->comment(PriceRequestStatus::comment());
$table->timestamp('finalized_at')->nullable();
$table->timestamp('created_at')->useCurrent();
$table->timestamp('updated_at')->useCurrent()->useCurrentOnUpdate();

View File

@ -16,7 +16,7 @@ public function up(): void
$table->id();
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
$table->unsignedBigInteger('change');
$table->enum('type', [PointRecordType::values()])->comment(PointRecordType::comment());
$table->enum('type', PointRecordType::values())->comment(PointRecordType::comment());
$table->string('description', 50);
$table->boolean('is_addition');
$table->timestamp('created_at')->useCurrent();

View File

@ -16,7 +16,7 @@ public function up(): void
$table->id();
$table->foreignId('outlet_id')->constrained()->cascadeOnDelete();
$table->string('period_month', 7);
$table->enum('status', [StockOpnameStatus::values()])->default(StockOpnameStatus::DRAFT)->comment(StockOpnameStatus::comment());
$table->enum('status', StockOpnameStatus::values())->default(StockOpnameStatus::DRAFT)->comment(StockOpnameStatus::comment());
$table->text('note')->nullable();
$table->timestamp('created_at')->useCurrent();
$table->timestamp('updated_at')->nullable()->useCurrentOnUpdate();