Agregar flujo de inmovilización/liberación de lotes (Inmovilizar, Liberar y Confirmar Liberación Lote)

- Inmovilizar Lotes: selección múltiple de almacén origen con cantidad editable, genera Solicitud de Transferencia hacia un almacén de inmovilizados.
- Liberar Lotes: inversa de la anterior, con almacenes/campos de usuario propios (U_SIS_MOVINV, U_EXX_TIPOOPER, U_SIS_TIPDESP, U_SIS_MOTALM).
- Confirmar Liberación Lote: lista las Solicitudes abiertas pendientes (U_SIS_MOTALM=108) y, por cada lote, resuelve contra el historial de transferencias en HANA a qué almacén(es) debe volver, repartiendo la cantidad entre orígenes; permite editar cantidad, almacén destino, y agregar/quitar líneas antes de actualizar la Solicitud en SAP.
- Backend: nuevo endpoint /api/batch/lot-source-warehouse (HANA) para resolver el origen histórico de un lote; endpoint genérico /api/Catalogs/UdfValidValues (Service Layer) para valores válidos de un UDF; PATCH genérico ahora reenvía cualquier header B1S-* que mande el frontend en vez de decidirlos en el backend.
- Registro de rutas, menú y permisos para las tres pantallas nuevas.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
GeorgeandClaude Sonnet 5 committed 2026-09-28 13:08:58 -05:00
1 parent d900b62f33
commit 7e0a646853
19 files changed
+2830 -5

No files matched your search

+43
View File
@@ -58,6 +58,49 @@ async def get_sunat_businesspartners_document_type():
extra_headers=base_headers
).json()
@router.get("/api/Catalogs/UdfValidValues")
async def get_udf_valid_values(table_name: str, field_name: str):
"""
Genérico para cualquier campo de usuario (UDF) con lista de valores
válidos: recibe la tabla SAP (ej. 'OWTQ') y el nombre del campo sin el
prefijo 'U_' (ej. 'SIS_TIPDESP'), y devuelve sus valores válidos vía
Service Layer (UserFieldsMD.ValidValuesMD), normalizados a {Code, Name}
para poder usarse con useSapCatalog igual que las tablas de usuario.
Equivale a lo que en HANA sería CUFD (por AliasID/TableID) + UFD1
(por FieldID), pero sin necesidad de acceso directo a HANA.
"""
def _escape(value: str) -> str:
return value.replace("'", "''")
sap_params = {
"$skip": 0,
"$top": 200,
"$inlinecount": "allpages",
}
sap_params["$filter"] = (
f"TableName eq '{_escape(table_name)}' and Name eq '{_escape(field_name)}'"
)
base_headers = {"B1S-PageSize": "200"}
response = forward_to_sapb1(
method="GET",
endpoint_path="UserFieldsMD",
params=sap_params,
extra_headers=base_headers,
).json()
fields = response.get("value", [])
valid_values = fields[0].get("ValidValuesMD", []) if fields else []
return {
"value": [
{"Code": v["Value"], "Name": v["Description"]} for v in valid_values
]
}
@router.get("/api/ItemGroups")
async def get_item_groups():