Files
KSNE/templates/admin_productos.html

219 lines
11 KiB
HTML

{% extends "macros/base.html" %}
{% 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 %}
{% block content %}
<div class="d-flex justify-content-between align-items-center mb-4">
<h2 class="mb-0">Catálogo de Productos por Zona</h2>
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#addProductModal">
<i class="bi bi-plus-lg"></i> Agregar Producto
</button>
</div>
{{ flashed_messages() }}
{{ edit_product_modal(zonas) }}
{{ add_product_modal(zonas) }}
<div class="input-group mb-3 shadow-sm">
<span class="input-group-text bg-body-tertiary"><i class="bi bi-search"></i></span>
<input type="text" class="form-control" id="searchProduct" placeholder="Buscar producto...">
</div>
<div class="card shadow-sm">
<div class="card-body p-0">
<table class="table table-striped table-hover mb-0">
<thead class="table-dark">
<tr>
<th>Producto Maestro</th>
<th>Complementos de Regalo</th>
<th class="text-end">Acciones</th>
</tr>
</thead>
<tbody>
{% 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>
<button type="button" class="btn btn-danger btn-sm" data-bs-toggle="modal" data-bs-target="#deleteProd{{ prod.id }}">
<i class="bi bi-trash"></i>
</button>
{{ confirm_modal(
id='deleteProd' ~ prod.id,
title='Eliminar Producto',
message='¿Eliminar "' ~ prod.name ~ '"? Esto fallará si el producto ya tiene ventas registradas.',
action_url=url_for('admin.delete_product', id=prod.id),
btn_class='btn-danger',
btn_text='Eliminar'
) }}
{{ manage_complementos_modal(prod, complementos_catalogo) }}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
{% for prod in productos %}
<div class="modal fade" id="pricesModal{{ prod.id }}" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<form method="POST" action="{{ url_for('admin.update_product_prices', id=prod.id) }}">
<div class="modal-header">
<h5 class="modal-title">Precios: {{ prod.name }}</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<div class="row fw-bold mb-2">
<div class="col-4">Zona</div>
<div class="col-4">Precio</div>
<div class="col-4">Comisión</div>
</div>
{% for z_id, datos in prod.precios.items() %}
<div class="row mb-2">
<div class="col-4 d-flex align-items-center">
<span class="badge bg-info text-dark w-100">{{ datos.zona_name }}</span>
</div>
<div class="col-4">
<div class="input-group input-group-sm">
<span class="input-group-text">$</span>
<input type="text" class="form-control money-input" name="price_{{ z_id }}" value="{{ datos.price }}">
</div>
</div>
<div class="col-4">
<div class="input-group input-group-sm">
<span class="input-group-text">$</span>
<input type="text" class="form-control money-input" name="comm_{{ z_id }}" value="{{ datos.commission }}">
</div>
</div>
</div>
{% endfor %}
</div>
<div class="modal-body bg-body-tertiary border-top pb-3">
<label class="form-label text-warning fw-bold mb-1">
<i class="bi bi-clock-history"></i> Programar Cambio de Precio (Opcional)
</label>
<div class="row g-2 mb-1">
<div class="col-6">
<input type="date" class="form-control form-control-sm" name="fecha_activacion_date">
</div>
<div class="col-6">
<input type="time" class="form-control form-control-sm" name="fecha_activacion_time">
</div>
</div>
<small class="text-muted" style="font-size: 0.85em;">Si lo dejas en blanco, el cambio se aplicará inmediatamente.</small>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cerrar</button>
<button type="submit" class="btn btn-primary">Guardar Precios</button>
</div>
</form>
{% if prod.futuros %}
<div class="modal-body border-top">
<h6 class="text-info fw-bold mb-3">
<i class="bi bi-calendar-event"></i> Cambios Programados a Futuro
</h6>
<div class="table-responsive">
<table class="table table-sm table-bordered text-center mb-0" style="font-size: 0.85rem;">
<thead class="table-dark">
<tr>
<th>Fecha Programada</th>
<th>Zona</th>
<th>Precio</th>
<th>Comisión</th>
<th>Cancelar</th>
</tr>
</thead>
<tbody>
{% for futuro in prod.futuros %}
<tr>
<td class="align-middle text-nowrap text-warning">{{ futuro.fecha }}</td>
<td class="align-middle fw-bold">{{ futuro.zona_name }}</td>
<td class="align-middle">${{ "{:,.0f}".format(futuro.price).replace(',', '.') }}</td>
<td class="align-middle">${{ "{:,.0f}".format(futuro.commission).replace(',', '.') }}</td>
<td class="align-middle">
<form action="{{ url_for('admin.cancel_scheduled_price', id=futuro.id) }}" method="POST" class="d-inline">
<button type="submit" class="btn btn-danger btn-sm py-0 px-2" title="Cancelar este cambio">
<i class="bi bi-x-lg"></i>
</button>
</form>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
{% endif %}
</div>
</div>
</div>
{% endfor %}
</tbody>
</table>
</div>
</div>
<div class="modal fade" id="chartModal" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="chartModalTitle">Historial de Precios</h5>
<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>
</div>
</div>
{% endblock %}
{% block scripts %}
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="{{ url_for('static', filename='js/product-history-chart.js') }}"></script>
<script src="{{ url_for('static', filename='js/admin_productos.js') }}"></script>
{% endblock %}