Mejoras de sesion: estabilizacion, IA, Nexus Yonke y marketplace B2B
Some checks failed
CI / lint-and-test (3.11) (push) Has been cancelled
CI / lint-and-test (3.13) (push) Has been cancelled

- F0 blindaje: Redis/Celery, pg_hba sin trust LAN, secretos a env 600, backups, webhook auth, jobs muertos
- F1 caja: bugs POS, reembolsos al corte, apartados, CFDI, topes de descuento en cotizacion/apartado
- F2/F7 IA de catalogo: autocategorizacion, dedup de SKUs con embeddings, OCR de facturas, descripciones, claves SAT, limpieza de fitment
- F3 IA en el flujo: vision Yonke, preguntas MeLi, venta cruzada, anomalias, sinonimos, busqueda semantica (rerank/embeddings)
- F4/F8 escala y cartera: /metrics+Prometheus+Grafana, pool, score de credito, churn, metricas multi-tenant
- Nexus Yonke (M1-M6): modelo de datos 1-de-1, alta por donador, vitrina publica, MeLi usado, consignacion, garantia por dias, reportes, etiquetas
- Marketplace B2B entre yonkes (catalogo + pedidos cross-tenant)
- Seguridad: auth en /api/admin/* (35 endpoints), alertas por tenant
- Migraciones v4.27/v4.28; timers expire-demos y rollup-metrics
This commit is contained in:
2026-10-12 00:57:31 +00:00
parent f2d4558b80
commit a386ca5b4a
165 changed files with 31313 additions and 2203 deletions

View File

@@ -13,36 +13,46 @@ from services.audit import log_action
def register_warranty(conn, sale_id, sale_item_id, inventory_id,
customer_id, warranty_months, supplier_id=None,
part_number=None, name=None, notes=None):
part_number=None, name=None, notes=None,
warranty_days=None):
"""Register a warranty for a sold item.
Args:
warranty_months: int (e.g., 12, 24, 36)
warranty_days: optional int. When given, end_date = today + warranty_days
(instead of 30 * warranty_months) and it is stored in the
warranty_days column. Used by the Yonke (used parts) module.
Returns:
int: warranty_id
"""
if not warranty_months or warranty_months <= 0:
if (not warranty_months or warranty_months <= 0) and not warranty_days:
raise ValueError("warranty_months must be a positive integer")
start = date.today()
end = start + timedelta(days=30 * warranty_months)
if warranty_days:
end = start + timedelta(days=int(warranty_days))
else:
end = start + timedelta(days=30 * warranty_months)
cur = conn.cursor()
cur.execute("""
INSERT INTO warranties
(sale_id, sale_item_id, inventory_id, customer_id, supplier_id,
part_number, name, warranty_months, start_date, end_date, notes)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
part_number, name, warranty_months, start_date, end_date, notes,
warranty_days)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
RETURNING id
""", (
sale_id, sale_item_id, inventory_id, customer_id, supplier_id,
part_number, name, warranty_months, start, end, notes
part_number, name, warranty_months, start, end, notes,
int(warranty_days) if warranty_days else None
))
w_id = cur.fetchone()[0]
cur.close()
log_action(conn, 'WARRANTY_REGISTER', 'warranty', w_id,
new_value={'months': warranty_months, 'end_date': str(end)})
new_value={'months': warranty_months, 'days': warranty_days,
'end_date': str(end)})
return w_id
@@ -141,7 +151,8 @@ def get_warranty(conn, warranty_id):
SELECT w.id, w.sale_id, w.sale_item_id, w.inventory_id, w.customer_id,
w.supplier_id, w.part_number, w.name, w.warranty_months,
w.start_date, w.end_date, w.status, w.notes, w.created_at,
c.name as customer_name, s.name as supplier_name
c.name as customer_name, s.name as supplier_name,
w.warranty_days
FROM warranties w
LEFT JOIN customers c ON w.customer_id = c.id
LEFT JOIN suppliers s ON w.supplier_id = s.id
@@ -158,6 +169,7 @@ def get_warranty(conn, warranty_id):
'start_date': str(row[9]), 'end_date': str(row[10]),
'status': row[11], 'notes': row[12], 'created_at': str(row[13]),
'customer_name': row[14], 'supplier_name': row[15],
'warranty_days': row[16],
}