Files
Vasyka 9609295a9e feat(labors): trilingual name — add name_en column + Labor::label() helper
- Migration: add nullable `labors.name_en` alongside existing name_ro/
  name_ru.
- Labor model: label(?locale) accessor returns name_{locale} with
  name_ro fallback.
- LaborResource form: expose 3rd 'Nume (EN)' field.
- Table + Select displays now go through label() so options show the
  locale-appropriate name:
    /app/labors table column,
    WorkOrderResource works Select ('[category] name (Nh)'),
    ServiceTemplate items Select,
    ServiceComposer WorkOrderWork snapshot on create.
- Snapshot name saved on wo_works.name at creation reflects the
  current locale; existing rows keep their stored snapshot untouched.

All 306 tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-26 10:54:00 +00:00

58 lines
1.6 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
namespace App\Models\Tenant;
use App\Models\Concerns\BelongsToTenant;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;
class Labor extends Model
{
use BelongsToTenant, SoftDeletes;
public const CATEGORIES = [
'Motor', 'Frâne', 'Suspensie', 'Anvelope', 'ITP', 'Cutie viteze',
'Caroserie', 'Electrică', 'Climatizare', 'Eșapament', 'Altele',
];
public const PRICING_MODES = [
'hourly' => 'Pe oră (normă × tarif)',
'fixed' => 'Preț fix',
];
protected $fillable = [
'company_id', 'category', 'name_ro', 'name_ru', 'name_en', 'code',
'hours', 'pricing_mode', 'fixed_price', 'price', 'is_active', 'notes',
];
/** Localised name — prefers name_{locale}, falls back to name_ro. */
public function label(?string $locale = null): string
{
$locale = $locale ?: app()->getLocale();
$col = 'name_' . $locale;
return $this->{$col} ?: ($this->name_ro ?: '');
}
protected $casts = [
'hours' => 'decimal:2',
'fixed_price' => 'decimal:2',
'price' => 'decimal:2',
'is_active' => 'boolean',
];
public function laborParts(): HasMany
{
return $this->hasMany(LaborPart::class);
}
/** Effective line total for this labor given the tenant hourly rate. */
public function effectiveTotal(float $hourlyRate): float
{
if ($this->pricing_mode === 'fixed') {
return (float) $this->fixed_price;
}
return round((float) $this->hours * $hourlyRate, 2);
}
}