feat: add complementos feature for linking multiple accessories and quantities to products
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
{% extends "macros/base.html" %}
|
||||
{% from 'macros/modals.html' import confirm_modal, edit_product_modal, add_product_modal %}
|
||||
{% from 'macros/modals.html' import confirm_modal, edit_product_modal, add_product_modal, manage_complementos_modal %}
|
||||
{% from "macros/ui.html" import flashed_messages %}
|
||||
|
||||
{% block title %}Catálogo de Productos{% endblock %}
|
||||
@@ -28,6 +28,7 @@
|
||||
<thead class="table-dark">
|
||||
<tr>
|
||||
<th>Producto Maestro</th>
|
||||
<th>Complementos de Regalo</th>
|
||||
<th class="text-end">Acciones</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -35,10 +36,22 @@
|
||||
{% for prod in productos %}
|
||||
<tr class="product-row">
|
||||
<td class="align-middle fw-bold">{{ prod.name }}</td>
|
||||
<td class="align-middle">
|
||||
{% if prod.complementos %}
|
||||
{% for comp in prod.complementos %}
|
||||
<span class="badge bg-secondary mb-1" style="font-size: 0.85em;">{{ comp.name }} (x{{ comp.cantidad }})</span>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<span class="text-muted italic small">Sin complementos</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="text-end">
|
||||
<button type="button" class="btn btn-info btn-sm text-white" onclick="showHistory({{ prod.id }}, '{{ prod.name }}')">
|
||||
<i class="bi bi-graph-up"></i> Historial
|
||||
</button>
|
||||
<button type="button" class="btn btn-warning btn-sm text-dark" data-bs-toggle="modal" data-bs-target="#complementosModal{{ prod.id }}">
|
||||
<i class="bi bi-gift"></i> Complementos
|
||||
</button>
|
||||
<button type="button" class="btn btn-success btn-sm" data-bs-toggle="modal" data-bs-target="#pricesModal{{ prod.id }}">
|
||||
<i class="bi bi-currency-dollar"></i> Precios
|
||||
</button>
|
||||
@@ -54,6 +67,7 @@
|
||||
btn_class='btn-danger',
|
||||
btn_text='Eliminar'
|
||||
) }}
|
||||
{{ manage_complementos_modal(prod, complementos_catalogo) }}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
@@ -174,6 +188,22 @@
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="row g-2 mb-3 bg-light-subtle border p-2 rounded align-items-end">
|
||||
<div class="col-md-5">
|
||||
<label class="form-label small text-muted mb-1">Desde</label>
|
||||
<input type="date" class="form-control form-control-sm" id="chartFilterDesde">
|
||||
</div>
|
||||
<div class="col-md-5">
|
||||
<label class="form-label small text-muted mb-1">Hasta</label>
|
||||
<input type="date" class="form-control form-control-sm" id="chartFilterHasta">
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<button type="button" class="btn btn-primary btn-sm w-100" id="btnFilterChart"><i class="bi bi-filter"></i> Filtrar</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="alert alert-info py-1 px-2 mb-2 text-center" style="font-size: 0.85em;">
|
||||
<i class="bi bi-info-circle-fill me-1"></i> Puedes hacer clic en los nombres de las zonas en la leyenda de arriba para ocultar o mostrar sus líneas en el gráfico.
|
||||
</div>
|
||||
<canvas id="priceChart" width="400" height="200"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -799,4 +799,85 @@
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
|
||||
{% macro manage_complementos_modal(prod, complementos_catalogo) %}
|
||||
<div class="modal fade" id="complementosModal{{ prod.id }}" tabindex="-1" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Complementos de: <span class="text-primary">{{ prod.name }}</span></h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body text-start">
|
||||
<h6 class="fw-bold mb-3">Complementos Vinculados (Se entregan de regalo al vender este producto)</h6>
|
||||
{% if prod.complementos %}
|
||||
<div class="table-responsive mb-4">
|
||||
<table class="table table-striped table-hover table-bordered mb-0 align-middle">
|
||||
<thead class="table-dark">
|
||||
<tr>
|
||||
<th>Nombre Complemento</th>
|
||||
<th class="text-center" style="width: 120px;">Cantidad</th>
|
||||
<th class="text-end" style="width: 100px;">Desvincular</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for comp in prod.complementos %}
|
||||
<tr>
|
||||
<td>{{ comp.name }}</td>
|
||||
<td class="text-center fw-bold">{{ comp.cantidad }}</td>
|
||||
<td class="text-end">
|
||||
<form method="POST" action="{{ url_for('admin.delete_producto_complemento', assoc_id=comp.id) }}" class="d-inline">
|
||||
<button type="submit" class="btn btn-danger btn-sm py-0 px-2" title="Desvincular">
|
||||
<i class="bi bi-trash"></i>
|
||||
</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="alert alert-light border text-center text-muted mb-4 py-3">
|
||||
<i class="bi bi-info-circle me-1"></i> Este producto aún no tiene complementos asociados.
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<hr>
|
||||
|
||||
<h6 class="fw-bold mb-3">Vincular Nuevo Complemento</h6>
|
||||
<form method="POST" action="{{ url_for('admin.add_producto_complemento', prod_id=prod.id) }}">
|
||||
<div class="row g-3 align-items-end">
|
||||
<div class="col-md-5">
|
||||
<label class="form-label small text-muted mb-1">Seleccionar del Catálogo</label>
|
||||
<select class="form-select form-select-sm" name="complemento_id" onchange="toggleNuevoComplementoInput({{ prod.id }}, this)" required>
|
||||
<option value="" selected disabled>Elegir...</option>
|
||||
{% for cat in complementos_catalogo %}
|
||||
<option value="{{ cat.id }}">{{ cat.name }}</option>
|
||||
{% endfor %}
|
||||
<option value="__nuevo__">+ Crear nuevo complemento...</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-5" id="nuevo_comp_wrapper_{{ prod.id }}" style="display:none;">
|
||||
<label class="form-label small text-muted mb-1">Nombre del Nuevo Complemento</label>
|
||||
<input type="text" class="form-control form-control-sm" name="complemento_nombre_nuevo" placeholder="Ej. Paño microfibra">
|
||||
</div>
|
||||
<div class="col-md-2" id="cantidad_comp_wrapper_{{ prod.id }}">
|
||||
<label class="form-label small text-muted mb-1">Cantidad</label>
|
||||
<input type="number" class="form-control form-control-sm text-center" name="cantidad" value="1" min="1" required>
|
||||
</div>
|
||||
<div class="col-md-12 text-end mt-2">
|
||||
<button type="submit" class="btn btn-success btn-sm"><i class="bi bi-plus-lg"></i> Vincular</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer py-2">
|
||||
<button type="button" class="btn btn-secondary btn-sm" data-bs-dismiss="modal">Cerrar</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endmacro %}
|
||||
Reference in New Issue
Block a user