feat: add companion2 support, fix UI rendering, and update test data generator
This commit is contained in:
10
database.py
10
database.py
@@ -246,6 +246,7 @@ def init_db():
|
||||
worker_id INTEGER NOT NULL,
|
||||
worker_comision BOOLEAN DEFAULT 1,
|
||||
companion_id INTEGER,
|
||||
companion2_id INTEGER,
|
||||
modulo_id INTEGER NOT NULL,
|
||||
fecha DATE NOT NULL,
|
||||
hora_entrada TEXT NOT NULL,
|
||||
@@ -253,6 +254,7 @@ def init_db():
|
||||
companion_hora_entrada TEXT,
|
||||
companion_hora_salida TEXT,
|
||||
companion_comision BOOLEAN DEFAULT 0,
|
||||
companion2_comision BOOLEAN DEFAULT 0,
|
||||
venta_debito INTEGER DEFAULT 0,
|
||||
venta_credito INTEGER DEFAULT 0,
|
||||
venta_mp INTEGER DEFAULT 0,
|
||||
@@ -265,6 +267,7 @@ def init_db():
|
||||
observaciones TEXT,
|
||||
FOREIGN KEY (worker_id) REFERENCES workers(id),
|
||||
FOREIGN KEY (companion_id) REFERENCES workers(id),
|
||||
FOREIGN KEY (companion2_id) REFERENCES workers(id),
|
||||
FOREIGN KEY (modulo_id) REFERENCES modulos(id))''')
|
||||
c.execute('''CREATE TABLE IF NOT EXISTS rendicion_items
|
||||
(id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
@@ -283,6 +286,13 @@ def init_db():
|
||||
except sqlite3.OperationalError:
|
||||
pass # column already exists
|
||||
|
||||
# Migrate: add companion2 columns
|
||||
for col in ['companion2_id', 'companion2_comision']:
|
||||
try:
|
||||
c.execute(f"ALTER TABLE rendiciones ADD COLUMN {col}")
|
||||
except sqlite3.OperationalError:
|
||||
pass
|
||||
|
||||
c.execute("SELECT id FROM workers WHERE is_admin = 1")
|
||||
if not c.fetchone():
|
||||
admin_pass = generate_password_hash("admin123")
|
||||
|
||||
@@ -122,14 +122,30 @@ def generar_historico_definitivo(dias_atras=180):
|
||||
companion_id = None
|
||||
comp_in, comp_out = None, None
|
||||
companion_comision = 0
|
||||
companion2_id = None
|
||||
companion2_comision = 0
|
||||
if random.random() < 0.70:
|
||||
posibles_comp = [w for w in todos_los_trabajadores if w != worker_id]
|
||||
posibles_comp = [w for w in workers_modulo if w != worker_id]
|
||||
if posibles_comp:
|
||||
companion_id = random.choice(posibles_comp)
|
||||
comp_in, comp_out = hora_entrada, hora_salida
|
||||
comp_tipo = workers_tipo.get(companion_id, "Part Time")
|
||||
companion_comision = 1 if comp_tipo == "Full Time" else random.choice([0, 1])
|
||||
|
||||
# Acompañante 2 (25% probability if companion 1 is present)
|
||||
if random.random() < 0.25:
|
||||
posibles_comp2 = [w for w in posibles_comp if w != companion_id]
|
||||
if posibles_comp2:
|
||||
companion2_id = random.choice(posibles_comp2)
|
||||
comp2_tipo = workers_tipo.get(companion2_id, "Part Time")
|
||||
companion2_comision = 1 if comp2_tipo == "Full Time" else random.choice([0, 1])
|
||||
|
||||
# If there is no companion, comision should be disabled (0)
|
||||
if companion_id is None:
|
||||
companion_comision = 0
|
||||
if companion2_id is None:
|
||||
companion2_comision = 0
|
||||
|
||||
num_prods = random.randint(1, 5)
|
||||
prods_elegidos = random.sample(productos, min(num_prods, len(productos)))
|
||||
items_a_insertar = []
|
||||
@@ -171,16 +187,16 @@ def generar_historico_definitivo(dias_atras=180):
|
||||
|
||||
c.execute('''
|
||||
INSERT INTO rendiciones
|
||||
(worker_id, worker_comision, companion_id, modulo_id, fecha,
|
||||
(worker_id, worker_comision, companion_id, companion2_id, modulo_id, fecha,
|
||||
hora_entrada, hora_salida, companion_hora_entrada, companion_hora_salida,
|
||||
companion_comision,
|
||||
companion_comision, companion2_comision,
|
||||
venta_debito, venta_credito, venta_mp, venta_efectivo,
|
||||
boletas_debito, boletas_credito, boletas_mp, boletas_efectivo,
|
||||
gastos, observaciones)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
''', (worker_id, worker_comision, companion_id, modulo_id, fecha_str,
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
''', (worker_id, worker_comision, companion_id, companion2_id, modulo_id, fecha_str,
|
||||
hora_entrada, hora_salida, comp_in, comp_out,
|
||||
companion_comision,
|
||||
companion_comision, companion2_comision,
|
||||
debito, credito, mp, efectivo,
|
||||
b_debito, b_credito, b_mp, b_efectivo,
|
||||
gastos, tipo_registro))
|
||||
|
||||
@@ -69,6 +69,7 @@ class Rendicion(db.Model):
|
||||
worker_id = db.Column(db.Integer, db.ForeignKey('workers.id'), nullable=False)
|
||||
worker_comision = db.Column(db.Boolean, default=True)
|
||||
companion_id = db.Column(db.Integer, db.ForeignKey('workers.id'))
|
||||
companion2_id = db.Column(db.Integer, db.ForeignKey('workers.id'))
|
||||
modulo_id = db.Column(db.Integer, db.ForeignKey('modulos.id'), nullable=False)
|
||||
fecha = db.Column(db.Date, nullable=False)
|
||||
hora_entrada = db.Column(db.String, nullable=False)
|
||||
@@ -76,6 +77,7 @@ class Rendicion(db.Model):
|
||||
companion_hora_entrada = db.Column(db.String)
|
||||
companion_hora_salida = db.Column(db.String)
|
||||
companion_comision = db.Column(db.Boolean, default=False)
|
||||
companion2_comision = db.Column(db.Boolean, default=False)
|
||||
venta_debito = db.Column(db.Integer, default=0)
|
||||
venta_credito = db.Column(db.Integer, default=0)
|
||||
venta_mp = db.Column(db.Integer, default=0)
|
||||
|
||||
@@ -2,3 +2,4 @@ Flask==3.1.3
|
||||
Flask-SQLAlchemy==3.1.1
|
||||
Werkzeug==3.1.6
|
||||
SQLAlchemy==2.0.45
|
||||
openpyxl==3.1.5
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from flask import Blueprint, render_template, request, redirect, url_for, flash, session, jsonify
|
||||
from flask import Blueprint, render_template, request, redirect, url_for, flash, session, jsonify, send_file
|
||||
from werkzeug.security import generate_password_hash
|
||||
from sqlalchemy import func, and_
|
||||
from sqlalchemy.exc import IntegrityError
|
||||
@@ -489,8 +489,18 @@ def edit_rendicion(id):
|
||||
if companion_id and worker_id == companion_id:
|
||||
flash("Error: No puedes asignarte a ti mismo como acompañante.", "danger")
|
||||
return redirect(url_for('admin.admin_rendiciones'))
|
||||
companion2_id = request.form.get('companion2_id') or None
|
||||
if companion2_id and worker_id == companion2_id:
|
||||
flash("Error: No puedes asignarte a ti mismo como acompañante 2.", "danger")
|
||||
return redirect(url_for('admin.admin_rendiciones'))
|
||||
worker_comision = 1 if request.form.get('worker_comision') else 0
|
||||
companion_comision = 1 if request.form.get('companion_comision') else 0
|
||||
companion2_comision = 1 if request.form.get('companion2_comision') else 0
|
||||
|
||||
if not companion_id:
|
||||
companion_comision = 0
|
||||
if not companion2_id:
|
||||
companion2_comision = 0
|
||||
|
||||
def clean_money(val):
|
||||
if not val:
|
||||
@@ -527,8 +537,10 @@ def edit_rendicion(id):
|
||||
rendicion.worker_id = int(worker_id)
|
||||
rendicion.modulo_id = int(modulo_id)
|
||||
rendicion.companion_id = int(companion_id) if companion_id else None
|
||||
rendicion.companion2_id = int(companion2_id) if companion2_id else None
|
||||
rendicion.worker_comision = bool(worker_comision)
|
||||
rendicion.companion_comision = bool(companion_comision)
|
||||
rendicion.companion2_comision = bool(companion2_comision)
|
||||
rendicion.venta_debito = debito
|
||||
rendicion.venta_credito = credito
|
||||
rendicion.venta_mp = mp
|
||||
@@ -653,3 +665,129 @@ def report_modulo_calculo_iva(modulo_id):
|
||||
workers_list=workers_list, worker_actual=worker_id,
|
||||
fecha_inicio=fecha_inicio, fecha_fin=fecha_fin,
|
||||
anios_disponibles=anios_list)
|
||||
|
||||
|
||||
@admin_bp.route('/reportes/modulo/<int:modulo_id>/exportar_excel')
|
||||
@admin_required
|
||||
def report_modulo_exportar_excel(modulo_id):
|
||||
fecha_inicio, fecha_fin, worker_id = get_report_params()
|
||||
data = report_service.get_modulo_periodo_data(modulo_id, fecha_inicio, fecha_fin, worker_id)
|
||||
mod_name, _, _ = report_service.get_modulo_workers_and_anios(modulo_id)
|
||||
|
||||
import io
|
||||
import openpyxl
|
||||
from openpyxl.styles import Font, Alignment, PatternFill, Border, Side
|
||||
from openpyxl.utils import get_column_letter
|
||||
|
||||
wb = openpyxl.Workbook()
|
||||
ws = wb.active
|
||||
ws.title = "Detalle Ventas"
|
||||
|
||||
thin = Side(style='thin')
|
||||
border = Border(left=thin, right=thin, top=thin, bottom=thin)
|
||||
center = Alignment(horizontal='center', vertical='center')
|
||||
|
||||
# ── column colors matching web table ──
|
||||
col_colors = {
|
||||
2: '198754', # Venta Total → text-success green
|
||||
3: '0DCAF0', # Comisión → text-info cyan
|
||||
4: 'DC3545', # Gastos → text-danger red
|
||||
5: '6C757D', # Crédito → text-muted gray
|
||||
6: '6C757D', # Débito → text-muted gray
|
||||
7: '6C757D', # Mercado Pago → text-muted gray
|
||||
8: '6C757D', # Efectivo/Dep. → text-muted gray
|
||||
9: 'e5904d', # Red. Crédito → custom orange
|
||||
10: 'e5904d', # Red. Débito → custom orange
|
||||
11: 'e5904d', # Red. MP → custom orange
|
||||
12: '20c997', # REDELCOM Neto → teal
|
||||
13: 'FFC107', # Efectivo - Gastos → text-warning
|
||||
14: '0D6EFD', # Venta Total Neto → text-primary blue
|
||||
}
|
||||
|
||||
hdr_fill = PatternFill(start_color="2B303A", end_color="2B303A", fill_type="solid")
|
||||
ws.merge_cells('A1:O1')
|
||||
ws['A1'] = f"Resumen Financiero — {mod_name} ({fecha_inicio} a {fecha_fin})"
|
||||
ws['A1'].font = Font(bold=True, size=14)
|
||||
|
||||
headers = ['Día', 'Venta Total', 'Comisión', 'Gastos',
|
||||
'Crédito', 'Débito', 'Mercado Pago', 'Efectivo/Dep.',
|
||||
'Red. Crédito', 'Red. Débito', 'Red. MP',
|
||||
'REDELCOM Neto', 'Efectivo - Gastos', 'Venta Total Neto']
|
||||
for col, h in enumerate(headers, 1):
|
||||
cell = ws.cell(row=3, column=col, value=h)
|
||||
cell.fill = hdr_fill
|
||||
cell.alignment = center
|
||||
cell.border = border
|
||||
font_color = col_colors.get(col, 'FFFFFF')
|
||||
cell.font = Font(bold=True, color=font_color, size=11)
|
||||
|
||||
for row_idx, dia in enumerate(data['dias_en_periodo'], 4):
|
||||
d = data['data_por_dia'][dia]
|
||||
vals = [
|
||||
dia,
|
||||
d['venta_total'],
|
||||
d['comision'],
|
||||
d['gastos'],
|
||||
d['credito'],
|
||||
d['debito'],
|
||||
d['mp'],
|
||||
d['efectivo'],
|
||||
d['credito'] * 0.97620,
|
||||
d['debito'] * 0.98453,
|
||||
d['mp'] * 0.98691,
|
||||
d['credito'] * 0.97620 + d['debito'] * 0.98453 + d['mp'] * 0.98691,
|
||||
d['efectivo'] - d['gastos'],
|
||||
d['credito'] * 0.97620 + d['debito'] * 0.98453 + d['mp'] * 0.98691 + d['efectivo'] - d['gastos'],
|
||||
]
|
||||
for col, v in enumerate(vals, 1):
|
||||
cell = ws.cell(row=row_idx, column=col, value=v)
|
||||
cell.border = border
|
||||
if col == 1:
|
||||
cell.alignment = center
|
||||
else:
|
||||
cell.number_format = '#,##0'
|
||||
if col in col_colors:
|
||||
cell.font = Font(color=col_colors[col])
|
||||
|
||||
total_row = 4 + len(data['dias_en_periodo'])
|
||||
totals = data['totales_mes']
|
||||
total_vals = [
|
||||
'TOTAL',
|
||||
totals['venta_total'],
|
||||
totals['comision'],
|
||||
totals['gastos'],
|
||||
totals['credito'],
|
||||
totals['debito'],
|
||||
totals['mp'],
|
||||
totals['efectivo'],
|
||||
totals['credito'] * 0.97620,
|
||||
totals['debito'] * 0.98453,
|
||||
totals['mp'] * 0.98691,
|
||||
totals['credito'] * 0.97620 + totals['debito'] * 0.98453 + totals['mp'] * 0.98691,
|
||||
totals['efectivo'] - totals['gastos'],
|
||||
totals['credito'] * 0.97620 + totals['debito'] * 0.98453 + totals['mp'] * 0.98691 + totals['efectivo'] - totals['gastos'],
|
||||
]
|
||||
total_fill = PatternFill(start_color="2B303A", end_color="2B303A", fill_type="solid")
|
||||
for col, v in enumerate(total_vals, 1):
|
||||
cell = ws.cell(row=total_row, column=col, value=v)
|
||||
cell.fill = total_fill
|
||||
cell.border = border
|
||||
if col == 1:
|
||||
cell.alignment = center
|
||||
cell.font = Font(bold=True, color="FFFFFF", size=11)
|
||||
else:
|
||||
cell.number_format = '#,##0'
|
||||
font_color = col_colors.get(col, 'FFFFFF')
|
||||
cell.font = Font(bold=True, color=font_color, size=11)
|
||||
|
||||
for col in range(1, 16):
|
||||
ws.column_dimensions[get_column_letter(col)].width = 16
|
||||
ws.column_dimensions['A'].width = 8
|
||||
|
||||
output = io.BytesIO()
|
||||
wb.save(output)
|
||||
output.seek(0)
|
||||
|
||||
filename = f"reporte_{mod_name}_{fecha_inicio}_{fecha_fin}.xlsx".replace(' ', '_')
|
||||
return send_file(output, as_attachment=True, download_name=filename,
|
||||
mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
|
||||
|
||||
@@ -31,6 +31,7 @@ def get_filtered_rendiciones(fecha_inicio, fecha_fin, zona_id, modulo_id):
|
||||
fin = datetime.strptime(fecha_fin, '%Y-%m-%d').date()
|
||||
|
||||
Companion = aliased(Worker)
|
||||
Companion2 = aliased(Worker)
|
||||
|
||||
filters = [
|
||||
Rendicion.fecha >= inicio,
|
||||
@@ -52,11 +53,14 @@ def get_filtered_rendiciones(fecha_inicio, fecha_fin, zona_id, modulo_id):
|
||||
Companion.name.label('companion_name'),
|
||||
Rendicion.worker_id, Rendicion.companion_id, Rendicion.modulo_id,
|
||||
Rendicion.worker_comision, Rendicion.companion_comision,
|
||||
Companion2.name.label('companion2_name'),
|
||||
Rendicion.companion2_id, Rendicion.companion2_comision,
|
||||
Rendicion.boletas_debito, Rendicion.boletas_credito,
|
||||
Rendicion.boletas_mp, Rendicion.boletas_efectivo,
|
||||
).join(Worker, Rendicion.worker_id == Worker.id
|
||||
).join(Modulo, Rendicion.modulo_id == Modulo.id
|
||||
).outerjoin(Companion, Rendicion.companion_id == Companion.id
|
||||
).outerjoin(Companion2, Rendicion.companion2_id == Companion2.id
|
||||
).filter(*filters
|
||||
).order_by(Rendicion.fecha.desc(), Rendicion.id.desc()).all()
|
||||
|
||||
|
||||
@@ -23,6 +23,13 @@ document.addEventListener("DOMContentLoaded", function () {
|
||||
window.updateComisionToggle(select, `cc_${id}`);
|
||||
};
|
||||
|
||||
window.toggleComp2Div = function (id, select) {
|
||||
const compDiv = document.getElementById(`comp2_com_div_${id}`);
|
||||
if (compDiv) compDiv.style.display = select.value ? 'flex' : 'none';
|
||||
window.updateBadge(select, `badge_comp2_${id}`);
|
||||
window.updateComisionToggle(select, `cc2_${id}`);
|
||||
};
|
||||
|
||||
window.updateComisionToggle = function (selectElement, toggleId) {
|
||||
const option = selectElement.options[selectElement.selectedIndex];
|
||||
const tipoJornada = option ? option.getAttribute('data-tipo') : null;
|
||||
@@ -99,6 +106,9 @@ document.addEventListener("DOMContentLoaded", function () {
|
||||
|
||||
const compSelect = this.querySelector('select[name="companion_id"]');
|
||||
if (compSelect && compSelect.value) window.updateBadge(compSelect, `badge_comp_${rid}`);
|
||||
|
||||
const comp2Select = this.querySelector('select[name="companion2_id"]');
|
||||
if (comp2Select && comp2Select.value) window.updateBadge(comp2Select, `badge_comp2_${rid}`);
|
||||
});
|
||||
|
||||
modal.addEventListener('hidden.bs.modal', function () {
|
||||
|
||||
@@ -80,8 +80,8 @@
|
||||
<button type="button" class="btn btn-sm btn-danger" data-bs-toggle="modal" data-bs-target="#deleteRendicion{{ r[0] }}" title="Eliminar Rendición"><i class="bi bi-trash"></i></button>
|
||||
</div>
|
||||
|
||||
{{ rendicion_detail_modal(r, r[20], r[21], r[22]) }}
|
||||
{{ edit_rendicion_modal(r, r[20], workers, modulos) }}
|
||||
{{ rendicion_detail_modal(r, r[23], r[24], r[25]) }}
|
||||
{{ edit_rendicion_modal(r, r[23], workers, modulos) }}
|
||||
|
||||
{{ confirm_modal(
|
||||
id='deleteRendicion' ~ r[0],
|
||||
|
||||
@@ -42,10 +42,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="card bg-warning text-dark shadow-sm h-100 border-0">
|
||||
<div class="card bg-primary text-white shadow-sm h-100 border-0">
|
||||
<div class="card-body">
|
||||
<div class="text-uppercase small mb-1 opacity-75">Días Trabajados</div>
|
||||
<h3 class="card-title mb-0">{{ dias_activos }} <span class="fs-6 fw-normal">/ 31</span></h3>
|
||||
<div class="text-uppercase small mb-1 opacity-75">Venta Total Neto</div>
|
||||
<h3 class="card-title mb-0">${{ "{:,.0f}".format(totales_mes.credito * 0.97620 + totales_mes.debito * 0.98453 + totales_mes.mp * 0.98691 + totales_mes.efectivo - totales_mes.gastos).replace(',', '.') }}</h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -63,9 +63,9 @@
|
||||
<div class="card-header border-0 bg-transparent d-flex justify-content-between align-items-center pb-0">
|
||||
<span class="fw-bold text-muted text-uppercase"><i class="bi bi-calendar3 me-1"></i> Desglose Diario</span>
|
||||
|
||||
<button class="btn btn-success btn-sm shadow-sm" onclick="alert('Próximamente: Esto descargará un Excel con el detalle de todos los productos vendidos por día.')">
|
||||
<a class="btn btn-success btn-sm shadow-sm" href="{{ url_for('admin.report_modulo_exportar_excel', modulo_id=modulo_id, fecha_inicio=fecha_inicio, fecha_fin=fecha_fin, worker_id=worker_actual) }}">
|
||||
<i class="bi bi-file-earmark-excel-fill me-1"></i> Exportar Detalle Completo (.xlsx)
|
||||
</button>
|
||||
</a>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="table-responsive">
|
||||
@@ -77,12 +77,20 @@
|
||||
<th class="py-2 text-info" rowspan="2">COMISIÓN</th>
|
||||
<th class="py-2 text-danger" rowspan="2">GASTOS</th>
|
||||
<th class="py-1 border-bottom-0" colspan="4">MEDIOS DE PAGO</th>
|
||||
<th class="py-1 border-bottom-0" colspan="3">COMISIÓN REDELCOM</th>
|
||||
<th class="py-1 border-bottom-0" colspan="3">TOTALES NETOS</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="py-1 text-muted">Crédito</th>
|
||||
<th class="py-1 text-muted">Débito</th>
|
||||
<th class="py-1 text-muted">Mercado Pago</th>
|
||||
<th class="py-1 text-muted">Efectivo/Dep.</th>
|
||||
<th class="py-1" style="color:#e5904d">Crédito (-2.38%)</th>
|
||||
<th class="py-1" style="color:#e5904d">Débito (-1.547%)</th>
|
||||
<th class="py-1" style="color:#e5904d">MP (-1.309%)</th>
|
||||
<th class="py-1" style="color:#20c997">REDELCOM Neto</th>
|
||||
<th class="py-1 text-warning">Efectivo - Gastos</th>
|
||||
<th class="py-1 text-primary fw-bold">Venta Total Neto</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@@ -105,6 +113,17 @@
|
||||
<td class="align-middle numeric-cell text-muted">{{ ("$" ~ "{:,.0f}".format(d.debito).replace(',', '.')) if d.debito > 0 else "-" }}</td>
|
||||
<td class="align-middle numeric-cell text-muted">{{ ("$" ~ "{:,.0f}".format(d.mp).replace(',', '.')) if d.mp > 0 else "-" }}</td>
|
||||
<td class="align-middle numeric-cell text-muted">{{ ("$" ~ "{:,.0f}".format(d.efectivo).replace(',', '.')) if d.efectivo > 0 else "-" }}</td>
|
||||
{% set red_credito = d.credito * 0.97620 %}
|
||||
{% set red_debito = d.debito * 0.98453 %}
|
||||
{% set red_mp = d.mp * 0.98691 %}
|
||||
{% set redelcom_neto = red_credito + red_debito + red_mp %}
|
||||
{% set efectivo_menos_gastos = d.efectivo - d.gastos %}
|
||||
<td class="align-middle numeric-cell" style="color:#e5904d">{{ ("$" ~ "{:,.0f}".format(red_credito).replace(',', '.')) if red_credito > 0 else "-" }}</td>
|
||||
<td class="align-middle numeric-cell" style="color:#e5904d">{{ ("$" ~ "{:,.0f}".format(red_debito).replace(',', '.')) if red_debito > 0 else "-" }}</td>
|
||||
<td class="align-middle numeric-cell" style="color:#e5904d">{{ ("$" ~ "{:,.0f}".format(red_mp).replace(',', '.')) if red_mp > 0 else "-" }}</td>
|
||||
<td class="align-middle numeric-cell" style="color:#20c997">{{ ("$" ~ "{:,.0f}".format(redelcom_neto).replace(',', '.')) if redelcom_neto > 0 else "-" }}</td>
|
||||
<td class="align-middle numeric-cell text-warning fw-bold">{{ ("$" ~ "{:,.0f}".format(efectivo_menos_gastos).replace(',', '.')) if efectivo_menos_gastos != 0 else "-" }}</td>
|
||||
<td class="align-middle numeric-cell text-primary fw-bold">{{ ("$" ~ "{:,.0f}".format(redelcom_neto + efectivo_menos_gastos).replace(',', '.')) if (redelcom_neto + efectivo_menos_gastos) != 0 else "-" }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
@@ -125,6 +144,14 @@
|
||||
<td class="align-middle numeric-cell py-2">${{ "{:,.0f}".format(totales_mes.debito).replace(',', '.') }}</td>
|
||||
<td class="align-middle numeric-cell py-2">${{ "{:,.0f}".format(totales_mes.mp).replace(',', '.') }}</td>
|
||||
<td class="align-middle numeric-cell py-2">${{ "{:,.0f}".format(totales_mes.efectivo).replace(',', '.') }}</td>
|
||||
<td class="align-middle numeric-cell py-2" style="color:#e5904d">${{ "{:,.0f}".format(totales_mes.credito * 0.97620).replace(',', '.') }}</td>
|
||||
<td class="align-middle numeric-cell py-2" style="color:#e5904d">${{ "{:,.0f}".format(totales_mes.debito * 0.98453).replace(',', '.') }}</td>
|
||||
<td class="align-middle numeric-cell py-2" style="color:#e5904d">${{ "{:,.0f}".format(totales_mes.mp * 0.98691).replace(',', '.') }}</td>
|
||||
{% set t_redelcom = totales_mes.credito * 0.97620 + totales_mes.debito * 0.98453 + totales_mes.mp * 0.98691 %}
|
||||
{% set t_efectivo_menos = totales_mes.efectivo - totales_mes.gastos %}
|
||||
<td class="align-middle numeric-cell py-2" style="color:#20c997">${{ "{:,.0f}".format(t_redelcom).replace(',', '.') }}</td>
|
||||
<td class="align-middle numeric-cell py-2 text-warning">${{ "{:,.0f}".format(t_efectivo_menos).replace(',', '.') }}</td>
|
||||
<td class="align-middle numeric-cell py-2 text-primary fw-bold">${{ "{:,.0f}".format(t_redelcom + t_efectivo_menos).replace(',', '.') }}</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
|
||||
@@ -328,7 +328,7 @@
|
||||
<dd class="col-sm-7">{{ rendicion[2] }}
|
||||
{% if session.get('is_admin') %}
|
||||
<span class="badge {% if rendicion[14] %}bg-success{% else %}bg-secondary{% endif %} ms-1" style="font-size: 0.65em;">
|
||||
{% if rendicion[14] %}$ Si Recibe Comision{% else %}$ No Recibe Comision{% endif %}
|
||||
{% if rendicion[14] %}Si Recibe Comision{% else %}No Recibe Comision{% endif %}
|
||||
</span>
|
||||
{% endif %}
|
||||
</dd>
|
||||
@@ -339,7 +339,21 @@
|
||||
{{ rendicion[10] }}
|
||||
{% if session.get('is_admin') %}
|
||||
<span class="badge {% if rendicion[15] %}bg-success{% else %}bg-secondary{% endif %} ms-1" style="font-size: 0.65em;">
|
||||
{% if rendicion[15] %}$ Si Recibe Comision{% else %}$ No Recibe Comision{% endif %}
|
||||
{% if rendicion[15] %}Si Recibe Comision{% else %}No Recibe Comision{% endif %}
|
||||
</span>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<span class="text-muted italic small">Sin acompañante</span>
|
||||
{% endif %}
|
||||
</dd>
|
||||
|
||||
<dt class="col-sm-5 text-muted">Acompañante 2</dt>
|
||||
<dd class="col-sm-7">
|
||||
{% if rendicion[16] %}
|
||||
{{ rendicion[16] }}
|
||||
{% if session.get('is_admin') %}
|
||||
<span class="badge {% if rendicion[18] %}bg-success{% else %}bg-secondary{% endif %} ms-1" style="font-size: 0.65em;">
|
||||
{% if rendicion[18] %}Si Recibe Comision{% else %}No Recibe Comision{% endif %}
|
||||
</span>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
@@ -352,19 +366,19 @@
|
||||
</dl>
|
||||
<hr>
|
||||
<div class="d-flex justify-content-between mb-2">
|
||||
<span class="text-muted">Débito <small>(x{{ rendicion[16] }})</small>:</span>
|
||||
<span class="text-muted">Débito <small>(x{{ rendicion[19] or 0 }})</small>:</span>
|
||||
<span>${{ "{:,.0f}".format(rendicion[4] or 0).replace(',', '.') }}</span>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between mb-2">
|
||||
<span class="text-muted">Crédito <small>(x{{ rendicion[17] }})</small>:</span>
|
||||
<span class="text-muted">Crédito <small>(x{{ rendicion[20] or 0 }})</small>:</span>
|
||||
<span>${{ "{:,.0f}".format(rendicion[5] or 0).replace(',', '.') }}</span>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between mb-2">
|
||||
<span class="text-muted">Mercado Pago <small>(x{{ rendicion[18] }})</small>:</span>
|
||||
<span class="text-muted">Mercado Pago <small>(x{{ rendicion[21] or 0 }})</small>:</span>
|
||||
<span>${{ "{:,.0f}".format(rendicion[6] or 0).replace(',', '.') }}</span>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between mb-2">
|
||||
<span class="text-muted">Efectivo <small>(x{{ rendicion[19] }})</small>:</span>
|
||||
<span class="text-muted">Efectivo <small>(x{{ rendicion[22] or 0 }})</small>:</span>
|
||||
<span>${{ "{:,.0f}".format(rendicion[7] or 0).replace(',', '.') }}</span>
|
||||
</div>
|
||||
|
||||
@@ -451,7 +465,7 @@
|
||||
<tr>
|
||||
<td colspan="3" class="text-end fw-bold">Total Calculado por Sistema:</td>
|
||||
<td class="text-end fw-bold fs-6 text-primary" id="sys_total_{{ rendicion[0] }}">
|
||||
${{ "{:,.0f}".format(rendicion[21] or 0).replace(',', '.') }}
|
||||
${{ "{:,.0f}".format(rendicion[24] or 0).replace(',', '.') }}
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
@@ -484,7 +498,7 @@
|
||||
<div id="badge_worker_{{ rendicion[0] }}"></div>
|
||||
<div class="form-check m-0">
|
||||
<input class="form-check-input" type="checkbox" name="worker_comision" id="wc_{{ rendicion[0] }}" {% if rendicion[14] %}checked{% endif %}>
|
||||
<label class="form-check-label text-warning small fw-bold" for="wc_{{ rendicion[0] }}">Recibe Comisión</label>
|
||||
<label class="form-check-label text-success small fw-bold" for="wc_{{ rendicion[0] }}">Recibe Comisión</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -503,7 +517,26 @@
|
||||
<div id="badge_comp_{{ rendicion[0] }}"></div>
|
||||
<div class="form-check m-0">
|
||||
<input class="form-check-input" type="checkbox" name="companion_comision" id="cc_{{ rendicion[0] }}" {% if rendicion[15] %}checked{% endif %}>
|
||||
<label class="form-check-label text-warning small fw-bold" for="cc_{{ rendicion[0] }}">Recibe Comisión</label>
|
||||
<label class="form-check-label text-success small fw-bold" for="cc_{{ rendicion[0] }}">Recibe Comisión</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-2 border-top pt-2">
|
||||
<label class="small text-muted mb-0">Acompañante 2</label>
|
||||
<select class="form-select form-select-sm" name="companion2_id" onchange="toggleComp2Div({{ rendicion[0] }}, this)">
|
||||
<option value="" data-tipo="">Sin acompañante</option>
|
||||
{% for w in workers %}
|
||||
{% if w[3] == rendicion[13] %}
|
||||
<option value="{{ w[0] }}" data-tipo="{{ w[2] }}" {% if w[0] == rendicion[17] %}selected{% endif %}>{{ w[1] }}</option>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</select>
|
||||
<div class="d-flex justify-content-between align-items-center mt-1" id="comp2_com_div_{{ rendicion[0] }}" {% if not rendicion[17] %}style="display:none;"{% endif %}>
|
||||
<div id="badge_comp2_{{ rendicion[0] }}"></div>
|
||||
<div class="form-check m-0">
|
||||
<input class="form-check-input" type="checkbox" name="companion2_comision" id="cc2_{{ rendicion[0] }}" {% if rendicion[18] %}checked{% endif %}>
|
||||
<label class="form-check-label text-success small fw-bold" for="cc2_{{ rendicion[0] }}">Recibe Comisión</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -514,7 +547,7 @@
|
||||
<input type="text" class="form-control form-control-sm text-end money-input mb-1" id="edit_debito_{{ rendicion[0] }}" name="venta_debito" value="{{ '{:,.0f}'.format(rendicion[4] or 0).replace(',', '.') }}" oninput="calcTotalEdit({{ rendicion[0] }})">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-text bg-body-tertiary text-muted" style="font-size: 0.7em;">Boletas</span>
|
||||
<input type="number" class="form-control text-center bg-body text-body border-secondary" name="boletas_debito" value="{{ rendicion[16] or 0 }}">
|
||||
<input type="number" class="form-control text-center bg-body text-body border-secondary" name="boletas_debito" value="{{ rendicion[19] or 0 }}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
@@ -522,7 +555,7 @@
|
||||
<input type="text" class="form-control form-control-sm text-end money-input mb-1" id="edit_credito_{{ rendicion[0] }}" name="venta_credito" value="{{ '{:,.0f}'.format(rendicion[5] or 0).replace(',', '.') }}" oninput="calcTotalEdit({{ rendicion[0] }})">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-text bg-body-tertiary text-muted" style="font-size: 0.7em;">Boletas</span>
|
||||
<input type="number" class="form-control text-center bg-body text-body border-secondary" name="boletas_credito" value="{{ rendicion[17] or 0 }}">
|
||||
<input type="number" class="form-control text-center bg-body text-body border-secondary" name="boletas_credito" value="{{ rendicion[20] or 0 }}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
@@ -530,7 +563,7 @@
|
||||
<input type="text" class="form-control form-control-sm text-end money-input mb-1" id="edit_mp_{{ rendicion[0] }}" name="venta_mp" value="{{ '{:,.0f}'.format(rendicion[6] or 0).replace(',', '.') }}" oninput="calcTotalEdit({{ rendicion[0] }})">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-text bg-body-tertiary text-muted" style="font-size: 0.7em;">Boletas</span>
|
||||
<input type="number" class="form-control text-center bg-body text-body border-secondary" name="boletas_mp" value="{{ rendicion[18] or 0 }}">
|
||||
<input type="number" class="form-control text-center bg-body text-body border-secondary" name="boletas_mp" value="{{ rendicion[21] or 0 }}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
@@ -538,7 +571,7 @@
|
||||
<input type="text" class="form-control form-control-sm text-end money-input mb-1" id="edit_efectivo_{{ rendicion[0] }}" name="venta_efectivo" value="{{ '{:,.0f}'.format(rendicion[7] or 0).replace(',', '.') }}" oninput="calcTotalEdit({{ rendicion[0] }})">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-text bg-body-tertiary text-muted" style="font-size: 0.7em;">Boletas</span>
|
||||
<input type="number" class="form-control text-center bg-body text-body border-secondary" name="boletas_efectivo" value="{{ rendicion[19] or 0 }}">
|
||||
<input type="number" class="form-control text-center bg-body text-body border-secondary" name="boletas_efectivo" value="{{ rendicion[22] or 0 }}">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user