feat(dashboard): add logs page, pagination, quick mapping modal, price pre-validation
- Add /logs page with per-order sync run details, filters (Toate/Importate/Fara Mapare/Erori) - Add price pre-validation (validate_prices + ensure_prices) to prevent ORA-20000 on direct articles - Add find_new_orders() to detect orders not yet in Oracle COMENZI - Extend missing_skus table with order context (order_count, order_numbers, customers) - Add server-side pagination on /api/validate/missing-skus and /missing-skus page - Replace confusing "Skip"/"Err" with "Fara Mapare"/"Erori" terminology - Add inline mapping modal on dashboard (replaces navigation to /mappings) - Add 2-row stat cards: orders (Comenzi Noi/Ready/Importate/Fara Mapare/Erori) + articles - Add ID_POL/ID_GESTIUNE/ID_SECTIE to config.py and .env - Update .gitignore (venv, *.db, api/api/, logs/) - 33/33 unit tests pass, E2E verified with Playwright Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -5,12 +5,12 @@
|
||||
{% block content %}
|
||||
<h4 class="mb-4">Dashboard</h4>
|
||||
|
||||
<!-- Stat cards row -->
|
||||
<div class="row g-3 mb-4" id="statsRow">
|
||||
<!-- Stat cards - Row 1: Comenzi -->
|
||||
<div class="row g-3 mb-2" id="statsRow">
|
||||
<div class="col">
|
||||
<div class="card stat-card">
|
||||
<div class="stat-value text-secondary" id="stat-pending">-</div>
|
||||
<div class="stat-label">In Asteptare</div>
|
||||
<div class="stat-value text-info" id="stat-new">-</div>
|
||||
<div class="stat-label">Comenzi Noi</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
@@ -22,28 +22,57 @@
|
||||
<div class="col">
|
||||
<div class="card stat-card">
|
||||
<div class="stat-value text-success" id="stat-imported">-</div>
|
||||
<div class="stat-label">Imported</div>
|
||||
<div class="stat-label">Importate</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="card stat-card">
|
||||
<div class="stat-value text-warning" id="stat-skipped">-</div>
|
||||
<div class="stat-label">Skipped</div>
|
||||
<div class="stat-label">Fără Mapare</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="card stat-card">
|
||||
<div class="stat-value text-danger" id="stat-missing">-</div>
|
||||
<div class="stat-label">SKU Lipsa</div>
|
||||
<div class="stat-value text-danger" id="stat-errors">-</div>
|
||||
<div class="stat-label">Erori Import</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Stat cards - Row 2: Articole -->
|
||||
<div class="row g-3 mb-4" id="statsRowArticles">
|
||||
<div class="col">
|
||||
<div class="card stat-card">
|
||||
<div class="stat-value text-secondary" id="stat-total-skus">-</div>
|
||||
<div class="stat-label">Total SKU Scanate</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="card stat-card">
|
||||
<div class="stat-value text-success" id="stat-mapped-skus">-</div>
|
||||
<div class="stat-label">Cu Mapare</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="card stat-card">
|
||||
<div class="stat-value text-warning" id="stat-missing-skus">-</div>
|
||||
<div class="stat-label">Fără Mapare</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col d-none d-md-block"></div>
|
||||
<div class="col d-none d-md-block"></div>
|
||||
</div>
|
||||
|
||||
<!-- Sync Control -->
|
||||
<div class="card mb-4">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<span>Sync Control</span>
|
||||
<span class="badge bg-secondary" id="syncStatusBadge">idle</span>
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
<a href="/logs" class="btn btn-sm btn-outline-info">
|
||||
<i class="bi bi-journal-text"></i> Jurnale Import
|
||||
</a>
|
||||
<span class="badge bg-secondary" id="syncStatusBadge">idle</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row align-items-center">
|
||||
@@ -91,8 +120,8 @@
|
||||
<th>Status</th>
|
||||
<th>Total</th>
|
||||
<th>OK</th>
|
||||
<th>Skip</th>
|
||||
<th>Err</th>
|
||||
<th>Fără mapare</th>
|
||||
<th>Erori</th>
|
||||
<th>Durata</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -117,17 +146,52 @@
|
||||
<tr>
|
||||
<th>SKU</th>
|
||||
<th>Produs</th>
|
||||
<th>Data</th>
|
||||
<th>Actiune</th>
|
||||
<th>Nr. Comenzi</th>
|
||||
<th>Primul Client</th>
|
||||
<th colspan="2">Acțiune</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="missingSkusBody">
|
||||
<tr><td colspan="4" class="text-center text-muted py-3">Se incarca...</td></tr>
|
||||
<tr><td colspan="5" class="text-center text-muted py-3">Se incarca...</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Map SKU Modal (copied from missing_skus.html) -->
|
||||
<div class="modal fade" id="mapModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Mapeaza SKU: <code id="mapSku"></code></h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="mb-3 position-relative">
|
||||
<label class="form-label">CODMAT (Articol ROA)</label>
|
||||
<input type="text" class="form-control" id="mapCodmat" placeholder="Cauta codmat sau denumire..." autocomplete="off">
|
||||
<div class="autocomplete-dropdown d-none" id="mapAutocomplete"></div>
|
||||
<small class="text-muted" id="mapSelectedArticle"></small>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-6 mb-3">
|
||||
<label class="form-label">Cantitate ROA</label>
|
||||
<input type="number" class="form-control" id="mapCantitate" value="1" step="0.001" min="0.001">
|
||||
</div>
|
||||
<div class="col-6 mb-3">
|
||||
<label class="form-label">Procent Pret (%)</label>
|
||||
<input type="number" class="form-control" id="mapProcent" value="100" step="0.01" min="0" max="100">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Anuleaza</button>
|
||||
<button type="button" class="btn btn-primary" onclick="saveQuickMap()">Salveaza</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
|
||||
Reference in New Issue
Block a user