Files
erp-efintel-2026-portainer/templates/expenses/project_list.html
T
2026-09-07 18:44:32 -03:00

125 lines
9.5 KiB
HTML

{% extends 'base.html' %}
{% load humanize %}
{% block content %}
<div class="view-header" style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 1.5rem;">
<div class="view-title">
<h2 style="margin:0; color:var(--efintel-petroleum); display:flex; align-items:center; gap:0.5rem;">
<i data-lucide="folder-kanban" style="color:var(--efintel-blue);"></i> Control de Proyectos y Centros de Costo
</h2>
<p style="margin-top:0.25rem; font-size:0.9rem; color:var(--efintel-gray);">Supervisión de presupuesto, forma de pago, ingresos, egresos y saldos por proyecto.</p>
</div>
<div>
{% if is_admin or is_pm %}
<a href="{% url 'project_create' %}" class="btn-primary" style="text-decoration: none;">
<i data-lucide="plus-circle" style="width:16px;"></i> + Nuevo Proyecto
</a>
{% endif %}
</div>
</div>
<!-- Requerimiento 2: Conteo exacto por estado -->
<div style="display:grid; grid-template-columns: repeat(4, 1fr); gap: 1rem; margin-bottom: 2rem;">
<div class="data-card" style="padding: 1rem; text-align: center; border-left: 4px solid #16a34a;">
<div style="font-size: 0.75rem; color: var(--efintel-gray); font-weight:600;">PROYECTOS ACTIVOS</div>
<div style="font-size: 1.8rem; font-weight: 800; color: #16a34a;">{{ project_count_active }}</div>
</div>
<div class="data-card" style="padding: 1rem; text-align: center; border-left: 4px solid #d97706;">
<div style="font-size: 0.75rem; color: var(--efintel-gray); font-weight:600;">EN PAUSA</div>
<div style="font-size: 1.8rem; font-weight: 800; color: #d97706;">{{ project_count_paused }}</div>
</div>
<div class="data-card" style="padding: 1rem; text-align: center; border-left: 4px solid #0284c7;">
<div style="font-size: 0.75rem; color: var(--efintel-gray); font-weight:600;">TERMINADOS</div>
<div style="font-size: 1.8rem; font-weight: 800; color: #0284c7;">{{ project_count_completed }}</div>
</div>
<div class="data-card" style="padding: 1rem; text-align: center; border-left: 4px solid #64748b;">
<div style="font-size: 0.75rem; color: var(--efintel-gray); font-weight:600;">TOTAL EN SISTEMA</div>
<div style="font-size: 1.8rem; font-weight: 800; color: #334155;">{{ project_count_total }}</div>
</div>
</div>
<div class="data-card" style="margin-bottom: 2rem;">
<form method="get" id="filter-form" style="display: flex; gap: 1rem; align-items: flex-end; flex-wrap: wrap;">
<div class="form-group" style="margin-bottom: 0; flex: 1; min-width: 200px;">
<label for="search" style="font-size: 0.8rem; font-weight: 600;">Buscar por nombre o código</label>
<input type="text" name="search" id="search" value="{{ request.GET.search }}" placeholder="Ej: PROY-2026-001" style="width: 100%; padding: 0.65rem; border: 1px solid var(--efintel-border); border-radius: 4px; outline: none; font-family: 'Inter';">
</div>
<div class="form-group" style="margin-bottom: 0; flex: 1; min-width: 200px;">
<label for="status" style="font-size: 0.8rem; font-weight: 600;">Estado</label>
<select name="status" id="status" style="width: 100%; padding: 0.65rem; border: 1px solid var(--efintel-border); border-radius: 4px; outline: none; font-family: 'Inter';" onchange="document.getElementById('filter-form').submit();">
<option value="">Todos los Estados</option>
<option value="ACTIVO" {% if request.GET.status == 'ACTIVO' %}selected{% endif %}>Activo</option>
<option value="PAUSADA" {% if request.GET.status == 'PAUSADA' %}selected{% endif %}>En Pausa</option>
<option value="TERMINADO" {% if request.GET.status == 'TERMINADO' %}selected{% endif %}>Terminado</option>
<option value="BORRADOR" {% if request.GET.status == 'BORRADOR' %}selected{% endif %}>Borrador</option>
</select>
</div>
<button type="submit" class="btn-outline" style="height: 42px;"><i data-lucide="filter" style="width:16px;"></i> Filtrar</button>
{% if request.GET.search or request.GET.status %}
<a href="{% url 'project_list' %}" class="btn-secondary" style="height: 42px; line-height: 24px; text-decoration: none;">Limpiar</a>
{% endif %}
</form>
</div>
<div class="project-grid" style="display: grid; grid-template-columns: repeat(auto-fill, minmax(350px, 1fr)); gap: 1.5rem;">
{% for project in projects %}
<div class="data-card project-card" style="padding: 1.5rem; display:flex; flex-direction:column; justify-content:space-between; position:relative; background:white;">
<div>
<div style="display:flex; justify-content:space-between; align-items:flex-start; margin-bottom:0.75rem;">
<div>
<span class="badge badge-blue" style="font-family:var(--font-mono); font-size:0.7rem;">{{ project.code }}</span>
<h3 style="margin:0.25rem 0 0 0; color:var(--efintel-petroleum); font-size:1.1rem; font-weight:700;">
<a href="{% url 'project_detail' project.id %}" style="text-decoration:none; color:inherit;">{{ project.name }}</a>
</h3>
</div>
<span class="badge {% if project.status == 'ACTIVO' %}badge-emerald{% elif project.status == 'PAUSADA' %}badge-amber{% elif project.status == 'BORRADOR' %}badge-gray{% else %}badge-blue{% endif %}" style="font-size:0.7rem;">
{{ project.get_status_display }}
</span>
</div>
<div style="color: var(--text-secondary); font-size: 0.8rem; margin-bottom: 1rem;">
<strong>Director:</strong> {{ project.manager.username|default:"No asignado" }} |
<strong>Forma Pago:</strong> {{ project.payment_method|truncatechars:20 }}
</div>
<!-- Requerimiento 9: Presupuesto, Ingresos, Egresos y Saldo -->
<div style="background:#f8fafc; padding:1rem; border-radius:6px; border:1px solid #e2e8f0; display:flex; flex-direction:column; gap:0.4rem;">
<div style="display: flex; justify-content: space-between; font-size:0.8rem;">
<span style="color: var(--efintel-gray);">Presupuesto Asignado:</span>
<span style="font-weight: 700; font-family: var(--font-mono);">${{ project.assigned_budget_clp|floatformat:"0"|intcomma }}</span>
</div>
<div style="display: flex; justify-content: space-between; font-size:0.8rem;">
<span style="color: #16a34a;">Ingresos Totales:</span>
<span style="font-weight: 700; font-family: var(--font-mono); color: #16a34a;">+${{ project.total_income_clp|floatformat:"0"|intcomma }}</span>
</div>
<div style="display: flex; justify-content: space-between; font-size:0.8rem;">
<span style="color: #dc2626;">Egresos Acumulados:</span>
<span style="font-weight: 700; font-family: var(--font-mono); color: #dc2626;">-${{ project.total_expenses_clp|floatformat:"0"|intcomma }}</span>
</div>
<div style="display: flex; justify-content: space-between; font-size:0.85rem; padding-top:0.4rem; border-top:1px dashed #cbd5e1; margin-top:0.2rem;">
<span style="font-weight: 700; color: var(--efintel-dark);">Saldo Neto:</span>
<span style="font-weight: 800; font-family: var(--font-mono); {% if project.balance_clp >= 0 %}color:#16a34a;{% else %}color:#dc2626;{% endif %}">
{% if project.balance_clp >= 0 %}+{% endif %}${{ project.balance_clp|floatformat:"0"|intcomma }}
</span>
</div>
</div>
</div>
<div style="margin-top: 1.25rem; display:flex; justify-content:space-between; align-items:center; border-top:1px solid #f1f5f9; padding-top:0.75rem;">
<span style="font-size:0.75rem; color:var(--efintel-gray);">{{ project.expense_count }} Erogaciones</span>
<div style="display:flex; gap:0.5rem;">
{% if is_admin or is_pm %}
<a href="{% url 'project_edit' project.id %}" class="btn-secondary" style="padding:0.3rem 0.6rem; font-size:0.75rem; text-decoration:none;" title="Editar Proyecto"><i data-lucide="pencil" style="width:12px;"></i></a>
{% endif %}
<a href="{% url 'project_detail' project.id %}" class="btn-primary" style="padding:0.3rem 0.8rem; font-size:0.75rem; text-decoration:none; background:var(--efintel-blue);">Ver Detalle & Fases &rarr;</a>
</div>
</div>
</div>
{% empty %}
<div class="data-card" style="padding: 2rem; text-align: center; grid-column: 1 / -1;">
No hay proyectos registrados en este perfil.
</div>
{% endfor %}
</div>
{% endblock %}