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

@@ -57,6 +57,19 @@ MIGRATIONS = {
"v4.8": "v4.8_workshop_permissions.sql",
"v4.9": "v4.9_workshop_customers_view.sql",
"v4.10": "v4.10_fleet_permissions.sql",
"v4.11": "v4.11_clean_workshop_mechanic_permissions.sql",
"v4.12": "v4.12_service_order_soft_delete.sql",
"v4.13": "v4.13_fleet_vehicle_customer.sql",
"v4.14": "v4.14_service_order_delivery_cleanup.sql",
"v4.15": "v4.15_counter_remission.sql",
"v4.16": "v4.16_remission_courier.sql",
"v4.17": "v4.17_service_order_invoice.sql",
"v4.18": "v4.18_rached_workshop.sql",
"v4.19": "v4.19_counter_inventory_create.sql",
"v4.20": "v4.20_cashier_sell_permissions.sql",
"v4.21": "v4.21_cashier_workshop_permissions.sql",
"v4.22": "v4.22_cashier_invoicing_permissions.sql",
"v4.23": "v4.23_service_order_mechanic_name.sql",
}
@@ -112,7 +125,10 @@ def apply_migration(db_name, version):
def run_migrations():
"""Apply pending migrations to all tenants."""
tenants = get_all_tenants()
sorted_versions = sorted(MIGRATIONS.keys())
def _version_key(v):
return tuple(int(x) for x in v.lstrip('v').split('.'))
sorted_versions = sorted(MIGRATIONS.keys(), key=_version_key)
print(f"Found {len(tenants)} active tenants")
print(f"Available migrations: {sorted_versions}")
@@ -120,8 +136,9 @@ def run_migrations():
for tenant_id, db_name, name, current_version in tenants:
print(f"\n[{name}] (db={db_name}, current={current_version})")
current_key = _version_key(current_version)
for version in sorted_versions:
if version <= current_version:
if _version_key(version) <= current_key:
continue
print(f" Applying {version}...", end=" ")