feat: create migration files for various tables including rejections, attendances, payrolls, leave requests, purchases, and stock mutations

- Added `rejections` table to track rejection reasons and related entities.
- Created `attendances` table for employee attendance records with geolocation data.
- Introduced `payroll_periods`, `payrolls`, and `payroll_adjustments` tables for payroll management.
- Established `leave_requests` table to manage employee leave applications.
- Implemented `purchases` and `purchase_items` tables for tracking supplier purchases.
- Created `media` table for file storage and management.
- Added `activity_log` table for tracking system activities.
- Established `orders` and `order_items` tables for managing customer orders.
- Created `cuttings`, `cutting_materials`, and `cutting_results` tables for production management.
- Introduced `system_configurations` table for application settings.
- Added `push_subscriptions` table for managing user push notifications.
- Created `homepage_configurations` table for homepage settings.
- Established `product_prices` table for managing product pricing.
- Added `owner_verification_requests` table for tracking ownership verification processes.
- Created `notifications` table for user notifications.
- Established `employee_advance_payments` table for managing advance payments to employees.
- Created `retail_stock_histories` table for tracking stock changes.
- Established `stok_opnames` and `stok_opname_items` tables for stock opname management.
- Created `cutting_material_combinations` table for managing material combinations.
- Added `restocks` and `restock_items` tables for managing stock replenishments.
- Established `stock_mutations` table for tracking stock changes across various operations.
This commit is contained in:
Yoga Pangestu 2026-07-28 18:51:00 +07:00
parent 3c64660586
commit 660d0a648c
150 changed files with 4890 additions and 144 deletions

View File

@ -0,0 +1,15 @@
<?php
namespace App\Enums;
use App\Enums\Concerns\HasValues;
enum CashTransactionType: string
{
use HasValues;
case DEPOSIT = 'deposit';
case WITHDRAWAL = 'withdrawal';
case EXPENSE = 'expense';
case TRANSFER = 'transfer';
}

View File

@ -0,0 +1,11 @@
<?php
namespace App\Enums\Concerns;
trait HasValues
{
public static function values(): array
{
return array_column(self::cases(), 'value');
}
}

View File

@ -0,0 +1,14 @@
<?php
namespace App\Enums;
use App\Enums\Concerns\HasValues;
enum CuttingStatus: string
{
use HasValues;
case IN_PROGRESS = 'in_progress';
case COMPLETED = 'completed';
case CANCELLED = 'cancelled';
}

View File

@ -0,0 +1,16 @@
<?php
namespace App\Enums;
use App\Enums\Concerns\HasValues;
enum EmployeeAdvanceStatus: string
{
use HasValues;
case PENDING = 'pending';
case APPROVED = 'approved';
case PAID = 'paid';
case REJECTED = 'rejected';
case CANCELLED = 'cancelled';
}

View File

@ -0,0 +1,16 @@
<?php
namespace App\Enums;
use App\Enums\Concerns\HasValues;
enum EmploymentStatus: string
{
use HasValues;
case FULL_TIME = 'full_time';
case PART_TIME = 'part_time';
case CONTRACT = 'contract';
case INTERNSHIP = 'internship';
case RESIGNED = 'resigned';
}

13
app/Enums/Gender.php Normal file
View File

@ -0,0 +1,13 @@
<?php
namespace App\Enums;
use App\Enums\Concerns\HasValues;
enum Gender: string
{
use HasValues;
case MALE = 'male';
case FEMALE = 'female';
}

View File

@ -0,0 +1,15 @@
<?php
namespace App\Enums;
use App\Enums\Concerns\HasValues;
enum LeaveRequestStatus: string
{
use HasValues;
case PENDING = 'pending';
case APPROVED = 'approved';
case REJECTED = 'rejected';
case CANCELLED = 'cancelled';
}

View File

@ -0,0 +1,16 @@
<?php
namespace App\Enums;
use App\Enums\Concerns\HasValues;
enum OrderChannel: string
{
use HasValues;
case OFFLINE = 'offline';
case ONLINE = 'online';
case WHATSAPP = 'whatsapp';
case SHOPEE = 'shopee';
case TIKTOK = 'tiktok';
}

16
app/Enums/OrderStatus.php Normal file
View File

@ -0,0 +1,16 @@
<?php
namespace App\Enums;
use App\Enums\Concerns\HasValues;
enum OrderStatus: string
{
use HasValues;
case PENDING = 'pending';
case PROCESSING = 'processing';
case COMPLETED = 'completed';
case CANCELLED = 'cancelled';
case REFUNDED = 'refunded';
}

15
app/Enums/PaymentType.php Normal file
View File

@ -0,0 +1,15 @@
<?php
namespace App\Enums;
use App\Enums\Concerns\HasValues;
enum PaymentType: string
{
use HasValues;
case CASH = 'cash';
case TRANSFER = 'transfer';
case DEBIT = 'debit';
case CREDIT = 'credit';
}

View File

@ -0,0 +1,14 @@
<?php
namespace App\Enums;
use App\Enums\Concerns\HasValues;
enum PayrollAdjustmentType: string
{
use HasValues;
case BONUS = 'bonus';
case DEDUCTION = 'deduction';
case CORRECTION = 'correction';
}

View File

@ -0,0 +1,13 @@
<?php
namespace App\Enums;
use App\Enums\Concerns\HasValues;
enum PayrollPeriodStatus: string
{
use HasValues;
case OPEN = 'open';
case CLOSED = 'closed';
}

View File

@ -0,0 +1,14 @@
<?php
namespace App\Enums;
use App\Enums\Concerns\HasValues;
enum PayrollStatus: string
{
use HasValues;
case UNPAID = 'unpaid';
case PAID = 'paid';
case CANCELLED = 'cancelled';
}

13
app/Enums/PriceType.php Normal file
View File

@ -0,0 +1,13 @@
<?php
namespace App\Enums;
use App\Enums\Concerns\HasValues;
enum PriceType: string
{
use HasValues;
case RETAIL = 'retail';
case WHOLESALE = 'wholesale';
}

View File

@ -0,0 +1,14 @@
<?php
namespace App\Enums;
use App\Enums\Concerns\HasValues;
enum ProductStatus: string
{
use HasValues;
case ACTIVE = 'active';
case INACTIVE = 'inactive';
case DRAFT = 'draft';
}

View File

@ -0,0 +1,14 @@
<?php
namespace App\Enums;
use App\Enums\Concerns\HasValues;
enum ProductStockQuality: string
{
use HasValues;
case GOOD = 'good';
case BAD = 'bad';
case DAMAGED = 'damaged';
}

View File

@ -0,0 +1,17 @@
<?php
namespace App\Enums;
use App\Enums\Concerns\HasValues;
enum RawMaterialUnit: string
{
use HasValues;
case KG = 'kg';
case METER = 'meter';
case PCS = 'pcs';
case ROLL = 'roll';
case LITER = 'liter';
case PACK = 'pack';
}

View File

@ -0,0 +1,16 @@
<?php
namespace App\Enums;
use App\Enums\Concerns\HasValues;
enum StokOpnameStatus: string
{
use HasValues;
case DRAFT = 'draft';
case IN_PROGRESS = 'in_progress';
case COMPLETED = 'completed';
case VERIFIED = 'verified';
case CANCELLED = 'cancelled';
}

View File

@ -0,0 +1,29 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Attributes\Hidden;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
#[Hidden(['id'])]
class AppNotification extends Model
{
use HasFactory;
protected $table = 'notifications';
protected function casts(): array
{
return [
'is_read' => 'boolean',
'read_at' => 'datetime',
];
}
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
}

29
app/Models/Attendance.php Normal file
View File

@ -0,0 +1,29 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Attributes\Hidden;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
#[Hidden(['id'])]
class Attendance extends Model
{
use HasFactory;
protected function casts(): array
{
return [
'attendance_date' => 'date:Y-m-d',
'check_in_at' => 'datetime',
'check_out_at' => 'datetime',
'work_duration_minutes' => 'integer',
];
}
public function employee(): BelongsTo
{
return $this->belongsTo(Employee::class);
}
}

View File

@ -0,0 +1,33 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Attributes\Hidden;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;
#[Hidden(['id'])]
class CashAccount extends Model
{
use HasFactory, SoftDeletes;
protected function casts(): array
{
return [
'balance' => 'integer',
];
}
public function createdBy(): BelongsTo
{
return $this->belongsTo(User::class, 'created_by_id');
}
public function cashTransactions(): HasMany
{
return $this->hasMany(CashTransaction::class);
}
}

View File

@ -0,0 +1,78 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Attributes\Hidden;
use Illuminate\Database\Eloquent\Attributes\Scope;
use Illuminate\Database\Eloquent\Builder;
use App\Enums\CashTransactionType;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\Relations\MorphTo;
use Illuminate\Database\Eloquent\SoftDeletes;
#[Hidden(['id'])]
class CashTransaction extends Model
{
use HasFactory, SoftDeletes;
protected function casts(): array
{
return [
'type' => CashTransactionType::class,
'amount' => 'integer',
'balance_after' => 'integer',
];
}
#[Scope]
protected function deposit(Builder $query): void
{
$query->where('type', CashTransactionType::DEPOSIT);
}
#[Scope]
protected function expense(Builder $query): void
{
$query->where('type', CashTransactionType::EXPENSE);
}
#[Scope]
protected function transfer(Builder $query): void
{
$query->where('type', CashTransactionType::TRANSFER);
}
#[Scope]
protected function withdrawal(Builder $query): void
{
$query->where('type', CashTransactionType::WITHDRAWAL);
}
public function cashAccount(): BelongsTo
{
return $this->belongsTo(CashAccount::class);
}
public function createdBy(): BelongsTo
{
return $this->belongsTo(User::class, 'created_by_id');
}
public function expense(): HasOne
{
return $this->hasOne(Expense::class);
}
public function order(): HasOne
{
return $this->hasOne(Order::class);
}
public function reference(): MorphTo
{
return $this->morphTo();
}
}

21
app/Models/Category.php Normal file
View File

@ -0,0 +1,21 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Attributes\Hidden;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\SoftDeletes;
#[Hidden(['id'])]
class Category extends Model
{
use HasFactory, SoftDeletes;
public function products(): BelongsToMany
{
return $this->belongsToMany(Product::class, 'product_categories')
->using(ProductCategory::class);
}
}

20
app/Models/Customer.php Normal file
View File

@ -0,0 +1,20 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Attributes\Hidden;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;
#[Hidden(['id'])]
class Customer extends Model
{
use HasFactory, SoftDeletes;
public function orders(): HasMany
{
return $this->hasMany(Order::class);
}
}

73
app/Models/Cutting.php Normal file
View File

@ -0,0 +1,73 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Attributes\Hidden;
use Illuminate\Database\Eloquent\Attributes\Scope;
use Illuminate\Database\Eloquent\Builder;
use App\Enums\CuttingStatus;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;
#[Hidden(['id'])]
class Cutting extends Model
{
use HasFactory, SoftDeletes;
protected function casts(): array
{
return [
'status' => CuttingStatus::class,
'total_material_cost' => 'integer',
'sewing_cost' => 'integer',
'other_cost' => 'integer',
'cost_per_unit' => 'integer',
];
}
#[Scope]
protected function cancelled(Builder $query): void
{
$query->where('status', CuttingStatus::CANCELLED);
}
#[Scope]
protected function completed(Builder $query): void
{
$query->where('status', CuttingStatus::COMPLETED);
}
#[Scope]
protected function inProgress(Builder $query): void
{
$query->where('status', CuttingStatus::IN_PROGRESS);
}
public function createdBy(): BelongsTo
{
return $this->belongsTo(User::class, 'created_by_id');
}
public function cuttingMaterialCombinations(): HasMany
{
return $this->hasMany(CuttingMaterialCombination::class);
}
public function cuttingMaterials(): HasMany
{
return $this->hasMany(CuttingMaterial::class);
}
public function cuttingResults(): HasMany
{
return $this->hasMany(CuttingResult::class);
}
public function submittedBy(): BelongsTo
{
return $this->belongsTo(User::class, 'submitted_by_id');
}
}

View File

@ -0,0 +1,43 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Attributes\Hidden;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
#[Hidden(['id'])]
class CuttingMaterial extends Model
{
use HasFactory, SoftDeletes;
protected function casts(): array
{
return [
'material_usage' => 'decimal:2',
'material_result' => 'integer',
];
}
public function combination(): BelongsTo
{
return $this->belongsTo(CuttingMaterialCombination::class, 'combination_id');
}
public function cutting(): BelongsTo
{
return $this->belongsTo(Cutting::class);
}
public function rawMaterialPrice(): BelongsTo
{
return $this->belongsTo(RawMaterialPrice::class);
}
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
}

View File

@ -0,0 +1,38 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Attributes\Hidden;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;
#[Hidden(['id'])]
class CuttingMaterialCombination extends Model
{
use HasFactory, SoftDeletes;
protected function casts(): array
{
return [
'material_result' => 'integer',
];
}
public function cutting(): BelongsTo
{
return $this->belongsTo(Cutting::class);
}
public function cuttingMaterials(): HasMany
{
return $this->hasMany(CuttingMaterial::class, 'combination_id');
}
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
}

View File

@ -0,0 +1,34 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Attributes\Hidden;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
#[Hidden(['id'])]
class CuttingResult extends Model
{
use HasFactory, SoftDeletes;
protected function casts(): array
{
return [
'cutting_result' => 'integer',
'sample' => 'integer',
'original_outside_sample' => 'integer',
];
}
public function cutting(): BelongsTo
{
return $this->belongsTo(Cutting::class);
}
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
}

84
app/Models/Employee.php Normal file
View File

@ -0,0 +1,84 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Attributes\Hidden;
use Illuminate\Database\Eloquent\Attributes\Scope;
use Illuminate\Database\Eloquent\Builder;
use App\Enums\EmploymentStatus;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;
#[Hidden(['id'])]
class Employee extends Model
{
use HasFactory, SoftDeletes;
protected function casts(): array
{
return [
'employment_status' => EmploymentStatus::class,
'base_salary' => 'integer',
'join_date' => 'date:Y-m-d',
'resign_date' => 'date:Y-m-d',
];
}
#[Scope]
protected function contract(Builder $query): void
{
$query->where('employment_status', EmploymentStatus::CONTRACT);
}
#[Scope]
protected function fullTime(Builder $query): void
{
$query->where('employment_status', EmploymentStatus::FULL_TIME);
}
#[Scope]
protected function internship(Builder $query): void
{
$query->where('employment_status', EmploymentStatus::INTERNSHIP);
}
#[Scope]
protected function partTime(Builder $query): void
{
$query->where('employment_status', EmploymentStatus::PART_TIME);
}
#[Scope]
protected function resigned(Builder $query): void
{
$query->where('employment_status', EmploymentStatus::RESIGNED);
}
public function attendances(): HasMany
{
return $this->hasMany(Attendance::class);
}
public function employeeAdvances(): HasMany
{
return $this->hasMany(EmployeeAdvance::class);
}
public function leaveRequests(): HasMany
{
return $this->hasMany(LeaveRequest::class);
}
public function payrolls(): HasMany
{
return $this->hasMany(Payroll::class);
}
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
}

View File

@ -0,0 +1,85 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Attributes\Hidden;
use Illuminate\Database\Eloquent\Attributes\Scope;
use Illuminate\Database\Eloquent\Builder;
use App\Enums\EmployeeAdvanceStatus;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
#[Hidden(['id'])]
class EmployeeAdvance extends Model
{
use HasFactory, SoftDeletes;
protected function casts(): array
{
return [
'status' => EmployeeAdvanceStatus::class,
'amount' => 'integer',
'paid_amount' => 'integer',
'due_date' => 'date:Y-m-d',
'verified_at' => 'datetime',
'paid_at' => 'datetime',
];
}
#[Scope]
protected function approved(Builder $query): void
{
$query->where('status', EmployeeAdvanceStatus::APPROVED);
}
#[Scope]
protected function cancelled(Builder $query): void
{
$query->where('status', EmployeeAdvanceStatus::CANCELLED);
}
#[Scope]
protected function paid(Builder $query): void
{
$query->where('status', EmployeeAdvanceStatus::PAID);
}
#[Scope]
protected function pending(Builder $query): void
{
$query->where('status', EmployeeAdvanceStatus::PENDING);
}
#[Scope]
protected function rejected(Builder $query): void
{
$query->where('status', EmployeeAdvanceStatus::REJECTED);
}
public function cashTransaction(): BelongsTo
{
return $this->belongsTo(CashTransaction::class);
}
public function employee(): BelongsTo
{
return $this->belongsTo(Employee::class);
}
public function paidBy(): BelongsTo
{
return $this->belongsTo(User::class, 'paid_by_id');
}
public function repaymentCashTransaction(): BelongsTo
{
return $this->belongsTo(CashTransaction::class, 'repayment_cash_transaction_id');
}
public function verifiedBy(): BelongsTo
{
return $this->belongsTo(User::class, 'verified_by_id');
}
}

32
app/Models/Expense.php Normal file
View File

@ -0,0 +1,32 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Attributes\Hidden;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
#[Hidden(['id'])]
class Expense extends Model
{
use HasFactory, SoftDeletes;
protected function casts(): array
{
return [
'amount' => 'integer',
];
}
public function cashTransaction(): BelongsTo
{
return $this->belongsTo(CashTransaction::class);
}
public function createdBy(): BelongsTo
{
return $this->belongsTo(User::class, 'created_by_id');
}
}

View File

@ -0,0 +1,13 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Attributes\Hidden;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
#[Hidden(['id'])]
class HomepageConfiguration extends Model
{
use HasFactory;
}

View File

@ -0,0 +1,63 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Attributes\Hidden;
use Illuminate\Database\Eloquent\Attributes\Scope;
use Illuminate\Database\Eloquent\Builder;
use App\Enums\LeaveRequestStatus;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
#[Hidden(['id'])]
class LeaveRequest extends Model
{
use HasFactory, SoftDeletes;
protected function casts(): array
{
return [
'status' => LeaveRequestStatus::class,
'start_date' => 'date:Y-m-d',
'end_date' => 'date:Y-m-d',
'total_days' => 'integer',
'verified_at' => 'datetime',
];
}
#[Scope]
protected function approved(Builder $query): void
{
$query->where('status', LeaveRequestStatus::APPROVED);
}
#[Scope]
protected function cancelled(Builder $query): void
{
$query->where('status', LeaveRequestStatus::CANCELLED);
}
#[Scope]
protected function pending(Builder $query): void
{
$query->where('status', LeaveRequestStatus::PENDING);
}
#[Scope]
protected function rejected(Builder $query): void
{
$query->where('status', LeaveRequestStatus::REJECTED);
}
public function employee(): BelongsTo
{
return $this->belongsTo(Employee::class);
}
public function verifiedBy(): BelongsTo
{
return $this->belongsTo(User::class, 'verified_by_id');
}
}

158
app/Models/Order.php Normal file
View File

@ -0,0 +1,158 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Attributes\Hidden;
use Illuminate\Database\Eloquent\Attributes\Scope;
use Illuminate\Database\Eloquent\Builder;
use App\Enums\OrderChannel;
use App\Enums\OrderStatus;
use App\Enums\PaymentType;
use App\Enums\PriceType;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;
#[Hidden(['id'])]
class Order extends Model
{
use HasFactory, SoftDeletes;
protected function casts(): array
{
return [
'channel' => OrderChannel::class,
'price_type' => PriceType::class,
'status' => OrderStatus::class,
'payment_type' => PaymentType::class,
'is_affiliate' => 'boolean',
'subtotal' => 'integer',
'discount' => 'integer',
'nego_price' => 'integer',
'total_amount' => 'integer',
];
}
#[Scope]
protected function cancelled(Builder $query): void
{
$query->where('status', OrderStatus::CANCELLED);
}
#[Scope]
protected function cash(Builder $query): void
{
$query->where('payment_type', PaymentType::CASH);
}
#[Scope]
protected function completed(Builder $query): void
{
$query->where('status', OrderStatus::COMPLETED);
}
#[Scope]
protected function credit(Builder $query): void
{
$query->where('payment_type', PaymentType::CREDIT);
}
#[Scope]
protected function debit(Builder $query): void
{
$query->where('payment_type', PaymentType::DEBIT);
}
#[Scope]
protected function offline(Builder $query): void
{
$query->where('channel', OrderChannel::OFFLINE);
}
#[Scope]
protected function online(Builder $query): void
{
$query->where('channel', OrderChannel::ONLINE);
}
#[Scope]
protected function pending(Builder $query): void
{
$query->where('status', OrderStatus::PENDING);
}
#[Scope]
protected function processing(Builder $query): void
{
$query->where('status', OrderStatus::PROCESSING);
}
#[Scope]
protected function refunded(Builder $query): void
{
$query->where('status', OrderStatus::REFUNDED);
}
#[Scope]
protected function retail(Builder $query): void
{
$query->where('price_type', PriceType::RETAIL);
}
#[Scope]
protected function shopee(Builder $query): void
{
$query->where('channel', OrderChannel::SHOPEE);
}
#[Scope]
protected function tiktok(Builder $query): void
{
$query->where('channel', OrderChannel::TIKTOK);
}
#[Scope]
protected function transfer(Builder $query): void
{
$query->where('payment_type', PaymentType::TRANSFER);
}
#[Scope]
protected function whatsapp(Builder $query): void
{
$query->where('channel', OrderChannel::WHATSAPP);
}
#[Scope]
protected function wholesale(Builder $query): void
{
$query->where('price_type', PriceType::WHOLESALE);
}
public function cashTransaction(): BelongsTo
{
return $this->belongsTo(CashTransaction::class);
}
public function createdBy(): BelongsTo
{
return $this->belongsTo(User::class, 'created_by_id');
}
public function customer(): BelongsTo
{
return $this->belongsTo(Customer::class);
}
public function marketing(): BelongsTo
{
return $this->belongsTo(User::class, 'marketing_id');
}
public function orderItems(): HasMany
{
return $this->hasMany(OrderItem::class);
}
}

61
app/Models/OrderItem.php Normal file
View File

@ -0,0 +1,61 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Attributes\Hidden;
use Illuminate\Database\Eloquent\Attributes\Scope;
use Illuminate\Database\Eloquent\Builder;
use App\Enums\ProductStockQuality;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
#[Hidden(['id'])]
class OrderItem extends Model
{
use HasFactory, SoftDeletes;
protected function casts(): array
{
return [
'stock_quality' => ProductStockQuality::class,
'quantity' => 'integer',
'unit_price' => 'integer',
'subtotal' => 'integer',
];
}
#[Scope]
protected function bad(Builder $query): void
{
$query->where('stock_quality', ProductStockQuality::BAD);
}
#[Scope]
protected function damaged(Builder $query): void
{
$query->where('stock_quality', ProductStockQuality::DAMAGED);
}
#[Scope]
protected function good(Builder $query): void
{
$query->where('stock_quality', ProductStockQuality::GOOD);
}
public function order(): BelongsTo
{
return $this->belongsTo(Order::class);
}
public function productVariant(): BelongsTo
{
return $this->belongsTo(ProductVariant::class);
}
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
}

View File

@ -0,0 +1,37 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Attributes\Hidden;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\MorphTo;
#[Hidden(['id'])]
class OwnerVerificationRequest extends Model
{
use HasFactory;
protected function casts(): array
{
return [
'verified_at' => 'datetime',
];
}
public function subject(): MorphTo
{
return $this->morphTo();
}
public function submittedBy(): BelongsTo
{
return $this->belongsTo(User::class, 'submitted_by_id');
}
public function verifiedBy(): BelongsTo
{
return $this->belongsTo(User::class, 'verified_by_id');
}
}

74
app/Models/Payroll.php Normal file
View File

@ -0,0 +1,74 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Attributes\Hidden;
use Illuminate\Database\Eloquent\Attributes\Scope;
use Illuminate\Database\Eloquent\Builder;
use App\Enums\PayrollStatus;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;
#[Hidden(['id'])]
class Payroll extends Model
{
use HasFactory, SoftDeletes;
protected function casts(): array
{
return [
'status' => PayrollStatus::class,
'base_salary' => 'integer',
'bonus_amount' => 'integer',
'deduction_amount' => 'integer',
'total_amount' => 'integer',
'paid_at' => 'datetime',
];
}
#[Scope]
protected function cancelled(Builder $query): void
{
$query->where('status', PayrollStatus::CANCELLED);
}
#[Scope]
protected function paid(Builder $query): void
{
$query->where('status', PayrollStatus::PAID);
}
#[Scope]
protected function unpaid(Builder $query): void
{
$query->where('status', PayrollStatus::UNPAID);
}
public function cashTransaction(): BelongsTo
{
return $this->belongsTo(CashTransaction::class);
}
public function employee(): BelongsTo
{
return $this->belongsTo(Employee::class);
}
public function paidBy(): BelongsTo
{
return $this->belongsTo(User::class, 'paid_by_id');
}
public function payrollAdjustments(): HasMany
{
return $this->hasMany(PayrollAdjustment::class);
}
public function payrollPeriod(): BelongsTo
{
return $this->belongsTo(PayrollPeriod::class);
}
}

View File

@ -0,0 +1,59 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Attributes\Hidden;
use Illuminate\Database\Eloquent\Attributes\Scope;
use Illuminate\Database\Eloquent\Builder;
use App\Enums\PayrollAdjustmentType;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
#[Hidden(['id'])]
class PayrollAdjustment extends Model
{
use HasFactory, SoftDeletes;
protected function casts(): array
{
return [
'type' => PayrollAdjustmentType::class,
'amount' => 'integer',
];
}
#[Scope]
protected function bonus(Builder $query): void
{
$query->where('type', PayrollAdjustmentType::BONUS);
}
#[Scope]
protected function correction(Builder $query): void
{
$query->where('type', PayrollAdjustmentType::CORRECTION);
}
#[Scope]
protected function deduction(Builder $query): void
{
$query->where('type', PayrollAdjustmentType::DEDUCTION);
}
public function attendance(): BelongsTo
{
return $this->belongsTo(Attendance::class);
}
public function createdBy(): BelongsTo
{
return $this->belongsTo(User::class, 'created_by_id');
}
public function payroll(): BelongsTo
{
return $this->belongsTo(Payroll::class);
}
}

View File

@ -0,0 +1,49 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Attributes\Hidden;
use Illuminate\Database\Eloquent\Attributes\Scope;
use Illuminate\Database\Eloquent\Builder;
use App\Enums\PayrollPeriodStatus;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;
#[Hidden(['id'])]
class PayrollPeriod extends Model
{
use HasFactory, SoftDeletes;
protected function casts(): array
{
return [
'status' => PayrollPeriodStatus::class,
'closed_at' => 'datetime',
];
}
#[Scope]
protected function closed(Builder $query): void
{
$query->where('status', PayrollPeriodStatus::CLOSED);
}
#[Scope]
protected function open(Builder $query): void
{
$query->where('status', PayrollPeriodStatus::OPEN);
}
public function closedBy(): BelongsTo
{
return $this->belongsTo(User::class, 'closed_by_id');
}
public function payrolls(): HasMany
{
return $this->hasMany(Payroll::class);
}
}

55
app/Models/Product.php Normal file
View File

@ -0,0 +1,55 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Attributes\Hidden;
use App\Enums\ProductStatus;
use Illuminate\Database\Eloquent\Attributes\Scope;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;
#[Hidden(['id'])]
class Product extends Model
{
use HasFactory, SoftDeletes;
protected function casts(): array
{
return [
'status' => ProductStatus::class,
];
}
#[Scope]
protected function active(Builder $query): void
{
$query->where('status', ProductStatus::ACTIVE);
}
#[Scope]
protected function draft(Builder $query): void
{
$query->where('status', ProductStatus::DRAFT);
}
#[Scope]
protected function inactive(Builder $query): void
{
$query->where('status', ProductStatus::INACTIVE);
}
public function categories(): BelongsToMany
{
return $this->belongsToMany(Category::class, 'product_categories')
->using(ProductCategory::class);
}
public function productVariants(): HasMany
{
return $this->hasMany(ProductVariant::class);
}
}

View File

@ -0,0 +1,28 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Attributes\Hidden;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
#[Hidden(['id'])]
class ProductCategory extends Model
{
use HasFactory;
public $timestamps = false;
protected $fillable = ['product_id', 'category_id'];
public function category(): BelongsTo
{
return $this->belongsTo(Category::class);
}
public function product(): BelongsTo
{
return $this->belongsTo(Product::class);
}
}

View File

@ -0,0 +1,43 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Attributes\Hidden;
use Illuminate\Database\Eloquent\Attributes\Scope;
use Illuminate\Database\Eloquent\Builder;
use App\Enums\PriceType;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
#[Hidden(['id'])]
class ProductPrice extends Model
{
use HasFactory, SoftDeletes;
protected function casts(): array
{
return [
'type' => PriceType::class,
'price' => 'integer',
];
}
#[Scope]
protected function retail(Builder $query): void
{
$query->where('type', PriceType::RETAIL);
}
#[Scope]
protected function wholesale(Builder $query): void
{
$query->where('type', PriceType::WHOLESALE);
}
public function variant(): BelongsTo
{
return $this->belongsTo(ProductVariant::class, 'variant_id');
}
}

View File

@ -0,0 +1,46 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Attributes\Hidden;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;
#[Hidden(['id'])]
class ProductVariant extends Model
{
use HasFactory, SoftDeletes;
public function orderItems(): HasMany
{
return $this->hasMany(OrderItem::class);
}
public function product(): BelongsTo
{
return $this->belongsTo(Product::class);
}
public function productPrices(): HasMany
{
return $this->hasMany(ProductPrice::class, 'variant_id');
}
public function restockItems(): HasMany
{
return $this->hasMany(RestockItem::class);
}
public function retailStockHistories(): HasMany
{
return $this->hasMany(RetailStockHistory::class);
}
public function stokOpnameItems(): HasMany
{
return $this->hasMany(StokOpnameItem::class);
}
}

41
app/Models/Purchase.php Normal file
View File

@ -0,0 +1,41 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Attributes\Hidden;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;
#[Hidden(['id'])]
class Purchase extends Model
{
use HasFactory, SoftDeletes;
protected function casts(): array
{
return [
'subtotal' => 'integer',
'discount' => 'integer',
'shipping_cost' => 'integer',
'total' => 'integer',
];
}
public function createdBy(): BelongsTo
{
return $this->belongsTo(User::class, 'created_by_id');
}
public function purchaseItems(): HasMany
{
return $this->hasMany(PurchaseItem::class);
}
public function supplier(): BelongsTo
{
return $this->belongsTo(Supplier::class);
}
}

View File

@ -0,0 +1,39 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Attributes\Hidden;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
#[Hidden(['id'])]
class PurchaseItem extends Model
{
use HasFactory, SoftDeletes;
protected function casts(): array
{
return [
'quantity' => 'decimal:4',
'unit_price' => 'integer',
'subtotal' => 'integer',
];
}
public function purchase(): BelongsTo
{
return $this->belongsTo(Purchase::class);
}
public function rawMaterialPrice(): BelongsTo
{
return $this->belongsTo(RawMaterialPrice::class);
}
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
}

View File

@ -0,0 +1,19 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Attributes\Hidden;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
#[Hidden(['id'])]
class PushSubscription extends Model
{
use HasFactory;
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
}

View File

@ -0,0 +1,29 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Attributes\Hidden;
use App\Enums\RawMaterialUnit;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;
#[Hidden(['id'])]
class RawMaterial extends Model
{
use HasFactory, SoftDeletes;
protected function casts(): array
{
return [
'unit' => RawMaterialUnit::class,
'is_active' => 'boolean',
];
}
public function rawMaterialPrices(): HasMany
{
return $this->hasMany(RawMaterialPrice::class);
}
}

View File

@ -0,0 +1,39 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Attributes\Hidden;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;
#[Hidden(['id'])]
class RawMaterialPrice extends Model
{
use HasFactory, SoftDeletes;
protected function casts(): array
{
return [
'price' => 'integer',
'stock' => 'decimal:4',
];
}
public function cuttingMaterials(): HasMany
{
return $this->hasMany(CuttingMaterial::class);
}
public function purchaseItems(): HasMany
{
return $this->hasMany(PurchaseItem::class);
}
public function rawMaterial(): BelongsTo
{
return $this->belongsTo(RawMaterial::class);
}
}

26
app/Models/Rejection.php Normal file
View File

@ -0,0 +1,26 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Attributes\Hidden;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\MorphTo;
use Illuminate\Database\Eloquent\SoftDeletes;
#[Hidden(['id'])]
class Rejection extends Model
{
use HasFactory, SoftDeletes;
public function rejectable(): MorphTo
{
return $this->morphTo();
}
public function rejectedBy(): BelongsTo
{
return $this->belongsTo(User::class, 'rejected_by_id');
}
}

56
app/Models/Restock.php Normal file
View File

@ -0,0 +1,56 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Attributes\Hidden;
use Illuminate\Database\Eloquent\Attributes\Scope;
use Illuminate\Database\Eloquent\Builder;
use App\Enums\ProductStockQuality;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;
#[Hidden(['id'])]
class Restock extends Model
{
use HasFactory, SoftDeletes;
protected function casts(): array
{
return [
'stock_type' => ProductStockQuality::class,
'subtotal' => 'integer',
'total' => 'integer',
];
}
#[Scope]
protected function bad(Builder $query): void
{
$query->where('stock_type', ProductStockQuality::BAD);
}
#[Scope]
protected function damaged(Builder $query): void
{
$query->where('stock_type', ProductStockQuality::DAMAGED);
}
#[Scope]
protected function good(Builder $query): void
{
$query->where('stock_type', ProductStockQuality::GOOD);
}
public function createdBy(): BelongsTo
{
return $this->belongsTo(User::class, 'created_by_id');
}
public function restockItems(): HasMany
{
return $this->hasMany(RestockItem::class);
}
}

View File

@ -0,0 +1,39 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Attributes\Hidden;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
#[Hidden(['id'])]
class RestockItem extends Model
{
use HasFactory, SoftDeletes;
protected function casts(): array
{
return [
'quantity' => 'integer',
'unit_price' => 'integer',
'subtotal' => 'integer',
];
}
public function productVariant(): BelongsTo
{
return $this->belongsTo(ProductVariant::class);
}
public function restock(): BelongsTo
{
return $this->belongsTo(Restock::class);
}
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
}

View File

@ -0,0 +1,37 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Attributes\Hidden;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
#[Hidden(['id'])]
class RetailStockHistory extends Model
{
use HasFactory;
public $timestamps = false;
protected function casts(): array
{
return [
'quantity' => 'integer',
'stock_before' => 'integer',
'retail_stock_before' => 'integer',
'stock_after' => 'integer',
'retail_stock_after' => 'integer',
];
}
public function productVariant(): BelongsTo
{
return $this->belongsTo(ProductVariant::class);
}
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
}

View File

@ -0,0 +1,39 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Attributes\Hidden;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\MorphTo;
#[Hidden(['id'])]
class StockMutation extends Model
{
use HasFactory;
protected function casts(): array
{
return [
'quantity' => 'decimal:4',
'stock_before' => 'decimal:4',
'stock_after' => 'decimal:4',
];
}
public function source(): MorphTo
{
return $this->morphTo();
}
public function stockable(): MorphTo
{
return $this->morphTo();
}
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
}

72
app/Models/StokOpname.php Normal file
View File

@ -0,0 +1,72 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Attributes\Hidden;
use Illuminate\Database\Eloquent\Attributes\Scope;
use Illuminate\Database\Eloquent\Builder;
use App\Enums\StokOpnameStatus;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;
#[Hidden(['id'])]
class StokOpname extends Model
{
use HasFactory, SoftDeletes;
protected function casts(): array
{
return [
'status' => StokOpnameStatus::class,
'opname_date' => 'date:Y-m-d',
];
}
#[Scope]
protected function cancelled(Builder $query): void
{
$query->where('status', StokOpnameStatus::CANCELLED);
}
#[Scope]
protected function completed(Builder $query): void
{
$query->where('status', StokOpnameStatus::COMPLETED);
}
#[Scope]
protected function draft(Builder $query): void
{
$query->where('status', StokOpnameStatus::DRAFT);
}
#[Scope]
protected function inProgress(Builder $query): void
{
$query->where('status', StokOpnameStatus::IN_PROGRESS);
}
#[Scope]
protected function verified(Builder $query): void
{
$query->where('status', StokOpnameStatus::VERIFIED);
}
public function createdBy(): BelongsTo
{
return $this->belongsTo(User::class, 'created_by_id');
}
public function stokOpnameItems(): HasMany
{
return $this->hasMany(StokOpnameItem::class);
}
public function verifiedBy(): BelongsTo
{
return $this->belongsTo(User::class, 'verified_by_id');
}
}

View File

@ -0,0 +1,55 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Attributes\Hidden;
use Illuminate\Database\Eloquent\Attributes\Scope;
use Illuminate\Database\Eloquent\Builder;
use App\Enums\ProductStockQuality;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
#[Hidden(['id'])]
class StokOpnameItem extends Model
{
use HasFactory;
protected function casts(): array
{
return [
'stock_quality' => ProductStockQuality::class,
'system_stock' => 'integer',
'physical_stock' => 'integer',
'difference' => 'integer',
];
}
#[Scope]
protected function bad(Builder $query): void
{
$query->where('stock_quality', ProductStockQuality::BAD);
}
#[Scope]
protected function damaged(Builder $query): void
{
$query->where('stock_quality', ProductStockQuality::DAMAGED);
}
#[Scope]
protected function good(Builder $query): void
{
$query->where('stock_quality', ProductStockQuality::GOOD);
}
public function productVariant(): BelongsTo
{
return $this->belongsTo(ProductVariant::class);
}
public function stokOpname(): BelongsTo
{
return $this->belongsTo(StokOpname::class);
}
}

21
app/Models/Supplier.php Normal file
View File

@ -0,0 +1,21 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Attributes\Hidden;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;
#[Hidden(['id'])]
class Supplier extends Model
{
use HasFactory, SoftDeletes;
public function purchases(): HasMany
{
return $this->hasMany(Purchase::class);
}
}

View File

@ -0,0 +1,13 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Attributes\Hidden;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
#[Hidden(['id'])]
class SystemConfiguration extends Model
{
use HasFactory;
}

View File

@ -2,49 +2,190 @@
namespace App\Models;
// use Illuminate\Contracts\Auth\MustVerifyEmail;
use Database\Factories\UserFactory;
use Illuminate\Database\Eloquent\Attributes\Fillable;
use Illuminate\Database\Eloquent\Attributes\Hidden;
use Database\Factories\UserFactory;
use Illuminate\Database\Eloquent\Attributes\Scope;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Support\Carbon;
use Laravel\Fortify\Contracts\PasskeyUser;
use Laravel\Fortify\PasskeyAuthenticatable;
use Laravel\Fortify\TwoFactorAuthenticatable;
use Spatie\Permission\Traits\HasRoles;
/**
* @property int $id
* @property string $name
* @property string $email
* @property Carbon|null $email_verified_at
* @property string $password
* @property string|null $two_factor_secret
* @property string|null $two_factor_recovery_codes
* @property Carbon|null $two_factor_confirmed_at
* @property string|null $remember_token
* @property Carbon|null $created_at
* @property Carbon|null $updated_at
*/
#[Fillable(['name', 'email', 'password'])]
#[Hidden(['password', 'two_factor_secret', 'two_factor_recovery_codes', 'remember_token'])]
class User extends Authenticatable implements PasskeyUser
#[Hidden(['id'])]
class User extends Authenticatable
{
/** @use HasFactory<UserFactory> */
use HasFactory, Notifiable, PasskeyAuthenticatable, TwoFactorAuthenticatable;
use HasFactory, HasRoles, Notifiable, SoftDeletes, TwoFactorAuthenticatable;
/**
* Get the attributes that should be cast.
*
* @return array<string, string>
*/
protected function casts(): array
{
return [
'email_verified_at' => 'datetime',
'is_active' => 'boolean',
'last_login_at' => 'datetime',
'password' => 'hashed',
'two_factor_confirmed_at' => 'datetime',
];
}
#[Scope]
protected function active(Builder $query): void
{
$query->where('is_active', true);
}
public function attendances(): HasMany
{
return $this->hasMany(Attendance::class);
}
public function cashAccounts(): HasMany
{
return $this->hasMany(CashAccount::class, 'created_by_id');
}
public function cashTransactions(): HasMany
{
return $this->hasMany(CashTransaction::class, 'created_by_id');
}
public function createdCuttings(): HasMany
{
return $this->hasMany(Cutting::class, 'created_by_id');
}
public function createdExpenses(): HasMany
{
return $this->hasMany(Expense::class, 'created_by_id');
}
public function createdOrders(): HasMany
{
return $this->hasMany(Order::class, 'created_by_id');
}
public function createdPayrollAdjustments(): HasMany
{
return $this->hasMany(PayrollAdjustment::class, 'created_by_id');
}
public function createdPurchases(): HasMany
{
return $this->hasMany(Purchase::class, 'created_by_id');
}
public function createdRestocks(): HasMany
{
return $this->hasMany(Restock::class, 'created_by_id');
}
public function employee(): HasOne
{
return $this->hasOne(Employee::class);
}
public function employeeAdvancesPaid(): HasMany
{
return $this->hasMany(EmployeeAdvance::class, 'paid_by_id');
}
public function employeeAdvancesVerified(): HasMany
{
return $this->hasMany(EmployeeAdvance::class, 'verified_by_id');
}
public function leaveRequestsVerified(): HasMany
{
return $this->hasMany(LeaveRequest::class, 'verified_by_id');
}
public function marketingOrders(): HasMany
{
return $this->hasMany(Order::class, 'marketing_id');
}
public function notifications(): HasMany
{
return $this->hasMany(AppNotification::class);
}
public function orderItems(): HasMany
{
return $this->hasMany(OrderItem::class);
}
public function ownerVerificationRequestsSubmitted(): HasMany
{
return $this->hasMany(OwnerVerificationRequest::class, 'submitted_by_id');
}
public function ownerVerificationRequestsVerified(): HasMany
{
return $this->hasMany(OwnerVerificationRequest::class, 'verified_by_id');
}
public function paidPayrolls(): HasMany
{
return $this->hasMany(Payroll::class, 'paid_by_id');
}
public function payrollPeriodsClosed(): HasMany
{
return $this->hasMany(PayrollPeriod::class, 'closed_by_id');
}
public function purchaseItems(): HasMany
{
return $this->hasMany(PurchaseItem::class);
}
public function pushSubscriptions(): HasMany
{
return $this->hasMany(PushSubscription::class);
}
public function rejections(): HasMany
{
return $this->hasMany(Rejection::class, 'rejected_by_id');
}
public function restockItems(): HasMany
{
return $this->hasMany(RestockItem::class);
}
public function retailStockHistories(): HasMany
{
return $this->hasMany(RetailStockHistory::class);
}
public function stockMutations(): HasMany
{
return $this->hasMany(StockMutation::class);
}
public function stokOpnamesCreated(): HasMany
{
return $this->hasMany(StokOpname::class, 'created_by_id');
}
public function stokOpnamesVerified(): HasMany
{
return $this->hasMany(StokOpname::class, 'verified_by_id');
}
public function submittedCuttings(): HasMany
{
return $this->hasMany(Cutting::class, 'submitted_by_id');
}
public function userProfile(): HasOne
{
return $this->hasOne(UserProfile::class);
}
}

View File

@ -0,0 +1,49 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Attributes\Hidden;
use Illuminate\Database\Eloquent\Attributes\Scope;
use Illuminate\Database\Eloquent\Builder;
use App\Enums\Gender;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
#[Hidden(['id'])]
class UserProfile extends Model
{
use HasFactory, SoftDeletes;
protected function casts(): array
{
return [
'gender' => Gender::class,
'birth_date' => 'date:Y-m-d',
];
}
#[Scope]
protected function female(Builder $query): void
{
$query->where('gender', Gender::FEMALE);
}
#[Scope]
protected function hasPhoneNumber(Builder $query): void
{
$query->whereNotNull('phone_number');
}
#[Scope]
protected function male(Builder $query): void
{
$query->where('gender', Gender::MALE);
}
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
}

View File

@ -15,7 +15,8 @@
"laravel/fortify": "^1.37.2",
"laravel/framework": "^13.17",
"laravel/tinker": "^3.0",
"laravel/wayfinder": "^0.1.14"
"laravel/wayfinder": "^0.1.14",
"spatie/laravel-permission": "^8.3"
},
"require-dev": {
"fakerphp/faker": "^1.24",
@ -114,4 +115,4 @@
},
"minimum-stability": "stable",
"prefer-stable": true
}
}

151
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "69a97377cfea5f400db9607e6d000338",
"content-hash": "06614299e9ee6d35887901c6b34eb24b",
"packages": [
{
"name": "bacon/bacon-qr-code",
@ -4122,6 +4122,155 @@
},
"time": "2026-06-18T03:57:49+00:00"
},
{
"name": "spatie/laravel-package-tools",
"version": "1.93.1",
"source": {
"type": "git",
"url": "https://github.com/spatie/laravel-package-tools.git",
"reference": "d5552849801f2642aea710557463234b59ef65eb"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/spatie/laravel-package-tools/zipball/d5552849801f2642aea710557463234b59ef65eb",
"reference": "d5552849801f2642aea710557463234b59ef65eb",
"shasum": ""
},
"require": {
"illuminate/contracts": "^10.0|^11.0|^12.0|^13.0",
"php": "^8.1"
},
"require-dev": {
"mockery/mockery": "^1.5",
"orchestra/testbench": "^8.0|^9.2|^10.0|^11.0",
"pestphp/pest": "^2.1|^3.1|^4.0",
"phpunit/php-code-coverage": "^10.0|^11.0|^12.0",
"phpunit/phpunit": "^10.5|^11.5|^12.5",
"spatie/pest-plugin-test-time": "^2.2|^3.0"
},
"type": "library",
"autoload": {
"psr-4": {
"Spatie\\LaravelPackageTools\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Freek Van der Herten",
"email": "freek@spatie.be",
"role": "Developer"
}
],
"description": "Tools for creating Laravel packages",
"homepage": "https://github.com/spatie/laravel-package-tools",
"keywords": [
"laravel-package-tools",
"spatie"
],
"support": {
"issues": "https://github.com/spatie/laravel-package-tools/issues",
"source": "https://github.com/spatie/laravel-package-tools/tree/1.93.1"
},
"funding": [
{
"url": "https://github.com/spatie",
"type": "github"
}
],
"time": "2026-05-19T14:06:37+00:00"
},
{
"name": "spatie/laravel-permission",
"version": "8.3.0",
"source": {
"type": "git",
"url": "https://github.com/spatie/laravel-permission.git",
"reference": "60e8ed5b2fbf043c2264433fc2680c76b8b66aa6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/spatie/laravel-permission/zipball/60e8ed5b2fbf043c2264433fc2680c76b8b66aa6",
"reference": "60e8ed5b2fbf043c2264433fc2680c76b8b66aa6",
"shasum": ""
},
"require": {
"illuminate/auth": "^12.0|^13.0",
"illuminate/container": "^12.0|^13.0",
"illuminate/contracts": "^12.0|^13.0",
"illuminate/database": "^12.0|^13.0",
"php": "^8.3",
"spatie/laravel-package-tools": "^1.0"
},
"require-dev": {
"larastan/larastan": "^3.9",
"laravel/octane": "^2.0",
"laravel/passport": "^13.0",
"laravel/pint": "^1.0",
"orchestra/testbench": "^10.0|^11.0",
"pestphp/pest": "^3.0|^4.0",
"pestphp/pest-plugin-laravel": "^3.0|^4.1",
"phpstan/phpstan": "^2.1"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"Spatie\\Permission\\PermissionServiceProvider"
]
},
"branch-alias": {
"dev-main": "8.x-dev",
"dev-master": "8.x-dev"
}
},
"autoload": {
"files": [
"src/helpers.php"
],
"psr-4": {
"Spatie\\Permission\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Freek Van der Herten",
"email": "freek@spatie.be",
"homepage": "https://spatie.be",
"role": "Developer"
}
],
"description": "Permission handling for Laravel 12 and up",
"homepage": "https://github.com/spatie/laravel-permission",
"keywords": [
"acl",
"laravel",
"permission",
"permissions",
"rbac",
"roles",
"security",
"spatie"
],
"support": {
"issues": "https://github.com/spatie/laravel-permission/issues",
"source": "https://github.com/spatie/laravel-permission/tree/8.3.0"
},
"funding": [
{
"url": "https://github.com/spatie",
"type": "github"
}
],
"time": "2026-07-03T15:36:01+00:00"
},
{
"name": "spomky-labs/cbor-php",
"version": "3.3.0",

View File

@ -0,0 +1,22 @@
<?php
namespace Database\Factories;
use App\Models\AppNotification;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class AppNotificationFactory extends Factory
{
public function definition(): array
{
return [
'user_id' => User::factory(),
'title' => fake()->sentence(),
'body' => fake()->paragraph(),
'url' => fake()->url(),
'is_read' => false,
'read_at' => null,
];
}
}

View File

@ -0,0 +1,25 @@
<?php
namespace Database\Factories;
use App\Models\Attendance;
use App\Models\Employee;
use Illuminate\Database\Eloquent\Factories\Factory;
class AttendanceFactory extends Factory
{
public function definition(): array
{
return [
'employee_id' => Employee::factory(),
'attendance_date' => fake()->date(),
'check_in_at' => fake()->dateTimeBetween('-1 day', 'now'),
'check_out_at' => fake()->dateTimeBetween('now', '+1 day'),
'check_in_latitude' => fake()->latitude(),
'check_in_longitude' => fake()->longitude(),
'check_out_latitude' => fake()->latitude(),
'check_out_longitude' => fake()->longitude(),
'work_duration_minutes' => fake()->numberBetween(240, 600),
];
}
}

View File

@ -0,0 +1,19 @@
<?php
namespace Database\Factories;
use App\Models\CashAccount;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class CashAccountFactory extends Factory
{
public function definition(): array
{
return [
'created_by_id' => User::factory(),
'name' => fake()->words(2, true),
'balance' => fake()->numberBetween(0, 100000000),
];
}
}

View File

@ -0,0 +1,23 @@
<?php
namespace Database\Factories;
use App\Models\CashAccount;
use App\Models\CashTransaction;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class CashTransactionFactory extends Factory
{
public function definition(): array
{
return [
'cash_account_id' => CashAccount::factory(),
'created_by_id' => User::factory(),
'amount' => fake()->numberBetween(1000, 1000000),
'balance_after' => fake()->numberBetween(1000, 10000000),
'type' => fake()->randomElement(['deposit', 'withdrawal', 'expense', 'transfer']),
'description' => fake()->sentence(),
];
}
}

View File

@ -0,0 +1,20 @@
<?php
namespace Database\Factories;
use App\Models\Category;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;
class CategoryFactory extends Factory
{
public function definition(): array
{
$name = fake()->unique()->word();
return [
'name' => $name,
'slug' => Str::slug($name),
];
}
}

View File

@ -0,0 +1,18 @@
<?php
namespace Database\Factories;
use App\Models\Customer;
use Illuminate\Database\Eloquent\Factories\Factory;
class CustomerFactory extends Factory
{
public function definition(): array
{
return [
'name' => fake()->name(),
'phone_number' => fake()->phoneNumber(),
'address' => fake()->address(),
];
}
}

View File

@ -0,0 +1,27 @@
<?php
namespace Database\Factories;
use App\Models\Cutting;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class CuttingFactory extends Factory
{
public function definition(): array
{
$materialCost = fake()->numberBetween(50000, 5000000);
$sewingCost = fake()->numberBetween(10000, 500000);
$otherCost = fake()->numberBetween(0, 200000);
return [
'created_by_id' => User::factory(),
'status' => fake()->randomElement(['in_progress', 'completed', 'cancelled']),
'description' => fake()->sentence(),
'total_material_cost' => $materialCost,
'sewing_cost' => $sewingCost,
'other_cost' => $otherCost,
'cost_per_unit' => fake()->numberBetween(1000, 50000),
];
}
}

View File

@ -0,0 +1,20 @@
<?php
namespace Database\Factories;
use App\Models\Cutting;
use App\Models\CuttingMaterialCombination;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class CuttingMaterialCombinationFactory extends Factory
{
public function definition(): array
{
return [
'user_id' => User::factory(),
'cutting_id' => Cutting::factory(),
'material_result' => fake()->numberBetween(0, 100),
];
}
}

View File

@ -0,0 +1,23 @@
<?php
namespace Database\Factories;
use App\Models\Cutting;
use App\Models\CuttingMaterial;
use App\Models\RawMaterialPrice;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class CuttingMaterialFactory extends Factory
{
public function definition(): array
{
return [
'user_id' => User::factory(),
'cutting_id' => Cutting::factory(),
'raw_material_price_id' => RawMaterialPrice::factory(),
'material_usage' => fake()->randomFloat(2, 0.1, 100),
'material_result' => fake()->numberBetween(0, 100),
];
}
}

View File

@ -0,0 +1,23 @@
<?php
namespace Database\Factories;
use App\Models\Cutting;
use App\Models\CuttingResult;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class CuttingResultFactory extends Factory
{
public function definition(): array
{
return [
'user_id' => User::factory(),
'cutting_id' => Cutting::factory(),
'product_name' => fake()->words(2, true),
'cutting_result' => fake()->numberBetween(1, 500),
'sample' => fake()->numberBetween(0, 50),
'original_outside_sample' => fake()->numberBetween(0, 20),
];
}
}

View File

@ -0,0 +1,24 @@
<?php
namespace Database\Factories;
use App\Models\Employee;
use App\Models\EmployeeAdvance;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class EmployeeAdvanceFactory extends Factory
{
public function definition(): array
{
return [
'employee_id' => Employee::factory(),
'paid_by_id' => User::factory(),
'amount' => fake()->numberBetween(50000, 1000000),
'paid_amount' => 0,
'description' => fake()->sentence(),
'due_date' => fake()->date(),
'status' => fake()->randomElement(['pending', 'approved', 'paid', 'rejected', 'cancelled']),
];
}
}

View File

@ -0,0 +1,21 @@
<?php
namespace Database\Factories;
use App\Models\Employee;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class EmployeeFactory extends Factory
{
public function definition(): array
{
return [
'user_id' => User::factory(),
'join_date' => fake()->date(),
'resign_date' => null,
'employment_status' => fake()->randomElement(['full_time', 'part_time', 'contract', 'internship', 'resigned']),
'base_salary' => fake()->numberBetween(1000000, 10000000),
];
}
}

View File

@ -0,0 +1,21 @@
<?php
namespace Database\Factories;
use App\Models\CashTransaction;
use App\Models\Expense;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class ExpenseFactory extends Factory
{
public function definition(): array
{
return [
'cash_transaction_id' => CashTransaction::factory(),
'created_by_id' => User::factory(),
'amount' => fake()->numberBetween(1000, 1000000),
'description' => fake()->sentence(),
];
}
}

View File

@ -0,0 +1,14 @@
<?php
namespace Database\Factories;
use App\Models\HomepageConfiguration;
use Illuminate\Database\Eloquent\Factories\Factory;
class HomepageConfigurationFactory extends Factory
{
public function definition(): array
{
return [];
}
}

View File

@ -0,0 +1,26 @@
<?php
namespace Database\Factories;
use App\Models\Employee;
use App\Models\LeaveRequest;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class LeaveRequestFactory extends Factory
{
public function definition(): array
{
$start = fake()->date();
$end = fake()->dateTimeBetween($start, '+7 days')->format('Y-m-d');
return [
'employee_id' => Employee::factory(),
'start_date' => $start,
'end_date' => $end,
'total_days' => fake()->numberBetween(1, 7),
'status' => fake()->randomElement(['pending', 'approved', 'rejected', 'cancelled']),
'verified_at' => null,
];
}
}

View File

@ -0,0 +1,32 @@
<?php
namespace Database\Factories;
use App\Models\Customer;
use App\Models\Order;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class OrderFactory extends Factory
{
public function definition(): array
{
$subtotal = fake()->numberBetween(10000, 1000000);
$discount = fake()->numberBetween(0, $subtotal);
return [
'customer_id' => Customer::factory(),
'created_by_id' => User::factory(),
'order_number' => fake()->unique()->numerify('ORD-####'),
'channel' => fake()->randomElement(['offline', 'online', 'whatsapp', 'shopee', 'tiktok']),
'price_type' => fake()->randomElement(['retail', 'wholesale']),
'status' => 'pending',
'payment_type' => fake()->randomElement(['cash', 'transfer', 'debit', 'credit']),
'is_affiliate' => false,
'subtotal' => $subtotal,
'discount' => $discount,
'total_amount' => $subtotal - $discount,
'notes' => fake()->sentence(),
];
}
}

View File

@ -0,0 +1,28 @@
<?php
namespace Database\Factories;
use App\Models\Order;
use App\Models\OrderItem;
use App\Models\ProductVariant;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class OrderItemFactory extends Factory
{
public function definition(): array
{
$quantity = fake()->numberBetween(1, 50);
$unitPrice = fake()->numberBetween(1000, 50000);
return [
'order_id' => Order::factory(),
'user_id' => User::factory(),
'product_variant_id' => ProductVariant::factory(),
'stock_quality' => 'good',
'quantity' => $quantity,
'unit_price' => $unitPrice,
'subtotal' => $quantity * $unitPrice,
];
}
}

View File

@ -0,0 +1,21 @@
<?php
namespace Database\Factories;
use App\Models\OwnerVerificationRequest;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class OwnerVerificationRequestFactory extends Factory
{
public function definition(): array
{
return [
'action' => fake()->randomElement(['create', 'update', 'delete']),
'status' => 'pending',
'submitted_by_id' => User::factory(),
'payload' => json_encode(['key' => fake()->word(), 'value' => fake()->sentence()]),
'verified_at' => null,
];
}
}

View File

@ -0,0 +1,24 @@
<?php
namespace Database\Factories;
use App\Models\Attendance;
use App\Models\Payroll;
use App\Models\PayrollAdjustment;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class PayrollAdjustmentFactory extends Factory
{
public function definition(): array
{
return [
'payroll_id' => Payroll::factory(),
'attendance_id' => Attendance::factory(),
'created_by_id' => User::factory(),
'type' => fake()->randomElement(['bonus', 'deduction', 'correction']),
'amount' => fake()->numberBetween(10000, 500000),
'description' => fake()->sentence(),
];
}
}

View File

@ -0,0 +1,30 @@
<?php
namespace Database\Factories;
use App\Models\Employee;
use App\Models\Payroll;
use App\Models\PayrollPeriod;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class PayrollFactory extends Factory
{
public function definition(): array
{
$baseSalary = fake()->numberBetween(1000000, 10000000);
$bonus = fake()->numberBetween(0, 500000);
$deduction = fake()->numberBetween(0, 200000);
return [
'payroll_period_id' => PayrollPeriod::factory(),
'employee_id' => Employee::factory(),
'base_salary' => $baseSalary,
'bonus_amount' => $bonus,
'deduction_amount' => $deduction,
'total_amount' => $baseSalary + $bonus - $deduction,
'status' => fake()->randomElement(['unpaid', 'paid', 'cancelled']),
'paid_at' => null,
];
}
}

View File

@ -0,0 +1,19 @@
<?php
namespace Database\Factories;
use App\Models\PayrollPeriod;
use Illuminate\Database\Eloquent\Factories\Factory;
class PayrollPeriodFactory extends Factory
{
public function definition(): array
{
return [
'year' => fake()->year(),
'month' => fake()->numberBetween(1, 12),
'status' => fake()->randomElement(['open', 'closed']),
'closed_at' => null,
];
}
}

View File

@ -0,0 +1,19 @@
<?php
namespace Database\Factories;
use App\Models\Category;
use App\Models\Product;
use App\Models\ProductCategory;
use Illuminate\Database\Eloquent\Factories\Factory;
class ProductCategoryFactory extends Factory
{
public function definition(): array
{
return [
'product_id' => Product::factory(),
'category_id' => Category::factory(),
];
}
}

View File

@ -0,0 +1,22 @@
<?php
namespace Database\Factories;
use App\Models\Product;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;
class ProductFactory extends Factory
{
public function definition(): array
{
$name = fake()->unique()->words(2, true);
return [
'name' => $name,
'slug' => Str::slug($name),
'description' => fake()->sentence(),
'status' => fake()->randomElement(['active', 'inactive', 'draft']),
];
}
}

View File

@ -0,0 +1,19 @@
<?php
namespace Database\Factories;
use App\Models\ProductPrice;
use App\Models\ProductVariant;
use Illuminate\Database\Eloquent\Factories\Factory;
class ProductPriceFactory extends Factory
{
public function definition(): array
{
return [
'variant_id' => ProductVariant::factory(),
'type' => fake()->randomElement(['retail', 'wholesale']),
'price' => fake()->numberBetween(1000, 1000000),
];
}
}

View File

@ -0,0 +1,21 @@
<?php
namespace Database\Factories;
use App\Models\Product;
use App\Models\ProductVariant;
use Illuminate\Database\Eloquent\Factories\Factory;
class ProductVariantFactory extends Factory
{
public function definition(): array
{
return [
'product_id' => Product::factory(),
'name' => fake()->words(2, true),
'stock' => fake()->numberBetween(0, 1000),
'reject_stock' => fake()->numberBetween(0, 100),
'retail_stock' => fake()->numberBetween(0, 500),
];
}
}

View File

@ -0,0 +1,26 @@
<?php
namespace Database\Factories;
use App\Models\Purchase;
use App\Models\Supplier;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class PurchaseFactory extends Factory
{
public function definition(): array
{
$subtotal = fake()->numberBetween(50000, 5000000);
return [
'supplier_id' => Supplier::factory(),
'created_by_id' => User::factory(),
'subtotal' => $subtotal,
'discount' => fake()->numberBetween(0, 500000),
'shipping_cost' => fake()->numberBetween(0, 200000),
'total' => $subtotal + fake()->numberBetween(0, 200000) - fake()->numberBetween(0, 500000),
'notes' => fake()->sentence(),
];
}
}

View File

@ -0,0 +1,27 @@
<?php
namespace Database\Factories;
use App\Models\Purchase;
use App\Models\PurchaseItem;
use App\Models\RawMaterialPrice;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class PurchaseItemFactory extends Factory
{
public function definition(): array
{
$quantity = fake()->randomFloat(4, 0.5, 100);
$unitPrice = fake()->numberBetween(1000, 100000);
return [
'purchase_id' => Purchase::factory(),
'user_id' => User::factory(),
'raw_material_price_id' => RawMaterialPrice::factory(),
'quantity' => $quantity,
'unit_price' => $unitPrice,
'subtotal' => (int) ($quantity * $unitPrice),
];
}
}

View File

@ -0,0 +1,20 @@
<?php
namespace Database\Factories;
use App\Models\PushSubscription;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class PushSubscriptionFactory extends Factory
{
public function definition(): array
{
return [
'user_id' => User::factory(),
'endpoint' => fake()->url(),
'public_key' => fake()->sha256(),
'auth_token' => fake()->sha256(),
];
}
}

View File

@ -0,0 +1,18 @@
<?php
namespace Database\Factories;
use App\Models\RawMaterial;
use Illuminate\Database\Eloquent\Factories\Factory;
class RawMaterialFactory extends Factory
{
public function definition(): array
{
return [
'name' => fake()->unique()->words(2, true),
'unit' => fake()->randomElement(['kg', 'meter', 'pcs', 'roll', 'liter', 'pack']),
'is_active' => true,
];
}
}

View File

@ -0,0 +1,20 @@
<?php
namespace Database\Factories;
use App\Models\RawMaterial;
use App\Models\RawMaterialPrice;
use Illuminate\Database\Eloquent\Factories\Factory;
class RawMaterialPriceFactory extends Factory
{
public function definition(): array
{
return [
'raw_material_id' => RawMaterial::factory(),
'variant' => fake()->words(2, true),
'price' => fake()->numberBetween(1000, 500000),
'stock' => fake()->randomFloat(4, 0, 1000),
];
}
}

View File

@ -0,0 +1,20 @@
<?php
namespace Database\Factories;
use App\Models\Rejection;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class RejectionFactory extends Factory
{
public function definition(): array
{
return [
'rejectable_type' => fake()->word(),
'rejectable_id' => 1,
'rejected_by_id' => User::factory(),
'reason' => fake()->sentence(),
];
}
}

View File

@ -0,0 +1,21 @@
<?php
namespace Database\Factories;
use App\Models\Restock;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class RestockFactory extends Factory
{
public function definition(): array
{
return [
'created_by_id' => User::factory(),
'subtotal' => fake()->numberBetween(50000, 5000000),
'total' => fake()->numberBetween(50000, 5000000),
'notes' => fake()->sentence(),
'stock_type' => fake()->randomElement(['good', 'bad', 'damaged']),
];
}
}

View File

@ -0,0 +1,27 @@
<?php
namespace Database\Factories;
use App\Models\ProductVariant;
use App\Models\Restock;
use App\Models\RestockItem;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class RestockItemFactory extends Factory
{
public function definition(): array
{
$quantity = fake()->numberBetween(1, 200);
$unitPrice = fake()->numberBetween(1000, 50000);
return [
'restock_id' => Restock::factory(),
'user_id' => User::factory(),
'product_variant_id' => ProductVariant::factory(),
'quantity' => $quantity,
'unit_price' => $unitPrice,
'subtotal' => $quantity * $unitPrice,
];
}
}

View File

@ -0,0 +1,29 @@
<?php
namespace Database\Factories;
use App\Models\ProductVariant;
use App\Models\RetailStockHistory;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class RetailStockHistoryFactory extends Factory
{
public function definition(): array
{
$stockBefore = fake()->numberBetween(0, 500);
$retailBefore = fake()->numberBetween(0, 200);
$quantity = fake()->numberBetween(1, 100);
return [
'product_variant_id' => ProductVariant::factory(),
'user_id' => User::factory(),
'quantity' => $quantity,
'stock_before' => $stockBefore,
'retail_stock_before' => $retailBefore,
'stock_after' => $stockBefore - $quantity,
'retail_stock_after' => $retailBefore + $quantity,
'notes' => fake()->sentence(),
];
}
}

View File

@ -0,0 +1,28 @@
<?php
namespace Database\Factories;
use App\Models\StockMutation;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class StockMutationFactory extends Factory
{
public function definition(): array
{
$stockBefore = fake()->randomFloat(4, 0, 1000);
$quantity = fake()->randomFloat(4, -100, 100);
return [
'stockable_type' => fake()->word(),
'stockable_id' => 1,
'type' => fake()->randomElement(['in', 'out', 'adjustment']),
'quantity' => $quantity,
'stock_before' => $stockBefore,
'stock_after' => $stockBefore + $quantity,
'stock_quality' => fake()->randomElement(['good', 'bad', 'damaged']),
'description' => fake()->sentence(),
'user_id' => User::factory(),
];
}
}

View File

@ -0,0 +1,20 @@
<?php
namespace Database\Factories;
use App\Models\StokOpname;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
class StokOpnameFactory extends Factory
{
public function definition(): array
{
return [
'created_by_id' => User::factory(),
'opname_date' => fake()->date(),
'status' => fake()->randomElement(['draft', 'in_progress', 'completed', 'verified', 'cancelled']),
'notes' => fake()->sentence(),
];
}
}

View File

@ -0,0 +1,27 @@
<?php
namespace Database\Factories;
use App\Models\ProductVariant;
use App\Models\StokOpname;
use App\Models\StokOpnameItem;
use Illuminate\Database\Eloquent\Factories\Factory;
class StokOpnameItemFactory extends Factory
{
public function definition(): array
{
$system = fake()->numberBetween(0, 500);
$physical = fake()->numberBetween(0, 500);
return [
'stok_opname_id' => StokOpname::factory(),
'product_variant_id' => ProductVariant::factory(),
'stock_quality' => 'good',
'system_stock' => $system,
'physical_stock' => $physical,
'difference' => $physical - $system,
'notes' => fake()->sentence(),
];
}
}

View File

@ -0,0 +1,18 @@
<?php
namespace Database\Factories;
use App\Models\Supplier;
use Illuminate\Database\Eloquent\Factories\Factory;
class SupplierFactory extends Factory
{
public function definition(): array
{
return [
'name' => fake()->company(),
'phone_number' => fake()->phoneNumber(),
'address' => fake()->address(),
];
}
}

View File

@ -0,0 +1,14 @@
<?php
namespace Database\Factories;
use App\Models\SystemConfiguration;
use Illuminate\Database\Eloquent\Factories\Factory;
class SystemConfigurationFactory extends Factory
{
public function definition(): array
{
return [];
}
}

Some files were not shown because too many files have changed in this diff Show More