feat: cashier/counter reports, service-order & remission flows, Rached migration utils
Some checks failed
CI / lint-and-test (3.11) (push) Has been cancelled
CI / lint-and-test (3.13) (push) Has been cancelled

- Add "Mis cortes de caja" report for cashiers/counters with sales detail.
- Cash register history scoped to own cuts for non-admin roles; new /register/<id>/sales endpoint.
- Remove dashboard from cashier menu; add Reports to cashier/counter.
- Service orders: assign mechanic, budget field, invoice flag, counter/cashier can add items/remissions, convert to remission.
- Remission notes module (UI, CSS, courier, counter remissions).
- Customer hard-delete and vehicle/customer linkage in workshop.
- POS: always show search results, compact payment grid, credit validation, tier pricing (5%/10%), ticket with customer/folio.
- Inventory: CSV template with sku_secondary, alias import.
- Rached migration scripts and DB migrations.
- Version-bump cached JS/CSS query strings.

Excludes local Rached session tokens/captures (rached_*.json / rached_*.txt).
This commit is contained in:
2026-07-02 12:51:56 +00:00
parent 483498cfcc
commit f42910f4f6
71 changed files with 5388 additions and 626 deletions

View File

@@ -229,6 +229,14 @@
</svg>
Histórico
</button>
<button class="tab-btn" onclick="switchTab('cortes', this)">
<svg viewBox="0 0 15 15" fill="none" stroke="currentColor" stroke-width="1.4">
<rect x="1" y="3" width="13" height="10" rx="1"/>
<path d="M4 7h7M4 10h5"/>
<circle cx="11" cy="10" r="1.5" fill="currentColor"/>
</svg>
Cortes de caja
</button>
</div>
<!-- ==================================================================
@@ -355,6 +363,38 @@
<!-- Sales detail table -->
<div class="table-card mb-5" id="historico-detalle"></div>
</div>
<!-- ==================================================================
TAB 6: CORTES DE CAJA
================================================================== -->
<div class="tab-panel" id="panel-cortes">
<!-- Filter Bar -->
<div class="filter-bar">
<span class="filter-bar__label">Desde</span>
<input type="date" class="filter-input" id="cortes-date-from" />
<span class="filter-bar__label">Hasta</span>
<input type="date" class="filter-input" id="cortes-date-to" />
<span id="cortes-employee-filter">
<span class="filter-bar__label">Cajero</span>
<select class="filter-select" id="cortes-employee">
<option value="">Todos</option>
</select>
</span>
<div class="filter-bar__spacer"></div>
<button class="btn btn-primary btn-sm" onclick="Reports.loadCortes()">Generar</button>
</div>
<!-- KPI Cards (dynamic) -->
<div class="kpi-grid" id="cortes-kpis"></div>
<!-- Cortes detail table -->
<div class="table-card mb-5" id="cortes-detalle"></div>
<!-- Detail of sales for the selected cash cut -->
<div class="table-card mb-5" id="corte-ventas-detalle" style="display:none;"></div>
</div>
<!-- End panels -->
@@ -365,12 +405,12 @@
</div>
<!-- End app-shell -->
<script src="/pos/static/js/i18n.js?v=36" defer></script>
<script src="/pos/static/js/app-init.js?v=2" defer></script>
<script src="/pos/static/js/i18n.js?v=39" defer></script>
<script src="/pos/static/js/app-init.js?v=5" defer></script>
<script src="/pos/static/js/splash-loader.js?v=33" defer></script>
<script src="/pos/static/js/pos-utils.js?v=33" defer></script>
<script src="/pos/static/js/sidebar.js?v=36" defer></script>
<script src="/pos/static/js/reports.js?v=33" defer></script>
<script src="/pos/static/js/sidebar.js?v=44" defer></script>
<script src="/pos/static/js/reports.js?v=35" defer></script>
<script src="/pos/static/js/sync-engine.js" defer></script>
<script>if('serviceWorker' in navigator){navigator.serviceWorker.register('/pos/sw.js',{scope:'/pos/'});}</script>
<script src="/pos/static/js/pwa-install.js" defer></script>