196 lines
24 KiB
HTML
196 lines
24 KiB
HTML
{% extends 'base.html' %}
|
|
{% block content %}
|
|
<div class="page-toolbar">
|
|
<div>
|
|
<h1 class="h3 mb-1">Contabilidad SaaS</h1>
|
|
<p class="text-muted mb-0">Facturación de uso de plataforma por institución: planes, suscripciones, liquidaciones, pagos, Mercado Pago e historial.</p>
|
|
</div>
|
|
<div class="d-flex flex-wrap gap-2">
|
|
<a class="btn btn-outline-success" href="{{ url_for('admin_accounting_export_xlsx', institution_id=selected_institution_id, status=selected_status, period_filter=selected_period, search=selected_search) }}"><i class="bi bi-file-earmark-excel"></i> Excel</a>
|
|
<a class="btn btn-outline-danger" href="{{ url_for('admin_accounting_export_pdf', institution_id=selected_institution_id, status=selected_status, period_filter=selected_period, search=selected_search) }}"><i class="bi bi-file-earmark-pdf"></i> PDF</a>
|
|
<a class="btn btn-outline-primary" href="{{ url_for('institution_billing') }}"><i class="bi bi-building-check"></i> Portal institución</a>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row g-3 mb-3">
|
|
<div class="col-md-3"><div class="stat-card"><div class="stat-label">Facturado activo</div><div class="stat-value">$ {{ '%.2f'|format(total_billed) }}</div></div></div>
|
|
<div class="col-md-3"><div class="stat-card"><div class="stat-label">Cobrado</div><div class="stat-value">$ {{ '%.2f'|format(total_paid) }}</div></div></div>
|
|
<div class="col-md-3"><div class="stat-card"><div class="stat-label">Deuda</div><div class="stat-value">$ {{ '%.2f'|format(total_debt) }}</div></div></div>
|
|
<div class="col-md-3"><div class="stat-card"><div class="stat-label">Vencidas</div><div class="stat-value">{{ overdue_count }}</div></div></div>
|
|
</div>
|
|
|
|
<ul class="nav nav-tabs mb-3">
|
|
{% for key,label in [('dashboard','Resumen'),('plans','Planes'),('subscriptions','Suscripciones'),('invoices','Liquidaciones'),('payments','Pagos'),('history','Historial'),('mercadopago','Mercado Pago')] %}
|
|
<li class="nav-item"><a class="nav-link {% if tab==key %}active{% endif %}" href="{{ url_for('admin_accounting', tab=key) }}">{{ label }}</a></li>
|
|
{% endfor %}
|
|
</ul>
|
|
|
|
{% if tab in ['dashboard','invoices','payments','history'] %}
|
|
<div class="card table-panel mb-3">
|
|
<div class="card-header"><strong>Filtros de gestión</strong></div>
|
|
<div class="card-body">
|
|
<form class="row g-2 align-items-end" method="get">
|
|
<input type="hidden" name="tab" value="{{ tab }}">
|
|
<div class="col-lg-3 col-md-6">
|
|
<label class="form-label">Institución</label>
|
|
<select class="form-select searchable-select" name="institution_id">
|
|
<option value="">Todas</option>
|
|
{% for inst in institutions %}<option value="{{ inst.id }}" {% if selected_institution_id==inst.id %}selected{% endif %}>{{ inst.name }}</option>{% endfor %}
|
|
</select>
|
|
</div>
|
|
<div class="col-lg-2 col-md-6">
|
|
<label class="form-label">Período</label>
|
|
<input class="form-control" type="month" name="period_filter" value="{{ selected_period }}">
|
|
</div>
|
|
<div class="col-lg-2 col-md-6">
|
|
<label class="form-label">Estado</label>
|
|
<select class="form-select" name="status">
|
|
<option value="">Todos</option>
|
|
{% for st in ['pendiente','parcial','pagada','anulada'] %}<option value="{{ st }}" {% if selected_status==st %}selected{% endif %}>{{ st|capitalize }}</option>{% endfor %}
|
|
</select>
|
|
</div>
|
|
<div class="col-lg-3 col-md-6">
|
|
<label class="form-label">Buscar</label>
|
|
<input class="form-control" name="search" value="{{ selected_search }}" placeholder="Institución, CUIT, período o notas">
|
|
</div>
|
|
<div class="col-lg-2 col-md-12 d-flex gap-2">
|
|
<button class="btn btn-primary w-100"><i class="bi bi-funnel"></i> Filtrar</button>
|
|
<a class="btn btn-outline-secondary" href="{{ url_for('admin_accounting', tab=tab) }}">Limpiar</a>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if tab == 'plans' %}
|
|
<div class="card table-panel mb-3">
|
|
<div class="card-header d-flex justify-content-between align-items-center">
|
|
<strong>Planes comerciales</strong>
|
|
<button class="btn btn-primary btn-sm" data-bs-toggle="modal" data-bs-target="#planModal"><i class="bi bi-plus-circle"></i> Nuevo plan</button>
|
|
</div>
|
|
<div class="table-responsive"><table class="table align-middle mb-0">
|
|
<thead><tr><th>Plan</th><th>Mensual</th><th>Por turno</th><th>Profesionales incluidos</th><th>Extra profesional</th><th>Turnos incluidos</th><th>Activo</th><th>Acciones</th></tr></thead>
|
|
<tbody>{% for p in plans %}
|
|
<tr>
|
|
<td><strong>{{ p.name }}</strong><br><span class="small text-muted">{{ p.description or '' }}</span></td>
|
|
<td>$ {{ '%.2f'|format(p.monthly_price or 0) }}</td>
|
|
<td>$ {{ '%.2f'|format(p.price_per_appointment or 0) }}</td>
|
|
<td>{{ p.included_professionals }}</td>
|
|
<td>$ {{ '%.2f'|format(p.extra_professional_price or 0) }}</td>
|
|
<td>{{ p.included_appointments }}</td>
|
|
<td>{% if p.active %}<span class="badge text-bg-success">Sí</span>{% else %}<span class="badge text-bg-secondary">No</span>{% endif %}</td>
|
|
<td><button class="btn btn-sm btn-outline-primary" data-bs-toggle="modal" data-bs-target="#planModal" data-plan-id="{{ p.id }}" data-name="{{ p.name }}" data-description="{{ p.description or '' }}" data-monthly-price="{{ p.monthly_price or 0 }}" data-price-per-appointment="{{ p.price_per_appointment or 0 }}" data-included-professionals="{{ p.included_professionals or 0 }}" data-extra-professional-price="{{ p.extra_professional_price or 0 }}" data-included-appointments="{{ p.included_appointments or 0 }}" data-active="{{ 1 if p.active else 0 }}"><i class="bi bi-pencil-square"></i> Editar</button></td>
|
|
</tr>
|
|
{% else %}<tr><td colspan="8" class="text-center text-muted py-4">Sin planes cargados.</td></tr>{% endfor %}</tbody>
|
|
</table></div>
|
|
</div>
|
|
|
|
{% elif tab == 'subscriptions' %}
|
|
<div class="card table-panel mb-3">
|
|
<div class="card-header d-flex justify-content-between align-items-center">
|
|
<strong>Suscripciones por institución</strong>
|
|
<button class="btn btn-primary btn-sm" data-bs-toggle="modal" data-bs-target="#subModal"><i class="bi bi-plus-circle"></i> Nueva suscripción</button>
|
|
</div>
|
|
<div class="table-responsive"><table class="table align-middle mb-0">
|
|
<thead><tr><th>Institución</th><th>Plan</th><th>Inicio</th><th>Día cobro</th><th>Estado</th><th>Generar</th><th>Acciones</th></tr></thead>
|
|
<tbody>{% for s in subscriptions %}
|
|
<tr>
|
|
<td>{{ s.institution.name }}</td><td>{{ s.plan.name }}</td><td>{{ s.start_date.strftime('%d/%m/%Y') if s.start_date else '—' }}</td><td>{{ s.billing_day }}</td><td><span class="badge text-bg-info">{{ s.status }}</span></td>
|
|
<td><form method="post" class="d-flex gap-2"><input type="hidden" name="action" value="generate_invoice"><input type="hidden" name="subscription_id" value="{{ s.id }}"><input class="form-control form-control-sm" type="month" name="period" value="{{ period }}"><button class="btn btn-sm btn-outline-primary">Liquidar</button></form></td>
|
|
<td><button class="btn btn-sm btn-outline-primary" data-bs-toggle="modal" data-bs-target="#subModal" data-sub-id="{{ s.id }}" data-institution-id="{{ s.institution_id }}" data-plan-id="{{ s.plan_id }}" data-start-date="{{ s.start_date.isoformat() if s.start_date else '' }}" data-billing-day="{{ s.billing_day }}" data-status="{{ s.status }}" data-notes="{{ s.notes or '' }}"><i class="bi bi-pencil-square"></i> Editar</button></td>
|
|
</tr>
|
|
{% else %}<tr><td colspan="7" class="text-center text-muted py-4">Sin suscripciones.</td></tr>{% endfor %}</tbody>
|
|
</table></div>
|
|
</div>
|
|
|
|
{% elif tab == 'payments' %}
|
|
<div class="card table-panel"><div class="card-header"><strong>Últimos pagos registrados</strong></div><div class="table-responsive"><table class="table align-middle mb-0"><thead><tr><th>Fecha</th><th>Institución</th><th>Factura</th><th>Método</th><th>Estado</th><th>Importe</th><th>Referencia</th><th>Comprobante</th></tr></thead><tbody>{% for p in payments %}<tr><td>{{ p.payment_date.strftime('%d/%m/%Y') }}</td><td>{{ p.invoice.institution.name }}</td><td>{{ p.invoice.period }}</td><td>{{ p.method }}</td><td><span class="badge text-bg-secondary">{{ p.status or p.mercadopago_status or 'registrado' }}</span></td><td>$ {{ '%.2f'|format(p.amount) }}</td><td>{{ p.reference or p.mercadopago_payment_id or '—' }}</td><td><a class="btn btn-sm btn-outline-danger" href="{{ url_for('accounting_invoice_receipt_pdf', invoice_id=p.invoice.id) }}"><i class="bi bi-file-earmark-pdf"></i></a></td></tr>{% else %}<tr><td colspan="8" class="text-center text-muted py-4">Sin pagos.</td></tr>{% endfor %}</tbody></table></div></div>
|
|
|
|
{% elif tab == 'history' %}
|
|
<div class="row g-3">
|
|
<div class="col-lg-4">
|
|
<div class="section-card">
|
|
<h5>Historial por institución</h5>
|
|
<form method="get" class="row g-2"><input type="hidden" name="tab" value="history"><div class="col-12"><label class="form-label">Institución</label><select class="form-select searchable-select" name="history_institution_id" required>{% for inst in institutions %}<option value="{{ inst.id }}" {% if history_institution and history_institution.id==inst.id %}selected{% endif %}>{{ inst.name }}</option>{% endfor %}</select></div><div class="col-12"><button class="btn btn-primary w-100">Ver historial</button></div></form>
|
|
{% if history_institution %}<hr><p class="mb-1"><strong>{{ history_institution.name }}</strong></p><p class="text-muted small mb-2">CUIT: {{ history_institution.cuit or '—' }}</p><div class="d-grid gap-2"><div class="stat-card"><div class="stat-label">Facturado</div><div class="stat-value">$ {{ '%.2f'|format(history_totals.billed) }}</div></div><div class="stat-card"><div class="stat-label">Pagado</div><div class="stat-value">$ {{ '%.2f'|format(history_totals.paid) }}</div></div><div class="stat-card"><div class="stat-label">Deuda</div><div class="stat-value">$ {{ '%.2f'|format(history_totals.debt) }}</div></div></div>{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="col-lg-8">
|
|
<div class="card table-panel mb-3"><div class="card-header"><strong>Liquidaciones históricas</strong></div><div class="table-responsive"><table class="table align-middle mb-0"><thead><tr><th>Período</th><th>Total</th><th>Pagado</th><th>Deuda</th><th>Estado</th><th>PDF</th></tr></thead><tbody>{% for i in history_invoices %}<tr><td>{{ i.period }}</td><td>$ {{ '%.2f'|format(i.total_amount or 0) }}</td><td>$ {{ '%.2f'|format(i.paid_amount or 0) }}</td><td>$ {{ '%.2f'|format(i.debt_amount) }}</td><td>{{ i.status }}</td><td><a class="btn btn-sm btn-outline-danger" href="{{ url_for('accounting_invoice_receipt_pdf', invoice_id=i.id) }}">PDF</a></td></tr>{% else %}<tr><td colspan="6" class="text-center text-muted py-4">Seleccioná una institución para ver su historial.</td></tr>{% endfor %}</tbody></table></div></div>
|
|
<div class="card table-panel"><div class="card-header"><strong>Pagos históricos</strong></div><div class="table-responsive"><table class="table align-middle mb-0"><thead><tr><th>Fecha</th><th>Periodo</th><th>Método</th><th>Importe</th><th>Referencia</th></tr></thead><tbody>{% for p in history_payments %}<tr><td>{{ p.payment_date.strftime('%d/%m/%Y') }}</td><td>{{ p.invoice.period }}</td><td>{{ p.method }}</td><td>$ {{ '%.2f'|format(p.amount or 0) }}</td><td>{{ p.reference or p.mercadopago_payment_id or '—' }}</td></tr>{% else %}<tr><td colspan="5" class="text-center text-muted py-4">Sin pagos para mostrar.</td></tr>{% endfor %}</tbody></table></div></div>
|
|
</div>
|
|
</div>
|
|
|
|
{% elif tab == 'mercadopago' %}
|
|
<div class="row g-3">
|
|
<div class="col-lg-7">
|
|
<div class="card table-panel"><div class="card-header"><strong>Configuración Mercado Pago</strong></div><div class="card-body">
|
|
<form method="post" class="row g-3"><input type="hidden" name="action" value="save_mp_config">
|
|
<div class="col-12"><label class="form-label">Access Token</label><input class="form-control" name="access_token" type="password" placeholder="APP_USR-... o TEST-..."><div class="form-hint">Actual: {{ mp_config.access_token_masked or 'sin configurar' }}. Por seguridad no se muestra completo.</div></div>
|
|
<div class="col-12"><label class="form-label">URL pública del sistema</label><input class="form-control" name="public_base_url" value="{{ mp_config.public_base_url }}" placeholder="https://tudominio.com"><div class="form-hint">Debe ser HTTPS real para recibir webhooks. En local podés usar ngrok.</div></div>
|
|
<div class="col-md-4"><label class="form-label">Moneda</label><input class="form-control" name="currency" value="{{ mp_config.currency or 'ARS' }}"></div>
|
|
<div class="col-md-8"><label class="form-label">Email pagador por defecto</label><input class="form-control" name="default_payer_email" value="{{ mp_config.default_payer_email }}"></div>
|
|
<div class="col-12"><button class="btn btn-primary">Guardar configuración</button></div>
|
|
</form>
|
|
</div></div>
|
|
</div>
|
|
<div class="col-lg-5"><div class="section-card"><h5>Webhook público</h5><p class="text-muted">Configurá esta URL en Mercado Pago:</p><div class="code-box">{{ (mp_config.public_base_url or request.host_url.rstrip('/')) }}/webhooks/mercadopago</div><hr><p class="mb-1"><strong>Estado:</strong> {% if mp_config.enabled %}<span class="badge text-bg-success">configurado</span>{% else %}<span class="badge text-bg-danger">sin token</span>{% endif %}</p><p class="text-muted small mb-0">La aprobación final se registra por webhook. El retorno del navegador solo informa al usuario.</p></div></div>
|
|
</div>
|
|
|
|
{% else %}
|
|
<div class="card table-panel">
|
|
<div class="card-header d-flex justify-content-between align-items-center"><strong>Liquidaciones SaaS</strong><span class="text-muted small">Mostrando {{ invoices|length }} registros</span></div>
|
|
<div class="table-responsive"><table class="table align-middle mb-0"><thead><tr><th>Período</th><th>Institución</th><th>Turnos</th><th>Profesionales</th><th>Total</th><th>Pagado</th><th>Deuda</th><th>Vence</th><th>Estado</th><th>Acciones</th></tr></thead><tbody>{% for i in invoices %}<tr class="{% if i.status=='anulada' %}table-light text-muted{% endif %}"><td>{{ i.period }}</td><td><strong>{{ i.institution.name }}</strong><br><span class="small text-muted">{{ i.institution.cuit or 'Sin CUIT' }}</span></td><td>{{ i.appointment_count }}<br><span class="small text-muted">$ {{ '%.2f'|format(i.appointment_amount or 0) }}</span></td><td>{{ i.professional_count }}<br><span class="small text-muted">$ {{ '%.2f'|format(i.extra_professional_amount or 0) }}</span></td><td>$ {{ '%.2f'|format(i.total_amount or 0) }}</td><td>$ {{ '%.2f'|format(i.paid_amount or 0) }}</td><td>$ {{ '%.2f'|format(i.debt_amount) }}</td><td>{{ i.due_date.strftime('%d/%m/%Y') if i.due_date else '—' }}</td><td><span class="badge {% if i.status=='pagada' %}text-bg-success{% elif i.status=='parcial' %}text-bg-warning{% elif i.status=='anulada' %}text-bg-secondary{% else %}text-bg-danger{% endif %}">{{ i.status }}</span></td><td><div class="d-flex flex-wrap gap-1"><a class="btn btn-sm btn-outline-danger" href="{{ url_for('accounting_invoice_receipt_pdf', invoice_id=i.id) }}">PDF</a>{% if i.status != 'anulada' %}<button class="btn btn-sm btn-outline-success" data-bs-toggle="modal" data-bs-target="#payModal" data-invoice="{{ i.id }}" data-amount="{{ '%.2f'|format(i.debt_amount) }}">Pago</button><form method="post" class="d-inline"><input type="hidden" name="action" value="prepare_mp"><input type="hidden" name="invoice_id" value="{{ i.id }}"><button class="btn btn-sm btn-outline-primary">Generar MP</button></form>{% if i.mercadopago_init_point or i.mercadopago_sandbox_init_point %}<a class="btn btn-sm btn-primary" href="{{ url_for('accounting_mp_pay', invoice_id=i.id) }}" target="_blank">Abrir link</a>{% endif %}{% if (i.paid_amount or 0)==0 %}<button class="btn btn-sm btn-outline-secondary" data-bs-toggle="modal" data-bs-target="#voidModal" data-invoice="{{ i.id }}" data-label="{{ i.institution.name }} - {{ i.period }}">Anular</button>{% endif %}{% endif %}</div>{% if i.mercadopago_status %}<div class="small text-muted mt-1">MP: {{ i.mercadopago_status }} {{ i.mercadopago_status_detail or '' }}</div>{% endif %}</td></tr>{% else %}<tr><td colspan="10" class="text-center text-muted py-4">Sin liquidaciones generadas.</td></tr>{% endfor %}</tbody></table></div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<div class="modal fade" id="planModal" tabindex="-1"><div class="modal-dialog modal-lg"><div class="modal-content"><div class="modal-header"><h5 class="modal-title" id="planModalTitle">Nuevo plan SaaS</h5><button class="btn-close" data-bs-dismiss="modal"></button></div><form method="post"><input type="hidden" name="action" value="save_plan"><input type="hidden" name="plan_id" id="plan_id"><div class="modal-body row g-3"><div class="col-md-6"><label class="form-label">Nombre</label><input class="form-control" name="name" id="plan_name" required></div><div class="col-md-6"><label class="form-label">Mensualidad</label><input class="form-control" name="monthly_price" id="plan_monthly_price" placeholder="0,00"></div><div class="col-md-6"><label class="form-label">Precio por turno</label><input class="form-control" name="price_per_appointment" id="plan_price_per_appointment" placeholder="0,00"></div><div class="col-md-6"><label class="form-label">Turnos incluidos</label><input class="form-control" name="included_appointments" id="plan_included_appointments" type="number" value="0"></div><div class="col-md-6"><label class="form-label">Profesionales incluidos</label><input class="form-control" name="included_professionals" id="plan_included_professionals" type="number" value="1"></div><div class="col-md-6"><label class="form-label">Precio profesional extra</label><input class="form-control" name="extra_professional_price" id="plan_extra_professional_price" placeholder="0,00"></div><div class="col-12"><label class="form-label">Descripción</label><textarea class="form-control" name="description" id="plan_description"></textarea></div><div class="col-12 form-check ms-2"><input class="form-check-input" type="checkbox" name="active" id="plan_active" checked><label class="form-check-label">Activo</label></div></div><div class="modal-footer"><button class="btn btn-primary">Guardar</button></div></form></div></div></div>
|
|
|
|
<div class="modal fade" id="subModal" tabindex="-1"><div class="modal-dialog modal-lg"><div class="modal-content"><div class="modal-header"><h5 class="modal-title" id="subModalTitle">Nueva suscripción</h5><button class="btn-close" data-bs-dismiss="modal"></button></div><form method="post"><input type="hidden" name="action" value="save_subscription"><input type="hidden" name="subscription_id" id="subscription_id"><div class="modal-body row g-3"><div class="col-md-6"><label class="form-label">Institución</label><select class="form-select searchable-select" name="institution_id" id="sub_institution_id" required>{% for inst in institutions %}<option value="{{ inst.id }}">{{ inst.name }}</option>{% endfor %}</select></div><div class="col-md-6"><label class="form-label">Plan</label><select class="form-select searchable-select" name="plan_id" id="sub_plan_id" required>{% for p in plans if p.active %}<option value="{{ p.id }}">{{ p.name }}</option>{% endfor %}</select></div><div class="col-md-6"><label class="form-label">Fecha inicio</label><input class="form-control" type="date" name="start_date" id="sub_start_date" value="{{ today_value }}"></div><div class="col-md-6"><label class="form-label">Día de facturación</label><input class="form-control" type="number" name="billing_day" id="sub_billing_day" min="1" max="28" value="1"></div><div class="col-md-6"><label class="form-label">Estado</label><select class="form-select" name="status" id="sub_status"><option value="activa">Activa</option><option value="pausada">Pausada</option><option value="baja">Baja</option></select></div><div class="col-12"><label class="form-label">Notas</label><textarea class="form-control" name="notes" id="sub_notes"></textarea></div></div><div class="modal-footer"><button class="btn btn-primary">Guardar</button></div></form></div></div></div>
|
|
|
|
<div class="modal fade" id="payModal" tabindex="-1"><div class="modal-dialog"><div class="modal-content"><div class="modal-header"><h5 class="modal-title">Registrar pago</h5><button class="btn-close" data-bs-dismiss="modal"></button></div><form method="post"><input type="hidden" name="action" value="register_payment"><input type="hidden" name="invoice_id" id="pay_invoice_id"><div class="modal-body row g-3"><div class="col-md-6"><label class="form-label">Fecha</label><input class="form-control" type="date" name="payment_date" value="{{ today_value }}"></div><div class="col-md-6"><label class="form-label">Importe</label><input class="form-control" name="amount" id="pay_amount"></div><div class="col-md-6"><label class="form-label">Método</label><select class="form-select" name="method"><option value="efectivo">Efectivo</option><option value="transferencia">Transferencia</option><option value="mercadopago">Mercado Pago</option></select></div><div class="col-md-6"><label class="form-label">Referencia</label><input class="form-control" name="reference"></div><div class="col-12"><label class="form-label">Notas</label><textarea class="form-control" name="notes"></textarea></div></div><div class="modal-footer"><button class="btn btn-success">Registrar pago</button></div></form></div></div></div>
|
|
|
|
<div class="modal fade" id="voidModal" tabindex="-1"><div class="modal-dialog"><div class="modal-content"><div class="modal-header"><h5 class="modal-title">Anular liquidación</h5><button class="btn-close" data-bs-dismiss="modal"></button></div><form method="post"><input type="hidden" name="action" value="void_invoice"><input type="hidden" name="invoice_id" id="void_invoice_id"><div class="modal-body"><p class="text-muted">Vas a anular: <strong id="void_label"></strong></p><label class="form-label">Motivo</label><textarea class="form-control" name="void_reason" placeholder="Ej.: error de liquidación, refacturación, ajuste comercial" required></textarea></div><div class="modal-footer"><button class="btn btn-outline-secondary" data-bs-dismiss="modal" type="button">Cancelar</button><button class="btn btn-danger">Anular</button></div></form></div></div></div>
|
|
{% endblock %}
|
|
|
|
{% block scripts %}{{ super() }}
|
|
<script>
|
|
document.addEventListener('show.bs.modal', e => {
|
|
const t = e.target;
|
|
const b = e.relatedTarget;
|
|
if (t.id === 'payModal') {
|
|
document.getElementById('pay_invoice_id').value = b?.dataset.invoice || '';
|
|
document.getElementById('pay_amount').value = b?.dataset.amount || '';
|
|
}
|
|
if (t.id === 'voidModal') {
|
|
document.getElementById('void_invoice_id').value = b?.dataset.invoice || '';
|
|
document.getElementById('void_label').textContent = b?.dataset.label || '';
|
|
}
|
|
if (t.id === 'planModal') {
|
|
const isEdit = !!b?.dataset.planId;
|
|
document.getElementById('planModalTitle').textContent = isEdit ? 'Editar plan SaaS' : 'Nuevo plan SaaS';
|
|
document.getElementById('plan_id').value = b?.dataset.planId || '';
|
|
document.getElementById('plan_name').value = b?.dataset.name || '';
|
|
document.getElementById('plan_description').value = b?.dataset.description || '';
|
|
document.getElementById('plan_monthly_price').value = b?.dataset.monthlyPrice || '';
|
|
document.getElementById('plan_price_per_appointment').value = b?.dataset.pricePerAppointment || '';
|
|
document.getElementById('plan_included_professionals').value = b?.dataset.includedProfessionals || '1';
|
|
document.getElementById('plan_extra_professional_price').value = b?.dataset.extraProfessionalPrice || '';
|
|
document.getElementById('plan_included_appointments').value = b?.dataset.includedAppointments || '0';
|
|
document.getElementById('plan_active').checked = !isEdit || b?.dataset.active === '1';
|
|
}
|
|
if (t.id === 'subModal') {
|
|
const isEdit = !!b?.dataset.subId;
|
|
document.getElementById('subModalTitle').textContent = isEdit ? 'Editar suscripción' : 'Nueva suscripción';
|
|
document.getElementById('subscription_id').value = b?.dataset.subId || '';
|
|
document.getElementById('sub_institution_id').value = b?.dataset.institutionId || document.getElementById('sub_institution_id').value;
|
|
document.getElementById('sub_plan_id').value = b?.dataset.planId || document.getElementById('sub_plan_id').value;
|
|
document.getElementById('sub_start_date').value = b?.dataset.startDate || '{{ today_value }}';
|
|
document.getElementById('sub_billing_day').value = b?.dataset.billingDay || '1';
|
|
document.getElementById('sub_status').value = b?.dataset.status || 'activa';
|
|
document.getElementById('sub_notes').value = b?.dataset.notes || '';
|
|
}
|
|
});
|
|
</script>
|
|
{% endblock %}
|