feat: Add Redemption and Reward factories, refactor existing factories to use explicit with methods, and update UserSeeder.
This commit is contained in:
parent
c5672366eb
commit
f657a5273f
@ -35,28 +35,28 @@ public function getSlugOptions(): SlugOptions
|
||||
->saveSlugsTo('slug');
|
||||
}
|
||||
|
||||
public function items(): MorphMany
|
||||
{
|
||||
return $this->morphMany(OrderItem::class, 'orderable');
|
||||
}
|
||||
|
||||
public function outlets(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Outlet::class)->withPivot('stock');
|
||||
}
|
||||
|
||||
public function warehouses(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Warehouse::class)->withPivot('stock');
|
||||
}
|
||||
|
||||
public function purchaseItems(): MorphMany
|
||||
{
|
||||
return $this->morphMany(PurchaseItem::class, 'purchasable');
|
||||
}
|
||||
|
||||
public function items(): MorphMany
|
||||
{
|
||||
return $this->morphMany(OrderItem::class, 'orderable');
|
||||
}
|
||||
|
||||
public function restockItems(): MorphMany
|
||||
{
|
||||
return $this->morphMany(RestockItem::class, 'restockable');
|
||||
}
|
||||
|
||||
public function warehouses(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Warehouse::class)->withPivot('stock');
|
||||
}
|
||||
}
|
||||
|
||||
@ -48,13 +48,13 @@ public function getSlugOptions(): SlugOptions
|
||||
->saveSlugsTo('slug');
|
||||
}
|
||||
|
||||
public function perfumes(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Perfume::class);
|
||||
}
|
||||
|
||||
public function articles(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Article::class);
|
||||
}
|
||||
|
||||
public function perfumes(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Perfume::class);
|
||||
}
|
||||
}
|
||||
|
||||
@ -37,13 +37,13 @@ public function yesterday(Builder $query): void
|
||||
$query->whereDate('created_at', today()->subDay());
|
||||
}
|
||||
|
||||
public function user(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
public function orders(): HasMany
|
||||
{
|
||||
return $this->hasMany(Order::class);
|
||||
}
|
||||
|
||||
public function user(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,16 +23,6 @@ protected function casts(): array
|
||||
];
|
||||
}
|
||||
|
||||
public function user(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
public function tier(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Tier::class);
|
||||
}
|
||||
|
||||
#[Scope]
|
||||
protected function scopeForSpending(Builder $query, $totalSpending): void
|
||||
{
|
||||
@ -43,4 +33,14 @@ protected function scopeForSpending(Builder $query, $totalSpending): void
|
||||
->orWhere('max_spending', '>=', $totalSpending);
|
||||
});
|
||||
}
|
||||
|
||||
public function tier(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Tier::class);
|
||||
}
|
||||
|
||||
public function user(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
}
|
||||
|
||||
@ -52,33 +52,33 @@ public function yesterday(Builder $query): void
|
||||
$query->whereDate('created_at', today()->subDay());
|
||||
}
|
||||
|
||||
public function outlet(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Outlet::class);
|
||||
}
|
||||
|
||||
public function user(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
public function customer(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Customer::class);
|
||||
}
|
||||
|
||||
public function voucher(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Voucher::class);
|
||||
}
|
||||
|
||||
public function items(): HasMany
|
||||
{
|
||||
return $this->hasMany(OrderItem::class);
|
||||
}
|
||||
|
||||
public function outlet(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Outlet::class);
|
||||
}
|
||||
|
||||
public function payments(): HasMany
|
||||
{
|
||||
return $this->hasMany(Payment::class);
|
||||
}
|
||||
|
||||
public function user(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
public function voucher(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Voucher::class);
|
||||
}
|
||||
}
|
||||
|
||||
@ -41,16 +41,16 @@ public function order(): BelongsTo
|
||||
return $this->belongsTo(Order::class);
|
||||
}
|
||||
|
||||
public function user(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
public function orderable(): MorphTo
|
||||
{
|
||||
return $this->morphTo()->withTrashed();
|
||||
}
|
||||
|
||||
public function user(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
public function volumes(): HasMany
|
||||
{
|
||||
return $this->hasMany(VolumeItem::class);
|
||||
|
||||
@ -45,9 +45,14 @@ public function operational(Builder $query): void
|
||||
$query->where('status', OutletStatus::OPERATIONAL->value);
|
||||
}
|
||||
|
||||
public function openingHours(): HasMany
|
||||
public function bottles(): BelongsToMany
|
||||
{
|
||||
return $this->hasMany(OpeningHour::class);
|
||||
return $this->belongsToMany(Bottle::class)->withPivot('stock');
|
||||
}
|
||||
|
||||
public function expenses(): HasMany
|
||||
{
|
||||
return $this->hasMany(Expense::class);
|
||||
}
|
||||
|
||||
public function facilities(): HasMany
|
||||
@ -55,9 +60,14 @@ public function facilities(): HasMany
|
||||
return $this->hasMany(Facility::class);
|
||||
}
|
||||
|
||||
public function vouchers(): BelongsToMany
|
||||
public function openingHours(): HasMany
|
||||
{
|
||||
return $this->belongsToMany(Voucher::class);
|
||||
return $this->hasMany(OpeningHour::class);
|
||||
}
|
||||
|
||||
public function orders(): HasMany
|
||||
{
|
||||
return $this->hasMany(Order::class);
|
||||
}
|
||||
|
||||
public function perfumes(): BelongsToMany
|
||||
@ -70,29 +80,14 @@ public function products(): BelongsToMany
|
||||
return $this->belongsToMany(Product::class)->withPivot('stock');
|
||||
}
|
||||
|
||||
public function bottles(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Bottle::class)->withPivot('stock');
|
||||
}
|
||||
|
||||
public function expenses(): HasMany
|
||||
{
|
||||
return $this->hasMany(Expense::class);
|
||||
}
|
||||
|
||||
public function users(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(User::class);
|
||||
}
|
||||
|
||||
public function purchases(): HasMany
|
||||
{
|
||||
return $this->hasMany(Purchase::class);
|
||||
}
|
||||
|
||||
public function orders(): HasMany
|
||||
public function restocks(): HasMany
|
||||
{
|
||||
return $this->hasMany(Order::class);
|
||||
return $this->hasMany(Restock::class);
|
||||
}
|
||||
|
||||
public function stockOpname(): HasMany
|
||||
@ -100,8 +95,13 @@ public function stockOpname(): HasMany
|
||||
return $this->hasMany(StockOpname::class);
|
||||
}
|
||||
|
||||
public function restocks(): HasMany
|
||||
public function users(): BelongsToMany
|
||||
{
|
||||
return $this->hasMany(Restock::class);
|
||||
return $this->belongsToMany(User::class);
|
||||
}
|
||||
|
||||
public function vouchers(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Voucher::class);
|
||||
}
|
||||
}
|
||||
|
||||
@ -54,13 +54,13 @@ public function forCurrentUser(Builder $query): void
|
||||
}
|
||||
}
|
||||
|
||||
public function user(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
public function adjustments(): HasMany
|
||||
{
|
||||
return $this->hasMany(PayrollAdjustment::class);
|
||||
}
|
||||
|
||||
public function user(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
}
|
||||
|
||||
@ -48,28 +48,28 @@ public function categories(): BelongsToMany
|
||||
return $this->belongsToMany(Category::class);
|
||||
}
|
||||
|
||||
public function items(): MorphMany
|
||||
{
|
||||
return $this->morphMany(OrderItem::class, 'orderable');
|
||||
}
|
||||
|
||||
public function outlets(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Outlet::class)->withPivot('stock');
|
||||
}
|
||||
|
||||
public function warehouses(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Warehouse::class)->withPivot('stock');
|
||||
}
|
||||
|
||||
public function purchaseItems(): MorphMany
|
||||
{
|
||||
return $this->morphMany(PurchaseItem::class, 'purchasable');
|
||||
}
|
||||
|
||||
public function items(): MorphMany
|
||||
{
|
||||
return $this->morphMany(OrderItem::class, 'orderable');
|
||||
}
|
||||
|
||||
public function restockItems(): MorphMany
|
||||
{
|
||||
return $this->morphMany(RestockItem::class, 'restockable');
|
||||
}
|
||||
|
||||
public function warehouses(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Warehouse::class)->withPivot('stock');
|
||||
}
|
||||
}
|
||||
|
||||
@ -35,28 +35,28 @@ public function getSlugOptions(): SlugOptions
|
||||
->saveSlugsTo('slug');
|
||||
}
|
||||
|
||||
public function items(): MorphMany
|
||||
{
|
||||
return $this->morphMany(OrderItem::class, 'orderable');
|
||||
}
|
||||
|
||||
public function outlets(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Outlet::class)->withPivot('stock');
|
||||
}
|
||||
|
||||
public function warehouses(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Warehouse::class)->withPivot('stock');
|
||||
}
|
||||
|
||||
public function purchaseItems(): MorphMany
|
||||
{
|
||||
return $this->morphMany(PurchaseItem::class, 'purchasable');
|
||||
}
|
||||
|
||||
public function items(): MorphMany
|
||||
{
|
||||
return $this->morphMany(OrderItem::class, 'orderable');
|
||||
}
|
||||
|
||||
public function restockItems(): MorphMany
|
||||
{
|
||||
return $this->morphMany(RestockItem::class, 'restockable');
|
||||
}
|
||||
|
||||
public function warehouses(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Warehouse::class)->withPivot('stock');
|
||||
}
|
||||
}
|
||||
|
||||
@ -39,21 +39,6 @@ public static function isOverlap(int $minSpending, ?int $maxSpending, ?int $igno
|
||||
});
|
||||
}
|
||||
|
||||
public function memberships(): HasMany
|
||||
{
|
||||
return $this->hasMany(Membership::class);
|
||||
}
|
||||
|
||||
public function vouchers(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Voucher::class);
|
||||
}
|
||||
|
||||
public function rewards(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Reward::class);
|
||||
}
|
||||
|
||||
public static function getHighestTier()
|
||||
{
|
||||
return self::orderByDesc('min_spending')->first();
|
||||
@ -142,4 +127,19 @@ public static function canDeleteTier(int $tierId): array
|
||||
'message' => 'Tidak dapat menghapus tier tengah karena akan mengacaukan sistem belanja. Tier harus membentuk rantai yang kontinyu.',
|
||||
];
|
||||
}
|
||||
|
||||
public function memberships(): HasMany
|
||||
{
|
||||
return $this->hasMany(Membership::class);
|
||||
}
|
||||
|
||||
public function rewards(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Reward::class);
|
||||
}
|
||||
|
||||
public function vouchers(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Voucher::class);
|
||||
}
|
||||
}
|
||||
|
||||
@ -57,44 +57,6 @@ protected function withoutDeveloper(Builder $query): void
|
||||
});
|
||||
}
|
||||
|
||||
// HasOne relationships (alphabetical)
|
||||
public function customer(): HasOne
|
||||
{
|
||||
return $this->hasOne(Customer::class);
|
||||
}
|
||||
|
||||
public function employee(): HasOne
|
||||
{
|
||||
return $this->hasOne(Employee::class);
|
||||
}
|
||||
|
||||
public function membership(): HasOne
|
||||
{
|
||||
return $this->hasOne(Membership::class);
|
||||
}
|
||||
|
||||
public function referralCode(): HasOne
|
||||
{
|
||||
return $this->hasOne(ReferralCode::class);
|
||||
}
|
||||
|
||||
public function referralUsage(): HasOne
|
||||
{
|
||||
return $this->hasOne(ReferralUsage::class);
|
||||
}
|
||||
|
||||
// BelongsToMany relationships (alphabetical)
|
||||
public function outlets(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Outlet::class);
|
||||
}
|
||||
|
||||
public function vouchers(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Voucher::class);
|
||||
}
|
||||
|
||||
// HasMany relationships (alphabetical)
|
||||
public function articles(): HasMany
|
||||
{
|
||||
return $this->hasMany(Article::class, 'author_id');
|
||||
@ -105,6 +67,16 @@ public function broadcasts(): HasMany
|
||||
return $this->hasMany(Broadcast::class);
|
||||
}
|
||||
|
||||
public function customer(): HasOne
|
||||
{
|
||||
return $this->hasOne(Customer::class);
|
||||
}
|
||||
|
||||
public function employee(): HasOne
|
||||
{
|
||||
return $this->hasOne(Employee::class);
|
||||
}
|
||||
|
||||
public function expenses(): HasMany
|
||||
{
|
||||
return $this->hasMany(Expense::class);
|
||||
@ -115,11 +87,21 @@ public function items(): HasMany
|
||||
return $this->hasMany(OrderItem::class);
|
||||
}
|
||||
|
||||
public function membership(): HasOne
|
||||
{
|
||||
return $this->hasOne(Membership::class);
|
||||
}
|
||||
|
||||
public function orders(): HasMany
|
||||
{
|
||||
return $this->hasMany(Order::class);
|
||||
}
|
||||
|
||||
public function outlets(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Outlet::class);
|
||||
}
|
||||
|
||||
public function payments(): HasMany
|
||||
{
|
||||
return $this->hasMany(Payment::class);
|
||||
@ -150,6 +132,16 @@ public function redemptions(): HasMany
|
||||
return $this->hasMany(Redemption::class);
|
||||
}
|
||||
|
||||
public function referralCode(): HasOne
|
||||
{
|
||||
return $this->hasOne(ReferralCode::class);
|
||||
}
|
||||
|
||||
public function referralUsage(): HasOne
|
||||
{
|
||||
return $this->hasOne(ReferralUsage::class);
|
||||
}
|
||||
|
||||
public function salaryHistories(): HasMany
|
||||
{
|
||||
return $this->hasMany(SalaryHistory::class);
|
||||
@ -164,4 +156,9 @@ public function verifiedRedemptions(): HasMany
|
||||
{
|
||||
return $this->hasMany(Redemption::class, 'verified_by');
|
||||
}
|
||||
|
||||
public function vouchers(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Voucher::class);
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,6 +18,11 @@ class Warehouse extends Model
|
||||
|
||||
protected $cascadeDeletes = ['perfumes', 'products', 'bottles', 'purchases', 'restocks'];
|
||||
|
||||
public function bottles(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Bottle::class)->withPivot('stock');
|
||||
}
|
||||
|
||||
public function perfumes(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Perfume::class)->withPivot('stock');
|
||||
@ -28,11 +33,6 @@ public function products(): BelongsToMany
|
||||
return $this->belongsToMany(Product::class)->withPivot('stock');
|
||||
}
|
||||
|
||||
public function bottles(): BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Bottle::class)->withPivot('stock');
|
||||
}
|
||||
|
||||
public function purchases(): HasMany
|
||||
{
|
||||
return $this->hasMany(Purchase::class);
|
||||
|
||||
@ -11,15 +11,17 @@ class BottleFactory extends Factory
|
||||
|
||||
public function definition(): array
|
||||
{
|
||||
$costPrice = $this->faker->randomNumber(2);
|
||||
|
||||
return [
|
||||
'name' => $this->faker->word(),
|
||||
'slug' => $this->faker->slug(),
|
||||
'size' => $this->faker->randomNumber(2),
|
||||
'cost_price' => $this->faker->randomNumber(2),
|
||||
'sale_price' => $this->faker->randomNumber(2),
|
||||
'description' => $this->faker->sentence(),
|
||||
];
|
||||
}
|
||||
|
||||
public function withDescription(): Factory
|
||||
{
|
||||
return $this->state(fn () => ['description' => $this->faker->sentence()]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,7 +14,6 @@ public function definition(): array
|
||||
return [
|
||||
'name' => $this->faker->unique()->company(),
|
||||
'slug' => $this->faker->slug(),
|
||||
'description' => $this->faker->optional()->text(),
|
||||
'sort_order' => function () {
|
||||
$max = Category::max('sort_order') ?? 0;
|
||||
|
||||
@ -22,4 +21,9 @@ public function definition(): array
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
public function withDescription(): Factory
|
||||
{
|
||||
return $this->state(fn () => ['description' => $this->faker->text()]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,6 +23,11 @@ public function definition(): array
|
||||
];
|
||||
}
|
||||
|
||||
public function withAddress(): Factory
|
||||
{
|
||||
return $this->state(fn () => ['address' => $this->faker->address()]);
|
||||
}
|
||||
|
||||
public function male(): Factory
|
||||
{
|
||||
return $this->state(fn () => ['gender' => Gender::MALE]);
|
||||
|
||||
@ -24,15 +24,23 @@ public function definition(): array
|
||||
$this->faker->numerify('0812 #### #####'),
|
||||
]),
|
||||
'base_salary' => $this->faker->randomNumber(6),
|
||||
'address' => $this->faker->address(),
|
||||
'birthdate' => $this->faker->dateTimeBetween('-60 years', '-18 years')->format('Y-m-d'),
|
||||
'hire_date' => $this->faker->date(),
|
||||
'resign_date' => $this->faker->optional()->date(),
|
||||
'gender' => $this->faker->randomElement(Gender::cases()),
|
||||
'status' => $this->faker->randomElement(EmploymentStatus::cases()),
|
||||
];
|
||||
}
|
||||
|
||||
public function withAddress(): Factory
|
||||
{
|
||||
return $this->state(fn () => ['address' => $this->faker->address()]);
|
||||
}
|
||||
|
||||
public function resigned(): Factory
|
||||
{
|
||||
return $this->state(fn () => ['resign_date' => $this->faker->date()]);
|
||||
}
|
||||
|
||||
public function male(): Factory
|
||||
{
|
||||
return $this->state(fn () => ['gender' => Gender::MALE]);
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
use App\Models\Membership;
|
||||
use App\Models\Tier;
|
||||
use App\Models\User;
|
||||
use DateTime;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
|
||||
class MembershipFactory extends Factory
|
||||
@ -18,7 +19,11 @@ public function definition(): array
|
||||
'tier_id' => Tier::factory(),
|
||||
'total_spending' => $this->faker->numberBetween(0, 5000000),
|
||||
'reward_points' => $this->faker->numberBetween(0, 1000),
|
||||
'last_transaction_at' => $this->faker->optional()->dateTimeBetween('-30 days', 'now'),
|
||||
];
|
||||
}
|
||||
|
||||
public function withLastTransaction(?DateTime $date = null): Factory
|
||||
{
|
||||
return $this->state(fn () => ['last_transaction_at' => $date ?? now()]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,8 +2,11 @@
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use App\Models\Bottle;
|
||||
use App\Models\Order;
|
||||
use App\Models\OrderItem;
|
||||
use App\Models\Perfume;
|
||||
use App\Models\Product;
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
|
||||
@ -17,13 +20,45 @@ public function definition(): array
|
||||
$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,
|
||||
];
|
||||
}
|
||||
|
||||
public function forOrder(?Order $order = null): Factory
|
||||
{
|
||||
return $this->state(fn () => ['order_id' => $order?->id ?? Order::factory()]);
|
||||
}
|
||||
|
||||
public function forProduct(?Product $product = null): Factory
|
||||
{
|
||||
$product = $product ?? Product::factory()->create();
|
||||
|
||||
return $this->state(fn () => [
|
||||
'orderable_type' => $product->getMorphClass(),
|
||||
'orderable_id' => $product->id,
|
||||
]);
|
||||
}
|
||||
|
||||
public function forPerfume(?Perfume $perfume = null): Factory
|
||||
{
|
||||
$perfume = $perfume ?? Perfume::factory()->create();
|
||||
|
||||
return $this->state(fn () => [
|
||||
'orderable_type' => $perfume->getMorphClass(),
|
||||
'orderable_id' => $perfume->id,
|
||||
]);
|
||||
}
|
||||
|
||||
public function forBottle(?Bottle $bottle = null): Factory
|
||||
{
|
||||
$bottle = $bottle ?? Bottle::factory()->create();
|
||||
|
||||
return $this->state(fn () => [
|
||||
'orderable_type' => $bottle->getMorphClass(),
|
||||
'orderable_id' => $bottle->id,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,13 +21,26 @@ public function definition(): array
|
||||
$this->faker->numerify('0812 #### #####'),
|
||||
]),
|
||||
'address' => $this->faker->address(),
|
||||
'landmark' => $this->faker->streetName(),
|
||||
'maps_url' => 'https://goo.gl/maps/'.$this->faker->regexify('[A-Za-z0-9]{6,10}'),
|
||||
'opened_date' => $this->faker->date(),
|
||||
'status' => $this->faker->randomElement(OutletStatus::cases()),
|
||||
];
|
||||
}
|
||||
|
||||
public function withLandmark(): Factory
|
||||
{
|
||||
return $this->state(fn () => ['landmark' => $this->faker->streetName()]);
|
||||
}
|
||||
|
||||
public function withMapsUrl(): Factory
|
||||
{
|
||||
return $this->state(fn () => ['maps_url' => 'https://goo.gl/maps/'.$this->faker->regexify('[A-Za-z0-9]{6,10}')]);
|
||||
}
|
||||
|
||||
public function closed(): Factory
|
||||
{
|
||||
return $this->state(fn () => ['closed_date' => $this->faker->date()]);
|
||||
}
|
||||
|
||||
public function operational(): Factory
|
||||
{
|
||||
return $this->state(fn () => ['status' => OutletStatus::OPERATIONAL]);
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
use App\Models\Order;
|
||||
use App\Models\Payment;
|
||||
use App\Models\User;
|
||||
use DateTime;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
|
||||
class PaymentFactory extends Factory
|
||||
@ -20,11 +21,19 @@ public function definition(): array
|
||||
'user_id' => User::factory(),
|
||||
'method' => $this->faker->randomElement(PaymentMethod::cases()),
|
||||
'amount' => $this->faker->numberBetween(20000, 400000),
|
||||
'paid_at' => $this->faker->dateTimeBetween('-7 days', 'now'),
|
||||
'status' => $this->faker->randomElement(PaymentStatus::cases()),
|
||||
];
|
||||
}
|
||||
|
||||
public function withPaidAt(?DateTime $paidAt = null): Factory
|
||||
{
|
||||
return $this->state(fn () => ['paid_at' => $paidAt ?? now()]);
|
||||
}
|
||||
|
||||
public function withStatus(PaymentStatus $status): Factory
|
||||
{
|
||||
return $this->state(fn () => ['status' => $status]);
|
||||
}
|
||||
|
||||
public function cash(): Factory
|
||||
{
|
||||
return $this->state(fn () => ['method' => PaymentMethod::CASH]);
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
use App\Enums\IsPaid;
|
||||
use App\Models\Payroll;
|
||||
use App\Models\User;
|
||||
use DateTime;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
|
||||
class PayrollFactory extends Factory
|
||||
@ -17,8 +18,6 @@ public function definition(): array
|
||||
$bonus = $this->faker->numberBetween(0, 2000000);
|
||||
$deduction = $this->faker->numberBetween(0, 500000);
|
||||
|
||||
$isPaid = $this->faker->randomElement(IsPaid::cases());
|
||||
|
||||
return [
|
||||
'user_id' => User::factory(),
|
||||
'period_month' => $this->faker->date('Y-m'),
|
||||
@ -26,13 +25,23 @@ public function definition(): array
|
||||
'bonus' => $bonus,
|
||||
'deduction' => $deduction,
|
||||
'total_salary' => $base + $bonus - $deduction,
|
||||
'is_paid' => $isPaid,
|
||||
'paid_at' => $isPaid === IsPaid::PAID
|
||||
? $this->faker->dateTimeBetween('-3 days', 'now')
|
||||
: null,
|
||||
'is_paid' => IsPaid::NOT_PAID,
|
||||
];
|
||||
}
|
||||
|
||||
public function withPaidAt(?DateTime $paidAt = null): Factory
|
||||
{
|
||||
return $this->state(fn () => [
|
||||
'is_paid' => IsPaid::PAID,
|
||||
'paid_at' => $paidAt ?? now(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function withPeriodMonth(string $periodMonth): Factory
|
||||
{
|
||||
return $this->state(fn () => ['period_month' => $periodMonth]);
|
||||
}
|
||||
|
||||
public function paid(): Factory
|
||||
{
|
||||
return $this->state(fn () => [
|
||||
|
||||
@ -24,13 +24,28 @@ public function definition(): array
|
||||
'concentration' => $this->faker->randomElement(Concentration::cases()),
|
||||
'cost_price' => $this->faker->numberBetween(50000, 250000),
|
||||
'sale_price' => $this->faker->numberBetween(80000, 400000),
|
||||
'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 withNotes(): Factory
|
||||
{
|
||||
return $this->state(fn () => [
|
||||
'base_notes' => $this->faker->words(3, true),
|
||||
'middle_notes' => $this->faker->words(3, true),
|
||||
'top_notes' => $this->faker->words(3, true),
|
||||
]);
|
||||
}
|
||||
|
||||
public function withDescription(): Factory
|
||||
{
|
||||
return $this->state(fn () => ['description' => $this->faker->paragraph()]);
|
||||
}
|
||||
|
||||
public function withoutBrand(): Factory
|
||||
{
|
||||
return $this->state(fn () => ['brand_id' => null]);
|
||||
}
|
||||
|
||||
public function extrait(): Factory
|
||||
{
|
||||
return $this->state(fn () => ['concentration' => Concentration::EXTRAIT_DE_PERFUME]);
|
||||
|
||||
@ -20,7 +20,11 @@ public function definition(): array
|
||||
'sku' => strtoupper($this->faker->unique()->bothify('PRD-#####')),
|
||||
'cost_price' => $this->faker->numberBetween(20000, 150000),
|
||||
'sale_price' => $this->faker->numberBetween(30000, 200000),
|
||||
'description' => $this->faker->optional()->paragraph(),
|
||||
];
|
||||
}
|
||||
|
||||
public function withDescription(): Factory
|
||||
{
|
||||
return $this->state(fn () => ['description' => $this->faker->paragraph()]);
|
||||
}
|
||||
}
|
||||
|
||||
43
database/factories/RedemptionFactory.php
Normal file
43
database/factories/RedemptionFactory.php
Normal file
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use App\Enums\RedemptionStatus;
|
||||
use App\Models\Redemption;
|
||||
use App\Models\Reward;
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class RedemptionFactory extends Factory
|
||||
{
|
||||
protected $model = Redemption::class;
|
||||
|
||||
public function definition(): array
|
||||
{
|
||||
return [
|
||||
'user_id' => User::factory(),
|
||||
'reward_id' => Reward::factory(),
|
||||
'code' => Str::upper(Str::random(10)),
|
||||
'points_spent' => 100,
|
||||
'status' => RedemptionStatus::WAITING_PICKUP,
|
||||
'expires_at' => $this->faker->dateTimeBetween('+1 week', '+1 month'),
|
||||
];
|
||||
}
|
||||
|
||||
public function verified(User $verifier): Factory
|
||||
{
|
||||
return $this->state(fn () => [
|
||||
'status' => RedemptionStatus::PICKED_UP,
|
||||
'verified_at' => now(),
|
||||
'verified_by' => $verifier->id,
|
||||
]);
|
||||
}
|
||||
|
||||
public function expired(): Factory
|
||||
{
|
||||
return $this->state(fn () => [
|
||||
'status' => RedemptionStatus::EXPIRED,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@ -7,18 +7,10 @@
|
||||
use App\Models\Warehouse;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
|
||||
/**
|
||||
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Restock>
|
||||
*/
|
||||
class RestockFactory extends Factory
|
||||
{
|
||||
protected $model = Restock::class;
|
||||
|
||||
/**
|
||||
* Define the model's default state.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function definition(): array
|
||||
{
|
||||
return [
|
||||
|
||||
@ -10,18 +10,10 @@
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
|
||||
/**
|
||||
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\RestockItem>
|
||||
*/
|
||||
class RestockItemFactory extends Factory
|
||||
{
|
||||
protected $model = RestockItem::class;
|
||||
|
||||
/**
|
||||
* Define the model's default state.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function definition(): array
|
||||
{
|
||||
$restockableType = fake()->randomElement([Perfume::class, Product::class, Bottle::class]);
|
||||
|
||||
44
database/factories/RewardFactory.php
Normal file
44
database/factories/RewardFactory.php
Normal file
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use App\Enums\IsShow;
|
||||
use App\Enums\RewardCategory;
|
||||
use App\Models\Reward;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
|
||||
class RewardFactory extends Factory
|
||||
{
|
||||
protected $model = Reward::class;
|
||||
|
||||
public function definition(): array
|
||||
{
|
||||
return [
|
||||
'name' => $this->faker->words(2, true),
|
||||
'points' => $this->faker->numberBetween(10, 500),
|
||||
'category' => RewardCategory::REGULAR,
|
||||
'is_show' => IsShow::SHOW,
|
||||
'start_date' => $this->faker->dateTimeBetween('now', '+1 week')->format('Y-m-d'),
|
||||
];
|
||||
}
|
||||
|
||||
public function withStock(int $stock): Factory
|
||||
{
|
||||
return $this->state(fn () => ['stock' => $stock]);
|
||||
}
|
||||
|
||||
public function withEndDate(string $date): Factory
|
||||
{
|
||||
return $this->state(fn () => ['end_date' => $date]);
|
||||
}
|
||||
|
||||
public function show(): Factory
|
||||
{
|
||||
return $this->state(fn () => ['is_show' => IsShow::SHOW]);
|
||||
}
|
||||
|
||||
public function hidden(): Factory
|
||||
{
|
||||
return $this->state(fn () => ['is_show' => IsShow::HIDDEN]);
|
||||
}
|
||||
}
|
||||
@ -14,7 +14,11 @@ public function definition(): array
|
||||
return [
|
||||
'name' => $this->faker->name(),
|
||||
'min_spending' => $this->faker->randomNumber(),
|
||||
'max_spending' => $this->faker->optional()->randomNumber(),
|
||||
];
|
||||
}
|
||||
|
||||
public function withMaxSpending(int $amount): Factory
|
||||
{
|
||||
return $this->state(fn () => ['max_spending' => $amount]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -30,4 +30,9 @@ public function inactive(): Factory
|
||||
{
|
||||
return $this->state(fn () => ['status' => UserStatus::INACTIVE]);
|
||||
}
|
||||
|
||||
public function verified(): Factory
|
||||
{
|
||||
return $this->state(fn () => ['email_verified_at' => now()]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,20 +21,39 @@ public function definition(): array
|
||||
'code' => Str::upper(Str::random(8)),
|
||||
'tags' => $this->faker->words(1, true),
|
||||
'type' => $type,
|
||||
'discount_amount' => $type === VoucherType::PERCENTAGE->value
|
||||
'discount_amount' => $type === VoucherType::PERCENTAGE
|
||||
? $this->faker->numberBetween(5, 50)
|
||||
: $this->faker->numberBetween(10000, 100000),
|
||||
'min_purchase' => $this->faker->optional()->numberBetween(50000, 200000),
|
||||
'max_discount' => $type === VoucherType::PERCENTAGE->value ? $this->faker->numberBetween(10000, 50000) : null,
|
||||
'quota' => $this->faker->optional()->numberBetween(50, 500),
|
||||
'limit_per_user' => $this->faker->optional()->numberBetween(1, 5),
|
||||
'limit_per_user' => 1,
|
||||
'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()),
|
||||
'is_show' => IsShow::SHOW,
|
||||
];
|
||||
}
|
||||
|
||||
public function withMinPurchase(int $amount): Factory
|
||||
{
|
||||
return $this->state(fn () => ['min_purchase' => $amount]);
|
||||
}
|
||||
|
||||
public function withMaxDiscount(int $amount): Factory
|
||||
{
|
||||
return $this->state(fn () => ['max_discount' => $amount]);
|
||||
}
|
||||
|
||||
public function withQuota(int $quota): Factory
|
||||
{
|
||||
return $this->state(fn () => [
|
||||
'quota' => $quota,
|
||||
'available_count' => $quota,
|
||||
]);
|
||||
}
|
||||
|
||||
public function withEndDate(string $date): Factory
|
||||
{
|
||||
return $this->state(fn () => ['end_date' => $date]);
|
||||
}
|
||||
|
||||
public function show(): Factory
|
||||
{
|
||||
return $this->state(fn () => ['is_show' => IsShow::SHOW]);
|
||||
|
||||
@ -5,23 +5,19 @@
|
||||
use App\Models\Warehouse;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
|
||||
/**
|
||||
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Warehouse>
|
||||
*/
|
||||
class WarehouseFactory extends Factory
|
||||
{
|
||||
protected $model = Warehouse::class;
|
||||
|
||||
/**
|
||||
* Define the model's default state.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function definition(): array
|
||||
{
|
||||
return [
|
||||
'name' => fake()->company().' Warehouse',
|
||||
'description' => fake()->optional()->sentence(),
|
||||
];
|
||||
}
|
||||
|
||||
public function withDescription(): Factory
|
||||
{
|
||||
return $this->state(fn () => ['description' => fake()->sentence()]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use App\Enums\CategoryType;
|
||||
use App\Models\Category;
|
||||
use Illuminate\Database\Seeder;
|
||||
use Illuminate\Support\Str;
|
||||
@ -11,16 +12,20 @@ class CategorySeeder extends Seeder
|
||||
public function run(): void
|
||||
{
|
||||
$categories = [
|
||||
['name' => 'Floral', 'description' => 'Perfume with floral scents', 'sort_order' => 1],
|
||||
['name' => 'Citrus', 'description' => 'Fresh citrus fragrances', 'sort_order' => 2],
|
||||
['name' => 'Woody', 'description' => 'Warm woody notes', 'sort_order' => 3],
|
||||
['name' => 'Oriental', 'description' => 'Spicy and exotic oriental scents', 'sort_order' => 4],
|
||||
['name' => 'Fruity', 'description' => 'Sweet and fresh fruity fragrances', 'sort_order' => 5],
|
||||
['name' => 'Aquatic', 'description' => 'Light, oceanic, and fresh scents', 'sort_order' => 6],
|
||||
['name' => 'Gourmand', 'description' => 'Edible, sweet and dessert-like scents', 'sort_order' => 7],
|
||||
['name' => 'Green', 'description' => 'Fresh, leafy, and herbal notes', 'sort_order' => 8],
|
||||
['name' => 'Chypre', 'description' => 'Classic blend of citrus, oakmoss, and labdanum', 'sort_order' => 9],
|
||||
['name' => 'Musk', 'description' => 'Warm, sensual musky fragrances', 'sort_order' => 10],
|
||||
['name' => 'Floral', 'description' => 'Perfume with floral scents', 'sort_order' => 1, 'type' => CategoryType::PERFUME],
|
||||
['name' => 'Citrus', 'description' => 'Fresh citrus fragrances', 'sort_order' => 2, 'type' => CategoryType::PERFUME],
|
||||
['name' => 'Woody', 'description' => 'Warm woody notes', 'sort_order' => 3, 'type' => CategoryType::PERFUME],
|
||||
['name' => 'Oriental', 'description' => 'Spicy and exotic oriental scents', 'sort_order' => 4, 'type' => CategoryType::PERFUME],
|
||||
['name' => 'Fruity', 'description' => 'Sweet and fresh fruity fragrances', 'sort_order' => 5, 'type' => CategoryType::PERFUME],
|
||||
['name' => 'Aquatic', 'description' => 'Light, oceanic, and fresh scents', 'sort_order' => 6, 'type' => CategoryType::PERFUME],
|
||||
['name' => 'Gourmand', 'description' => 'Edible, sweet and dessert-like scents', 'sort_order' => 7, 'type' => CategoryType::PERFUME],
|
||||
['name' => 'Green', 'description' => 'Fresh, leafy, and herbal notes', 'sort_order' => 8, 'type' => CategoryType::PERFUME],
|
||||
['name' => 'Chypre', 'description' => 'Classic blend of citrus, oakmoss, and labdanum', 'sort_order' => 9, 'type' => CategoryType::PERFUME],
|
||||
['name' => 'Musk', 'description' => 'Warm, sensual musky fragrances', 'sort_order' => 10, 'type' => CategoryType::PERFUME],
|
||||
['name' => 'Tips n Tricks', 'description' => 'Tips and tricks for using perfumes', 'sort_order' => 11, 'type' => CategoryType::ARTICLE],
|
||||
['name' => 'Perfume Review', 'description' => 'Reviews of perfumes', 'sort_order' => 12, 'type' => CategoryType::ARTICLE],
|
||||
['name' => 'Perfume Set', 'description' => 'Perfume sets', 'sort_order' => 13, 'type' => CategoryType::ARTICLE],
|
||||
['name' => 'How To', 'description' => 'How to use perfumes', 'sort_order' => 14, 'type' => CategoryType::ARTICLE],
|
||||
];
|
||||
|
||||
foreach ($categories as $category) {
|
||||
@ -29,6 +34,7 @@ public function run(): void
|
||||
'slug' => Str::slug($category['name']),
|
||||
'description' => $category['description'],
|
||||
'sort_order' => $category['sort_order'],
|
||||
'type' => $category['type'],
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -46,8 +46,10 @@ public function run(): void
|
||||
foreach ($outlets as $data) {
|
||||
$outlet = Outlet::create([
|
||||
...$data,
|
||||
'maps_url' => null,
|
||||
'status' => OutletStatus::OPERATIONAL,
|
||||
'opened_date' => now()->toDateString(),
|
||||
'closed_date' => null,
|
||||
]);
|
||||
|
||||
$hours = collect(Day::cases())->map(fn ($day) => [
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
use App\Enums\EmploymentStatus;
|
||||
use App\Enums\Gender;
|
||||
use App\Enums\UserRole;
|
||||
use App\Enums\UserStatus;
|
||||
use App\Models\Employee;
|
||||
use App\Models\Outlet;
|
||||
use App\Models\ReferralCode;
|
||||
@ -23,6 +24,8 @@ public function run(): void
|
||||
'email' => 'project.pangestuyoga@gmail.com',
|
||||
'username' => 'pangestu',
|
||||
'password' => Hash::make(config('myconfig.password_default')),
|
||||
'status' => UserStatus::ACTIVE,
|
||||
'email_verified_at' => now(),
|
||||
]);
|
||||
|
||||
Employee::create([
|
||||
@ -50,6 +53,8 @@ public function run(): void
|
||||
'email' => 'mulyadi@gmail.com',
|
||||
'username' => 'mulyadi',
|
||||
'password' => Hash::make(config('myconfig.password_default')),
|
||||
'status' => UserStatus::ACTIVE,
|
||||
'email_verified_at' => now(),
|
||||
]);
|
||||
|
||||
Employee::create([
|
||||
|
||||
Loading…
Reference in New Issue
Block a user