diff --git a/py_app/app/__pycache__/order_labels.cpython-312.pyc b/py_app/app/__pycache__/order_labels.cpython-312.pyc
index e547fba..fc8592a 100644
Binary files a/py_app/app/__pycache__/order_labels.cpython-312.pyc and b/py_app/app/__pycache__/order_labels.cpython-312.pyc differ
diff --git a/py_app/app/db_create_scripts/recreate_order_for_labels_table.py b/py_app/app/db_create_scripts/recreate_order_for_labels_table.py
new file mode 100644
index 0000000..ef090c6
--- /dev/null
+++ b/py_app/app/db_create_scripts/recreate_order_for_labels_table.py
@@ -0,0 +1,50 @@
+import mariadb
+
+# Database connection credentials
+DB_CONFIG = {
+ "user": "trasabilitate",
+ "password": "Initial01!",
+ "host": "localhost",
+ "database": "trasabilitate_database"
+}
+
+def recreate_order_for_labels_table():
+ conn = mariadb.connect(**DB_CONFIG)
+ cursor = conn.cursor()
+ print("Connected to the database successfully!")
+
+ # Drop the table if it exists
+ cursor.execute("DROP TABLE IF EXISTS order_for_labels")
+ print("Dropped existing 'order_for_labels' table.")
+
+ # Create the table with the new unique constraint
+ create_table_sql = """
+ CREATE TABLE order_for_labels (
+ id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT 'Unique identifier',
+ comanda_productie VARCHAR(15) NOT NULL UNIQUE COMMENT 'Production Order (unique)',
+ cod_articol VARCHAR(15) COMMENT 'Article Code',
+ descr_com_prod VARCHAR(50) NOT NULL COMMENT 'Production Order Description',
+ cantitate INT(3) NOT NULL COMMENT 'Quantity',
+ data_livrare DATE COMMENT 'Delivery date',
+ dimensiune VARCHAR(20) COMMENT 'Dimensions',
+ com_achiz_client VARCHAR(25) COMMENT 'Client Purchase Order',
+ nr_linie_com_client INT(3) COMMENT 'Client Order Line Number',
+ customer_name VARCHAR(50) COMMENT 'Customer Name',
+ customer_article_number VARCHAR(25) COMMENT 'Customer Article Number',
+ open_for_order VARCHAR(25) COMMENT 'Open for Order Status',
+ line_number INT(3) COMMENT 'Line Number',
+ printed_labels TINYINT(1) NOT NULL DEFAULT 0 COMMENT 'Boolean flag: 0=labels not printed, 1=labels printed',
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'Record creation timestamp',
+ updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'Record update timestamp'
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Table for storing order information for label generation';
+ """
+ cursor.execute(create_table_sql)
+ print("Created new 'order_for_labels' table with unique comanda_productie.")
+
+ conn.commit()
+ cursor.close()
+ conn.close()
+ print("Done.")
+
+if __name__ == "__main__":
+ recreate_order_for_labels_table()
diff --git a/py_app/app/order_labels.py b/py_app/app/order_labels.py
index 3dc557c..7eaed8b 100644
--- a/py_app/app/order_labels.py
+++ b/py_app/app/order_labels.py
@@ -7,6 +7,7 @@ import mariadb
from flask import current_app, request, render_template, session, redirect, url_for, flash
import csv
import os
+import json
import tempfile
from datetime import datetime
@@ -236,6 +237,24 @@ def process_csv_file(file_path):
return orders_data, all_errors, all_warnings
def upload_orders_handler():
+ # Handle clear table POST
+ if request.method == 'POST' and request.form.get('clear_table') == '1':
+ session.pop('orders_csv_data', None)
+ session.pop('csv_filename', None)
+ session.pop('orders_csv_filepath', None)
+ session.pop('orders_validation_errors', None)
+ session.pop('orders_validation_warnings', None)
+ session.pop('leftover_orders', None)
+ session.pop('leftover_description', None)
+ # Remove the leftovers JSON file if it exists
+ leftovers_path = os.path.join(current_app.root_path, 'static', 'leftover_orders.json')
+ try:
+ if os.path.exists(leftovers_path):
+ os.remove(leftovers_path)
+ except Exception:
+ pass
+ flash('Leftover orders have been cleared.', 'info')
+ return redirect(url_for('main.view_orders'))
"""
Main handler for the upload orders functionality
Handles both CSV upload/preview and database insertion
@@ -295,12 +314,28 @@ def upload_orders_handler():
success_count += 1
else:
failed_count += 1
- failed_orders.append(f"{order.get('comanda_productie', 'Unknown')}: {message}")
+ order_with_error = order.copy()
+ order_with_error['error_message'] = message
+ failed_orders.append(order_with_error)
+
+ # Save leftovers to static/leftover_orders.json if any
+ if failed_orders:
+ static_folder = os.path.join(current_app.root_path, 'static')
+ os.makedirs(static_folder, exist_ok=True)
+ leftovers_path = os.path.join(static_folder, 'leftover_orders.json')
+ with open(leftovers_path, 'w', encoding='utf-8') as f:
+ json.dump(failed_orders, f, ensure_ascii=False, indent=2)
# Create report
report = f"✅ Successfully imported {success_count} orders."
if failed_count > 0:
report += f" ❌ {failed_count} orders failed to import."
+ leftover_description = (
+ "These orders were not uploaded to the database because they already exist. "
+ "Check your order list or modify them in the database."
+ )
+ session['leftover_orders'] = failed_orders
+ session['leftover_description'] = leftover_description
for failure in failed_orders[:5]: # Show first 5 failures
report += f"
• {failure}"
if len(failed_orders) > 5:
@@ -313,10 +348,30 @@ def upload_orders_handler():
session.pop('orders_csv_filepath', None)
session.pop('orders_validation_errors', None)
session.pop('orders_validation_warnings', None)
+ session.pop('leftover_orders', None)
+ session.pop('leftover_description', None)
flash(report, "success" if failed_count == 0 else "warning")
-
- return redirect(url_for('main.view_orders'))
+ if failed_count > 0:
+ # Show leftover orders on the upload_orders page
+ # Try to reload leftovers from JSON if available
+ leftovers_path = os.path.join(current_app.root_path, 'static', 'leftover_orders.json')
+ orders_data = session.get('leftover_orders', [])
+ try:
+ if os.path.exists(leftovers_path):
+ with open(leftovers_path, 'r', encoding='utf-8') as f:
+ orders_data = json.load(f)
+ except Exception:
+ pass
+ leftover_description = session.get('leftover_description', '')
+ return render_template('upload_orders.html',
+ orders=orders_data,
+ leftover_description=leftover_description,
+ validation_errors=validation_errors,
+ validation_warnings=validation_warnings,
+ report=report)
+ else:
+ return redirect(url_for('main.view_orders'))
# Load data from session if available
elif 'orders_csv_data' in session:
diff --git a/py_app/app/static/qz-tray.js.backup b/py_app/app/static/qz-tray.js.backup
deleted file mode 100644
index 46633a1..0000000
--- a/py_app/app/static/qz-tray.js.backup
+++ /dev/null
@@ -1,2859 +0,0 @@
-'use strict';
-
-/**
- * @version 2.2.4
- * @overview QZ Tray Connector
- * @license LGPL-2.1-only
- *
qz.configs.setDefaults docs for available values.
- *
- * @see qz.configs.setDefaults
- */
- this.reconfigure = function(newOpts) {
- for(var key in newOpts) {
- if (newOpts[key] !== undefined) {
- this._dirtyOpts[key] = true;
- }
- }
-
- _qz.tools.extend(this.config, newOpts);
- };
-
- /**
- * @returns {Object} The currently applied options on this config.
- */
- this.getOptions = function() {
- return _qz.compatible.config(this.config, this._dirtyOpts);
- };
-
- // init calls for new config object
- this.setPrinter(printer);
- this.reconfigure(opts);
- }
-
- /**
- * Shortcut method for calling qz.print with a particular config.
- * @param {Array