'decimal:4', 'material_result' => 'integer', ]; } // 3. Attribute public function materialUsageFormatted(): Attribute { return Attribute::make( get: fn () => $this->formatQuantity($this->material_usage), ); } public function materialUsageInput(): Attribute { return Attribute::make( get: fn () => $this->formatQuantityInput($this->material_usage), ); } public function unitAbbreviation(): Attribute { return Attribute::make( get: fn () => $this->attributes['unit_abbreviation'] ?? $this->rawMaterialPrice?->rawMaterial?->unit?->abbreviation(), ); } // 4. Other Methods public function materialCost(): int { $price = $this->rawMaterialPrice; if ($price === null) { return 0; } return (int) round((float) $this->material_usage * (int) $price->price); } private function formatQuantity(float|string|null $value): string { $formatted = rtrim(rtrim(number_format((float) $value, 4, ',', '.'), '0'), ','); return "{$formatted} {$this->unitAbbreviation}"; } private function formatQuantityInput(float|string|null $value): string { return rtrim(rtrim(number_format((float) $value, 4, '.', ''), '0'), '.'); } // 5. Relation public function cutting(): BelongsTo { return $this->belongsTo(Cutting::class)->withTrashed(); } public function rawMaterialPrice(): BelongsTo { return $this->belongsTo(RawMaterialPrice::class)->withTrashed(); } public function combination(): BelongsTo { return $this->belongsTo(CuttingMaterialCombination::class, 'combination_id')->withTrashed(); } public function user(): BelongsTo { return $this->belongsTo(User::class)->withTrashed(); } }