Files
GeorgeandClaude Sonnet 5 fef21898f9 Backport de mejoras genéricas de backend (desde cliente/tagumedica) + limpieza de datos de cliente en main
Mejoras genéricas traídas:
- core/crud_router.py: el PATCH genérico reenvía cualquier header B1S-* recibido del caller en vez de decidirlo el backend.
- routers/catalogs.py: nuevo endpoint /api/Catalogs/UdfValidValues (valores válidos de cualquier UDF vía Service Layer).
- routers/batch.py: /api/batch/stock (stock de un lote por almacén) y /api/batch/lot-source-warehouse (resuelve contra HANA de qué almacén salió un lote, repartiendo por origen).
- routers/inventory_transfer_requests.py + core/inventory_transfer_requests.py: CRUD genérico de Solicitudes de Transferencia de Inventario.
- routers/series.py + core/series.py: series activas de un tipo de documento.
- routers/user_tables.py: catálogo Code/Name genérico de tablas de usuario (mapeo USER_TABLES vacío, cada cliente completa el suyo).
- routers/reports.py / templates/reports/stickers.html: fix de márgenes/alto de página del reporte de etiquetas.
- mini-backend/test/ -> mini-backend/tools/ (rename organizativo).

Limpieza de datos de Tagumedica que ya estaban en el commit base de main (anteriores a la branch cliente/tagumedica, no relacionados con el backport):
- tools/sap-tagumedica/sl.http: eliminado (tenía CompanyDB y password reales).
- tools/ApiGateway/Login.yml: CompanyDB/host/password reemplazados por placeholders.
- templates/reports/stickers.html: título hardcodeado "TAGUMEDICA" reemplazado por "EMPRESA".
- menu_permissions.json: reemplazado por un ejemplo demo (usuarios/módulos ficticios) en vez de emails reales.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-28 14:18:42 -05:00

132 lines
2.6 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<style>
@font-face {
font-family: 'Orbitron';
src: url('fonts/Orbitron-Bold.ttf') format('truetype');
font-weight: bold;
}
@page {
size: {{ paper_size }} landscape;
margin: 1.6cm 3cm 1cm 2.2cm;
}
body {
font-family: Arial, Helvetica, sans-serif;
margin: 0;
padding: 0;
}
.pagina {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
gap: 0.15in;
height: {{ pagina_alto }};
page-break-after: always;
}
.pagina:last-child {
page-break-after: auto;
}
.sticker {
height: 100%;
border: 2px solid #000;
padding: 0.15in 0.35in;
box-sizing: border-box;
position: relative;
display: flex;
flex-direction: column;
}
.titulo {
color: #E8781E;
font-family: 'Orbitron', 'Arial Black', Arial, sans-serif;
font-size: 20pt;
font-weight: bold;
letter-spacing: 1px;
margin-bottom: 10px;
}
.campo {
margin-bottom: 8px;
}
.campo-direccion {
min-height: 0.5in;
}
.campo-label {
font-family: Arial, Helvetica, sans-serif;
font-size: 13pt;
font-weight: normal;
}
.campo-valor {
font-family: Arial, Helvetica, sans-serif;
font-size: 13pt;
font-weight: bold;
}
.contador {
font-family: Arial, Helvetica, sans-serif;
font-size: 38pt;
font-weight: bold;
}
.documento-linea {
position: absolute;
left: 0.35in;
right: 0.35in;
bottom: 0.15in;
display: flex;
justify-content: space-between;
align-items: flex-end;
}
.documento-linea .campo {
margin-bottom: 0;
}
</style>
</head>
<body>
{% for pagina in paginas %}
<div class="pagina">
{% for sticker in pagina %}
<div class="sticker">
<div class="titulo">EMPRESA</div>
<div class="campo">
<div class="campo-label">DATOS DEL CLIENTE:</div>
<div class="campo-valor">{{ datos.cliente }}</div>
</div>
<div class="campo campo-direccion">
<div class="campo-label">DIRECCIÓN:</div>
<div class="campo-valor">{{ datos.direccion }}</div>
</div>
<div class="campo">
<div class="campo-label">LUGAR:</div>
<div class="campo-valor">{{ datos.lugar }}</div>
</div>
<div class="documento-linea">
<div class="campo">
<div class="campo-label">DOCUMENTO:</div>
<div class="campo-valor">{{ datos.documento }}</div>
</div>
<div class="contador">{{ sticker.numero }}/{{ sticker.total }}</div>
</div>
</div>
{% endfor %}
</div>
{% endfor %}
</body>
</html>