diff --git a/src/page/cajas.js b/src/page/cajas.js
index 4470c6d..f0f07eb 100644
--- a/src/page/cajas.js
+++ b/src/page/cajas.js
@@ -22,6 +22,11 @@ PAGES.cajas = {
var render_foto = safeuuid();
var btn_volver = safeuuid();
var btn_borrar = safeuuid();
+ var btn_editar = safeuuid();
+ var btn_guardar = safeuuid();
+ var btn_cancelar = safeuuid();
+ var div_buttons = safeuuid();
+ var isEditMode = false;
container.innerHTML = html`
Movimiento de Caja
@@ -44,23 +49,34 @@ PAGES.cajas = {
-
-
+
+
+
+
+
+
+
`;
// Load transaction data
+ var movimientoData = null;
+ var resized = '';
+
DB.get('cajas_movimientos', movimientoId).then((data) => {
function load_data(data) {
if (!data) return;
+ movimientoData = data;
+
// Format datetime for datetime-local input
var fechaValue = data['Fecha'] || '';
if (fechaValue) {
@@ -82,17 +98,25 @@ PAGES.cajas = {
document.getElementById(field_notas).value = data['Notas'] || '';
// Load photo attachment if present
- DB.getAttachment('cajas_movimientos', movimientoId, 'foto')
- .then((durl) => {
- if (durl) {
- document.getElementById(render_foto).src = durl;
- } else {
- document.getElementById(render_foto).style.display = 'none';
- }
- })
- .catch(() => {
- document.getElementById(render_foto).style.display = 'none';
- });
+ if (DB.getAttachment) {
+ DB.getAttachment('cajas_movimientos', movimientoId, 'foto')
+ .then((durl) => {
+ try {
+ if (durl) {
+ var fotoElement = document.getElementById(render_foto);
+ if (fotoElement) {
+ fotoElement.src = durl;
+ fotoElement.style.display = 'block';
+ }
+ }
+ } catch (e) {
+ console.warn('Error setting foto:', e);
+ }
+ })
+ .catch((e) => {
+ console.warn('Error loading foto:', e);
+ });
+ }
}
if (typeof data === 'string') {
@@ -110,24 +134,190 @@ PAGES.cajas = {
}
});
+ // Enable edit mode
+ function enableEditMode() {
+ isEditMode = true;
+ document.getElementById(field_fecha).disabled = false;
+ document.getElementById(field_tipo).disabled = false;
+ document.getElementById(field_monto).disabled = false;
+ document.getElementById(field_persona).disabled = false;
+ document.getElementById(field_notas).disabled = false;
+ document.getElementById(render_foto).style.cursor = 'pointer';
+
+ document.getElementById(btn_editar).style.display = 'none';
+ document.getElementById(btn_volver).style.display = 'none';
+ document.getElementById(btn_guardar).style.display = 'inline-block';
+ document.getElementById(btn_cancelar).style.display = 'inline-block';
+ document.getElementById(btn_borrar).style.display = 'none';
+ }
+
+ // Disable edit mode
+ function disableEditMode() {
+ isEditMode = false;
+ document.getElementById(field_fecha).disabled = true;
+ document.getElementById(field_tipo).disabled = true;
+ document.getElementById(field_monto).disabled = true;
+ document.getElementById(field_persona).disabled = true;
+ document.getElementById(field_notas).disabled = true;
+ document.getElementById(render_foto).style.cursor = 'default';
+
+ document.getElementById(btn_editar).style.display = checkRole('cajas:edit') ? 'inline-block' : 'none';
+ document.getElementById(btn_volver).style.display = 'inline-block';
+ document.getElementById(btn_guardar).style.display = 'none';
+ document.getElementById(btn_cancelar).style.display = 'none';
+ document.getElementById(btn_borrar).style.display = checkRole('cajas:edit') ? 'inline-block' : 'none';
+ }
+
+ // Button handlers
document.getElementById(btn_volver).onclick = () => {
setUrlHash('cajas,' + cajaId);
};
- // Show delete button only if user has edit permission
- if (checkRole('cajas:edit')) {
- document.getElementById(btn_borrar).style.display = 'inline-block';
- document.getElementById(btn_borrar).onclick = () => {
- if (confirm('¿Quieres borrar este movimiento?')) {
- DB.del('cajas_movimientos', movimientoId).then(() => {
- toastr.success('Movimiento borrado!');
- setTimeout(() => {
- setUrlHash('cajas,' + cajaId);
- }, SAVE_WAIT);
- });
+ document.getElementById(btn_editar).onclick = () => {
+ enableEditMode();
+ };
+
+ document.getElementById(btn_cancelar).onclick = () => {
+ disableEditMode();
+ // Reload data to discard changes
+ DB.get('cajas_movimientos', movimientoId).then((data) => {
+ if (typeof data === 'string') {
+ TS_decrypt(data, SECRET, (d) => { load_data(d); }, 'cajas_movimientos', movimientoId);
+ } else {
+ load_data(data || {});
}
+ });
+ };
+
+ // Photo click handler
+ document.getElementById(render_foto).onclick = () => {
+ if (isEditMode) {
+ // In edit mode: upload new photo
+ document.getElementById(field_foto).click();
+ } else {
+ // In read mode: open photo in new tab
+ var fotoElement = document.getElementById(render_foto);
+ if (fotoElement && fotoElement.src) {
+ window.open(fotoElement.src, '_blank');
+ }
+ }
+ };
+
+ document.getElementById(field_foto).addEventListener('change', function (e) {
+ const file = e.target.files[0];
+ if (!file) return;
+
+ const reader = new FileReader();
+ reader.onload = function (ev) {
+ const url = ev.target.result;
+ document.getElementById(render_foto).src = url;
+ resized = url;
};
+ reader.readAsDataURL(file);
+ });
+
+ // Save handler
+ document.getElementById(btn_guardar).onclick = () => {
+ var guardarBtn = document.getElementById(btn_guardar);
+ if (guardarBtn.disabled) return;
+
+ var tipo = document.getElementById(field_tipo).value;
+ var monto = parseFloat(document.getElementById(field_monto).value);
+ var fecha = document.getElementById(field_fecha).value;
+ var notas = document.getElementById(field_notas).value;
+
+ // Validation
+ if (!tipo) {
+ alert('Por favor selecciona el tipo de movimiento');
+ return;
+ }
+ if (!monto || monto <= 0) {
+ alert('Por favor ingresa un monto válido');
+ return;
+ }
+ if (!fecha) {
+ alert('Por favor selecciona una fecha');
+ return;
+ }
+
+ guardarBtn.disabled = true;
+ guardarBtn.style.opacity = '0.5';
+
+ var fechaISO = new Date(fecha).toISOString();
+
+ var data = {
+ Caja: movimientoData.Caja,
+ Fecha: fechaISO,
+ Tipo: tipo,
+ Monto: monto,
+ Persona: movimientoData.Persona,
+ Notas: notas,
+ };
+
+ // Preserve transfer destination if applicable
+ if (movimientoData.CajaDestino) {
+ data.CajaDestino = movimientoData.CajaDestino;
+ }
+
+ document.getElementById('actionStatus').style.display = 'block';
+ DB.put('cajas_movimientos', movimientoId, data)
+ .then(() => {
+ // Save photo attachment if a new one was provided
+ var attachPromise = Promise.resolve(true);
+ if (resized && resized.indexOf('data:') === 0) {
+ attachPromise = DB.putAttachment(
+ 'cajas_movimientos',
+ movimientoId,
+ 'foto',
+ resized,
+ 'image/png'
+ );
+ }
+
+ attachPromise
+ .then(() => {
+ toastr.success('Movimiento actualizado!');
+ disableEditMode();
+ document.getElementById('actionStatus').style.display = 'none';
+ // Reload to show updates
+ setTimeout(() => {
+ PAGES.cajas.movimiento(cajaId, movimientoId);
+ }, SAVE_WAIT);
+ })
+ .catch((e) => {
+ console.warn('Error saving:', e);
+ document.getElementById('actionStatus').style.display = 'none';
+ guardarBtn.disabled = false;
+ guardarBtn.style.opacity = '1';
+ toastr.error('Error al guardar el movimiento');
+ });
+ })
+ .catch((e) => {
+ console.warn('DB.put error', e);
+ document.getElementById('actionStatus').style.display = 'none';
+ guardarBtn.disabled = false;
+ guardarBtn.style.opacity = '1';
+ toastr.error('Error al guardar el movimiento');
+ });
+ };
+
+ // Show/hide edit button based on permissions
+ if (checkRole('cajas:edit')) {
+ document.getElementById(btn_editar).style.display = 'inline-block';
+ document.getElementById(btn_borrar).style.display = 'inline-block';
}
+
+ // Delete handler
+ document.getElementById(btn_borrar).onclick = () => {
+ if (confirm('¿Quieres borrar este movimiento?')) {
+ DB.del('cajas_movimientos', movimientoId).then(() => {
+ toastr.success('Movimiento borrado!');
+ setTimeout(() => {
+ setUrlHash('cajas,' + cajaId);
+ }, SAVE_WAIT);
+ });
+ }
+ };
},
// Create new transaction (movimiento)
@@ -162,9 +352,9 @@ PAGES.cajas = {
Tipo de Movimiento