up
This commit is contained in:
@@ -53,9 +53,6 @@ class TelaResource extends Resource
|
||||
$valor_total = $get('valor_total');
|
||||
$metros_comprados = $state;
|
||||
|
||||
// Establecer automáticamente metros disponibles igual a metros comprados al crear/editar
|
||||
$set('metros_disponibles', $metros_comprados);
|
||||
|
||||
if ($valor_total && $metros_comprados) {
|
||||
$costo_por_metro = $valor_total / $metros_comprados;
|
||||
$set('costo_por_metro', $costo_por_metro);
|
||||
@@ -75,10 +72,13 @@ class TelaResource extends Resource
|
||||
|
||||
TextInput::make('costo_por_metro')->numeric()->prefix('$')->readOnly()->dehydrated()->default(0)->step(0.01),
|
||||
|
||||
TextInput::make('metros_disponibles')->numeric()->reactive()->disabled()->dehydrated()
|
||||
->default(function ($get) {
|
||||
return $get('metros_comprados');
|
||||
})->helperText('Se establece automáticamente igual a "Metros comprados" al crear.'),
|
||||
Forms\Components\Placeholder::make('metros_disponibles_display')
|
||||
->label('Metros disponibles')
|
||||
->content(function ($record) {
|
||||
if (!$record) return 'Se calculará después de guardar';
|
||||
return number_format($record->metros_disponibles, 2) . ' m (Comprados - Usados en OPs)';
|
||||
})
|
||||
->helperText('Este valor se calcula automáticamente: Metros comprados - Total usado en órdenes de producción'),
|
||||
|
||||
DatePicker::make('fecha_compra')->required()->default(now()),
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@ class OrdenProduccion extends Model
|
||||
$orden->referencia = '';
|
||||
}
|
||||
|
||||
// Reserva de tela al crear cuando la OP usa una tela: restar metros_disponibles inmediatamente
|
||||
// Reserva de tela al crear cuando la OP usa una tela: validar disponibilidad
|
||||
if ($orden->tela_id && ($orden->metros_requeridos ?? 0) > 0) {
|
||||
$tela = \App\Models\Tela::find($orden->tela_id);
|
||||
if (! $tela) {
|
||||
@@ -113,70 +113,46 @@ class OrdenProduccion extends Model
|
||||
]);
|
||||
}
|
||||
|
||||
if ($tela->metros_disponibles < $orden->metros_requeridos) {
|
||||
// Calcular metros ya usados por otras OPs
|
||||
$metrosUsados = \App\Models\OrdenProduccion::where('tela_id', $orden->tela_id)->sum('metros_requeridos');
|
||||
$disponible = max(0, $tela->metros_comprados - $metrosUsados);
|
||||
|
||||
if ($disponible < $orden->metros_requeridos) {
|
||||
throw \Illuminate\Validation\ValidationException::withMessages([
|
||||
'metros_requeridos' => 'No hay suficientes metros disponibles para reservar (' . $tela->metros_disponibles . ').',
|
||||
'metros_requeridos' => 'No hay suficientes metros disponibles para reservar (' . $disponible . ' disponibles).',
|
||||
]);
|
||||
}
|
||||
|
||||
// Reservar: restar metros y marcar orden
|
||||
$tela->metros_disponibles = $tela->metros_disponibles - $orden->metros_requeridos;
|
||||
$tela->save();
|
||||
|
||||
$orden->tela_reservada = true;
|
||||
}
|
||||
});
|
||||
|
||||
// Validar y reservar tela al cambiar de estado a 'en_corte'
|
||||
// Validar disponibilidad de tela al actualizar
|
||||
static::updating(function ($orden) {
|
||||
// Validación: si se especifica tela y metros_requeridos, verificar disponibilidad
|
||||
if ($orden->tela_id && $orden->metros_requeridos !== null) {
|
||||
$tela = \App\Models\Tela::find($orden->tela_id);
|
||||
$originalMetros = $orden->getOriginal('metros_requeridos') ?? 0;
|
||||
$reservedAlready = $orden->tela_reservada ? $originalMetros : 0;
|
||||
$available = $tela ? ($tela->metros_disponibles + $reservedAlready) : null;
|
||||
|
||||
// Calcular metros usados por otras OPs (excluyendo esta OP)
|
||||
$metrosUsadosOtros = \App\Models\OrdenProduccion::where('tela_id', $orden->tela_id)
|
||||
->where('id', '!=', $orden->id)
|
||||
->sum('metros_requeridos');
|
||||
|
||||
$disponible = max(0, $tela->metros_comprados - $metrosUsadosOtros);
|
||||
|
||||
if ($available !== null && $orden->metros_requeridos > $available) {
|
||||
if ($orden->metros_requeridos > $disponible) {
|
||||
throw \Illuminate\Validation\ValidationException::withMessages([
|
||||
'metros_requeridos' => 'No hay suficientes metros de tela disponibles. Disponibles: ' . ($available),
|
||||
'metros_requeridos' => 'No hay suficientes metros de tela disponibles. Disponibles: ' . $disponible,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
// Ajustes automáticos de reserva cuando cambia la tela o los metros requeridos
|
||||
$originalTelaId = $orden->getOriginal('tela_id');
|
||||
$originalMetros = $orden->getOriginal('metros_requeridos') ?? 0;
|
||||
$newTelaId = $orden->tela_id;
|
||||
$newMetros = $orden->metros_requeridos ?? 0;
|
||||
|
||||
// Si cambió la tela en la OP, devolver los metros reservados en la tela anterior (si aplica)
|
||||
if ($originalTelaId && $originalTelaId != $newTelaId && $originalMetros > 0) {
|
||||
$oldTela = \App\Models\Tela::find($originalTelaId);
|
||||
if ($oldTela) {
|
||||
$oldTela->metros_disponibles = $oldTela->metros_disponibles + $originalMetros;
|
||||
$oldTela->save();
|
||||
}
|
||||
}
|
||||
|
||||
// Reservar metros en la nueva tela si se cambió
|
||||
if ($newTelaId && $originalTelaId != $newTelaId && $newMetros > 0) {
|
||||
$newTela = \App\Models\Tela::find($newTelaId);
|
||||
if (! $newTela) {
|
||||
throw \Illuminate\Validation\ValidationException::withMessages([
|
||||
'tela_id' => 'No se encontró la tela asociada.',
|
||||
]);
|
||||
}
|
||||
|
||||
if ($newTela->metros_disponibles < $newMetros) {
|
||||
throw \Illuminate\Validation\ValidationException::withMessages([
|
||||
'metros_requeridos' => 'No hay suficientes metros disponibles para reservar (' . $newTela->metros_disponibles . ').',
|
||||
]);
|
||||
}
|
||||
|
||||
$newTela->metros_disponibles = $newTela->metros_disponibles - $newMetros;
|
||||
$newTela->save();
|
||||
// Marcar como reservada si tiene tela y metros
|
||||
if ($orden->tela_id && $orden->metros_requeridos > 0) {
|
||||
$orden->tela_reservada = true;
|
||||
}
|
||||
});
|
||||
|
||||
// Si la misma tela y cambiaron los metros, ajustar la diferencia
|
||||
if ($originalTelaId == $newTelaId && $originalMetros != $newMetros && $newTelaId) {
|
||||
|
||||
@@ -34,6 +34,14 @@ class Tela extends Model
|
||||
return $this->hasMany(OrdenProduccion::class);
|
||||
}
|
||||
|
||||
// Calcular metros disponibles dinámicamente
|
||||
public function getMetrosDisponiblesAttribute()
|
||||
{
|
||||
$metrosComprados = (float) ($this->attributes['metros_comprados'] ?? 0);
|
||||
$metrosUsados = (float) $this->ordenesProduccion()->sum('metros_requeridos');
|
||||
return max(0, $metrosComprados - $metrosUsados);
|
||||
}
|
||||
|
||||
protected static function booted()
|
||||
{
|
||||
static::saving(function ($tela) {
|
||||
|
||||
Reference in New Issue
Block a user