feat: enhance validation rules for various requests and update attribute names
This commit is contained in:
parent
cd0995f04e
commit
f7ce2f1620
@ -826,6 +826,42 @@ ### Stock Adjustment Pattern
|
||||
|
||||
## Form Request
|
||||
|
||||
### Validasi harus SESUAI dengan DB Schema
|
||||
```php
|
||||
// ✅ SELALU samakan max length dengan DB column
|
||||
// DB: varchar(50) → max:50
|
||||
'name' => ['required', 'string', 'max:50'],
|
||||
|
||||
// DB: varchar(200) → max:200
|
||||
'name' => ['required', 'string', 'max:200'],
|
||||
|
||||
// DB: varchar(100) → max:100
|
||||
'description' => ['required', 'string', 'max:100'],
|
||||
|
||||
// DB: text → tidak perlu max (atau max sesuai UI)
|
||||
'address' => ['nullable', 'string'],
|
||||
|
||||
// DB: decimal(10,7) → numeric + min/max range
|
||||
'latitude' => ['required', 'numeric', 'min:-90', 'max:90'],
|
||||
'longitude' => ['required', 'numeric', 'min:-180', 'max:180'],
|
||||
|
||||
// DB: uint → integer, min:0
|
||||
'base_salary' => ['required', 'integer', 'min:0'],
|
||||
|
||||
// DB: ubig → integer, min:1 (untuk amount)
|
||||
'amount' => ['required', 'integer', 'min:1'],
|
||||
|
||||
// DB: enum → Rule::in(Enum::values()) atau Rule::in(['val1', 'val2'])
|
||||
'status' => ['required', Rule::in(OrderStatus::values())],
|
||||
'gender' => ['nullable', 'in:male,female'],
|
||||
|
||||
// DB: date → 'date'
|
||||
'join_date' => ['required', 'date'],
|
||||
|
||||
// DB: datetime → 'date' (Laravel handle)
|
||||
'paid_at' => ['nullable', 'date'],
|
||||
```
|
||||
|
||||
### Struktur Dasar
|
||||
```php
|
||||
class ProductRequest extends FormRequest
|
||||
@ -860,6 +896,38 @@ ### Struktur Dasar
|
||||
}
|
||||
```
|
||||
|
||||
### Rule Classes — Gunakan `Illuminate\Validation\Rule`
|
||||
```php
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
// ✅ SELALU gunakan Rule classes, JANGAN string-based rules
|
||||
|
||||
// exists → Rule::exists('table', 'column')
|
||||
'category_ids.*' => [Rule::exists('categories', 'id')],
|
||||
'customer_id' => ['nullable', 'integer', Rule::exists('customers', 'id')],
|
||||
'existing_items.*.raw_material_price_id' => ['required', 'integer', Rule::exists('raw_material_prices', 'id')],
|
||||
|
||||
// required_if → Rule::requiredIf(fn () => ...)
|
||||
'shared_prices' => [Rule::requiredIf(fn () => $useSamePrice), 'nullable', 'array'],
|
||||
'existing_items' => [Rule::requiredIf(fn () => $this->input('mode') === 'existing'), 'array', 'min:1'],
|
||||
|
||||
// required_unless → Rule::requiredUnless(fn () => ...)
|
||||
'name' => [Rule::requiredUnless(fn () => $this->input('mode') === 'existing'), 'string', 'max:200'],
|
||||
'unit' => [$this->isMethod('post') ? Rule::requiredUnless(fn () => $this->input('mode') === 'existing') : 'nullable', Rule::in(RawMaterialUnit::values())],
|
||||
|
||||
// in → Rule::in(Enum::values()) atau Rule::in(['val1', 'val2'])
|
||||
'status' => ['required', Rule::in(OrderStatus::values())],
|
||||
'gender' => ['nullable', 'in:male,female'],
|
||||
|
||||
// unique → Rule::unique('table')->ignore($id)
|
||||
'name' => ['required', 'string', 'max:100', Rule::unique('categories')->ignore($this->route('category')?->id)],
|
||||
|
||||
// ❌ JANGAN pakai string-based rules
|
||||
'category_ids.*' => ['exists:categories,id'], // JANGAN
|
||||
'shared_prices' => ['required_if:use_same_price,true', ...], // JANGAN
|
||||
'name' => ['required_unless:mode,existing', ...], // JANGAN
|
||||
```
|
||||
|
||||
### Currency Stripping
|
||||
```php
|
||||
use App\Concerns\CurrencyStripping;
|
||||
@ -874,11 +942,11 @@ ### Currency Stripping
|
||||
|
||||
### Unique Ignore
|
||||
```php
|
||||
// ✅ Saat update, ignore ID sendiri
|
||||
Rule::unique('products')->ignore($this->route('product')?->id)
|
||||
// ✅ Saat update, ignore ID sendiri — gunakan Rule::unique()
|
||||
'name' => ['required', 'string', 'max:100', Rule::unique('categories')->ignore($this->route('category')?->id)],
|
||||
|
||||
// ✅ Saat store, tidak perlu ignore
|
||||
Rule::unique('products')
|
||||
'name' => ['required', 'string', 'max:100', Rule::unique('categories')],
|
||||
```
|
||||
|
||||
### Shared Store/Update Request
|
||||
@ -1468,6 +1536,7 @@ ### ✅ Do
|
||||
- Tidak perlu accessor untuk label — Enum sudah handle via `->label()`
|
||||
- Selalu select kolom yang dibutuhkan + eager load relasi
|
||||
- Selalu strip currency di FormRequest sebelum validasi
|
||||
- Selalu pakai `Rule::exists()`, `Rule::requiredIf()`, `Rule::requiredUnless()` (bukan string-based rules)
|
||||
- Selalu pakai constructor promotion di controller (`public function __construct(private XService $service) {}`)
|
||||
- Selalu kirim enum options dari controller ke view (`Enum::toSelect()`)
|
||||
- Selalu pakai `handleAction()` untuk 2+ query
|
||||
@ -1495,6 +1564,7 @@ ### ❌ Don't
|
||||
- Jangan hardcode enum values di view (ambil dari controller)
|
||||
- Jangan pakai `= new XService` (pakai dependency injection)
|
||||
- Jangan lupa strip currency saat input Rupiah
|
||||
- Jangan pakai string-based rules seperti `'exists:table,id'`, `'required_if:field,value'`, `'required_unless:field,value'` (pakai Rule classes)
|
||||
- Jangan lupa `authorize()` di FormRequest (return true)
|
||||
- Jangan lupa `attributes()` di FormRequest (label Bahasa Indonesia)
|
||||
- JANGAN ada logic di controller (SEKECIL APAPUN)
|
||||
|
||||
@ -312,3 +312,89 @@ ## Service Concerns
|
||||
| `HasStockAdjustment` | adjustStock(), adjustVariantStock(), applyStock(), reverseStock() | TransactionService, RestockService |
|
||||
| `RegistersMedia` | registerMedia(), syncPhoto() | CashAccountService, CuttingService, ExpenseService, PurchaseService, RestockService, TransactionService |
|
||||
|
||||
---
|
||||
|
||||
## Form Request Validation Rules
|
||||
|
||||
> Validasi harus SESUAI dengan DB schema (type + max length).
|
||||
|
||||
### Master
|
||||
|
||||
| Request | Field | Rules | DB Match |
|
||||
|---------|-------|-------|----------|
|
||||
| `CategoryRequest` | `name` | `required, string, max:50, unique:categories,name` | ✅ varchar(50) |
|
||||
| `CustomerRequest` | `name` | `required, string, max:200, unique:customers,name` | ✅ varchar(200) |
|
||||
| `CustomerRequest` | `phone_number` | `nullable, string, max:20` | ✅ varchar(20) |
|
||||
| `CustomerRequest` | `address` | `nullable, string` | ✅ text |
|
||||
| `SupplierRequest` | `name` | `required, string, max:200, unique:suppliers,name` | ✅ varchar(200) |
|
||||
| `SupplierRequest` | `phone_number` | `nullable, string, max:20` | ✅ varchar(20) |
|
||||
| `RawMaterialRequest` | `name` | `required, string, max:200` | ✅ varchar(200) |
|
||||
| `RawMaterialRequest` | `unit` | `required, in:kg,meter,yard` | ✅ enum |
|
||||
| `RawMaterialVariantRequest` | `variant` | `required, string, max:200` | ✅ varchar(200) |
|
||||
| `RawMaterialVariantRequest` | `price` | `required, integer, min:0` | ✅ uint |
|
||||
| `ProductRequest` | `name` | `required, string, max:200` | ✅ varchar(200) |
|
||||
| `ProductVariantRequest` | `name` | `required, string, max:200` | ✅ varchar(200) |
|
||||
|
||||
### Finance
|
||||
|
||||
| Request | Field | Rules | DB Match |
|
||||
|---------|-------|-------|----------|
|
||||
| `CashAccountRequest` | `name` | `required, string, max:200, unique:cash_accounts,name` | ✅ varchar(200) |
|
||||
| `CashTransactionRequest` | `amount` | `required, integer, min:1` | ✅ ubig |
|
||||
| `CashTransactionRequest` | `description` | `required, string, max:100` | ✅ varchar(100) |
|
||||
| `ExpenseRequest` | `amount` | `required, integer, min:1` | ✅ ubig |
|
||||
| `ExpenseRequest` | `description` | `required, string, max:100` | ✅ varchar(100) |
|
||||
| `EmployeeAdvanceRequest` | `amount` | `required, integer, min:1` | ✅ ubig |
|
||||
| `EmployeeAdvanceRequest` | `description` | `required, string, max:100` | ✅ varchar(100) |
|
||||
| `EmployeeAdvanceRequest` | `due_date` | `required, date, after_or_equal:today` | ✅ date |
|
||||
| `EmployeeAdvancePaymentRequest` | `amount` | `required, integer, min:1` | ✅ ubig |
|
||||
| `EmployeeAdvancePaymentRequest` | `description` | `nullable, string, max:100` | ✅ varchar(100) nullable |
|
||||
| `PayrollAdjustmentRequest` | `type` | `required, in:bonus,deduction` | ✅ enum |
|
||||
| `PayrollAdjustmentRequest` | `amount` | `required, integer, min:1` | ✅ ubig |
|
||||
| `PayrollAdjustmentRequest` | `description` | `required, string, max:100` | ✅ varchar(100) |
|
||||
|
||||
### HR
|
||||
|
||||
| Request | Field | Rules | DB Match |
|
||||
|---------|-------|-------|----------|
|
||||
| `EmployeeRequest` | `email` | `required, email, max:100, unique:users,email` | ✅ varchar(100) |
|
||||
| `EmployeeRequest` | `username` | `required, string, max:20, alpha_dash, unique:users,username` | ✅ varchar(20) |
|
||||
| `EmployeeRequest` | `full_name` | `required, string, max:200` | ✅ varchar(200) |
|
||||
| `EmployeeRequest` | `phone_number` | `nullable, string, max:20` | ✅ varchar(20) |
|
||||
| `EmployeeRequest` | `gender` | `nullable, in:male,female` | ✅ enum |
|
||||
| `EmployeeRequest` | `base_salary` | `required, integer, min:0` | ✅ uint |
|
||||
| `AttendanceRequest` | `latitude` | `required, numeric, min:-90, max:90` | ✅ decimal(10,7) |
|
||||
| `AttendanceRequest` | `longitude` | `required, numeric, min:-180, max:180` | ✅ decimal(10,7) |
|
||||
| `LeaveRequestRequest` | `start_date` | `required, date, after:today` | ✅ date |
|
||||
| `LeaveRequestRequest` | `end_date` | `required, date, after_or_equal:start_date` | ✅ date |
|
||||
|
||||
### Sales
|
||||
|
||||
| Request | Field | Rules | DB Match |
|
||||
|---------|-------|-------|----------|
|
||||
| `TransactionRequest` | `channel` | `required, in:store,shopee,tiktok` | ✅ enum |
|
||||
| `TransactionRequest` | `price_type` | `required, in:retail,wholesale` | ✅ enum |
|
||||
| `TransactionRequest` | `payment_type` | `required, in:cash,transfer,qris` | ✅ enum |
|
||||
| `TransactionRequest` | `tiktok_order_id` | `nullable, string, max:100` | ✅ varchar(100) |
|
||||
| `TransactionRequest` | `shopee_order_id` | `nullable, string, max:100` | ✅ varchar(100) |
|
||||
| `TransactionRequest` | `notes` | `nullable, string, max:100` | ✅ text (UI limit) |
|
||||
|
||||
### Production
|
||||
|
||||
| Request | Field | Rules | DB Match |
|
||||
|---------|-------|-------|----------|
|
||||
| `CuttingRequest` | `description` | `nullable, string, max:100` | ✅ varchar(100) |
|
||||
| `CuttingRequest` | `product_name` | `required, string, max:255` | ✅ varchar(255) |
|
||||
| `CuttingRequest` | `cutting_result` | `required, integer, min:1` | ✅ uint |
|
||||
| `CuttingRequest` | `sample` | `required, integer` | ✅ uint |
|
||||
| `CuttingRequest` | `original_outside_sample` | `required, integer` | ✅ uint |
|
||||
|
||||
### Inventory
|
||||
|
||||
| Request | Field | Rules | DB Match |
|
||||
|---------|-------|-------|----------|
|
||||
| `PurchaseRequest` | `supplier_id` | `required, integer, exists:suppliers,id` | ✅ FK |
|
||||
| `PurchaseRequest` | `notes` | `nullable, string, max:100` | ✅ varchar(100) |
|
||||
| `RestockRequest` | `stock_type` | `required, in:good,reject` | ✅ enum |
|
||||
| `RestockRequest` | `notes` | `nullable, string, max:100` | ✅ varchar(100) |
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@ class CashAccountRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
return $this->user()->can('cash.update');
|
||||
}
|
||||
|
||||
public function rules(): array
|
||||
|
||||
@ -12,7 +12,8 @@ class CashTransactionRequest extends FormRequest
|
||||
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
return $this->user()->can('cash.deposit')
|
||||
|| $this->user()->can('cash.withdraw');
|
||||
}
|
||||
|
||||
#[Override]
|
||||
|
||||
@ -12,7 +12,7 @@ class EmployeeAdvancePaymentRequest extends FormRequest
|
||||
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
return $this->user()->can('employee_advances.pay');
|
||||
}
|
||||
|
||||
#[Override]
|
||||
|
||||
@ -12,7 +12,8 @@ class EmployeeAdvanceRequest extends FormRequest
|
||||
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
return $this->user()->can('employee_advances.create')
|
||||
|| $this->user()->can('employee_advances.update');
|
||||
}
|
||||
|
||||
#[Override]
|
||||
|
||||
@ -12,7 +12,8 @@ class ExpenseRequest extends FormRequest
|
||||
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
return $this->user()->can('expenses.create')
|
||||
|| $this->user()->can('expenses.update');
|
||||
}
|
||||
|
||||
#[Override]
|
||||
|
||||
@ -14,7 +14,7 @@ class PayrollAdjustmentRequest extends FormRequest
|
||||
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
return $this->user()->can('payroll.adjust');
|
||||
}
|
||||
|
||||
#[Override]
|
||||
@ -29,7 +29,6 @@ public function rules(): array
|
||||
'type' => ['required', Rule::in(PayrollAdjustmentType::values())],
|
||||
'amount' => ['required', 'integer', 'min:1'],
|
||||
'description' => ['required', 'string', 'max:100'],
|
||||
'attendance_id' => ['nullable', 'integer', 'exists:attendances,id'],
|
||||
];
|
||||
}
|
||||
|
||||
@ -39,7 +38,6 @@ public function attributes(): array
|
||||
'type' => 'jenis',
|
||||
'amount' => 'jumlah',
|
||||
'description' => 'keterangan',
|
||||
'attendance_id' => 'presensi',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,15 +8,15 @@ class AttendanceRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
return $this->user()->can('attendances.create');
|
||||
}
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'photo' => ['required'],
|
||||
'latitude' => ['required', 'numeric'],
|
||||
'longitude' => ['required', 'numeric'],
|
||||
'latitude' => ['required', 'numeric', 'min:-90', 'max:90'],
|
||||
'longitude' => ['required', 'numeric', 'min:-180', 'max:180'],
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@ -2,6 +2,8 @@
|
||||
|
||||
namespace App\Http\Requests\Admin\HR;
|
||||
|
||||
use App\Enums\EmploymentStatus;
|
||||
use App\Enums\Gender;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
@ -9,7 +11,8 @@ class EmployeeRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
return $this->user()->can('employees.create')
|
||||
|| $this->user()->can('employees.update');
|
||||
}
|
||||
|
||||
public function rules(): array
|
||||
@ -34,7 +37,7 @@ public function rules(): array
|
||||
'role' => ['required', 'string', Rule::exists('roles', 'name')],
|
||||
'full_name' => ['required', 'string', 'max:200'],
|
||||
'phone_number' => ['nullable', 'string', 'max:20'],
|
||||
'gender' => ['nullable', 'in:male,female'],
|
||||
'gender' => ['nullable', Rule::in(Gender::values())],
|
||||
'birth_date' => ['nullable', 'date'],
|
||||
'address' => ['nullable', 'string'],
|
||||
'join_date' => [
|
||||
@ -48,7 +51,7 @@ public function rules(): array
|
||||
],
|
||||
'employment_status' => [
|
||||
Rule::requiredIf(! $isOwner),
|
||||
Rule::in(['full_time', 'part_time', 'contract', 'internship', 'resigned']),
|
||||
Rule::in(EmploymentStatus::values()),
|
||||
],
|
||||
'base_salary' => [
|
||||
Rule::requiredIf(! $isOwner),
|
||||
|
||||
@ -9,7 +9,8 @@ class LeaveRequestRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
return $this->user()->can('leave_requests.create')
|
||||
|| $this->user()->can('leave_requests.update');
|
||||
}
|
||||
|
||||
public function rules(): array
|
||||
@ -30,7 +31,7 @@ function ($attribute, $value, $fail) use ($leaveRequest) {
|
||||
|
||||
$query = LeaveRequest::where('employee_id', $employee->id)
|
||||
->where('start_date', $value)
|
||||
->where('status', '!=', 'cancelled');
|
||||
->where('status', '!=', LeaveRequest::cancelled());
|
||||
|
||||
if ($leaveRequest) {
|
||||
$query->where('id', '!=', $leaveRequest->id);
|
||||
|
||||
@ -3,12 +3,14 @@
|
||||
namespace App\Http\Requests\Admin\Manage;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class CuttingRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
return $this->user()->can('cuttings.create')
|
||||
|| $this->user()->can('cuttings.update');
|
||||
}
|
||||
|
||||
public function rules(): array
|
||||
@ -20,7 +22,7 @@ public function rules(): array
|
||||
'original_outside_sample' => ['required', 'integer'],
|
||||
'cutting_result' => ['required', 'integer', 'min:1'],
|
||||
'materials' => ['required', 'array', 'min:1'],
|
||||
'materials.*.raw_material_price_id' => ['required', 'integer', 'exists:raw_material_prices,id'],
|
||||
'materials.*.raw_material_price_id' => ['required', 'integer', Rule::exists('raw_material_prices', 'id')],
|
||||
'materials.*.material_usage' => ['required', 'integer', 'min:1'],
|
||||
'materials.*.material_result' => ['required', 'integer'],
|
||||
'materials.*.combination_index' => ['nullable', 'integer'],
|
||||
|
||||
@ -13,7 +13,8 @@ class PurchaseRequest extends FormRequest
|
||||
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
return $this->user()->can('purchases.create')
|
||||
|| $this->user()->can('purchases.update');
|
||||
}
|
||||
|
||||
public function prepareForValidation(): void
|
||||
@ -25,18 +26,18 @@ public function rules(): array
|
||||
{
|
||||
return [
|
||||
'mode' => ['sometimes', 'required', 'in:new,existing'],
|
||||
'name' => ['required_unless:mode,existing', 'string', 'max:200'],
|
||||
'unit' => [$this->isMethod('post') ? 'required_unless:mode,existing' : 'nullable', Rule::in(RawMaterialUnit::values())],
|
||||
'variants' => ['required_unless:mode,existing', 'array', 'min:1'],
|
||||
'variants.*.variant' => ['required_unless:mode,existing', 'string', 'max:200'],
|
||||
'variants.*.price' => ['required_unless:mode,existing', 'integer', 'min:0'],
|
||||
'variants.*.stock' => ['required_unless:mode,existing', 'integer', 'min:0'],
|
||||
'variants.*.photo_key' => ['required_unless:mode,existing', 'string', 'max:500'],
|
||||
'existing_items' => ['required_if:mode,existing', 'array', 'min:1'],
|
||||
'existing_items.*.raw_material_price_id' => ['required', 'integer', 'exists:raw_material_prices,id'],
|
||||
'name' => [Rule::requiredUnless(fn () => $this->input('mode') === 'existing'), 'string', 'max:200'],
|
||||
'unit' => [$this->isMethod('post') ? Rule::requiredUnless(fn () => $this->input('mode') === 'existing') : 'nullable', Rule::in(RawMaterialUnit::values())],
|
||||
'variants' => [Rule::requiredUnless(fn () => $this->input('mode') === 'existing'), 'array', 'min:1'],
|
||||
'variants.*.variant' => [Rule::requiredUnless(fn () => $this->input('mode') === 'existing'), 'string', 'max:200'],
|
||||
'variants.*.price' => [Rule::requiredUnless(fn () => $this->input('mode') === 'existing'), 'integer', 'min:0'],
|
||||
'variants.*.stock' => [Rule::requiredUnless(fn () => $this->input('mode') === 'existing'), 'integer', 'min:0'],
|
||||
'variants.*.photo_key' => [Rule::requiredUnless(fn () => $this->input('mode') === 'existing'), 'string', 'max:500'],
|
||||
'existing_items' => [Rule::requiredIf(fn () => $this->input('mode') === 'existing'), 'array', 'min:1'],
|
||||
'existing_items.*.raw_material_price_id' => ['required', 'integer', Rule::exists('raw_material_prices', 'id')],
|
||||
'existing_items.*.quantity' => ['required', 'integer', 'min:1'],
|
||||
'existing_items.*.unit_price' => ['required', 'integer', 'min:0'],
|
||||
'supplier_id' => ['required', 'integer', 'exists:suppliers,id'],
|
||||
'supplier_id' => ['required', 'integer', Rule::exists('suppliers', 'id')],
|
||||
'discount' => ['nullable', 'integer', 'min:0'],
|
||||
'shipping_cost' => ['nullable', 'integer', 'min:0'],
|
||||
'notes' => ['nullable', 'string', 'max:100'],
|
||||
|
||||
@ -10,7 +10,8 @@ class RestockRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
return $this->user()->can('restocks.create')
|
||||
|| $this->user()->can('restocks.update');
|
||||
}
|
||||
|
||||
public function rules(): array
|
||||
@ -18,7 +19,7 @@ public function rules(): array
|
||||
return [
|
||||
'stock_type' => ['sometimes', 'required', Rule::in(ProductStockQuality::values())],
|
||||
'items' => ['required', 'array', 'min:1'],
|
||||
'items.*.product_variant_id' => ['required', 'integer', 'exists:product_variants,id'],
|
||||
'items.*.product_variant_id' => ['required', 'integer', Rule::exists('product_variants', 'id')],
|
||||
'items.*.quantity' => ['required', 'integer', 'min:1'],
|
||||
'notes' => ['nullable', 'string', 'max:100'],
|
||||
'photo_key' => ['nullable', 'string', 'max:500'],
|
||||
|
||||
@ -16,7 +16,8 @@ class TransactionRequest extends FormRequest
|
||||
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
return $this->user()->can('orders.create')
|
||||
|| $this->user()->can('orders.update');
|
||||
}
|
||||
|
||||
public function prepareForValidation(): void
|
||||
@ -26,15 +27,13 @@ public function prepareForValidation(): void
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
$sellingPriceTypes = array_diff(PriceType::values(), [PriceType::CAPITAL->value]);
|
||||
|
||||
return [
|
||||
'stock_type' => ['sometimes', 'required', Rule::in(ProductStockQuality::values())],
|
||||
'channel' => ['sometimes', 'required', Rule::in(OrderChannel::values())],
|
||||
'price_type' => ['sometimes', 'required', Rule::in($sellingPriceTypes)],
|
||||
'price_type' => ['sometimes', 'required', Rule::in(array_diff(PriceType::values(), [PriceType::CAPITAL->value]))],
|
||||
'payment_type' => ['sometimes', 'required', Rule::in(PaymentType::values())],
|
||||
'customer_id' => ['nullable', 'integer', 'exists:customers,id'],
|
||||
'marketing_id' => ['nullable', 'integer', 'exists:users,id'],
|
||||
'customer_id' => ['nullable', 'integer', Rule::exists('customers', 'id')],
|
||||
'marketing_id' => ['nullable', 'integer', Rule::exists('users', 'id')],
|
||||
'discount' => ['nullable', 'integer', 'min:0'],
|
||||
'nego_price' => ['nullable', 'integer'],
|
||||
'is_completed' => ['sometimes', 'boolean'],
|
||||
@ -42,7 +41,7 @@ public function rules(): array
|
||||
'tiktok_order_id' => ['nullable', 'string', 'max:100'],
|
||||
'shopee_order_id' => ['nullable', 'string', 'max:100'],
|
||||
'items' => ['required', 'array', 'min:1'],
|
||||
'items.*.product_variant_id' => ['required', 'integer', 'exists:product_variants,id'],
|
||||
'items.*.product_variant_id' => ['required', 'integer', Rule::exists('product_variants', 'id')],
|
||||
'items.*.quantity' => ['required', 'integer', 'min:1'],
|
||||
'notes' => ['nullable', 'string', 'max:100'],
|
||||
'photo_key' => [
|
||||
|
||||
@ -9,7 +9,8 @@ class CategoryRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
return $this->user()->can('categories.create')
|
||||
|| $this->user()->can('categories.update');
|
||||
}
|
||||
|
||||
public function rules(): array
|
||||
@ -17,7 +18,7 @@ public function rules(): array
|
||||
$category = $this->route('category');
|
||||
|
||||
return [
|
||||
'name' => ['required', 'string', 'max:100', Rule::unique('categories', 'name')->ignore($category)],
|
||||
'name' => ['required', 'string', 'max:50', Rule::unique('categories', 'name')->ignore($category)],
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@ -9,7 +9,8 @@ class CustomerRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
return $this->user()->can('customers.create')
|
||||
|| $this->user()->can('customers.update');
|
||||
}
|
||||
|
||||
public function rules(): array
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
|
||||
use App\Concerns\CurrencyStripping;
|
||||
use App\Enums\PriceType;
|
||||
use App\Enums\ProductStatus;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Override;
|
||||
@ -14,7 +15,8 @@ class ProductRequest extends FormRequest
|
||||
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
return $this->user()->can('products.create')
|
||||
|| $this->user()->can('products.update');
|
||||
}
|
||||
|
||||
#[Override]
|
||||
@ -34,13 +36,13 @@ public function rules(): array
|
||||
'max:200',
|
||||
],
|
||||
'description' => ['nullable', 'string'],
|
||||
'status' => ['nullable', Rule::in(['active', 'inactive', 'draft', 'pending', 'rejected'])],
|
||||
'status' => ['nullable', Rule::in(ProductStatus::values())],
|
||||
'category_ids' => ['required', 'array', 'min:1'],
|
||||
'category_ids.*' => ['exists:categories,id'],
|
||||
'category_ids.*' => [Rule::exists('categories', 'id')],
|
||||
'use_same_price' => ['nullable', 'boolean'],
|
||||
'shared_prices' => ['required_if:use_same_price,true', 'nullable', 'array', ...($useSamePrice ? ['size:9'] : [])],
|
||||
'shared_prices.*.type' => ['required_if:use_same_price,true', 'nullable', Rule::in(PriceType::values())],
|
||||
'shared_prices.*.price' => ['required_if:use_same_price,true', 'nullable', 'integer', 'min:0'],
|
||||
'shared_prices' => [Rule::requiredIf(fn() => $useSamePrice), 'nullable', 'array', ...($useSamePrice ? ['size:9'] : [])],
|
||||
'shared_prices.*.type' => [Rule::requiredIf(fn() => $useSamePrice), 'nullable', Rule::in(PriceType::values())],
|
||||
'shared_prices.*.price' => [Rule::requiredIf(fn() => $useSamePrice), 'nullable', 'integer', 'min:0'],
|
||||
'variants' => ['required', 'array', 'min:1'],
|
||||
'variants.*.id' => ['nullable', 'integer'],
|
||||
'variants.*.name' => ['required', 'string', 'max:200'],
|
||||
@ -49,10 +51,10 @@ public function rules(): array
|
||||
'variants.*.retail_stock' => ['required', 'integer', 'min:0'],
|
||||
'variants.*.photo_keys' => ['required', 'array', 'min:1', 'max:5'],
|
||||
'variants.*.photo_keys.*' => ['required', 'string', 'max:500'],
|
||||
'variants.*.prices' => ['required_if:use_same_price,false', 'nullable', 'array', ...(! $useSamePrice ? ['size:9'] : [])],
|
||||
'variants.*.prices' => [Rule::requiredIf(fn() => ! $useSamePrice), 'nullable', 'array', ...(! $useSamePrice ? ['size:9'] : [])],
|
||||
'variants.*.prices.*.id' => ['nullable', 'integer'],
|
||||
'variants.*.prices.*.type' => ['required_if:use_same_price,false', 'nullable', Rule::in(PriceType::values())],
|
||||
'variants.*.prices.*.price' => ['required_if:use_same_price,false', 'nullable', 'integer', 'min:0'],
|
||||
'variants.*.prices.*.type' => [Rule::requiredIf(fn() => ! $useSamePrice), 'nullable', Rule::in(PriceType::values())],
|
||||
'variants.*.prices.*.price' => [Rule::requiredIf(fn() => ! $useSamePrice), 'nullable', 'integer', 'min:0'],
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@ -13,7 +13,8 @@ class ProductVariantRequest extends FormRequest
|
||||
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
return $this->user()->can('products.create')
|
||||
|| $this->user()->can('products.update');
|
||||
}
|
||||
|
||||
public function prepareForValidation(): void
|
||||
|
||||
@ -8,7 +8,7 @@ class TransferStockRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
return $this->user()->can('products.transfer_stock');
|
||||
}
|
||||
|
||||
public function rules(): array
|
||||
|
||||
@ -13,7 +13,8 @@ class RawMaterialRequest extends FormRequest
|
||||
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
return $this->user()->can('raw_materials.create')
|
||||
|| $this->user()->can('raw_materials.update');
|
||||
}
|
||||
|
||||
public function prepareForValidation(): void
|
||||
|
||||
@ -11,7 +11,8 @@ class RawMaterialVariantRequest extends FormRequest
|
||||
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
return $this->user()->can('raw_materials.create')
|
||||
|| $this->user()->can('raw_materials.update');
|
||||
}
|
||||
|
||||
public function prepareForValidation(): void
|
||||
|
||||
@ -9,7 +9,8 @@ class SupplierRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
return $this->user()->can('suppliers.create')
|
||||
|| $this->user()->can('suppliers.update');
|
||||
}
|
||||
|
||||
public function rules(): array
|
||||
|
||||
@ -9,7 +9,8 @@ class RoleRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
return $this->user()->can('roles.create')
|
||||
|| $this->user()->can('roles.update');
|
||||
}
|
||||
|
||||
public function rules(): array
|
||||
@ -24,7 +25,7 @@ public function rules(): array
|
||||
Rule::unique('roles', 'name')->ignore($roleId, 'id'),
|
||||
],
|
||||
'permissions' => ['present', 'array'],
|
||||
'permissions.*' => ['string', 'exists:permissions,name'],
|
||||
'permissions.*' => ['string', Rule::exists('permissions', 'name')],
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@ -12,7 +12,7 @@ class UpdateHRRequest extends FormRequest
|
||||
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
return $this->user()->can('settings.update_hr');
|
||||
}
|
||||
|
||||
#[Override]
|
||||
|
||||
@ -8,7 +8,7 @@ class UpdateHomepageRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
return $this->user()->can('settings.update_homepage');
|
||||
}
|
||||
|
||||
public function rules(): array
|
||||
|
||||
@ -8,7 +8,7 @@ class UpdateMarketplaceRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
return $this->user()->can('settings.update_marketplace');
|
||||
}
|
||||
|
||||
private function feeRuleRules(): array
|
||||
|
||||
@ -8,7 +8,7 @@ class UpdateSocialMediaRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
return $this->user()->can('settings.update_social_media');
|
||||
}
|
||||
|
||||
public function rules(): array
|
||||
|
||||
@ -8,7 +8,7 @@ class UpdateSystemRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
return $this->user()->can('settings.update_system');
|
||||
}
|
||||
|
||||
public function rules(): array
|
||||
|
||||
@ -27,7 +27,7 @@ public function rules(): array
|
||||
'required',
|
||||
'string',
|
||||
'email',
|
||||
'max:255',
|
||||
'max:100',
|
||||
Rule::unique('users', 'email')->ignore($userId),
|
||||
],
|
||||
'username' => [
|
||||
|
||||
Loading…
Reference in New Issue
Block a user