V0.8.6 - Frefractor: Counting.py

This commit is contained in:
Javier
2026-01-23 11:45:35 -06:00
parent 6789f0899a
commit 53158e76e4
10 changed files with 705 additions and 669 deletions

View File

@@ -8,8 +8,9 @@
<div>
<a href="{{ url_for('dashboard') }}" class="breadcrumb">← Back to Dashboard</a>
<h1 class="page-title">{{ count_session.session_name }}</h1>
<!-- Fixed variable name from session.session_type to count_session.session_type -->
<span class="session-type-badge session-type-{{ count_session.session_type }}">
{{ 'Full Physical' if session.session_type == 'full_physical' else 'Cycle Count' }}
{{ 'Full Physical' if count_session.session_type == 'full_physical' else 'Cycle Count' }}
</span>
</div>
</div>
@@ -30,6 +31,7 @@
{% endif %}
</div>
{% if not count_session.master_baseline_timestamp %}
<!-- Note: Using data_imports blueprint URL -->
<form method="POST" action="{{ url_for('data_imports.upload_master', session_id=count_session.session_id) }}" enctype="multipart/form-data" class="upload-form">
<input type="file" name="csv_file" accept=".csv" required class="file-input">
<button type="submit" class="btn btn-primary btn-sm">Upload MASTER</button>
@@ -41,8 +43,8 @@
<div class="baseline-label">CURRENT Baseline (Optional)</div>
<div class="baseline-status">
{% if count_session.current_baseline_timestamp %}
<span class="status-badge status-success">Last Updated:
<div>{{ count_session.current_baseline_timestamp[:16] if count_session.current_baseline_timestamp else 'Never' }}</div>
<span class="status-badge status-success">✓ Uploaded</span>
<small class="baseline-time">{{ count_session.current_baseline_timestamp[:16] }}</small>
{% else %}
<span class="status-badge status-neutral">Not Uploaded</span>
{% endif %}
@@ -65,27 +67,27 @@
<h2 class="section-title">Real-Time Statistics</h2>
<div class="stats-grid">
<div class="stat-card stat-match" onclick="showStatusDetails('match', {{ count_session.session_id }})">
<div class="stat-card stat-match" onclick="showStatusDetails('match')">
<div class="stat-number">{{ stats.matched or 0 }}</div>
<div class="stat-label">✓ Matched</div>
</div>
<div class="stat-card stat-duplicate" onclick="showStatusDetails('duplicates', {{ count_session.session_id }})">
<div class="stat-card stat-duplicate" onclick="showStatusDetails('duplicates')">
<div class="stat-number">{{ stats.duplicates or 0 }}</div>
<div class="stat-label">🔵 Duplicates</div>
</div>
<div class="stat-card stat-weight-disc" onclick="showStatusDetails('weight_discrepancy', {{ count_session.session_id }})">
<div class="stat-card stat-weight-disc" onclick="showStatusDetails('weight_discrepancy')">
<div class="stat-number">{{ stats.weight_discrepancy or 0 }}</div>
<div class="stat-label">⚖️ Weight Discrepancy</div>
</div>
<div class="stat-card stat-wrong" onclick="showStatusDetails('wrong_location', {{ count_session.session_id }})">
<div class="stat-card stat-wrong" onclick="showStatusDetails('wrong_location')">
<div class="stat-number">{{ stats.wrong_location or 0 }}</div>
<div class="stat-label">⚠ Wrong Location</div>
</div>
<div class="stat-card stat-ghost" onclick="showStatusDetails('ghost_lot', {{ count_session.session_id }})">
<div class="stat-card stat-ghost" onclick="showStatusDetails('ghost_lot')">
<div class="stat-number">{{ stats.ghost_lots or 0 }}</div>
<div class="stat-label">🟣 Ghost Lots</div>
</div>
<div class="stat-card stat-missing" onclick="showStatusDetails('missing', {{ count_session.session_id }})">
<div class="stat-card stat-missing" onclick="showStatusDetails('missing')">
<div class="stat-number">{{ stats.missing_lots or 0 }}</div>
<div class="stat-label">🔴 Missing</div>
</div>
@@ -129,7 +131,12 @@
</thead>
<tbody>
{% for loc in locations %}
<tr class="location-row-clickable" onclick="showLocationDetails({{ loc.location_count_id }}, '{{ loc.location_name }}', '{{ loc.status }}')">
<!-- Refactored to use data attributes instead of direct Jinja injection in onclick -->
<tr class="location-row-clickable"
data-id="{{ loc.location_count_id }}"
data-name="{{ loc.location_name }}"
data-status="{{ loc.status }}"
onclick="handleLocationClick(this)">
<td><strong>{{ loc.location_name }}</strong></td>
<td>
<span class="status-badge status-{{ loc.status }}">
@@ -246,7 +253,10 @@
</div>
<script>
function showStatusDetails(status, sessionId) {
// Store the Session ID globally to use in functions without passing it every time
const CURRENT_SESSION_ID = "{{ count_session.session_id }}";
function showStatusDetails(status) {
document.getElementById('statusModal').style.display = 'flex';
document.getElementById('statusDetailContent').innerHTML = '<div class="loading-spinner">Loading...</div>';
@@ -261,8 +271,8 @@ function showStatusDetails(status, sessionId) {
};
document.getElementById('statusModalTitle').textContent = titles[status] || 'Details';
// Fetch details
fetch(`/session/${sessionId}/status-details/${status}`)
// Fetch details using the blueprint URL structure
fetch(`/session/${CURRENT_SESSION_ID}/status-details/${status}`)
.then(response => response.json())
.then(data => {
if (data.success) {
@@ -421,6 +431,14 @@ let currentLocationName = '';
let currentLocationStatus = '';
let currentLocationData = null;
// New helper function to handle click from data attributes
function handleLocationClick(row) {
const id = row.getAttribute('data-id');
const name = row.getAttribute('data-name');
const status = row.getAttribute('data-status');
showLocationDetails(id, name, status);
}
function showLocationDetails(locationCountId, locationName, status) {
currentLocationId = locationCountId;
currentLocationName = locationName;
@@ -594,6 +612,7 @@ function closeFinalizeConfirm() {
}
function confirmFinalize() {
// Note: The /complete endpoint is handled by blueprints/counting.py
fetch(`/location/${currentLocationId}/complete`, {
method: 'POST',
headers: {
@@ -625,6 +644,7 @@ function closeReopenConfirm() {
}
function confirmReopen() {
// Note: The /reopen endpoint is handled by blueprints/admin_locations.py
fetch(`/location/${currentLocationId}/reopen`, {
method: 'POST',
headers: {
@@ -656,4 +676,4 @@ document.addEventListener('keydown', function(e) {
}
});
</script>
{% endblock %}
{% endblock %}