feat(pos): add open-register UI flow
- Add 'Open Register' modal with register number and opening amount inputs - loadRegister now shows clickable warning when no register is open - checkout() opens register modal instead of plain alert when no register - Add openRegister() API call to POST /pos/api/register/open - Expose showOpenRegisterModal, closeOpenRegisterModal, openRegister globally - Add cache-bust query params to pos.css and pos.js
This commit is contained in:
@@ -120,14 +120,48 @@ const POS = (() => {
|
||||
document.getElementById('registerInfo').innerHTML =
|
||||
`<span>Caja #${data.register.register_number}</span>`;
|
||||
} else {
|
||||
currentRegister = null;
|
||||
document.getElementById('registerInfo').innerHTML =
|
||||
'<span>Sin caja abierta</span>';
|
||||
'<span style="color:var(--color-error);cursor:pointer;" onclick="POS.showOpenRegisterModal()" title="Clic para abrir caja">⚠ Sin caja abierta — Clic para abrir</span>';
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('Register check failed:', e);
|
||||
}
|
||||
}
|
||||
|
||||
function showOpenRegisterModal() {
|
||||
document.getElementById('openRegisterModal').classList.add('open');
|
||||
document.getElementById('registerOpenResult').innerHTML = '';
|
||||
}
|
||||
function closeOpenRegisterModal() {
|
||||
document.getElementById('openRegisterModal').classList.remove('open');
|
||||
document.getElementById('registerOpenResult').innerHTML = '';
|
||||
}
|
||||
async function openRegister() {
|
||||
const number = parseInt(document.getElementById('regNumber').value);
|
||||
const amount = parseFloat(document.getElementById('regOpeningAmount').value) || 0;
|
||||
if (!number || number < 1) {
|
||||
document.getElementById('registerOpenResult').innerHTML = '<span style="color:var(--color-error);">Numero de caja invalido</span>';
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const data = await api('/pos/api/register/open', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ register_number: number, opening_amount: amount })
|
||||
});
|
||||
if (data.error) {
|
||||
document.getElementById('registerOpenResult').innerHTML = '<span style="color:var(--color-error);">' + (data.error || 'Error') + '</span>';
|
||||
return;
|
||||
}
|
||||
currentRegister = data;
|
||||
document.getElementById('registerInfo').innerHTML = `<span>Caja #${data.register_number}</span>`;
|
||||
closeOpenRegisterModal();
|
||||
showToast(`Caja #${data.register_number} abierta con $${amount.toFixed(2)}`);
|
||||
} catch (e) {
|
||||
document.getElementById('registerOpenResult').innerHTML = '<span style="color:var(--color-error);">Error de red</span>';
|
||||
}
|
||||
}
|
||||
|
||||
// ─── Cart ────────────────────────────
|
||||
function addToCart(item) {
|
||||
const existing = cart.find(c => c.inventory_id === item.inventory_id);
|
||||
@@ -548,7 +582,7 @@ const POS = (() => {
|
||||
// ─── Payment ─────────────────────────
|
||||
function checkout() {
|
||||
if (cart.length === 0) { showToast('Carrito vacio'); return; }
|
||||
if (!currentRegister) { alert('No hay caja abierta. Abra una caja primero.'); return; }
|
||||
if (!currentRegister) { showOpenRegisterModal(); return; }
|
||||
|
||||
paymentMethod = 'efectivo';
|
||||
const total = getTotal();
|
||||
@@ -1160,5 +1194,6 @@ const POS = (() => {
|
||||
showLastSale, openDrawer,
|
||||
showTicket, closeTicketModal, printTicket,
|
||||
connectThermal, thermalPrint,
|
||||
showOpenRegisterModal, closeOpenRegisterModal, openRegister,
|
||||
};
|
||||
})();
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<meta name="theme-color" content="#F5A623" />
|
||||
<script src="/pos/static/js/native-bridge.js" defer></script>
|
||||
|
||||
<link rel="stylesheet" href="/pos/static/css/pos.css">
|
||||
<link rel="stylesheet" href="/pos/static/css/pos.css?v=2">
|
||||
</head>
|
||||
|
||||
<body class="pos-shell" id="appBody">
|
||||
@@ -490,6 +490,35 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ================================================================
|
||||
OPEN REGISTER MODAL
|
||||
================================================================ -->
|
||||
<div class="modal-overlay" id="openRegisterModal">
|
||||
<div class="modal-pago" style="width:420px;">
|
||||
<div class="modal-header">
|
||||
<h3>Abrir Caja</h3>
|
||||
<button class="modal-close" onclick="POS.closeOpenRegisterModal()">✕</button>
|
||||
</div>
|
||||
<div style="padding:var(--space-6);">
|
||||
<div style="display:grid;grid-template-columns:1fr 1fr;gap:var(--space-3);margin-bottom:var(--space-4);">
|
||||
<div class="form-group">
|
||||
<label class="form-label">No. de Caja *</label>
|
||||
<input type="number" class="form-input" id="regNumber" value="1" min="1" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">Efectivo inicial *</label>
|
||||
<input type="number" class="form-input" id="regOpeningAmount" value="0" min="0" step="0.01" />
|
||||
</div>
|
||||
</div>
|
||||
<div id="registerOpenResult" style="min-height:1.5em;font-size:var(--text-body-sm);"></div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-ghost" onclick="POS.closeOpenRegisterModal()">Cancelar</button>
|
||||
<button class="btn btn-primary" onclick="POS.openRegister()">Abrir Caja</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ================================================================
|
||||
TOAST CONTAINER
|
||||
================================================================ -->
|
||||
@@ -504,7 +533,7 @@
|
||||
<script src="/pos/static/js/app-init.js" defer></script>
|
||||
<script src="/pos/static/js/push.js" defer></script>
|
||||
<script src="/pos/static/js/printer.js" defer></script>
|
||||
<script src="/pos/static/js/pos.js" defer></script>
|
||||
<script src="/pos/static/js/pos.js?v=2" defer></script>
|
||||
|
||||
<script>
|
||||
// Cancel sale button wiring
|
||||
|
||||
Reference in New Issue
Block a user