From c226b1cf77229ada3d2ac2b7492f4a9a0e7b741d Mon Sep 17 00:00:00 2001 From: consultoria-as Date: Thu, 2 Jul 2026 14:38:29 +0000 Subject: [PATCH] fix(workshop): restrict workshop/mechanic views to only 'autorizada' status --- pos/blueprints/service_order_bp.py | 12 ++++++----- pos/static/js/workshop.js | 32 +++++++++++++++++++++++++++++- pos/templates/workshop.html | 2 +- 3 files changed, 39 insertions(+), 7 deletions(-) diff --git a/pos/blueprints/service_order_bp.py b/pos/blueprints/service_order_bp.py index 670595c..7b12e20 100644 --- a/pos/blueprints/service_order_bp.py +++ b/pos/blueprints/service_order_bp.py @@ -48,6 +48,9 @@ _MECHANIC_HIDDEN_STATUSES = { 'por_facturar', 'facturada' } +# Statuses visible to workshop/mechanic accounts (taller only works on authorized orders). +_TALLER_ALLOWED_STATUSES = {'autorizada'} + def _can_view_workshop(): return g.employee_role in _WORKSHOP_VIEW_ROLES or 'workshop.view' in g.permissions @@ -143,11 +146,10 @@ def list_orders(): ) if _is_restricted_workshop_viewer(): result['data'] = [_redact_order_for_mechanic(o) for o in result.get('data', [])] - # Shared mechanic account can see all orders except commercial/closed statuses. - if g.employee_role == 'mechanic': + # Workshop/mechanic accounts only see orders ready to be worked on. result['data'] = [ o for o in result.get('data', []) - if o.get('status') not in _MECHANIC_HIDDEN_STATUSES + if o.get('status') in _TALLER_ALLOWED_STATUSES ] return jsonify(result) finally: @@ -237,8 +239,8 @@ def get_order(so_id): order = get_service_order(conn, so_id) if not order: return jsonify({'error': 'Service order not found'}), 404 - # Shared mechanic account cannot view commercial/closed statuses. - if g.employee_role == 'mechanic' and order.get('status') in _MECHANIC_HIDDEN_STATUSES: + # Workshop/mechanic accounts can only view orders that are ready to be worked on. + if _is_restricted_workshop_viewer() and order.get('status') not in _TALLER_ALLOWED_STATUSES: return jsonify({'error': 'No tienes acceso a esta orden'}), 403 return jsonify(_redact_order_for_mechanic(order)) finally: diff --git a/pos/static/js/workshop.js b/pos/static/js/workshop.js index 92b1e87..3fcf7ec 100644 --- a/pos/static/js/workshop.js +++ b/pos/static/js/workshop.js @@ -196,6 +196,14 @@ var Workshop = (function() { document.querySelectorAll('.restricted-hide').forEach(function(el) { el.style.display = 'none'; }); var searchInput = document.getElementById('filterSearch'); if (searchInput) searchInput.placeholder = 'Buscar orden'; + // Limit status filter to the only status taller accounts can see. + var statusSel = document.getElementById('filterStatus'); + if (statusSel) { + Array.from(statusSel.options).forEach(function(opt) { + if (opt.value && opt.value !== 'autorizada') opt.remove(); + }); + statusSel.value = 'autorizada'; + } } if (hidePrices) { var btnCatalog = document.getElementById('btnCatalog'); @@ -251,6 +259,22 @@ var Workshop = (function() { fetch(API + '/kanban/summary', {headers: headers()}) .then(function(r) { return r.json(); }) .then(function(d) { + var cards = document.querySelectorAll('#statsRow .summary-card'); + if (isRestricted) { + // Taller accounts only see authorized orders. + cards.forEach(function(card, idx) { + if (idx === 0) { + card.style.display = ''; + var label = card.querySelector('.summary-card__label'); + if (label) label.textContent = 'Autorizadas'; + } else { + card.style.display = 'none'; + } + }); + document.getElementById('statReceived').textContent = fmt(d.autorizada || 0); + return; + } + cards.forEach(function(card) { card.style.display = ''; }); document.getElementById('statReceived').textContent = fmt(d.por_revisar || 0); document.getElementById('statRepair').textContent = fmt((d.en_reparacion || 0) + (d.en_revision || 0) + (d.revisada || 0) + (d.cotizada || 0) + (d.por_autorizar || 0)); document.getElementById('statReady').textContent = fmt(d.por_entregar || 0); @@ -379,7 +403,13 @@ var Workshop = (function() { function renderKanban() { var board = document.getElementById('kanbanBoard'); board.innerHTML = ''; - var hiddenCols = isMechanic ? ['cotizada','por_autorizar','autorizada','autorizacion_parcial','por_facturar','facturada'] : []; + var hiddenCols = []; + if (isRestricted) { + // Taller accounts only see the "autorizada" column. + hiddenCols = COLUMNS.filter(function(c) { return c.key !== 'autorizada'; }).map(function(c) { return c.key; }); + } else if (isMechanic) { + hiddenCols = ['cotizada','por_autorizar','autorizada','autorizacion_parcial','por_facturar','facturada']; + } COLUMNS.filter(function(col) { return hiddenCols.indexOf(col.key) === -1; }).forEach(function(col) { var colOrders = orders.filter(function(o) { return o.status === col.key; }); var colEl = document.createElement('div'); diff --git a/pos/templates/workshop.html b/pos/templates/workshop.html index 215245a..6ec9bb4 100644 --- a/pos/templates/workshop.html +++ b/pos/templates/workshop.html @@ -499,7 +499,7 @@ - +