public function store(Request $request): JsonResponse
{
$rules = [
'id_venta' => 'nullable|exists:ventas,id_venta',
'destinatario_tipo_doc' => 'required|in:1,6',
'destinatario_documento' => 'required|string|max:15',
'destinatario_nombre' => 'required|string|max:255',
'destinatario_direccion' => 'required|string|max:500',
'destinatario_ubigeo' => 'nullable|string|max:6',
'motivo_traslado' => 'required|string|max:2',
'descripcion_motivo' => 'nullable|string|max:255',
'mod_transporte' => 'required|in:01,02',
'fecha_traslado' => 'required|date',
'peso_total' => 'required|numeric|min:0.001',
'detalles' => 'required|array|min:1',
'detalles.*.descripcion' => 'required|string',
'detalles.*.cantidad' => 'required|numeric|min:0.001',
];
// Transporte público: transportista requerido
if ($request->mod_transporte === '01') {
$rules['transportista_tipo_doc'] = 'required|string|max:1';
$rules['transportista_documento'] = 'required|string|max:15';
$rules['transportista_nombre'] = 'required|string|max:255';
}
// Transporte privado: conductor y vehículo requeridos
if ($request->mod_transporte === '02') {
if (!$request->boolean('vehiculo_m1l')) {
$rules['conductor_tipo_doc'] = 'required|string|max:1';
$rules['conductor_documento'] = 'required|string|max:15';
$rules['conductor_nombres'] = 'required|string|max:255';
$rules['conductor_apellidos'] = 'required|string|max:255';
$rules['conductor_licencia'] = 'required|string|max:20';
$rules['vehiculo_placa'] = 'required|string|max:10';
}
}
$request->validate($rules);
return DB::transaction(function () use ($request) {
$idEmpresa = $request->user()->id_empresa;
$empresa = Empresa::findOrFail($idEmpresa);
$ultimoNumero = GuiaRemision::where('serie', 'T001')
->where('id_empresa', $idEmpresa)
->max('numero') ?? 0;
$guia = GuiaRemision::create([
'id_empresa' => $idEmpresa,
'id_usuario' => $request->user()->id,
'id_venta' => $request->id_venta,
'serie' => 'T001',
'numero' => $ultimoNumero + 1,
'fecha_emision' => now()->toDateString(),
'destinatario_tipo_doc' => $request->destinatario_tipo_doc,
'destinatario_documento' => $request->destinatario_documento,
'destinatario_nombre' => $request->destinatario_nombre,
'motivo_traslado' => $request->motivo_traslado,
'mod_transporte' => $request->mod_transporte,
'fecha_traslado' => $request->fecha_traslado,
'peso_total' => $request->peso_total,
'ubigeo_partida' => $request->ubigeo_partida ?: $empresa->ubigeo,
'dir_partida' => $request->dir_partida ?: $empresa->direccion,
'ubigeo_llegada' => $request->destinatario_ubigeo ?: '150101',
'dir_llegada' => $request->destinatario_direccion,
'transportista_documento' => $request->transportista_documento,
'transportista_nombre' => $request->transportista_nombre,
'conductor_documento' => $request->conductor_documento,
'conductor_nombres' => $request->conductor_nombres,
'conductor_apellidos' => $request->conductor_apellidos,
'conductor_licencia' => $request->conductor_licencia,
'vehiculo_placa' => $request->vehiculo_placa,
'vehiculo_m1l' => $request->boolean('vehiculo_m1l'),
'estado' => 'pendiente',
]);
foreach ($request->detalles as $detalle) {
GuiaRemisionDetalle::create([
'id_guia' => $guia->id,
'id_producto' => $detalle['id_producto'] ?? null,
'codigo' => $detalle['codigo'] ?? null,
'descripcion' => $detalle['descripcion'],
'cantidad' => $detalle['cantidad'],
'unidad' => $detalle['unidad'] ?? 'NIU',
]);
}
$resultado = $this->sunatService->generarGuiaRemisionXml($guia);
return response()->json([
'success' => true,
'data' => $guia,
'xml' => $resultado,
], 201);
});
}