Refactor AGENTS.md to create a comprehensive module/feature development checklist, consolidating session notes, model relationships, casting, scopes, reorganized model structures, and conventions for backend and frontend development. Added mandatory reading section for project context and conventions.
This commit is contained in:
parent
bc02af2a66
commit
7a1b107ce5
88
.ai/CONTEXT.md
Normal file
88
.ai/CONTEXT.md
Normal file
@ -0,0 +1,88 @@
|
||||
# DST Collection — Project Context
|
||||
|
||||
## Tentang Project
|
||||
**DST Collection** adalah aplikasi ERP untuk brand pakaian wanita (daster, dress, dll). Aplikasi ini mengelola dua area bisnis utama:
|
||||
|
||||
1. **Toko** — penjualan, produk, keuangan, HR
|
||||
2. **Konveksi** — bahan baku, cutting, pembelian bahan
|
||||
|
||||
## Tech Stack
|
||||
| Layer | Technology |
|
||||
|-------|------------|
|
||||
| Backend | Laravel 13, PHP 8.3 |
|
||||
| Frontend | React 19, Inertia.js 3, TypeScript |
|
||||
| UI | shadcn/ui, Radix UI, Tailwind CSS 4 |
|
||||
| Auth | Laravel Fortify, Spatie Permission |
|
||||
| DB | MySQL (SoftDeletes di semua model utama) |
|
||||
|
||||
## Roles & Akses
|
||||
|
||||
### role: `developer`, `owner`
|
||||
- **Akses**: Semua module, semua aksi
|
||||
- **Catatan**: Selalu muncul di semua sidebar
|
||||
|
||||
### role: `admin-toko`
|
||||
- **Akses**: Full CRUD semua module toko
|
||||
- **Modules**: Kategori, Produk, Customer, Transaksi, Restock, Kas Toko, Pengeluaran, Kasbon, Gaji, Pegawai, Presensi, Cuti, Settings
|
||||
- **Catatan**: TIDAK akses Supplier, Bahan Baku, Belanja, Cutting
|
||||
|
||||
### role: `direktur`
|
||||
- **Akses**: Readonly semua data toko + bisa ajukan kasbon
|
||||
- **Modules**: Semua module toko (readonly), kecuali Supplier, Bahan Baku, Belanja, Cutting
|
||||
- **Catatan**: Bisa lihat semua data pegawai toko, tapi bukan admin bahan baku
|
||||
|
||||
### role: `admin-bahan-baku`
|
||||
- **Akses**: Full CRUD untuk konveksi
|
||||
- **Modules**: Bahan Baku, Supplier, Belanja, Cutting, Pegawai (hanya role admin-bahan-baku), Kasbon (lihat semua + ACC/bayar)
|
||||
- **Catatan**: TIDAK akses module toko lainnya
|
||||
|
||||
### role: `cashier`
|
||||
- **Akses**: Transaksi (full CRUD), Customer (full CRUD), Produk (readonly), Kasbon (CRUD own data)
|
||||
- **Modules**: Transaksi, Customer, Produk (view), Kasbon, Gaji (view), Presensi, Cuti
|
||||
|
||||
### role: `marketing-offline`, `marketing-online`
|
||||
- **Akses**: Transaksi (readonly yang punya dia), Produk (readonly), Customer (full CRUD)
|
||||
- **Modules**: Transaksi (view only own), Produk (view), Customer, Kasbon (CRUD own data), Presensi, Cuti
|
||||
|
||||
### role: `stok-opname`
|
||||
- **Akses**: Stok Opname (full CRUD + submit)
|
||||
- **Modules**: Stok Opname, Produk (view), Presensi, Cuti
|
||||
|
||||
### role: `non-operator`
|
||||
- **Akses**: Basic (dashboard, presensi, cuti, kasbon)
|
||||
- **Modules**: Presensi, Cuti, Kasbon (CRUD own data)
|
||||
|
||||
## Module Overview
|
||||
|
||||
| # | Module | Route Group | Controller Path | Service Path |
|
||||
|---|--------|-------------|-----------------|--------------|
|
||||
| 1 | Kategori | `admin/master/categories` | `Admin/Master/CategoryController` | `Admin/Master/CategoryService` |
|
||||
| 2 | Produk | `admin/master/products` | `Admin/Master/Product/ProductController` | `Admin/Master/Product/ProductService` |
|
||||
| 3 | Bahan Baku | `admin/master/raw-materials` | `Admin/Master/RawMaterial/RawMaterialController` | `Admin/Master/RawMaterial/RawMaterialService` |
|
||||
| 4 | Supplier | `admin/master/suppliers` | `Admin/Master/SupplierController` | `Admin/Master/SupplierService` |
|
||||
| 5 | Customer | `admin/master/customers` | `Admin/Master/CustomerController` | `Admin/Master/CustomerService` |
|
||||
| 6 | Belanja | `admin/manage/purchases` | `Admin/Manage/PurchaseController` | `Admin/Manage/PurchaseService` |
|
||||
| 7 | Cutting | `admin/manage/cuttings` | `Admin/Manage/CuttingController` | `Admin/Manage/CuttingService` |
|
||||
| 8 | Transaksi | `admin/manage/transactions` | `Admin/Manage/TransactionController` | `Admin/Manage/TransactionService` |
|
||||
| 9 | Restock | `admin/manage/restocks` | `Admin/Manage/RestockController` | `Admin/Manage/RestockService` |
|
||||
| 10 | Stok Opname | `admin/manage/stok-opnames` | (via StockMutationController) | — |
|
||||
| 11 | Kas Toko | `admin/finance/cash-accounts` | `Admin/Finance/CashAccountController` | `Admin/Finance/CashAccountService` |
|
||||
| 12 | Pengeluaran | `admin/finance/expenses` | `Admin/Finance/ExpenseController` | `Admin/Finance/ExpenseService` |
|
||||
| 13 | Kasbon | `admin/finance/employee-advances` | `Admin/Finance/EmployeeAdvanceController` | `Admin/Finance/EmployeeAdvanceService` |
|
||||
| 14 | Gaji | `admin/finance/payroll-periods` | `Admin/Finance/PayrollController` | `Admin/Finance/PayrollPeriodService` |
|
||||
| 15 | Pegawai | `admin/hr/employees` | `Admin/HR/EmployeeController` | `Admin/HR/EmployeeService` |
|
||||
| 16 | Presensi | `admin/hr/attendances` | `Admin/HR/AttendanceController` | `Admin/HR/AttendanceService` |
|
||||
| 17 | Cuti | `admin/hr/leave-requests` | `Admin/HR/LeaveRequestController` | `Admin/HR/LeaveRequestService` |
|
||||
| 18 | Role & Permission | `admin/settings/roles` | `Admin/RoleController` | `Admin/Settings/RoleService` |
|
||||
| 19 | Pengaturan | `admin/settings` | `Admin/AdminSettingsController` | `Admin/AdminSettingsService` |
|
||||
|
||||
## Statistics
|
||||
| Metric | Count |
|
||||
|--------|-------|
|
||||
| Tables | 49 |
|
||||
| Models | 42 |
|
||||
| Enums | 20 + 1 trait |
|
||||
| Services | 28 (including 3 concerns) |
|
||||
| Controllers | 30 |
|
||||
| Roles | 9 |
|
||||
| Permissions | ~120 |
|
||||
1406
.ai/CONVENTIONS.md
Normal file
1406
.ai/CONVENTIONS.md
Normal file
File diff suppressed because it is too large
Load Diff
308
.ai/REFERENCE.md
Normal file
308
.ai/REFERENCE.md
Normal file
@ -0,0 +1,308 @@
|
||||
# Database Reference
|
||||
|
||||
> Format: `table_name` → `model_name` | columns | relationships
|
||||
|
||||
---
|
||||
|
||||
## Auth & User
|
||||
|
||||
### `users` → User
|
||||
`id` `email`(unique) `username`(unique) `password` `is_active`(bool) `last_login_at`(datetime) `created_at` `updated_at` `deleted_at`
|
||||
- Casts: email_verified_at(datetime), is_active(bool), last_login_at(datetime), password(hashed), two_factor_confirmed_at(datetime)
|
||||
- Scopes: active()
|
||||
- Relations: userProfile(HasOne→UserProfile), employee(HasOne→Employee), attendances(HasMany→Attendance), cashAccounts(HasMany→CashAccount,created_by_id), cashTransactions(HasMany→CashTransaction,created_by_id), createdCuttings(HasMany→Cutting,created_by_id), submittedCuttings(HasMany→Cutting,submitted_by_id), createdExpenses(HasMany→Expense,created_by_id), createdOrders(HasMany→Order,created_by_id), marketingOrders(HasMany→Order,marketing_id), orderItems(HasMany→OrderItem), createdPurchases(HasMany→Purchase,created_by_id), createdRestocks(HasMany→Restock,created_by_id), stokOpnamesCreated(HasMany→StokOpname,created_by_id), stokOpnamesVerified(HasMany→StokOpname,verified_by_id), employeeAdvancesPaid(HasMany→EmployeeAdvance,paid_by_id), employeeAdvancesVerified(HasMany→EmployeeAdvance,verified_by_id), paidPayrolls(HasMany→Payroll,paid_by_id), payrollPeriodsClosed(HasMany→PayrollPeriod,closed_by_id), notifications(HasMany→AppNotification), ownerVerificationRequestsSubmitted(HasMany→OwnerVerificationRequest,submitted_by_id), ownerVerificationRequestsVerified(HasMany→OwnerVerificationRequest,verified_by_id), rejections(HasMany→Rejection,rejected_by_id), pushSubscriptions(HasMany→PushSubscription,morph)
|
||||
|
||||
### `user_profiles` → UserProfile
|
||||
`id` `user_id`(FK→users,unique) `full_name`(200) `phone_number`(20,null) `gender`(enum,null) `birth_date`(date,null) `address`(text,null) `created_at` `updated_at` `deleted_at`
|
||||
- Casts: gender(Gender), birth_date(date:Y-m-d)
|
||||
- Scopes: female(), male(), hasPhoneNumber()
|
||||
- Relations: user(BelongsTo→User)
|
||||
|
||||
### `push_subscriptions` → PushSubscription
|
||||
`id` `subscribable_type` `subscribable_id` `endpoint`(500,unique) `public_key`(null) `auth_token`(null) `content_encoding`(null) `created_at` `updated_at`
|
||||
- Relations: user(MorphTo)
|
||||
|
||||
### `notifications` → AppNotification
|
||||
`id` `user_id`(FK→users) `title` `body`(text,null) `url`(null) `is_read`(bool,default:false) `read_at`(datetime,null) `created_at` `updated_at`
|
||||
- Casts: is_read(bool), read_at(datetime)
|
||||
- Relations: user(BelongsTo→User)
|
||||
|
||||
---
|
||||
|
||||
## Master Data
|
||||
|
||||
### `categories` → Category
|
||||
`id` `name`(50) `slug`(50,unique) `created_at` `updated_at` `deleted_at`
|
||||
- Relations: products(BelongsToMany→Product via product_categories)
|
||||
- Accessor: formattedName → ucfirst(name)
|
||||
|
||||
### `product_categories` → Category (Pivot)
|
||||
`product_id`(FK→products) `category_id`(FK→categories)
|
||||
- No id, no timestamps
|
||||
- Relations: category(BelongsTo→Category), product(BelongsTo→Product)
|
||||
|
||||
### `products` → Product
|
||||
`id` `name`(200) `slug`(200,unique) `description`(text,null) `status`(enum,default:active) `created_at` `updated_at` `deleted_at`
|
||||
- Casts: status(ProductStatus)
|
||||
- Scopes: active(), draft(), inactive()
|
||||
- Relations: categories(BelongsToMany→Category), productVariants(HasMany→ProductVariant)
|
||||
|
||||
### `product_variants` → ProductVariant
|
||||
`id` `product_id`(FK→products) `name`(200) `stock`(uint,default:0) `reject_stock`(uint,default:0) `retail_stock`(uint,default:0) `created_at` `updated_at` `deleted_at`
|
||||
- Casts: stock(int), reject_stock(int), retail_stock(int)
|
||||
- GlobalScope: orderBy(name)
|
||||
- Relations: product(BelongsTo→Product), productPrices(HasMany→ProductPrice,variant_id), orderItems(HasMany→OrderItem), restockItems(HasMany→RestockItem), retailStockHistories(HasMany→RetailStockHistory), stokOpnameItems(HasMany→StokOpnameItem), stockMutations(HasMany→StockMutation,morph)
|
||||
|
||||
### `product_prices` → ProductPrice
|
||||
`id` `variant_id`(FK→product_variants) `type`(enum) `price`(uint) `created_at` `updated_at`
|
||||
- UNIQUE(variant_id, type)
|
||||
- Casts: type(PriceType), price(int)
|
||||
- Scopes: retail(), wholesale()
|
||||
- Relations: variant(BelongsTo→ProductVariant)
|
||||
|
||||
### `customers` → Customer
|
||||
`id` `name`(200) `phone_number`(20,null) `address`(text,null) `created_at` `updated_at` `deleted_at`
|
||||
- Relations: orders(HasMany→Order)
|
||||
- Accessor: formattedPhoneNumber (get: "0821 2121 2121", set: strip whitespace)
|
||||
|
||||
### `suppliers` → Supplier
|
||||
`id` `name`(200) `phone_number`(20,null) `address`(text,null) `created_at` `updated_at` `deleted_at`
|
||||
- Relations: purchases(HasMany→Purchase)
|
||||
- Accessor: formattedPhoneNumber (get: "0821 2121 2121", set: strip whitespace)
|
||||
|
||||
### `raw_materials` → RawMaterial
|
||||
`id` `name`(200) `unit`(enum) `is_active`(bool,default:true) `created_at` `updated_at` `deleted_at`
|
||||
- Casts: unit(RawMaterialUnit), is_active(bool)
|
||||
- Scopes: active(), nonactive(), kg(), meter(), yard()
|
||||
- Relations: rawMaterialPrices(HasMany→RawMaterialPrice)
|
||||
|
||||
### `raw_material_prices` → RawMaterialPrice
|
||||
`id` `raw_material_id`(FK→raw_materials) `variant`(200) `price`(uint) `stock`(uint,default:0) `created_at` `updated_at` `deleted_at`
|
||||
- Casts: price(int), stock(int)
|
||||
- GlobalScope: orderBy(variant)
|
||||
- Relations: rawMaterial(BelongsTo→RawMaterial,withTrashed), cuttingMaterials(HasMany→CuttingMaterial), purchaseItems(HasMany→PurchaseItem)
|
||||
- Accessor: photo_url → first media presigned S3 URL
|
||||
|
||||
---
|
||||
|
||||
## Finance
|
||||
|
||||
### `cash_accounts` → CashAccount
|
||||
`id` `created_by_id`(FK→users) `name`(200) `balance`(ubig,default:0) `created_at` `updated_at` `deleted_at`
|
||||
- Casts: balance(int)
|
||||
- Relations: cashTransactions(HasMany→CashTransaction), createdBy(BelongsTo→User)
|
||||
|
||||
### `cash_transactions` → CashTransaction
|
||||
`id` `cash_account_id`(FK→cash_accounts) `created_by_id`(FK→users) `reference_id`(ubig,null,morph) `reference_type`(string,null,morph) `amount`(ubig) `balance_after`(ubig) `type`(enum,default:deposit) `description`(100) `created_at` `updated_at` `deleted_at`
|
||||
- Casts: type(CashTransactionType), amount(int), balance_after(int)
|
||||
- Scopes: deposit(), expenseType(), transfer(), withdrawal()
|
||||
- Relations: cashAccount(BelongsTo→CashAccount), createdBy(BelongsTo→User), reference(MorphTo), expense(HasOne→Expense), order(HasOne→Order), employeeAdvances(HasMany→EmployeeAdvance), payrolls(HasMany→Payroll)
|
||||
|
||||
### `expenses` → Expense
|
||||
`id` `cash_transaction_id`(FK→cash_transactions,unique,null) `created_by_id`(FK→users) `amount`(ubig) `description`(100) `created_at` `updated_at` `deleted_at`
|
||||
- Casts: amount(int), date(date:Y-m-d)
|
||||
- Relations: cashTransaction(BelongsTo→CashTransaction), createdBy(BelongsTo→User)
|
||||
|
||||
### `employee_advances` → EmployeeAdvance
|
||||
`id` `paid_by_id`(FK→users,null) `employee_id`(FK→employees) `verified_by_id`(FK→users,null) `repayment_cash_transaction_id`(FK→cash_transactions,unique,null) `cash_transaction_id`(FK→cash_transactions,unique,null) `amount`(ubig) `paid_amount`(ubig,default:0) `description`(100) `due_date`(date) `status`(enum,default:pending) `verified_at`(datetime,null) `paid_at`(datetime,null) `created_at` `updated_at` `deleted_at`
|
||||
- Casts: status(EmployeeAdvanceStatus), amount(int), paid_amount(int), due_date(date:Y-m-d), verified_at(datetime), paid_at(datetime)
|
||||
- Scopes: approved(), cancelled(), paid(), pending(), rejected()
|
||||
- Relations: employee(BelongsTo→Employee), cashTransaction(BelongsTo→CashTransaction), repaymentCashTransaction(BelongsTo→CashTransaction), paidBy(BelongsTo→User), verifiedBy(BelongsTo→User), payments(HasMany→EmployeeAdvancePayment)
|
||||
|
||||
### `employee_advance_payments` → EmployeeAdvancePayment
|
||||
`id` `employee_advance_id`(FK→employee_advances) `paid_by_id`(FK→users,null) `cash_transaction_id`(FK→cash_transactions,unique,null) `amount`(ubig) `description`(100,null) `paid_at`(datetime) `created_at` `updated_at`
|
||||
- No soft deletes
|
||||
- Casts: amount(int), paid_at(datetime)
|
||||
- Relations: employeeAdvance(BelongsTo→EmployeeAdvance), paidBy(BelongsTo→User), cashTransaction(BelongsTo→CashTransaction)
|
||||
|
||||
---
|
||||
|
||||
## HR
|
||||
|
||||
### `employees` → Employee
|
||||
`id` `user_id`(FK→users,unique) `join_date`(date) `resign_date`(date,null) `employment_status`(enum,default:full_time) `base_salary`(uint) `created_at` `updated_at` `deleted_at`
|
||||
- Casts: employment_status(EmploymentStatus), base_salary(int), join_date(date:Y-m-d), resign_date(date:Y-m-d)
|
||||
- Scopes: contract(), fullTime(), internship(), partTime(), resigned()
|
||||
- Relations: user(BelongsTo→User), attendances(HasMany→Attendance), employeeAdvances(HasMany→EmployeeAdvance), leaveRequests(HasMany→LeaveRequest), payrolls(HasMany→Payroll)
|
||||
|
||||
### `attendances` → Attendance
|
||||
`id` `employee_id`(FK→employees) `attendance_date`(date) `check_in_at`(datetime) `check_out_at`(datetime,null) `check_in_latitude`(decimal(10,7),null) `check_in_longitude`(decimal(10,7),null) `check_out_latitude`(decimal(10,7),null) `check_out_longitude`(decimal(10,7),null) `work_duration_minutes`(uint,null) `created_at` `updated_at`
|
||||
- No soft deletes
|
||||
- Casts: attendance_date(date:Y-m-d), check_in_at(datetime), check_out_at(datetime), check_in/out_latitude/longitude(decimal:7), work_duration_minutes(int)
|
||||
- Relations: employee(BelongsTo→Employee), payrollAdjustments(HasMany→PayrollAdjustment)
|
||||
|
||||
### `payroll_periods` → PayrollPeriod
|
||||
`id` `closed_by_id`(FK→users,null) `year`(usmall) `month`(utiny) `status`(enum,default:open) `closed_at`(datetime,null) `created_at` `updated_at` `deleted_at`
|
||||
- Casts: status(PayrollPeriodStatus), year(int), month(int), closed_at(datetime)
|
||||
- Scopes: closed(), open()
|
||||
- Relations: closedBy(BelongsTo→User), payrolls(HasMany→Payroll)
|
||||
|
||||
### `payrolls` → Payroll
|
||||
`id` `payroll_period_id`(FK→payroll_periods) `employee_id`(FK→employees) `cash_transaction_id`(FK→cash_transactions,unique,null) `paid_by_id`(FK→users,null) `base_salary`(uint) `bonus_amount`(ubig,default:0) `deduction_amount`(ubig,default:0) `total_amount`(ubig) `status`(enum,default:unpaid) `paid_at`(datetime,null) `created_at` `updated_at` `deleted_at`
|
||||
- Casts: status(PayrollStatus), base_salary(int), bonus_amount(int), deduction_amount(int), total_amount(int), paid_at(datetime)
|
||||
- Scopes: cancelled(), paid(), unpaid()
|
||||
- Relations: payrollPeriod(BelongsTo→PayrollPeriod), employee(BelongsTo→Employee), cashTransaction(BelongsTo→CashTransaction), paidBy(BelongsTo→User), payrollAdjustments(HasMany→PayrollAdjustment)
|
||||
|
||||
### `payroll_adjustments` → PayrollAdjustment
|
||||
`id` `payroll_id`(FK→payrolls) `attendance_id`(FK→attendances,null) `created_by_id`(FK→users) `type`(enum) `amount`(ubig) `description`(100) `created_at` `updated_at` `deleted_at`
|
||||
- Casts: type(PayrollAdjustmentType), amount(int)
|
||||
- Scopes: bonus(), deduction()
|
||||
- Relations: payroll(BelongsTo→Payroll), attendance(BelongsTo→Attendance), createdBy(BelongsTo→User)
|
||||
|
||||
### `leave_requests` → LeaveRequest
|
||||
`id` `employee_id`(FK→employees) `verified_by_id`(FK→users,null) `start_date`(date) `end_date`(date) `total_days`(uint) `status`(enum,default:pending) `verified_at`(datetime,null) `created_at` `updated_at` `deleted_at`
|
||||
- Casts: status(LeaveRequestStatus), start_date(date:Y-m-d), end_date(date:Y-m-d), total_days(int), verified_at(datetime)
|
||||
- Scopes: approved(), cancelled(), pending(), rejected()
|
||||
- Relations: employee(BelongsTo→Employee), verifiedBy(BelongsTo→User)
|
||||
|
||||
---
|
||||
|
||||
## Sales
|
||||
|
||||
### `orders` → Order
|
||||
`id` `customer_id`(FK→customers,null) `marketing_id`(FK→users,null) `cash_transaction_id`(FK→cash_transactions,unique,null) `created_by_id`(FK→users) `order_number`(30,unique) `channel`(enum) `price_type`(enum) `status`(enum,default:pending) `payment_type`(enum,default:cash) `is_affiliate`(bool,default:false) `tiktok_order_id`(100,null) `shopee_order_id`(100,null) `subtotal`(ubig) `discount`(ubig,default:0) `nego_price`(ubig,null) `marketplace_settings_snapshot`(json,null) `total_amount`(ubig) `cogs`(ubig,default:0) `notes`(text,null) `created_at` `updated_at` `deleted_at`
|
||||
- Casts: channel(OrderChannel), price_type(PriceType), status(OrderStatus), payment_type(PaymentType), is_affiliate(bool), subtotal(int), discount(int), nego_price(int), total_amount(int), cogs(int), marketplace_settings_snapshot(array)
|
||||
- Scopes: cancelled(), cash(), completed(), pending(), processing(), qris(), refunded(), retail(), shopee(), store(), tiktok(), transfer(), wholesale()
|
||||
- Relations: cashTransaction(BelongsTo→CashTransaction), createdBy(BelongsTo→User), customer(BelongsTo→Customer), marketing(BelongsTo→User), orderItems(HasMany→OrderItem)
|
||||
|
||||
### `order_items` → OrderItem
|
||||
`id` `order_id`(FK→orders,null) `user_id`(FK→users,null) `product_variant_id`(FK→product_variants) `stock_quality`(enum,default:good) `quantity`(uint) `unit_price`(ubig) `subtotal`(ubig) `created_at` `updated_at` `deleted_at`
|
||||
- Casts: stock_quality(ProductStockQuality), quantity(int), unit_price(int), subtotal(int)
|
||||
- Scopes: good(), reject()
|
||||
- Relations: order(BelongsTo→Order), productVariant(BelongsTo→ProductVariant), user(BelongsTo→User)
|
||||
|
||||
### `rejections` → Rejection
|
||||
`id` `rejectable_type`(string,null,morph) `rejectable_id`(ubig,null,morph) `rejected_by_id`(FK→users) `reason`(500) `created_at` `updated_at` `deleted_at`
|
||||
- Relations: rejectable(MorphTo), rejectedBy(BelongsTo→User)
|
||||
|
||||
---
|
||||
|
||||
## Production
|
||||
|
||||
### `cuttings` → Cutting
|
||||
`id` `created_by_id`(FK→users) `submitted_by_id`(FK→users,null) `status`(enum,default:in_progress) `description`(100,null) `total_material_cost`(ubig,null) `sewing_cost`(ubig,default:0) `other_cost`(ubig,default:0) `cost_per_unit`(ubig,null) `created_at` `updated_at` `deleted_at`
|
||||
- Casts: status(CuttingStatus), total_material_cost(int), cost_per_unit(int), sewing_cost(int), other_cost(int)
|
||||
- Scopes: cancelled(), completed(), inProgress()
|
||||
- Relations: createdBy(BelongsTo→User), submittedBy(BelongsTo→User), cuttingMaterialCombinations(HasMany→CuttingMaterialCombination), cuttingMaterials(HasMany→CuttingMaterial), cuttingResults(HasMany→CuttingResult)
|
||||
|
||||
### `cutting_material_combinations` → CuttingMaterialCombination
|
||||
`id` `user_id`(FK→users,null) `cutting_id`(FK→cuttings,null) `material_result`(int,null) `created_at` `updated_at` `deleted_at`
|
||||
- Casts: material_result(int)
|
||||
- Relations: cutting(BelongsTo→Cutting), cuttingMaterials(HasMany→CuttingMaterial,combination_id), user(BelongsTo→User)
|
||||
|
||||
### `cutting_materials` → CuttingMaterial
|
||||
`id` `user_id`(FK→users,null) `cutting_id`(FK→cuttings,null) `raw_material_price_id`(FK→raw_material_prices) `combination_id`(FK→cutting_material_combinations,null) `material_usage`(int) `material_result`(int,null) `created_at` `updated_at` `deleted_at`
|
||||
- Casts: material_usage(int), material_result(int)
|
||||
- Relations: cutting(BelongsTo→Cutting), rawMaterialPrice(BelongsTo→RawMaterialPrice), combination(BelongsTo→CuttingMaterialCombination), user(BelongsTo→User)
|
||||
|
||||
### `cutting_results` → CuttingResult
|
||||
`id` `user_id`(FK→users,null) `cutting_id`(FK→cuttings,null) `product_name`(255,null) `cutting_result`(uint,null) `sample`(uint,null) `original_outside_sample`(uint,null) `created_at` `updated_at` `deleted_at`
|
||||
- Casts: cutting_result(int), sample(int), original_outside_sample(int)
|
||||
- Relations: cutting(BelongsTo→Cutting), user(BelongsTo→User)
|
||||
|
||||
---
|
||||
|
||||
## Inventory
|
||||
|
||||
### `purchases` → Purchase
|
||||
`id` `supplier_id`(FK→suppliers) `created_by_id`(FK→users) `subtotal`(ubig) `discount`(ubig,default:0) `shipping_cost`(ubig,default:0) `total`(ubig) `notes`(100,null) `created_at` `updated_at` `deleted_at`
|
||||
- Casts: subtotal(int), discount(int), shipping_cost(int), total(int)
|
||||
- Relations: createdBy(BelongsTo→User), supplier(BelongsTo→Supplier), purchaseItems(HasMany→PurchaseItem)
|
||||
|
||||
### `purchase_items` → PurchaseItem
|
||||
`id` `purchase_id`(FK→purchases,null) `user_id`(FK→users,null) `raw_material_price_id`(FK→raw_material_prices) `quantity`(uint) `unit_price`(ubig) `subtotal`(ubig) `created_at` `updated_at` `deleted_at`
|
||||
- Casts: quantity(int), unit_price(int), subtotal(int)
|
||||
- Relations: purchase(BelongsTo→Purchase), rawMaterialPrice(BelongsTo→RawMaterialPrice,withTrashed), user(BelongsTo→User)
|
||||
|
||||
### `restocks` → Restock
|
||||
`id` `created_by_id`(FK→users) `subtotal`(ubig) `total`(ubig) `notes`(100,null) `stock_type`(enum,default:good) `created_at` `updated_at` `deleted_at`
|
||||
- Casts: stock_type(ProductStockQuality), subtotal(int), total(int)
|
||||
- Scopes: good(), reject()
|
||||
- Relations: createdBy(BelongsTo→User), restockItems(HasMany→RestockItem)
|
||||
|
||||
### `restock_items` → RestockItem
|
||||
`id` `restock_id`(FK→restocks,null) `user_id`(FK→users,null) `product_variant_id`(FK→product_variants) `quantity`(int) `unit_price`(ubig) `subtotal`(ubig) `created_at` `updated_at` `deleted_at`
|
||||
- Casts: quantity(int), unit_price(int), subtotal(int)
|
||||
- Relations: restock(BelongsTo→Restock), productVariant(BelongsTo→ProductVariant), user(BelongsTo→User)
|
||||
|
||||
### `stok_opnames` → StokOpname
|
||||
`id` `created_by_id`(FK→users) `verified_by_id`(FK→users,null) `opname_date`(date) `status`(enum,default:draft) `notes`(text,null) `verification_notes`(text,null) `created_at` `updated_at` `deleted_at`
|
||||
- Casts: status(StokOpnameStatus), opname_date(date:Y-m-d)
|
||||
- Scopes: cancelled(), completed(), draft(), inProgress(), verified()
|
||||
- Relations: createdBy(BelongsTo→User), verifiedBy(BelongsTo→User), stokOpnameItems(HasMany→StokOpnameItem)
|
||||
|
||||
### `stok_opname_items` → StokOpnameItem
|
||||
`id` `stok_opname_id`(FK→stok_opnames) `product_variant_id`(FK→product_variants) `stock_quality`(enum,default:good) `system_stock`(uint,default:0) `physical_stock`(uint,default:0) `difference`(int,default:0) `notes`(text,null) `created_at` `updated_at`
|
||||
- No soft deletes
|
||||
- Casts: stock_quality(ProductStockQuality), system_stock(int), physical_stock(int), difference(int)
|
||||
- Scopes: good(), reject()
|
||||
- Relations: stokOpname(BelongsTo→StokOpname), productVariant(BelongsTo→ProductVariant)
|
||||
|
||||
### `retail_stock_histories` → RetailStockHistory
|
||||
`id` `product_variant_id`(FK→product_variants) `user_id`(FK→users) `quantity`(uint) `stock_before`(uint) `retail_stock_before`(uint) `stock_after`(uint) `retail_stock_after`(uint) `notes`(255,null) `created_at`
|
||||
- No soft deletes, no updated_at
|
||||
- $timestamps = false
|
||||
- Casts: quantity(int), stock_before(int), retail_stock_before(int), stock_after(int), retail_stock_after(int)
|
||||
- Relations: productVariant(BelongsTo→ProductVariant), user(BelongsTo→User)
|
||||
|
||||
### `stock_mutations` → StockMutation
|
||||
`id` `user_id`(FK→users) `stockable_type`(string) `stockable_id`(ubig) `type`(string) `source_type`(string,null) `source_id`(ubig,null) `quantity`(int) `stock_before`(int) `stock_after`(int) `stock_quality`(string,null) `description`(string,null) `created_at` `updated_at`
|
||||
- No soft deletes
|
||||
- Casts: quantity(int), stock_before(int), stock_after(int)
|
||||
- Relations: stockable(MorphTo), source(MorphTo), user(BelongsTo→User)
|
||||
|
||||
---
|
||||
|
||||
## Settings
|
||||
|
||||
### `system_configurations` → SystemConfiguration
|
||||
`id` `created_at` `updated_at`
|
||||
- Singleton table
|
||||
|
||||
### `homepage_configurations` → HomepageConfiguration
|
||||
`id` `created_at` `updated_at`
|
||||
- Singleton table
|
||||
|
||||
### `owner_verification_requests` → OwnerVerificationRequest
|
||||
`id` `action`(50) `status`(50,default:pending) `subject_id`(ubig,null,morph) `subject_type`(string,null,morph) `submitted_by_id`(FK→users) `verified_by_id`(FK→users,null) `payload`(json) `verified_at`(datetime,null) `created_at` `updated_at`
|
||||
- Casts: payload(array), verified_at(datetime)
|
||||
- Relations: subject(MorphTo), submittedBy(BelongsTo→User), verifiedBy(BelongsTo→User)
|
||||
|
||||
### `settings` (laravel-settings)
|
||||
`id` `group`(string) `name`(string) `locked`(bool,default:false) `payload`(json) `created_at` `updated_at`
|
||||
- UNIQUE(group, name)
|
||||
|
||||
---
|
||||
|
||||
## Enums
|
||||
|
||||
| Enum | Values | Used In |
|
||||
|------|--------|---------|
|
||||
| `CashTransactionType` | deposit, expense, transfer, withdrawal | cash_transactions.type |
|
||||
| `CuttingStatus` | in_progress, completed, cancelled | cuttings.status |
|
||||
| `EmployeeAdvanceStatus` | pending, approved, rejected, paid, cancelled | employee_advances.status |
|
||||
| `EmploymentStatus` | full_time, part_time, contract, internship, resigned | employees.employment_status |
|
||||
| `Gender` | male, female | user_profiles.gender |
|
||||
| `LeaveRequestStatus` | pending, approved, rejected, cancelled | leave_requests.status |
|
||||
| `Modules` | — | Permission module names |
|
||||
| `OrderChannel` | store, shopee, tiktok | orders.channel |
|
||||
| `OrderStatus` | pending, processing, completed, cancelled, refunded | orders.status |
|
||||
| `PaymentType` | cash, transfer, qris | orders.payment_type |
|
||||
| `PayrollAdjustmentType` | bonus, deduction | payroll_adjustments.type |
|
||||
| `PayrollPeriodStatus` | open, closed | payroll_periods.status |
|
||||
| `PayrollStatus` | unpaid, paid, cancelled | payrolls.status |
|
||||
| `Permission` | — | Permission action names |
|
||||
| `PriceType` | retail, wholesale, capital | product_prices.type, orders.price_type |
|
||||
| `ProductStatus` | active, draft, inactive | products.status |
|
||||
| `ProductStockQuality` | good, reject | order_items.stock_quality, restocks.stock_type, stok_opname_items.stock_quality |
|
||||
| `RawMaterialUnit` | kg, meter, yard | raw_materials.unit |
|
||||
| `Role` | — | Role names |
|
||||
| `StokOpnameStatus` | draft, in_progress, completed, verified, cancelled | stok_opnames.status |
|
||||
|
||||
## Service Concerns
|
||||
|
||||
| Trait | Methods | Used By |
|
||||
|-------|---------|---------|
|
||||
| `HandlesCashTransactions` | getCashAccount(), creditCash(), debitCash() | CashAccountService, ExpenseService, EmployeeAdvanceService, PayrollPeriodService |
|
||||
| `HasStockAdjustment` | adjustStock(), adjustVariantStock(), applyStock(), reverseStock() | TransactionService, RestockService |
|
||||
| `RegistersMedia` | registerMedia(), syncPhoto() | CashAccountService, CuttingService, ExpenseService, PurchaseService, RestockService, TransactionService |
|
||||
Loading…
Reference in New Issue
Block a user