feat: add formatted accessors for various models and enhance date formatting
This commit is contained in:
parent
4733df5827
commit
cd0995f04e
@ -258,7 +258,7 @@ ### Accessor & Mutator — Nama harus BERBEDA dari kolom DB
|
||||
|
||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
|
||||
// Currency → prefix 'formatted_'
|
||||
// Currency → prefix 'formatted_' + 'Rp ' prefix
|
||||
protected function formattedAmount(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
@ -266,7 +266,15 @@ ### Accessor & Mutator — Nama harus BERBEDA dari kolom DB
|
||||
);
|
||||
}
|
||||
|
||||
// Date → prefix 'formatted_'
|
||||
// Number (bukan rupiah) → prefix 'formatted_'
|
||||
protected function formattedStock(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => number_format($this->stock, 0, ',', '.'),
|
||||
);
|
||||
}
|
||||
|
||||
// Date → prefix 'formatted_' + format 'l, d F Y'
|
||||
protected function formattedJoinDate(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
@ -274,6 +282,14 @@ ### Accessor & Mutator — Nama harus BERBEDA dari kolom DB
|
||||
);
|
||||
}
|
||||
|
||||
// DateTime → prefix 'formatted_' + format 'l, d F Y H:i'
|
||||
protected function formattedCheckInAt(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->check_in_at?->translatedFormat('l, d F Y H:i'),
|
||||
);
|
||||
}
|
||||
|
||||
// String → prefix 'formatted_'
|
||||
protected function formattedName(): Attribute
|
||||
{
|
||||
@ -293,6 +309,14 @@ ### Accessor & Mutator — Nama harus BERBEDA dari kolom DB
|
||||
);
|
||||
}
|
||||
|
||||
// Month name → suffix '_name'
|
||||
protected function monthName(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->month ? Carbon::create()->month($this->month)->translatedFormat('F') : null,
|
||||
);
|
||||
}
|
||||
|
||||
// Label → suffix '_label' (TIDAK pakai formatted_)
|
||||
// TIDAK PERLU accessor manual — Enum sudah punya method label()
|
||||
// Cukup panggil langsung: $this->status->label()
|
||||
@ -303,6 +327,31 @@ ### Accessor & Mutator — Nama harus BERBEDA dari kolom DB
|
||||
// ✅ BENAR: formattedAmount(), formattedName()
|
||||
```
|
||||
|
||||
### Accessor Format Rules
|
||||
```php
|
||||
// ✅ Format yang WAJIB diikuti untuk accessor:
|
||||
|
||||
// 1. Date (kolom date) → 'l, d F Y'
|
||||
// Contoh: "Selasa, 25 Agu 2026"
|
||||
$this->join_date?->translatedFormat('l, d F Y')
|
||||
|
||||
// 2. DateTime (kolom datetime) → 'l, d F Y H:i'
|
||||
// Contoh: "Selasa, 25 Agu 2026 12:12"
|
||||
$this->check_in_at?->translatedFormat('l, d F Y H:i')
|
||||
|
||||
// 3. Currency (rupiah) → 'Rp ' + number_format(0, ',', '.')
|
||||
// Contoh: "Rp 1.000.000"
|
||||
'Rp ' . number_format($this->amount, 0, ',', '.')
|
||||
|
||||
// 4. Number (angka biasa) → number_format(0, ',', '.')
|
||||
// Contoh: "1.000"
|
||||
number_format($this->stock, 0, ',', '.')
|
||||
|
||||
// 5. Month name → Carbon translatedFormat('F')
|
||||
// Contoh: "Januari", "Februari"
|
||||
Carbon::create()->month($this->month)->translatedFormat('F')
|
||||
```
|
||||
|
||||
### Appends — Data yang Ditampilkan
|
||||
```php
|
||||
// ✅ Gunakan snake_case (sama dengan nama accessor)
|
||||
|
||||
@ -25,6 +25,7 @@ ### `push_subscriptions` → PushSubscription
|
||||
### `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)
|
||||
- Accessor: formatted_read_at → 'l, d F Y H:i'
|
||||
- Relations: user(BelongsTo→User)
|
||||
|
||||
---
|
||||
@ -113,6 +114,7 @@ ### `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)
|
||||
- Accessor: formatted_amount → 'Rp X.XXX', formatted_paid_at → 'l, d F Y H:i'
|
||||
- Relations: employeeAdvance(BelongsTo→EmployeeAdvance), paidBy(BelongsTo→User), cashTransaction(BelongsTo→CashTransaction)
|
||||
|
||||
---
|
||||
@ -129,11 +131,13 @@ ### `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)
|
||||
- Accessor: formatted_attendance_date → 'l, d F Y', formatted_check_in_at → 'l, d F Y H:i', formatted_check_out_at → 'l, d F Y H:i'
|
||||
- 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)
|
||||
- Accessor: formatted_closed_at → 'l, d F Y H:i', month_name → 'Januari', status_label
|
||||
- Scopes: closed(), open()
|
||||
- Relations: closedBy(BelongsTo→User), payrolls(HasMany→Payroll)
|
||||
|
||||
@ -188,16 +192,19 @@ ### `cuttings` → Cutting
|
||||
### `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)
|
||||
- Accessor: formatted_material_result → 'X.XXX'
|
||||
- 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)
|
||||
- Accessor: formatted_material_result → 'X.XXX', formatted_material_usage → 'X.XXX'
|
||||
- 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)
|
||||
- Accessor: formatted_cutting_result → 'X.XXX', formatted_original_outside_sample → 'X.XXX', formatted_sample → 'X.XXX'
|
||||
- Relations: cutting(BelongsTo→Cutting), user(BelongsTo→User)
|
||||
|
||||
---
|
||||
@ -243,12 +250,14 @@ ### `retail_stock_histories` → RetailStockHistory
|
||||
- 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)
|
||||
- Accessor: formatted_quantity → 'X.XXX', formatted_retail_stock_before → 'X.XXX', formatted_retail_stock_after → 'X.XXX', formatted_stock_before → 'X.XXX', formatted_stock_after → 'X.XXX'
|
||||
- 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)
|
||||
- Accessor: formatted_quantity → 'X.XXX', formatted_stock_after → 'X.XXX', formatted_stock_before → 'X.XXX'
|
||||
- Relations: stockable(MorphTo), source(MorphTo), user(BelongsTo→User)
|
||||
|
||||
---
|
||||
|
||||
@ -2,11 +2,14 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Attributes\Appends;
|
||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
#[Appends(['formatted_read_at'])]
|
||||
#[Guarded(['id'])]
|
||||
class AppNotification extends Model
|
||||
{
|
||||
@ -22,6 +25,13 @@ protected function casts(): array
|
||||
];
|
||||
}
|
||||
|
||||
protected function formattedReadAt(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->read_at?->translatedFormat('l, d F Y H:i'),
|
||||
);
|
||||
}
|
||||
|
||||
public function user(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
namespace App\Models;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Attributes\Appends;
|
||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
@ -12,6 +13,7 @@
|
||||
use Spatie\MediaLibrary\HasMedia;
|
||||
use Spatie\MediaLibrary\InteractsWithMedia;
|
||||
|
||||
#[Appends(['formatted_attendance_date', 'formatted_check_in_at', 'formatted_check_out_at'])]
|
||||
#[Guarded(['id'])]
|
||||
class Attendance extends Model implements HasMedia
|
||||
{
|
||||
@ -34,7 +36,21 @@ protected function casts(): array
|
||||
protected function formattedAttendanceDate(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn ($value) => $value ? Carbon::parse($value)->translatedFormat('l, d F Y') : null,
|
||||
get: fn () => $this->attendance_date?->translatedFormat('l, d F Y'),
|
||||
);
|
||||
}
|
||||
|
||||
protected function formattedCheckInAt(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->check_in_at?->translatedFormat('l, d F Y H:i'),
|
||||
);
|
||||
}
|
||||
|
||||
protected function formattedCheckOutAt(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->check_out_at?->translatedFormat('l, d F Y H:i'),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -2,12 +2,15 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Attributes\Appends;
|
||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
#[Appends(['formatted_material_result', 'formatted_material_usage'])]
|
||||
#[Guarded(['id'])]
|
||||
class CuttingMaterial extends Model
|
||||
{
|
||||
@ -21,6 +24,20 @@ protected function casts(): array
|
||||
];
|
||||
}
|
||||
|
||||
protected function formattedMaterialResult(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => number_format($this->material_result, 0, ',', '.'),
|
||||
);
|
||||
}
|
||||
|
||||
protected function formattedMaterialUsage(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => number_format($this->material_usage, 0, ',', '.'),
|
||||
);
|
||||
}
|
||||
|
||||
public function combination(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(CuttingMaterialCombination::class, 'combination_id');
|
||||
|
||||
@ -2,13 +2,16 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Attributes\Appends;
|
||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
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;
|
||||
|
||||
#[Appends(['formatted_material_result'])]
|
||||
#[Guarded(['id'])]
|
||||
class CuttingMaterialCombination extends Model
|
||||
{
|
||||
@ -21,6 +24,13 @@ protected function casts(): array
|
||||
];
|
||||
}
|
||||
|
||||
protected function formattedMaterialResult(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => number_format($this->material_result, 0, ',', '.'),
|
||||
);
|
||||
}
|
||||
|
||||
public function cutting(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Cutting::class);
|
||||
|
||||
@ -2,12 +2,15 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Attributes\Appends;
|
||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
#[Appends(['formatted_cutting_result', 'formatted_original_outside_sample', 'formatted_sample'])]
|
||||
#[Guarded(['id'])]
|
||||
class CuttingResult extends Model
|
||||
{
|
||||
@ -22,6 +25,27 @@ protected function casts(): array
|
||||
];
|
||||
}
|
||||
|
||||
protected function formattedCuttingResult(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => number_format($this->cutting_result, 0, ',', '.'),
|
||||
);
|
||||
}
|
||||
|
||||
protected function formattedOriginalOutsideSample(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => number_format($this->original_outside_sample, 0, ',', '.'),
|
||||
);
|
||||
}
|
||||
|
||||
protected function formattedSample(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => number_format($this->sample, 0, ',', '.'),
|
||||
);
|
||||
}
|
||||
|
||||
public function cutting(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Cutting::class);
|
||||
|
||||
@ -33,7 +33,7 @@ protected function formattedAmount(): Attribute
|
||||
protected function formattedPaidAt(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->paid_at?->translatedFormat('l, d F Y'),
|
||||
get: fn () => $this->paid_at?->translatedFormat('l, d F Y H:i'),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
namespace App\Models;
|
||||
|
||||
use App\Enums\PayrollPeriodStatus;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Attributes\Appends;
|
||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
||||
use Illuminate\Database\Eloquent\Attributes\Scope;
|
||||
@ -14,7 +15,7 @@
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
#[Appends(['status_label'])]
|
||||
#[Appends(['formatted_closed_at', 'month_name', 'status_label'])]
|
||||
#[Guarded(['id'])]
|
||||
class PayrollPeriod extends Model
|
||||
{
|
||||
@ -30,6 +31,20 @@ protected function casts(): array
|
||||
];
|
||||
}
|
||||
|
||||
protected function formattedClosedAt(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->closed_at?->translatedFormat('l, d F Y H:i'),
|
||||
);
|
||||
}
|
||||
|
||||
protected function monthName(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => $this->month ? Carbon::create()->month($this->month)->translatedFormat('F') : null,
|
||||
);
|
||||
}
|
||||
|
||||
protected function statusLabel(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
|
||||
@ -2,11 +2,14 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Attributes\Appends;
|
||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
#[Appends(['formatted_quantity', 'formatted_retail_stock_before', 'formatted_retail_stock_after', 'formatted_stock_before', 'formatted_stock_after'])]
|
||||
#[Guarded(['id'])]
|
||||
class RetailStockHistory extends Model
|
||||
{
|
||||
@ -25,6 +28,41 @@ protected function casts(): array
|
||||
];
|
||||
}
|
||||
|
||||
protected function formattedQuantity(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => number_format($this->quantity, 0, ',', '.'),
|
||||
);
|
||||
}
|
||||
|
||||
protected function formattedRetailStockBefore(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => number_format($this->retail_stock_before, 0, ',', '.'),
|
||||
);
|
||||
}
|
||||
|
||||
protected function formattedRetailStockAfter(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => number_format($this->retail_stock_after, 0, ',', '.'),
|
||||
);
|
||||
}
|
||||
|
||||
protected function formattedStockBefore(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => number_format($this->stock_before, 0, ',', '.'),
|
||||
);
|
||||
}
|
||||
|
||||
protected function formattedStockAfter(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => number_format($this->stock_after, 0, ',', '.'),
|
||||
);
|
||||
}
|
||||
|
||||
public function productVariant(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(ProductVariant::class);
|
||||
|
||||
@ -2,12 +2,15 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Attributes\Appends;
|
||||
use Illuminate\Database\Eloquent\Attributes\Guarded;
|
||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\MorphTo;
|
||||
|
||||
#[Appends(['formatted_quantity', 'formatted_stock_after', 'formatted_stock_before'])]
|
||||
#[Guarded(['id'])]
|
||||
class StockMutation extends Model
|
||||
{
|
||||
@ -22,6 +25,27 @@ protected function casts(): array
|
||||
];
|
||||
}
|
||||
|
||||
protected function formattedQuantity(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => number_format($this->quantity, 0, ',', '.'),
|
||||
);
|
||||
}
|
||||
|
||||
protected function formattedStockAfter(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => number_format($this->stock_after, 0, ',', '.'),
|
||||
);
|
||||
}
|
||||
|
||||
protected function formattedStockBefore(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => number_format($this->stock_before, 0, ',', '.'),
|
||||
);
|
||||
}
|
||||
|
||||
public function source(): MorphTo
|
||||
{
|
||||
return $this->morphTo();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user