Rework the demo into a faithful Mago4 look-and-feel and expand it with core ERP modules modelled on the real Mago4 database schema. UI (ispirata a Mago4): - Blue header with logo/search/operation date, desktop-style window tabs - White sidebar with coloured module icons (Anagrafiche, Vendite, Acquisti, Amministrazione, Logistica) - Card-based module landing pages with breadcrumb + tab strip - Document detail forms with left tabs, line grid and totals box Fatturazione (InvoiceMng / MA_SaleDoc): - Document types (Fattura Immediata, DDT, Nota di Credito, ProForma) - Lines with discount/IVA, automatic taxable/tax/total computation - Document states (draft -> printed -> issued / posted_to_inventory) Magazzino (Inventory / MA_InventoryEntries + MA_InventoryReasons): - Inventory movements with load/unload reasons (DebitCreditSign) - Posting a movement actually updates item balances - Causali and stock valuation pages Amministrazione / Scadenzario (AP_AR / MA_PyblsRcvbls): - Open items (receivables/payables) with due date, method, state - Settle action closes the item and recomputes the cash forecast Dashboard riprogettata (focus su scadenze e to-do): - Overdue alert banner, KPI for overdue payables/receivables - Upcoming deadlines table, prioritised "Cose da fare" action list - 30-day cash-flow forecast and customer credit-limit check Adds REST endpoints for invoices, movements, schedules and dashboard data. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
84 lines
5.0 KiB
HTML
84 lines
5.0 KiB
HTML
{% extends "base.html" %}
|
|
{% block title %}Giacenze - Mago4 Demo{% endblock %}
|
|
{% block window_tabs %}<a href="/warehouse" class="window-tab active"><i class="material-icons">inventory</i> Giacenze</a>{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="module-bar">
|
|
<div class="module-title">Giacenze Articoli</div>
|
|
<div class="breadcrumb"><a href="/">Mago4</a><span class="sep">»</span><a href="/magazzino">Logistica</a><span class="sep">»</span><span class="current">Giacenze</span></div>
|
|
</div>
|
|
<div class="tab-strip">
|
|
<a href="/magazzino">Magazzino</a>
|
|
<a href="/inventory-movements">Movimenti</a>
|
|
<a href="/warehouse" class="active">Giacenze</a>
|
|
<a href="/inventory-reasons">Causali</a>
|
|
</div>
|
|
|
|
<div class="content-pad">
|
|
<div class="kpi-grid">
|
|
<div class="kpi-card" style="border-left-color: var(--c-blue)">
|
|
<div class="kpi-title">Articoli in Catalogo</div>
|
|
<div class="kpi-row"><div class="kpi-icon"><i class="material-icons" style="color:var(--c-blue)">inventory_2</i></div><div class="kpi-value">{{ products|length }}</div></div>
|
|
</div>
|
|
<div class="kpi-card" style="border-left-color: var(--c-red)">
|
|
<div class="kpi-title">Articoli Sotto Scorta</div>
|
|
<div class="kpi-row"><div class="kpi-icon"><i class="material-icons" style="color:var(--c-red)">warning</i></div><div class="kpi-value">{{ low_stock|length }}</div></div>
|
|
</div>
|
|
<div class="kpi-card" style="border-left-color: var(--c-purple)">
|
|
<div class="kpi-title">Valore Magazzino (a costo)</div>
|
|
<div class="kpi-row"><div class="kpi-icon"><i class="material-icons" style="color:var(--c-purple)">euro_symbol</i></div><div class="kpi-value">€ {{ "{:,.0f}".format(warehouse_value) }}</div></div>
|
|
</div>
|
|
</div>
|
|
|
|
{% if low_stock %}
|
|
<div class="panel">
|
|
<div class="panel-header"><h3><i class="material-icons" style="color:var(--c-red)">warning</i> Articoli Sotto Scorta Minima</h3></div>
|
|
<table class="data-table">
|
|
<thead><tr><th>Codice</th><th>Descrizione</th><th class="text-right">Giacenza</th><th class="text-right">Scorta Min.</th><th class="text-right">Da Riordinare</th><th></th></tr></thead>
|
|
<tbody>
|
|
{% for p in low_stock %}
|
|
<tr class="low-stock">
|
|
<td class="text-bold mono">{{ p.code }}</td>
|
|
<td>{{ p.description }}</td>
|
|
<td class="text-right text-danger text-bold">{{ p.quantity_in_stock }} {{ p.uom }}</td>
|
|
<td class="text-right">{{ p.reorder_level }} {{ p.uom }}</td>
|
|
<td class="text-right text-danger">{{ p.max_stock - p.quantity_in_stock }} {{ p.uom }}</td>
|
|
<td class="text-center"><button class="btn-icon-sm act-cart" title="Genera ordine" onclick="alert('Genera ordine di acquisto (demo)')"><i class="material-icons">add_shopping_cart</i></button></td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<div class="panel">
|
|
<div class="panel-header"><h3><i class="material-icons">inventory</i> Inventario Completo — Deposito MAG01</h3></div>
|
|
<table class="data-table">
|
|
<thead><tr><th>Codice</th><th>Descrizione</th><th>Categoria</th><th class="text-right">Giacenza</th><th class="text-right">Scorta Min.</th><th class="text-right">Costo Unit.</th><th class="text-right">Valore</th><th class="text-center">Stato</th></tr></thead>
|
|
<tbody>
|
|
{% for p in products %}
|
|
<tr class="{% if p.quantity_in_stock <= p.reorder_level %}low-stock{% endif %}">
|
|
<td class="text-bold mono">{{ p.code }}</td>
|
|
<td>{{ p.description }}</td>
|
|
<td>{{ p.category }}</td>
|
|
<td class="text-right {% if p.quantity_in_stock <= p.reorder_level %}text-danger text-bold{% endif %}">{{ p.quantity_in_stock }} {{ p.uom }}</td>
|
|
<td class="text-right">{{ p.reorder_level }} {{ p.uom }}</td>
|
|
<td class="text-right text-mute">€ {{ "%.2f"|format(p.purchase_price) }}</td>
|
|
<td class="text-right text-bold">€ {{ "%.2f"|format(p.quantity_in_stock * p.purchase_price) }}</td>
|
|
<td class="text-center">
|
|
{% if p.quantity_in_stock <= p.reorder_level %}
|
|
<span class="badge badge-danger"><i class="material-icons">warning</i> Sottoscorta</span>
|
|
{% elif p.quantity_in_stock <= p.reorder_level + 20 %}
|
|
<span class="badge badge-warning"><i class="material-icons">info</i> In esaurimento</span>
|
|
{% else %}
|
|
<span class="badge badge-success"><i class="material-icons">check</i> OK</span>
|
|
{% endif %}
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|