updated print module
This commit is contained in:
Binary file not shown.
99
py_app/app/print_module.py
Normal file
99
py_app/app/print_module.py
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
import mariadb
|
||||||
|
from flask import current_app
|
||||||
|
|
||||||
|
def get_db_connection():
|
||||||
|
"""Get database connection using external server configuration"""
|
||||||
|
settings_file = current_app.instance_path + '/external_server.conf'
|
||||||
|
settings = {}
|
||||||
|
with open(settings_file, 'r') as f:
|
||||||
|
for line in f:
|
||||||
|
key, value = line.strip().split('=', 1)
|
||||||
|
settings[key] = value
|
||||||
|
return mariadb.connect(
|
||||||
|
user=settings['username'],
|
||||||
|
password=settings['password'],
|
||||||
|
host=settings['server_domain'],
|
||||||
|
port=int(settings['port']),
|
||||||
|
database=settings['database_name']
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_unprinted_orders_data(limit=100):
|
||||||
|
"""
|
||||||
|
Retrieve unprinted orders from the database for display
|
||||||
|
Returns list of order dictionaries where printed_labels != 1
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
conn = get_db_connection()
|
||||||
|
cursor = conn.cursor()
|
||||||
|
|
||||||
|
# Check if printed_labels column exists
|
||||||
|
cursor.execute("SHOW COLUMNS FROM order_for_labels LIKE 'printed_labels'")
|
||||||
|
column_exists = cursor.fetchone()
|
||||||
|
|
||||||
|
if column_exists:
|
||||||
|
# Use printed_labels column
|
||||||
|
cursor.execute("""
|
||||||
|
SELECT id, comanda_productie, cod_articol, descr_com_prod, cantitate,
|
||||||
|
com_achiz_client, nr_linie_com_client, customer_name,
|
||||||
|
customer_article_number, open_for_order, line_number,
|
||||||
|
printed_labels, created_at, updated_at
|
||||||
|
FROM order_for_labels
|
||||||
|
WHERE printed_labels != 1
|
||||||
|
ORDER BY created_at DESC
|
||||||
|
LIMIT %s
|
||||||
|
""", (limit,))
|
||||||
|
else:
|
||||||
|
# Fallback: get all orders if no printed_labels column
|
||||||
|
cursor.execute("""
|
||||||
|
SELECT id, comanda_productie, cod_articol, descr_com_prod, cantitate,
|
||||||
|
com_achiz_client, nr_linie_com_client, customer_name,
|
||||||
|
customer_article_number, open_for_order, line_number,
|
||||||
|
created_at, updated_at
|
||||||
|
FROM order_for_labels
|
||||||
|
ORDER BY created_at DESC
|
||||||
|
LIMIT %s
|
||||||
|
""", (limit,))
|
||||||
|
|
||||||
|
orders = []
|
||||||
|
for row in cursor.fetchall():
|
||||||
|
if column_exists:
|
||||||
|
orders.append({
|
||||||
|
'id': row[0],
|
||||||
|
'comanda_productie': row[1],
|
||||||
|
'cod_articol': row[2],
|
||||||
|
'descr_com_prod': row[3],
|
||||||
|
'cantitate': row[4],
|
||||||
|
'com_achiz_client': row[5],
|
||||||
|
'nr_linie_com_client': row[6],
|
||||||
|
'customer_name': row[7],
|
||||||
|
'customer_article_number': row[8],
|
||||||
|
'open_for_order': row[9],
|
||||||
|
'line_number': row[10],
|
||||||
|
'printed_labels': row[11],
|
||||||
|
'created_at': row[12],
|
||||||
|
'updated_at': row[13]
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
orders.append({
|
||||||
|
'id': row[0],
|
||||||
|
'comanda_productie': row[1],
|
||||||
|
'cod_articol': row[2],
|
||||||
|
'descr_com_prod': row[3],
|
||||||
|
'cantitate': row[4],
|
||||||
|
'com_achiz_client': row[5],
|
||||||
|
'nr_linie_com_client': row[6],
|
||||||
|
'customer_name': row[7],
|
||||||
|
'customer_article_number': row[8],
|
||||||
|
'open_for_order': row[9],
|
||||||
|
'line_number': row[10],
|
||||||
|
'printed_labels': 0, # Default to not printed
|
||||||
|
'created_at': row[11],
|
||||||
|
'updated_at': row[12]
|
||||||
|
})
|
||||||
|
|
||||||
|
conn.close()
|
||||||
|
return orders
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error retrieving unprinted orders: {e}")
|
||||||
|
return []
|
||||||
@@ -21,6 +21,7 @@ from app.settings import (
|
|||||||
delete_user_handler,
|
delete_user_handler,
|
||||||
save_external_db_handler
|
save_external_db_handler
|
||||||
)
|
)
|
||||||
|
from .print_module import get_unprinted_orders_data
|
||||||
|
|
||||||
bp = Blueprint('main', __name__)
|
bp = Blueprint('main', __name__)
|
||||||
warehouse_bp = Blueprint('warehouse', __name__)
|
warehouse_bp = Blueprint('warehouse', __name__)
|
||||||
@@ -1148,6 +1149,19 @@ def view_orders():
|
|||||||
orders = get_orders_from_database(200) # Get last 200 orders
|
orders = get_orders_from_database(200) # Get last 200 orders
|
||||||
return render_template('view_orders.html', orders=orders)
|
return render_template('view_orders.html', orders=orders)
|
||||||
|
|
||||||
|
@bp.route('/get_unprinted_orders', methods=['GET'])
|
||||||
|
def get_unprinted_orders():
|
||||||
|
"""Get all rows from order_for_labels where printed != 1"""
|
||||||
|
if 'role' not in session or session['role'] not in ['superadmin', 'warehouse_manager', 'etichete']:
|
||||||
|
return jsonify({'error': 'Access denied'}), 403
|
||||||
|
|
||||||
|
try:
|
||||||
|
data = get_unprinted_orders_data()
|
||||||
|
return jsonify(data)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
return jsonify({'error': str(e)}), 500
|
||||||
|
|
||||||
@warehouse_bp.route('/create_locations', methods=['GET', 'POST'])
|
@warehouse_bp.route('/create_locations', methods=['GET', 'POST'])
|
||||||
def create_locations():
|
def create_locations():
|
||||||
from app.warehouse import create_locations_handler
|
from app.warehouse import create_locations_handler
|
||||||
|
|||||||
@@ -1,10 +1,184 @@
|
|||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
|
|
||||||
{% block title %}Print Module{% endblock %}
|
{% block head %}
|
||||||
|
<style>
|
||||||
|
#label-preview {
|
||||||
|
background: #fafafa;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="print-module-container">
|
<div class="scan-container">
|
||||||
<h1>Print Module</h1>
|
<!-- Label Preview Card -->
|
||||||
<p>This page will allow users to access the print module for labels.</p>
|
<div class="card scan-form-card" style="display: flex; justify-content: center; align-items: center; min-height: 400px;">
|
||||||
|
<h3 style="position: absolute; top: 15px; left: 15px;">Label Preview</h3>
|
||||||
|
<div id="label-preview" style="border: 1px solid #ddd; padding: 10px; position: relative; background: #fafafa; width: 301px; height: 434.7px;">
|
||||||
|
<!-- Label content rectangle -->
|
||||||
|
<div id="label-content" style="position: absolute; top: 65.7px; left: 11.34px; width: 227.4px; height: 321.3px; border: 2px solid #333; background: white;">
|
||||||
|
<!-- Top row content: Company name -->
|
||||||
|
<div style="position: absolute; top: 0; left: 0; right: 0; height: 32.13px; display: flex; align-items: center; justify-content: center; font-weight: bold; font-size: 12px; color: #000; z-index: 10;">
|
||||||
|
INNOFA RROMANIA SRL
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Second row content: Customer Name -->
|
||||||
|
<div id="customer-name-row" style="position: absolute; top: 32.13px; left: 0; right: 0; height: 32.13px; display: flex; align-items: center; justify-content: center; font-size: 11px; color: #000;">
|
||||||
|
<!-- Customer name will be populated here -->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Horizontal dividing lines for 9 parts (row 6 is double height) -->
|
||||||
|
<div style="position: absolute; top: 32.13px; left: 0; right: 0; height: 1px; background: #999;"></div>
|
||||||
|
<div style="position: absolute; top: 67.83px; left: 0; right: 0; height: 1px; background: #999;"></div>
|
||||||
|
<div style="position: absolute; top: 103.53px; left: 0; right: 0; height: 1px; background: #999;"></div>
|
||||||
|
<div style="position: absolute; top: 139.23px; left: 0; right: 0; height: 1px; background: #999;"></div>
|
||||||
|
<div style="position: absolute; top: 175.23px; left: 0; right: 0; height: 1px; background: #999;"></div>
|
||||||
|
<!-- Row 6 is double height, so no line at 210.63px -->
|
||||||
|
<div style="position: absolute; top: 246.33px; left: 0; right: 0; height: 1px; background: #999;"></div>
|
||||||
|
<div style="position: absolute; top: 282.03px; left: 0; right: 0; height: 1px; background: #999;"></div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Row 3 content: Quantity ordered -->
|
||||||
|
<div style="position: absolute; top: 67.83px; left: 0; width: 90.96px; height: 35.7px; display: flex; align-items: center; padding-left: 5px; font-size: 10px; color: #000;">
|
||||||
|
Quantity ordered
|
||||||
|
</div>
|
||||||
|
<div id="quantity-ordered-value" style="position: absolute; top: 67.83px; left: 90.96px; width: 136.44px; height: 35.7px; display: flex; align-items: center; justify-content: center; font-size: 11px; font-weight: bold; color: #000;">
|
||||||
|
<!-- Quantity value will be populated here -->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Row 4 content: Client Order Info -->
|
||||||
|
<div id="client-order-info" style="position: absolute; top: 103.53px; left: 90.96px; width: 136.44px; height: 35.7px; display: flex; align-items: center; justify-content: center; font-size: 10px; color: #000;">
|
||||||
|
<!-- Client order info will be populated here -->
|
||||||
|
</div>
|
||||||
|
<!-- Row 4 content: Customer order -->
|
||||||
|
<div style="position: absolute; top: 103.53px; left: 0; width: 90.96px; height: 35.7px; display: flex; align-items: center; padding-left: 5px; font-size: 10px; color: #000;">
|
||||||
|
Customer order
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Row 5 content: Delivery date -->
|
||||||
|
<div style="position: absolute; top: 139.23px; left: 0; width: 90.96px; height: 35.7px; display: flex; align-items: center; padding-left: 5px; font-size: 10px; color: #000;">
|
||||||
|
Delivery date
|
||||||
|
</div>
|
||||||
|
<div id="delivery-date-value" style="position: absolute; top: 139.23px; left: 90.96px; width: 136.44px; height: 35.7px; display: flex; align-items: center; justify-content: center; font-size: 10px; color: #000;">
|
||||||
|
<!-- Delivery date value will be populated here -->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Row 6 content: Description (double height row) -->
|
||||||
|
<div style="position: absolute; top: 174.93px; left: 0; width: 90.96px; height: 71.4px; display: flex; align-items: center; padding-left: 5px; font-size: 10px; color: #000;">
|
||||||
|
Description
|
||||||
|
</div>
|
||||||
|
<div id="description-value" style="position: absolute; top: 174.93px; left: 90.96px; width: 136.44px; height: 71.4px; display: flex; align-items: center; justify-content: center; font-size: 9px; color: #000; text-align: center; line-height: 1.2; padding: 2px; overflow: hidden; word-wrap: break-word;">
|
||||||
|
<!-- Description value will be populated here -->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Data Preview Card -->
|
||||||
|
<div class="card scan-table-card">
|
||||||
|
<h3>Data Preview (Unprinted Orders)</h3>
|
||||||
|
<button id="check-db-btn" class="btn btn-primary mb-3">Check Database</button>
|
||||||
|
<div class="report-table-container">
|
||||||
|
<table class="scan-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>ID</th>
|
||||||
|
<th>Comanda Productie</th>
|
||||||
|
<th>Cod Articol</th>
|
||||||
|
<th>Descr. Com. Prod</th>
|
||||||
|
<th>Cantitate</th>
|
||||||
|
<th>Com.Achiz.Client</th>
|
||||||
|
<th>Nr. Linie</th>
|
||||||
|
<th>Customer Name</th>
|
||||||
|
<th>Customer Art. Nr.</th>
|
||||||
|
<th>Open Order</th>
|
||||||
|
<th>Line</th>
|
||||||
|
<th>Printed</th>
|
||||||
|
<th>Created</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="unprinted-orders-table">
|
||||||
|
<!-- Data will be loaded here via JavaScript -->
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.getElementById('check-db-btn').addEventListener('click', function() {
|
||||||
|
fetch('/get_unprinted_orders')
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
const tbody = document.getElementById('unprinted-orders-table');
|
||||||
|
tbody.innerHTML = '';
|
||||||
|
data.forEach(order => {
|
||||||
|
const tr = document.createElement('tr');
|
||||||
|
tr.innerHTML = `
|
||||||
|
<td>${order.id}</td>
|
||||||
|
<td><strong>${order.comanda_productie}</strong></td>
|
||||||
|
<td>${order.cod_articol || '-'}</td>
|
||||||
|
<td>${order.descr_com_prod}</td>
|
||||||
|
<td style="text-align: right; font-weight: 600;">${order.cantitate}</td>
|
||||||
|
<td>${order.com_achiz_client || '-'}</td>
|
||||||
|
<td style="text-align: right;">${order.nr_linie_com_client || '-'}</td>
|
||||||
|
<td>${order.customer_name || '-'}</td>
|
||||||
|
<td>${order.customer_article_number || '-'}</td>
|
||||||
|
<td>${order.open_for_order || '-'}</td>
|
||||||
|
<td style="text-align: right;">${order.line_number || '-'}</td>
|
||||||
|
<td style="text-align: center;">
|
||||||
|
${order.printed_labels == 1 ?
|
||||||
|
'<span style="color: #28a745; font-weight: bold;">✓ Yes</span>' :
|
||||||
|
'<span style="color: #dc3545;">✗ No</span>'}
|
||||||
|
</td>
|
||||||
|
<td style="font-size: 11px; color: #6c757d;">
|
||||||
|
${order.created_at ? new Date(order.created_at).toLocaleString() : '-'}
|
||||||
|
</td>
|
||||||
|
`;
|
||||||
|
tbody.appendChild(tr);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Update the label preview with customer name from first row
|
||||||
|
if (data.length > 0) {
|
||||||
|
const customerName = data[0].customer_name || 'N/A';
|
||||||
|
document.getElementById('customer-name-row').textContent = customerName;
|
||||||
|
|
||||||
|
// Update quantity ordered value
|
||||||
|
const quantity = data[0].cantitate || '0';
|
||||||
|
document.getElementById('quantity-ordered-value').textContent = quantity;
|
||||||
|
|
||||||
|
// Update client order info (Com.Achiz.Client - Nr. Linie)
|
||||||
|
const comAchizClient = data[0].com_achiz_client || '';
|
||||||
|
const nrLinie = data[0].nr_linie_com_client || '';
|
||||||
|
const clientOrderInfo = comAchizClient && nrLinie ? `${comAchizClient}-${nrLinie}` : 'N/A';
|
||||||
|
document.getElementById('client-order-info').textContent = clientOrderInfo;
|
||||||
|
|
||||||
|
// Update delivery date (using created_at as placeholder since delivery_date column doesn't exist)
|
||||||
|
const deliveryDate = data[0].created_at ? new Date(data[0].created_at).toLocaleDateString() : 'N/A';
|
||||||
|
document.getElementById('delivery-date-value').textContent = deliveryDate;
|
||||||
|
|
||||||
|
// Update description (Descr. Com. Prod)
|
||||||
|
const description = data[0].descr_com_prod || 'N/A';
|
||||||
|
document.getElementById('description-value').textContent = description;
|
||||||
|
} else {
|
||||||
|
document.getElementById('customer-name-row').textContent = 'No data available';
|
||||||
|
document.getElementById('quantity-ordered-value').textContent = '0';
|
||||||
|
document.getElementById('client-order-info').textContent = 'N/A';
|
||||||
|
document.getElementById('delivery-date-value').textContent = 'N/A';
|
||||||
|
document.getElementById('description-value').textContent = 'N/A';
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('Error fetching data:', error);
|
||||||
|
document.getElementById('customer-name-row').textContent = 'Error loading data';
|
||||||
|
document.getElementById('quantity-ordered-value').textContent = 'Error';
|
||||||
|
document.getElementById('client-order-info').textContent = 'Error';
|
||||||
|
document.getElementById('delivery-date-value').textContent = 'Error';
|
||||||
|
document.getElementById('description-value').textContent = 'Error';
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
Reference in New Issue
Block a user