feat(config): allow admin/owner to delete branches
- 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.
This commit is contained in:
@@ -150,6 +150,33 @@ def update_branch(branch_id):
|
|||||||
return jsonify({'ok': True, 'message': 'Branch updated'})
|
return jsonify({'ok': True, 'message': 'Branch updated'})
|
||||||
|
|
||||||
|
|
||||||
|
@config_bp.route('/branches/<int:branch_id>', methods=['DELETE'])
|
||||||
|
@require_auth('config.edit')
|
||||||
|
def delete_branch(branch_id):
|
||||||
|
"""Soft-delete a branch. Only owner/admin can delete; main branch cannot be deleted."""
|
||||||
|
if g.employee_role not in ('owner', 'admin'):
|
||||||
|
return jsonify({'error': 'Solo administradores pueden eliminar sucursales'}), 403
|
||||||
|
|
||||||
|
conn = get_tenant_conn(g.tenant_id)
|
||||||
|
cur = conn.cursor()
|
||||||
|
|
||||||
|
cur.execute("SELECT is_main FROM branches WHERE id = %s", (branch_id,))
|
||||||
|
row = cur.fetchone()
|
||||||
|
if not row:
|
||||||
|
cur.close(); conn.close()
|
||||||
|
return jsonify({'error': 'Branch not found'}), 404
|
||||||
|
|
||||||
|
if row[0]:
|
||||||
|
cur.close(); conn.close()
|
||||||
|
return jsonify({'error': 'No se puede eliminar la sucursal principal'}), 403
|
||||||
|
|
||||||
|
cur.execute("UPDATE branches SET is_active = false WHERE id = %s", (branch_id,))
|
||||||
|
conn.commit()
|
||||||
|
cur.close()
|
||||||
|
conn.close()
|
||||||
|
return jsonify({'ok': True, 'message': 'Sucursal eliminada'})
|
||||||
|
|
||||||
|
|
||||||
@config_bp.route('/employees', methods=['GET'])
|
@config_bp.route('/employees', methods=['GET'])
|
||||||
@require_auth()
|
@require_auth()
|
||||||
def list_employees():
|
def list_employees():
|
||||||
|
|||||||
@@ -4,6 +4,9 @@
|
|||||||
const Config = (() => {
|
const Config = (() => {
|
||||||
const API = '/pos/api/config';
|
const API = '/pos/api/config';
|
||||||
|
|
||||||
|
const user = window.POS_USER || {};
|
||||||
|
const canDeleteBranch = (user.role === 'owner' || user.role === 'admin');
|
||||||
|
|
||||||
// Cache for branches (used by employee modal selector)
|
// Cache for branches (used by employee modal selector)
|
||||||
let _branches = [];
|
let _branches = [];
|
||||||
|
|
||||||
@@ -183,6 +186,7 @@ const Config = (() => {
|
|||||||
+ '</div>'
|
+ '</div>'
|
||||||
+ '<div class="device-card__actions">'
|
+ '<div class="device-card__actions">'
|
||||||
+ '<button class="btn btn--ghost btn--sm" onclick="Config.editBranch(' + b.id + ')">Editar</button>'
|
+ '<button class="btn btn--ghost btn--sm" onclick="Config.editBranch(' + b.id + ')">Editar</button>'
|
||||||
|
+ (canDeleteBranch && b.is_active && !b.is_main ? '<button class="btn btn--danger btn--sm" style="margin-left:4px;" onclick="Config.deleteBranch(' + b.id + ')">Eliminar</button>' : '')
|
||||||
+ '</div></div>';
|
+ '</div></div>';
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -238,6 +242,22 @@ const Config = (() => {
|
|||||||
openBranchModal(b);
|
openBranchModal(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function deleteBranch(branchId) {
|
||||||
|
var b = _branches.find(function(x) { return x.id === branchId; });
|
||||||
|
if (!b) { toast('Sucursal no encontrada', 'error'); return; }
|
||||||
|
if (b.is_main) { toast('No se puede eliminar la sucursal principal', 'error'); return; }
|
||||||
|
if (!confirm('¿Eliminar la sucursal "' + b.name + '"? Se marcará como inactiva.')) return;
|
||||||
|
try {
|
||||||
|
var res = await fetch(API + '/branches/' + branchId, { method: 'DELETE', headers: headers() });
|
||||||
|
var json = await res.json().catch(function() { return {}; });
|
||||||
|
if (!res.ok) throw new Error(json.error || res.statusText);
|
||||||
|
toast('Sucursal eliminada');
|
||||||
|
loadBranches();
|
||||||
|
} catch (e) {
|
||||||
|
toast(e.message || 'Error al eliminar sucursal', 'error');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function saveBranch(data) {
|
async function saveBranch(data) {
|
||||||
var branchId = document.getElementById('branch-id').value;
|
var branchId = document.getElementById('branch-id').value;
|
||||||
var url = API + '/branches' + (branchId ? '/' + branchId : '');
|
var url = API + '/branches' + (branchId ? '/' + branchId : '');
|
||||||
@@ -1047,6 +1067,7 @@ const Config = (() => {
|
|||||||
return {
|
return {
|
||||||
init, setTheme, selectThemeOption, loadAllowedBrands, saveAllowedBrands,
|
init, setTheme, selectThemeOption, loadAllowedBrands, saveAllowedBrands,
|
||||||
loadBranches, loadEmployees, saveBranch, saveEmployee, editEmployee, deleteEmployee,
|
loadBranches, loadEmployees, saveBranch, saveEmployee, editEmployee, deleteEmployee,
|
||||||
|
deleteBranch,
|
||||||
loadBusiness, saveBusiness, saveTaxParams, saveAll,
|
loadBusiness, saveBusiness, saveTaxParams, saveAll,
|
||||||
loadCurrency, saveCurrency,
|
loadCurrency, saveCurrency,
|
||||||
loadVehicleCompatSource, saveVehicleCompatSource,
|
loadVehicleCompatSource, saveVehicleCompatSource,
|
||||||
|
|||||||
@@ -928,7 +928,7 @@
|
|||||||
<script src="/pos/static/js/pos-utils.js?v=33" defer></script>
|
<script src="/pos/static/js/pos-utils.js?v=33" defer></script>
|
||||||
<script src="/pos/static/js/sidebar.js" defer></script>
|
<script src="/pos/static/js/sidebar.js" defer></script>
|
||||||
<script src="/pos/static/js/kiosk.js" defer></script>
|
<script src="/pos/static/js/kiosk.js" defer></script>
|
||||||
<script src="/pos/static/js/config.js?v=33" defer></script>
|
<script src="/pos/static/js/config.js?v=34" defer></script>
|
||||||
<script src="/pos/static/js/sync-engine.js" 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>if('serviceWorker' in navigator){navigator.serviceWorker.register('/pos/sw.js',{scope:'/pos/'});}</script>
|
||||||
<script src="/pos/static/js/pwa-install.js" defer></script>
|
<script src="/pos/static/js/pwa-install.js" defer></script>
|
||||||
|
|||||||
Reference in New Issue
Block a user