'datetime', 'fecha_recepcion' => 'datetime', ]; public function ordenProduccion() { return $this->belongsTo(OrdenProduccion::class); } public function referencia() { return $this->morphTo(); } public function ingresadoPor() { return $this->belongsTo(User::class, 'ingresado_por'); } public static function crearDesdeReferencia(Model $referencia, string $origen, string $destino, array $payload = []) : self { $defaults = [ 'orden_produccion_id' => $referencia->orden_produccion_id, 'referencia_type' => get_class($referencia), 'referencia_id' => $referencia->id, 'origen' => $origen, 'destino' => $destino, 'cantidad_enviada' => $payload['cantidad_enviada'] ?? ($referencia->cantidad_enviada ?? 0), 'cantidad_recibida' => $payload['cantidad_recibida'] ?? ($referencia->cantidad_recibida ?? null), 'prendas_defectuosas' => $payload['prendas_defectuosas'] ?? ($referencia->prendas_defectuosas ?? 0), 'reparaciones' => $payload['reparaciones'] ?? ($referencia->reparaciones ?? 0), 'saldos' => $payload['saldos'] ?? ($referencia->saldos ?? 0), 'fecha_envio' => $payload['fecha_envio'] ?? ($referencia->fecha_envio ?? null), 'fecha_recepcion' => $payload['fecha_recepcion'] ?? ($referencia->fecha_recepcion ?? null), 'estado' => 'recibido', ]; $cantidad_enviada = (int) $defaults['cantidad_enviada']; $cantidad_recibida = (int) ($defaults['cantidad_recibida'] ?? 0); $prendas_defectuosas = (int) ($defaults['prendas_defectuosas'] ?? 0); $reparaciones = (int) ($defaults['reparaciones'] ?? 0); $saldos = (int) ($defaults['saldos'] ?? 0); $defaults['residual'] = $cantidad_enviada - ($cantidad_recibida + $prendas_defectuosas + $reparaciones + $saldos); $traslado = self::create($defaults); // Si el traslado es a bodega y la OP ya está finalizada, crear inventario (si no existe) if ($traslado->destino === 'bodega') { $traslado->maybeCreateInventory(); } return $traslado; } public function markAsReceived(array $data = [], $userId = null) { // Actualizar campos si se envían $this->cantidad_recibida = $data['cantidad_recibida'] ?? $this->cantidad_recibida; $this->prendas_defectuosas = $data['prendas_defectuosas'] ?? $this->prendas_defectuosas ?? 0; $this->reparaciones = $data['reparaciones'] ?? $this->reparaciones ?? 0; $this->saldos = $data['saldos'] ?? $this->saldos ?? 0; $this->fecha_recepcion = $data['fecha_recepcion'] ?? now(); $this->estado = 'recibido'; // Si cantidad_recibida no se proporcionó, inferirla if ($this->cantidad_recibida === null) { $this->cantidad_recibida = (int) $this->cantidad_enviada - ((int) $this->prendas_defectuosas + (int) $this->reparaciones + (int) $this->saldos); if ($this->cantidad_recibida < 0) { $this->cantidad_recibida = 0; } } if ($userId) { $this->ingresado_por = $userId; } $this->residual = (int) $this->cantidad_enviada - ((int) $this->cantidad_recibida + (int) $this->prendas_defectuosas + (int) $this->reparaciones + (int) $this->saldos); $this->save(); // Si destino bodega, intentar crear inventario if ($this->destino === 'bodega') { $this->maybeCreateInventory(); } return $this; } protected function maybeCreateInventory() { $op = $this->ordenProduccion; if (! $op) return; if ($op->estado === 'finalizada' && !\App\Models\InventarioPrenda::where('orden_produccion_id', $op->id)->exists()) { $cantidad = self::where('orden_produccion_id', $op->id) ->where('destino', 'bodega') ->sum('cantidad_recibida'); if ($cantidad > 0) { \App\Models\InventarioPrenda::create([ 'orden_produccion_id' => $op->id, 'cantidad_terminada' => $cantidad, 'cantidad_disponible' => $cantidad, 'fecha_ingreso' => now(), 'estado' => 'en_bodega', ]); } } } }