dicom evidence update
This commit is contained in:
25
app.py
25
app.py
@@ -178,7 +178,7 @@ def checkout():
|
|||||||
@login_required
|
@login_required
|
||||||
def dicom():
|
def dicom():
|
||||||
with sqlite3.connect(DB_FILE) as conn:
|
with sqlite3.connect(DB_FILE) as conn:
|
||||||
debtors = conn.execute('SELECT id, name, amount, notes, datetime(last_updated, "localtime") FROM dicom ORDER BY amount DESC').fetchall()
|
debtors = conn.execute('SELECT id, name, amount, notes, datetime(last_updated, "localtime"), image_url FROM dicom ORDER BY amount DESC').fetchall()
|
||||||
return render_template('dicom.html', active_page='dicom', user=current_user, debtors=debtors)
|
return render_template('dicom.html', active_page='dicom', user=current_user, debtors=debtors)
|
||||||
|
|
||||||
@app.route('/sales')
|
@app.route('/sales')
|
||||||
@@ -474,29 +474,26 @@ def update_dicom():
|
|||||||
name = data.get('name', '').strip()
|
name = data.get('name', '').strip()
|
||||||
amount = float(data.get('amount', 0))
|
amount = float(data.get('amount', 0))
|
||||||
notes = data.get('notes', '')
|
notes = data.get('notes', '')
|
||||||
action = data.get('action') # 'add' or 'pay'
|
image_url = data.get('image_url', '')
|
||||||
|
action = data.get('action')
|
||||||
|
|
||||||
if not name or amount <= 0:
|
if not name or amount <= 0:
|
||||||
return jsonify({"error": "Nombre y monto válidos son requeridos"}), 400
|
return jsonify({"error": "Nombre y monto válidos son requeridos"}), 400
|
||||||
|
|
||||||
# If we are giving them credit (Fiar), their balance drops into the negative
|
|
||||||
if action == 'add':
|
if action == 'add':
|
||||||
amount = -amount
|
amount = -amount
|
||||||
|
|
||||||
try:
|
with sqlite3.connect(DB_FILE) as conn:
|
||||||
with sqlite3.connect(DB_FILE) as conn:
|
cur = conn.cursor()
|
||||||
cur = conn.cursor()
|
cur.execute('''INSERT INTO dicom (name, amount, notes, image_url, last_updated)
|
||||||
# Upsert logic: if they exist, modify debt. If they don't, create them.
|
VALUES (?, ?, ?, ?, CURRENT_TIMESTAMP)
|
||||||
cur.execute('''INSERT INTO dicom (name, amount, notes, last_updated)
|
|
||||||
VALUES (?, ?, ?, CURRENT_TIMESTAMP)
|
|
||||||
ON CONFLICT(name) DO UPDATE SET
|
ON CONFLICT(name) DO UPDATE SET
|
||||||
amount = amount + excluded.amount,
|
amount = amount + excluded.amount,
|
||||||
notes = excluded.notes,
|
notes = excluded.notes,
|
||||||
last_updated = CURRENT_TIMESTAMP''', (name, amount, notes))
|
image_url = CASE WHEN excluded.image_url != "" THEN excluded.image_url ELSE dicom.image_url END,
|
||||||
conn.commit()
|
last_updated = CURRENT_TIMESTAMP''', (name, amount, notes, image_url))
|
||||||
return jsonify({"status": "success"}), 200
|
conn.commit()
|
||||||
except Exception as e:
|
return jsonify({"status": "success"}), 200
|
||||||
return jsonify({"error": str(e)}), 500
|
|
||||||
|
|
||||||
@app.route('/api/dicom/<int:debtor_id>', methods=['DELETE'])
|
@app.route('/api/dicom/<int:debtor_id>', methods=['DELETE'])
|
||||||
@login_required
|
@login_required
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{% extends "macros/base.html" %}
|
{% extends "macros/base.html" %}
|
||||||
{% from 'macros/modals.html' import confirm_modal, scanner_modal %}
|
{% from 'macros/modals.html' import confirm_modal, scanner_modal, render_receipt %}
|
||||||
|
|
||||||
{% block title %}Caja{% endblock %}
|
{% block title %}Caja{% endblock %}
|
||||||
|
|
||||||
@@ -16,54 +16,11 @@
|
|||||||
-moz-appearance: textfield;
|
-moz-appearance: textfield;
|
||||||
appearance: textfield;
|
appearance: textfield;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media print {
|
|
||||||
body * {
|
|
||||||
visibility: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
#receipt-print-zone, #receipt-print-zone * {
|
|
||||||
visibility: visible;
|
|
||||||
}
|
|
||||||
|
|
||||||
#receipt-print-zone {
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
width: 58mm;
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
display: block !important;
|
|
||||||
font-family: 'Courier New', Courier, monospace;
|
|
||||||
font-size: 10px;
|
|
||||||
color: #000;
|
|
||||||
}
|
|
||||||
|
|
||||||
.container-fluid, .main, body {
|
|
||||||
margin: 0 !important;
|
|
||||||
padding: 0 !important;
|
|
||||||
background: #fff !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.receipt-table {
|
|
||||||
width: 100%;
|
|
||||||
border-collapse: collapse;
|
|
||||||
font-family: monospace;
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.receipt-header {
|
|
||||||
text-align: center;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
border-bottom: 1px dashed #000;
|
|
||||||
padding-bottom: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
{{ render_receipt() }}
|
||||||
{% call confirm_modal('removeConfirmModal', 'Quitar Producto', 'btn-danger-discord', 'Quitar', 'executeRemoveItem()') %}
|
{% call confirm_modal('removeConfirmModal', 'Quitar Producto', 'btn-danger-discord', 'Quitar', 'executeRemoveItem()') %}
|
||||||
¿Estás seguro de que quieres quitar <strong id="removeItemName"></strong> del carrito?
|
¿Estás seguro de que quieres quitar <strong id="removeItemName"></strong> del carrito?
|
||||||
{% endcall %}
|
{% endcall %}
|
||||||
@@ -117,41 +74,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="receipt-print-zone" class="d-none d-print-block">
|
|
||||||
<div class="receipt-header">
|
|
||||||
<h3 style="margin: 0; font-weight: 800;">SekiPOS</h3>
|
|
||||||
<div style="font-size: 10px; margin-bottom: 5px;">Comprobante de Venta</div>
|
|
||||||
<div style="font-size: 11px; font-weight: bold;">
|
|
||||||
Ticket Nº <span id="receipt-ticket-id"></span>
|
|
||||||
</div>
|
|
||||||
<div id="receipt-date" style="font-size: 11px;"></div>
|
|
||||||
</div>
|
|
||||||
<table class="receipt-table">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th style="width: 15%;">Cant</th>
|
|
||||||
<th style="width: 60%; padding-left: 5px;">Desc</th>
|
|
||||||
<th style="width: 25%; text-align: right;">Total</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody id="receipt-items-print">
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<div class="receipt-total-row d-flex justify-content-between pt-2">
|
|
||||||
<span>TOTAL:</span>
|
|
||||||
<span id="receipt-total-print"></span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="d-flex justify-content-between">
|
|
||||||
<span>RECIBIDO:</span>
|
|
||||||
<span id="receipt-paid-print"></span>
|
|
||||||
</div>
|
|
||||||
<div class="d-flex justify-content-between">
|
|
||||||
<span>VUELTO:</span>
|
|
||||||
<span id="receipt-change-print"></span>
|
|
||||||
</div>
|
|
||||||
<div style="text-align: center; margin-top: 20px; font-size: 10px;">¡Gracias por su compra!</div>
|
|
||||||
</div>
|
|
||||||
<div class="modal fade" id="successModal" tabindex="-1">
|
<div class="modal fade" id="successModal" tabindex="-1">
|
||||||
<div class="modal-dialog modal-dialog-centered">
|
<div class="modal-dialog modal-dialog-centered">
|
||||||
<div class="modal-content border-success">
|
<div class="modal-content border-success">
|
||||||
@@ -488,7 +411,6 @@
|
|||||||
|
|
||||||
document.getElementById('grand-total').innerText = clp.format(total);
|
document.getElementById('grand-total').innerText = clp.format(total);
|
||||||
|
|
||||||
// This will actually run now
|
|
||||||
saveCart();
|
saveCart();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,12 +27,29 @@
|
|||||||
<label class="small text-muted mb-1">Monto (CLP)</label>
|
<label class="small text-muted mb-1">Monto (CLP)</label>
|
||||||
<input type="number" id="dicom-amount" class="form-control" placeholder="Ej: 5000">
|
<input type="number" id="dicom-amount" class="form-control" placeholder="Ej: 5000">
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-4">
|
|
||||||
|
<div class="mb-3">
|
||||||
<label class="small text-muted mb-1">Nota (Opcional)</label>
|
<label class="small text-muted mb-1">Nota (Opcional)</label>
|
||||||
<input type="text" id="dicom-notes" class="form-control" placeholder="Ej: Pan y bebida"
|
<input type="text" id="dicom-notes" class="form-control" placeholder="Ej: Pan y bebida"
|
||||||
onkeydown="if(event.key === 'Enter') submitDicom('add')">
|
onkeydown="if(event.key === 'Enter') submitDicom('add')">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-4">
|
||||||
|
<label class="small text-muted mb-1">Foto / Comprobante</label>
|
||||||
|
<div class="input-group">
|
||||||
|
<input type="text" id="dicom-image-url" class="form-control" placeholder="URL de imagen" readonly>
|
||||||
|
<input type="file" id="dicom-camera-input" accept="image/*" capture="environment" style="display: none;"
|
||||||
|
onchange="handleDicomUpload(this)">
|
||||||
|
<button class="btn btn-outline-secondary" type="button"
|
||||||
|
onclick="document.getElementById('dicom-camera-input').click()">
|
||||||
|
<i class="bi bi-camera"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div id="dicom-img-preview-container" class="mt-2 d-none">
|
||||||
|
<img id="dicom-img-preview" src="" class="img-thumbnail" style="max-height: 100px;">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="d-flex flex-column gap-2">
|
<div class="d-flex flex-column gap-2">
|
||||||
<button class="btn btn-danger py-2 fw-bold" onclick="submitDicom('add')">
|
<button class="btn btn-danger py-2 fw-bold" onclick="submitDicom('add')">
|
||||||
<i class="bi bi-cart-plus me-1"></i> Fiar (Sumar Deuda)
|
<i class="bi bi-cart-plus me-1"></i> Fiar (Sumar Deuda)
|
||||||
@@ -57,6 +74,7 @@
|
|||||||
<table class="table mb-0" id="dicom-table">
|
<table class="table mb-0" id="dicom-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
<th>Foto</th>
|
||||||
<th>Nombre</th>
|
<th>Nombre</th>
|
||||||
<th>Deuda Total</th>
|
<th>Deuda Total</th>
|
||||||
<th>Última Nota</th>
|
<th>Última Nota</th>
|
||||||
@@ -67,6 +85,16 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
{% for d in debtors %}
|
{% for d in debtors %}
|
||||||
<tr>
|
<tr>
|
||||||
|
<td>
|
||||||
|
{% if d[5] %}
|
||||||
|
<img src="{{ d[5] }}" class="rounded" style="width: 40px; height: 40px; object-fit: cover; cursor: pointer;"
|
||||||
|
onclick="window.open(this.src, '_blank')">
|
||||||
|
{% else %}
|
||||||
|
<div class="bg-secondary rounded" style="width: 40px; height: 40px; display: flex; align-items: center; justify-content: center; opacity: 0.3;">
|
||||||
|
<i class="bi bi-image text-white"></i>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
<td class="fw-bold">{{ d[1] }}</td>
|
<td class="fw-bold">{{ d[1] }}</td>
|
||||||
<td class="fw-bold price-cell" data-value="{{ d[2] }}"></td>
|
<td class="fw-bold price-cell" data-value="{{ d[2] }}"></td>
|
||||||
<td class="text-muted small">{{ d[3] }}</td>
|
<td class="text-muted small">{{ d[3] }}</td>
|
||||||
@@ -112,14 +140,62 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function clearDicomForm() {
|
function compressImage(file, maxWidth, quality) {
|
||||||
document.getElementById('dicom-name').value = '';
|
return new Promise((resolve, reject) => {
|
||||||
document.getElementById('dicom-amount').value = '';
|
const reader = new FileReader();
|
||||||
document.getElementById('dicom-notes').value = '';
|
reader.readAsDataURL(file);
|
||||||
document.getElementById('dicom-name').focus();
|
reader.onload = event => {
|
||||||
|
const img = new Image();
|
||||||
|
img.src = event.target.result;
|
||||||
|
img.onload = () => {
|
||||||
|
const canvas = document.createElement('canvas');
|
||||||
|
let width = img.width;
|
||||||
|
let height = img.height;
|
||||||
|
if (width > maxWidth) {
|
||||||
|
height = Math.round((height * maxWidth) / width);
|
||||||
|
width = maxWidth;
|
||||||
|
}
|
||||||
|
canvas.width = width;
|
||||||
|
canvas.height = height;
|
||||||
|
const ctx = canvas.getContext('2d');
|
||||||
|
ctx.drawImage(img, 0, 0, width, height);
|
||||||
|
canvas.toBlob(blob => resolve(blob), 'image/jpeg', quality);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Search Filter
|
async function handleDicomUpload(input) {
|
||||||
|
const name = document.getElementById('dicom-name').value;
|
||||||
|
if (!name) {
|
||||||
|
alert("Primero ingresa un nombre para asociar la foto.");
|
||||||
|
input.value = '';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const file = input.files[0];
|
||||||
|
if (!file) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const compressedBlob = await compressImage(file, 800, 0.7);
|
||||||
|
const formData = new FormData();
|
||||||
|
// Use a unique name for the file based on the debtor
|
||||||
|
formData.append('image', compressedBlob, `debt_${name}_${Date.now()}.jpg`);
|
||||||
|
formData.append('barcode', `debt_${name}`); // Reusing the barcode field as a prefix
|
||||||
|
|
||||||
|
const res = await fetch('/upload_image', { method: 'POST', body: formData });
|
||||||
|
const data = await res.json();
|
||||||
|
|
||||||
|
if (res.ok) {
|
||||||
|
document.getElementById('dicom-image-url').value = data.image_url;
|
||||||
|
document.getElementById('dicom-img-preview').src = data.image_url;
|
||||||
|
document.getElementById('dicom-img-preview-container').classList.remove('d-none');
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
alert("Error procesando imagen.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function filterDicom() {
|
function filterDicom() {
|
||||||
const q = document.getElementById('dicom-search').value.toLowerCase();
|
const q = document.getElementById('dicom-search').value.toLowerCase();
|
||||||
document.querySelectorAll('#dicom-table tbody tr').forEach(row => {
|
document.querySelectorAll('#dicom-table tbody tr').forEach(row => {
|
||||||
@@ -139,6 +215,7 @@
|
|||||||
const name = document.getElementById('dicom-name').value;
|
const name = document.getElementById('dicom-name').value;
|
||||||
const amount = document.getElementById('dicom-amount').value;
|
const amount = document.getElementById('dicom-amount').value;
|
||||||
const notes = document.getElementById('dicom-notes').value;
|
const notes = document.getElementById('dicom-notes').value;
|
||||||
|
const image_url = document.getElementById('dicom-image-url').value; // Added
|
||||||
|
|
||||||
if (!name || amount <= 0) {
|
if (!name || amount <= 0) {
|
||||||
alert('Ingresa un nombre y monto válido.');
|
alert('Ingresa un nombre y monto válido.');
|
||||||
@@ -149,17 +226,20 @@
|
|||||||
const res = await fetch('/api/dicom/update', {
|
const res = await fetch('/api/dicom/update', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ name, amount, notes, action })
|
body: JSON.stringify({ name, amount, notes, action, image_url }) // Added image_url
|
||||||
});
|
});
|
||||||
|
if (res.ok) window.location.reload();
|
||||||
|
} catch (e) { alert("Error de conexión."); }
|
||||||
|
}
|
||||||
|
|
||||||
if (res.ok) {
|
// UPDATE your existing clearDicomForm
|
||||||
window.location.reload();
|
function clearDicomForm() {
|
||||||
} else {
|
document.getElementById('dicom-name').value = '';
|
||||||
alert('Error actualizando la base de datos.');
|
document.getElementById('dicom-amount').value = '';
|
||||||
}
|
document.getElementById('dicom-notes').value = '';
|
||||||
} catch (e) {
|
document.getElementById('dicom-image-url').value = ''; // Added
|
||||||
alert("Error de conexión.");
|
document.getElementById('dicom-img-preview-container').classList.add('d-none'); // Added
|
||||||
}
|
document.getElementById('dicom-name').focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function forgiveDebt(id, name) {
|
async function forgiveDebt(id, name) {
|
||||||
|
|||||||
@@ -44,3 +44,60 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
||||||
|
{% macro render_receipt(id_suffix="") %}
|
||||||
|
<div id="receipt-print-zone{{ id_suffix }}" class="d-none d-print-block">
|
||||||
|
<style>
|
||||||
|
@media print {
|
||||||
|
body * { visibility: hidden; }
|
||||||
|
#receipt-print-zone{{ id_suffix }}, #receipt-print-zone{{ id_suffix }} * { visibility: visible; }
|
||||||
|
#receipt-print-zone{{ id_suffix }} {
|
||||||
|
position: absolute; left: 0; top: 0; width: 80mm;
|
||||||
|
padding: 5mm; margin: 0; display: block !important;
|
||||||
|
font-family: 'Courier New', Courier, monospace; font-size: 10px; color: #000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.receipt-table { width: 100%; border-collapse: collapse; font-family: monospace; font-size: 12px; }
|
||||||
|
.receipt-header { text-align: center; margin-bottom: 10px; border-bottom: 1px dashed #000; padding-bottom: 5px; }
|
||||||
|
.receipt-total-row { border-top: 1px dashed #000; margin-top: 5px; padding-top: 5px; font-weight: bold; }
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="receipt-header">
|
||||||
|
<h3 style="margin: 0; font-weight: 800;">SekiPOS</h3>
|
||||||
|
<div style="font-size: 10px; margin-bottom: 5px;" id="receipt-type{{ id_suffix }}">Comprobante de Venta</div>
|
||||||
|
<div style="font-size: 11px; font-weight: bold;">
|
||||||
|
Ticket Nº <span id="receipt-ticket-id{{ id_suffix }}"></span>
|
||||||
|
</div>
|
||||||
|
<div id="receipt-date{{ id_suffix }}" style="font-size: 11px;"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<table class="receipt-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th style="width: 15%; text-align: left;">Cant</th>
|
||||||
|
<th style="width: 60%; padding-left: 5px; text-align: left;">Desc</th>
|
||||||
|
<th style="width: 25%; text-align: right;">Total</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="receipt-items-print{{ id_suffix }}"></tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<div class="receipt-total-row d-flex justify-content-between">
|
||||||
|
<span>TOTAL:</span>
|
||||||
|
<span id="receipt-total-print{{ id_suffix }}"></span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="receipt-payment-info{{ id_suffix }}">
|
||||||
|
<div class="d-flex justify-content-between">
|
||||||
|
<span>RECIBIDO:</span>
|
||||||
|
<span id="receipt-paid-print{{ id_suffix }}"></span>
|
||||||
|
</div>
|
||||||
|
<div class="d-flex justify-content-between">
|
||||||
|
<span>VUELTO:</span>
|
||||||
|
<span id="receipt-change-print{{ id_suffix }}"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="text-align: center; margin-top: 20px; font-size: 10px;">¡Gracias por su compra!</div>
|
||||||
|
</div>
|
||||||
|
{% endmacro %}
|
||||||
@@ -1,71 +1,14 @@
|
|||||||
{% extends "macros/base.html" %}
|
{% extends "macros/base.html" %}
|
||||||
{% from 'macros/modals.html' import confirm_modal, scanner_modal %}
|
{% from 'macros/modals.html' import confirm_modal, scanner_modal, render_receipt %}
|
||||||
|
|
||||||
{% block title %}Ventas{% endblock %}
|
{% block title %}Ventas{% endblock %}
|
||||||
|
|
||||||
{% block head %}
|
{% block head %}
|
||||||
<style>
|
<!--HEAD-->
|
||||||
@media print {
|
|
||||||
body * { visibility: hidden; }
|
|
||||||
#receipt-print-zone, #receipt-print-zone * { visibility: visible; }
|
|
||||||
#receipt-print-zone {
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
width: 58mm;
|
|
||||||
margin: 0;
|
|
||||||
padding: 5mm;
|
|
||||||
display: block !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
|
||||||
.table td, .table th {
|
|
||||||
padding: 0.5rem 0.25rem;
|
|
||||||
font-size: 0.85rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-sm span {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.table th:last-child,
|
|
||||||
.table td:last-child {
|
|
||||||
width: 1%;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
{{ render_receipt() }}
|
||||||
<div id="receipt-print-zone" class="d-none d-print-block">
|
|
||||||
<div class="receipt-header" style="text-align: center; margin-bottom: 10px; border-bottom: 1px dashed #000; padding-bottom: 5px;">
|
|
||||||
<h3 style="margin: 0; font-weight: 800;">SekiPOS</h3>
|
|
||||||
<div style="font-size: 10px; margin-bottom: 5px;">Re-impresión de Comprobante</div>
|
|
||||||
<div style="font-size: 11px; font-weight: bold;">
|
|
||||||
Ticket Nº <span id="receipt-ticket-id"></span>
|
|
||||||
</div>
|
|
||||||
<div id="receipt-date" style="font-size: 11px;"></div>
|
|
||||||
</div>
|
|
||||||
<table class="receipt-table" style="width: 100%; border-collapse: collapse; font-family: monospace; font-size: 12px;">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th style="width: 15%; text-align: left;">Cant</th>
|
|
||||||
<th style="width: 60%; padding-left: 5px; text-align: left;">Desc</th>
|
|
||||||
<th style="width: 25%; text-align: right;">Total</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody id="receipt-items-print">
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<div class="receipt-total-row d-flex justify-content-between pt-2" style="display: flex; justify-content: space-between; font-weight: bold; border-top: 1px dashed #000; margin-top: 5px;">
|
|
||||||
<span>TOTAL:</span>
|
|
||||||
<span id="receipt-total-print"></span>
|
|
||||||
</div>
|
|
||||||
<div style="text-align: center; margin-top: 20px; font-size: 10px;">¡Gracias por su compra!</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row g-3 mb-3">
|
<div class="row g-3 mb-3">
|
||||||
<div class="col-12 col-md-4">
|
<div class="col-12 col-md-4">
|
||||||
@@ -286,6 +229,7 @@
|
|||||||
document.getElementById('receipt-ticket-id').innerText = id;
|
document.getElementById('receipt-ticket-id').innerText = id;
|
||||||
document.getElementById('receipt-total-print').innerText = clp.format(total);
|
document.getElementById('receipt-total-print').innerText = clp.format(total);
|
||||||
document.getElementById('receipt-date').innerText = new Date(rawDate + " UTC").toLocaleString('es-CL');
|
document.getElementById('receipt-date').innerText = new Date(rawDate + " UTC").toLocaleString('es-CL');
|
||||||
|
document.getElementById('receipt-payment-info').style.display = 'none';
|
||||||
|
|
||||||
window.print();
|
window.print();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|||||||
Reference in New Issue
Block a user