- Added POST /pos/api/service-orders/vehicles endpoint for workshop.edit users.
- Added 'Nuevo vehiculo' modal in edit order with plate, VIN, make, model, year, color and owner.
- After creation the vehicle is automatically selected in the order.
- Removed 'Control de calidad' from service order pipeline (VALID_TRANSITIONS, status labels, Kanban columns).
- Added editable fields for customer, vehicle, branch, mechanic, priority, mileage, fuel level, estimated completion/cost and reception notes.
- Added customer/vehicle autocomplete in the edit order modal.
- i18n.js now locks currentLang to 'es' and overwrites pos_lang in localStorage.
- Disabled setLang language switching.
- Removed ES/EN toggle from sidebar.
- Bumped i18n.js and sidebar.js cache version on all templates.
- Added DELETE /pos/api/config/branches/<id> that soft-deletes the branch (is_active=false).
- Restricted to owner/admin; main branch cannot be deleted.
- Added 'Eliminar' button in the branches grid for admin/owner.
- Soft-delete service orders via is_deleted flag.
- Added DELETE /pos/api/service-orders/<id> restricted to owner/admin.
- Updated list, detail, summary, status and assignment queries to exclude deleted orders.
- Added 'Eliminar orden' button in the detail modal for administrators.
- Service orders can no longer move backwards through the workshop pipeline.
- Added editable Reception / Diagnosis / Repair / Delivery notes in the detail modal.
- Added inventory-aware autocomplete when attaching parts to a service order.
- Backend: nuevo endpoint DELETE /employees/<id> que desactiva (soft-delete).
No permite eliminar cuentas de dueno.
- Frontend: boton Eliminar en la tabla de empleados con confirmacion.
- Exponer deleteEmployee en el modulo Config.
Tests: 35 passed
- Elimina el script inline que redirigia a todos los usuarios.
- auth_bp.py: la respuesta de login ahora setea cookie pos_role.
- app.py: before_request redirige a /pos/workshop solo cuando la cookie
indica rol workshop/mechanic (no depende de JS cacheado).
- login.js/login.min.js/app-init.js: sincronizan/limpian la cookie pos_role
junto con el token en login y logout.
Tests: 35 passed
- sidebar.js: itemAllowed incluye mechanic junto a workshop -> solo muestra Taller
- app-init.js: redirige a /pos/workshop si el rol es workshop/mechanic
- config_bp.py: remueve customers.view y fleet.view de los permisos por defecto de workshop/mechanic
- workshop.js: hidePrices ahora tambien aplica para mechanic; oculta columnas/inputs de precio
- app-init.js/config.js: agrega etiquetas de rol para workshop y mechanic
- workshop.html: marca columnas de precio con price-col y oculta input catRate
Tests: 35 passed
- Agrega opciones workshop y mechanic al select de rol en config.html
- Actualiza ROLE_LABELS y ROLE_BADGE en config.js
- Valida roles mechanic y workshop en config_bp.py con permisos por defecto
- Añade clases CSS badge--orange y badge--teal
Tests: 35 passed
- Nuevos endpoints /pos/api/config/receipt (GET/PUT)
- Sección en config.html para subir logo, datos del negocio y toggles visuales
- pos.js carga la config y renderiza el ticket usando logo, RFC, dirección,
teléfono, mensajes y opciones de desglose/empleado/pago configurables
- Logo se redimensiona a 300px de ancho y se guarda como base64 JPEG en tenant_config
Tests: 35 passed
- Arregla @require_auth, permisos, race conditions, locks de caja/stock
- Elimina N+1 en layaway, flotilla, dashboard y global_invoice
- Asegura folios atomicos para CFDI, ordenes de servicio y polizas
- Protege client_secret de MercadoLibre en backend
- Conecta botones/filtros de config, customers, accounting e invoicing
- Mejora accesibilidad (labels/aria-label) y estados de carga/vacio
- Limpia accounting.js obsoleto y consolida accounting.v9.js
- Actualiza cache busting a v32 y Service Worker a v32
- Documenta todo en docs/AUDIT_Y_MEJORAS_2026-06-15.md
Tests: 35 passed
- catalog_service.get_models ahora agrupa variantes (p. ej. AVEO Saloon,
AVEO Hatchback) bajo un unico display_name y devuelve variant_ids.
- Se elige el id_model mas bajo como canonico para presentacion.
- /catalog/years y /catalog/engines aceptan model_id como lista separada
por comas para consultar todos los MYEs de las variantes agrupadas.
- catalog.js usa variant_ids al cargar años/motores y en el selector
desplegable (incluyendo carga desde VIN).
- Hace clickeables las filas de la tabla para seleccionar un cliente y
mostrar su panel de detalle (donde ya existe el botón Editar).
- Agrega botón de acción rápida con icono de lápiz en cada fila para
abrir directamente el modal de edición.
- Extrae openEditModal y agrega editCustomer(id) para cargar el cliente
vía API y abrir el modal sin depender de la selección previa.
- Actualiza colspan del estado vacío de 9 a 11 por la nueva columna.
El enlace <a> a /pos/api/supplier-catalog/prices/template fallaba con 401
porque la navegación normal no envía el header Authorization. Se reemplaza
por un botón que descarga el blob vía fetch con Bearer token y dispara la
descarga del cliente. También se corrige clase btn-primary -> btn--primary.
- Usa app-shell/main, page-header con eyebrow, summary-strip y cards con iconos.
- Reemplaza badges personalizados por .badge del design system.
- Unifica tablas con .data-table y .table-wrapper.
- Estandariza modales con .modal-overlay/.modal y formularios con .form-grid.
- Actualiza workshop.js para usar clases del sistema y toggle is-open en modales.
- Corrige tokens rotos (--text-sm, --color-warn, etc.) y usa variables del tema.
- Add generate_service_order_ticket() in thermal_printer.py with ESC/POS commands for 58mm and 80mm printers.
- Add POST /pos/api/service-orders/:id/print endpoint returning raw bytes or JSON for browser rendering.
- Extend printer.js with printServiceOrder() using WebUSB/Web Serial.
- Add Imprimir orden button in workshop.js detail modal.
- Update FASES_IMPLEMENTADAS.md.
- Normalize Facturapi key/org_id resolution (supports both cfdi_ prefixed
tenant_config keys and short names used by invoicing_bp).
- Add CSD upload end-to-end (backend + frontend).
- Add helper scripts: setup_facturapi_orgs.py and check_facturapi_tenants.py.
- Add 20 unit tests with mocks (pos/tests/test_facturapi_service.py).
- Add CI workflow for lint + console tests on Python 3.11/3.13.
- Add pyproject.toml and requirements-dev.txt with ruff/pytest config.
- Update FASES_IMPLEMENTADAS.md with FASE 8 documentation.
Tests: 81 passing (61 console + 20 Facturapi).
- Replace ID Producto input with autocomplete search by name/part number/barcode
- Support Enter key for barcode/part number exact match
- Keep hidden inventory_id field for API compatibility
- Bump inventory.js cache version
- get_org_status now returns has_key, has_org_id, pending_steps, error
- add find_organization_by_rfc and create_organization helpers
- add /facturapi/setup endpoint to link/create Facturapi org
- frontend shows detailed PAC status and setup button
- support using tenant sk_user_* key when FACTURAPI_USER_KEY env is absent
- Month view now groups by weeks of the current calendar month
- Labels are Sem 1, Sem 2, Sem 3, Sem 4
- Historical sales grouped by day-of-month into the 4 week buckets
- Bump dashboard.js to ?v=7
- Replace placeholder setPeriod() with functional period switcher
- loadChart() supports Hoy (1 day), Semana (7 days), Mes (4 weeks), Año (12 months)
- Includes both normal POS sales and imported historical sales
- Updates chart title, total label and legend dynamically
- Bump dashboard.js to ?v=6
- Add 'Histórico' tab inside Reports page with date/customer filters
- Show historical sales KPIs and detail table in reports
- Add historical sales summary cards to Dashboard
- Load current month totals and total imported records
- Add upload_image() to MeliService using ML /pictures endpoint
- Add get_listing_price() to fetch exact ML fees
- Auto-upload inventory images to ML before validate/publish
- Show fee breakdown and net earnings in validate modal
- Fallback to approximate fees (13-18%) if ML API fails
- Add address and cp to list_customers() backend response
- Show razon_social as subtitle in customer table rows
- Add razon_social and cp fields to detail panel
- Update customers.html detail panel layout
Fase 1: Lista de precios de proveedor
- Tabla supplier_catalog_prices en master DB
- Endpoints GET/POST/PUT/DELETE /supplier-catalog/prices
- Upload CSV/Excel de precios de proveedor
- Visualizacion de supplier_price en catalogo y POS
Fase 2: Multi-sucursal completo
- Migracion v4.0: inventory.branch_id=NULL, tabla inventory_stock
- Campos fiscales en branches (RFC, regimen, CP, serie CFDI, certificados)
- Trigger trg_update_inventory_stock para sincronizar stock por sucursal
- Backend config_bp.py con CRUD de sucursales fiscales
- Backend inventory_bp.py y pos_bp.py refactorizados para inventario compartido
- Backend invoicing_bp.py usa datos fiscales de la sucursal de la venta
- Frontend config.html/js con modal de sucursales expandido
Fase 3: Factura global mensual
- Migracion v4.1: tablas global_invoice_sales, sales.global_invoiced_at
- build_global_invoice_xml() con InformacionGlobal SAT-compliant
- Servicio global_invoice.py para agrupar ventas PUE <=000
- Endpoints POST/GET /global-invoice y /global-invoice/eligible-sales
- Frontend invoicing.html/js con boton y modal de factura global
- Convert sidebar.js IIFE to window.renderSidebar() so it can be re-rendered
- Call window.renderSidebar(data) from app-init.js after fetching modules
- Ensures sidebar reflects actual tenant module config, not stale localStorage