Files
Autoparts-DB/scripts/migrate_workshop_permissions.py
consultoria-as 6e85497e42
Some checks failed
CI / lint-and-test (3.11) (push) Has been cancelled
CI / lint-and-test (3.13) (push) Has been cancelled
feat(permissions): granular module permissions + workshop permissions matrix
2026-07-03 07:55:17 +00:00

82 lines
2.8 KiB
Python

#!/usr/bin/env python3
"""Initialize workshop_permissions tenant_config for all existing tenants.
Uses the same defaults defined in pos/blueprints/config_bp.py. Safe to run
multiple times (it overwrites with defaults).
Example:
sudo -u postgres python3 scripts/migrate_workshop_permissions.py
"""
import json
import os
import sys
import psycopg2
# Mirror of pos/blueprints/config_bp.py defaults
_WORKSHOP_STATUSES = [
'por_revisar', 'en_revision', 'revisada', 'cotizada', 'por_autorizar',
'autorizada', 'autorizacion_parcial', 'en_reparacion', 'reparada',
'por_entregar', 'entregado', 'por_enviar', 'enviado',
'por_facturar', 'facturada', 'por_recolectar', 'cancelada'
]
_ALL_ACTIONS = [
'create_order', 'edit_order', 'delete_order', 'assign_mechanic',
'add_items', 'add_labor', 'change_status', 'convert_to_sale',
'convert_to_remission', 'view_customer_data', 'view_prices', 'view_notes',
]
_DEFAULT_WORKSHOP_PERMISSIONS = {
'owner': {'statuses': _WORKSHOP_STATUSES, 'actions': _ALL_ACTIONS},
'admin': {'statuses': _WORKSHOP_STATUSES, 'actions': _ALL_ACTIONS},
'manager': {'statuses': _WORKSHOP_STATUSES, 'actions': [a for a in _ALL_ACTIONS if a != 'delete_order']},
'counter': {'statuses': _WORKSHOP_STATUSES, 'actions': [a for a in _ALL_ACTIONS if a != 'delete_order']},
'cashier': {'statuses': _WORKSHOP_STATUSES, 'actions': [a for a in _ALL_ACTIONS if a not in ('delete_order', 'convert_to_sale')]},
'workshop': {
'statuses': [s for s in _WORKSHOP_STATUSES if s not in ('por_entregar', 'entregado', 'por_enviar', 'enviado', 'por_recolectar')],
'actions': ['change_status', 'add_labor', 'view_notes']
},
'mechanic': {
'statuses': ['por_revisar', 'en_revision', 'revisada', 'en_reparacion', 'reparada', 'autorizada', 'cancelada'],
'actions': ['change_status', 'add_labor', 'view_notes']
},
}
def get_tenant_dbs(master_db='nexus_autoparts'):
conn = psycopg2.connect(f"postgresql://postgres@/{master_db}")
cur = conn.cursor()
cur.execute("SELECT db_name FROM tenants WHERE is_active = true")
dbs = [r[0] for r in cur.fetchall() if r[0]]
cur.close(); conn.close()
return dbs
def migrate(db_name):
conn = psycopg2.connect(f"postgresql://postgres@/{db_name}")
cur = conn.cursor()
cur.execute("""
INSERT INTO tenant_config (key, value) VALUES ('workshop_permissions', %s)
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value
""", (json.dumps(_DEFAULT_WORKSHOP_PERMISSIONS),))
conn.commit()
cur.close(); conn.close()
return True
def main():
dbs = get_tenant_dbs()
print(f"Migrating {len(dbs)} tenant(s)...")
for db in dbs:
try:
migrate(db)
print(f" OK {db}")
except Exception as e:
print(f" ERR {db}: {e}")
print("Done.")
if __name__ == '__main__':
main()