- Add boxes_crates database table with BIGINT IDs and 8-digit auto-numbered box_numbers - Implement boxes CRUD operations (add, edit, update, delete, delete_multiple) - Create boxes route handlers with POST actions for all operations - Add boxes.html template with 3-panel layout matching warehouse locations module - Implement barcode generation and printing with JsBarcode and QZ Tray integration - Add browser print fallback for when QZ Tray is not available - Simplify create box form to single button with auto-generation - Fix JavaScript null reference errors with proper element validation - Convert tuple data to dictionaries for Jinja2 template compatibility - Register boxes blueprint in Flask app initialization
126 lines
4.5 KiB
Python
126 lines
4.5 KiB
Python
"""
|
|
Warehouse Module Routes
|
|
"""
|
|
from flask import Blueprint, render_template, session, redirect, url_for, request, flash, jsonify
|
|
from app.modules.warehouse.warehouse import (
|
|
get_all_locations, add_location, update_location, delete_location,
|
|
delete_multiple_locations, get_location_by_id
|
|
)
|
|
import logging
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
warehouse_bp = Blueprint('warehouse', __name__, url_prefix='/warehouse')
|
|
|
|
|
|
@warehouse_bp.route('/', methods=['GET'])
|
|
def warehouse_index():
|
|
"""Warehouse module main page - launcher for all warehouse operations"""
|
|
if 'user_id' not in session:
|
|
return redirect(url_for('main.login'))
|
|
|
|
return render_template('modules/warehouse/index.html')
|
|
|
|
|
|
@warehouse_bp.route('/set-boxes-locations', methods=['GET', 'POST'])
|
|
def set_boxes_locations():
|
|
"""Set boxes locations - add or update articles in warehouse inventory"""
|
|
if 'user_id' not in session:
|
|
return redirect(url_for('main.login'))
|
|
|
|
return render_template('modules/warehouse/set_boxes_locations.html')
|
|
|
|
|
|
@warehouse_bp.route('/locations', methods=['GET', 'POST'])
|
|
def locations():
|
|
"""Create and manage warehouse locations"""
|
|
if 'user_id' not in session:
|
|
return redirect(url_for('main.login'))
|
|
|
|
message = None
|
|
message_type = 'info'
|
|
|
|
if request.method == 'POST':
|
|
# Handle edit location
|
|
if request.form.get('edit_location'):
|
|
location_id = request.form.get('location_id', '')
|
|
size = request.form.get('edit_size', '').strip()
|
|
description = request.form.get('edit_description', '').strip()
|
|
|
|
try:
|
|
location_id = int(location_id)
|
|
success, msg = update_location(location_id, None, size if size else None, description if description else None)
|
|
message = msg
|
|
message_type = 'success' if success else 'error'
|
|
except Exception as e:
|
|
message = f"Error: {str(e)}"
|
|
message_type = 'error'
|
|
# Handle delete locations
|
|
elif request.form.get('delete_locations'):
|
|
delete_ids_str = request.form.get('delete_ids', '')
|
|
try:
|
|
location_ids = [int(id.strip()) for id in delete_ids_str.split(',') if id.strip().isdigit()]
|
|
success, msg = delete_multiple_locations(location_ids)
|
|
message = msg
|
|
message_type = 'success' if success else 'error'
|
|
except Exception as e:
|
|
message = f"Error: {str(e)}"
|
|
message_type = 'error'
|
|
# Handle add location
|
|
elif request.form.get('add_location'):
|
|
location_code = request.form.get('location_code', '').strip()
|
|
size = request.form.get('size', '').strip()
|
|
description = request.form.get('description', '').strip()
|
|
|
|
if not location_code:
|
|
message = "Location code is required"
|
|
message_type = 'error'
|
|
else:
|
|
success, msg = add_location(location_code, size if size else None, description if description else None)
|
|
message = msg
|
|
message_type = 'success' if success else 'error'
|
|
|
|
# Get all locations
|
|
locations_list = get_all_locations()
|
|
|
|
return render_template('modules/warehouse/locations.html',
|
|
locations=locations_list,
|
|
message=message,
|
|
message_type=message_type)
|
|
|
|
|
|
@warehouse_bp.route('/boxes', methods=['GET', 'POST'])
|
|
def boxes():
|
|
"""Manage boxes and crates in the warehouse"""
|
|
if 'user_id' not in session:
|
|
return redirect(url_for('main.login'))
|
|
|
|
return render_template('modules/warehouse/boxes.html')
|
|
|
|
|
|
@warehouse_bp.route('/inventory', methods=['GET'])
|
|
def inventory():
|
|
"""View warehouse inventory - products, boxes, and locations"""
|
|
if 'user_id' not in session:
|
|
return redirect(url_for('main.login'))
|
|
|
|
return render_template('modules/warehouse/inventory.html')
|
|
|
|
|
|
@warehouse_bp.route('/reports', methods=['GET'])
|
|
def reports():
|
|
"""Warehouse activity and inventory reports"""
|
|
if 'user_id' not in session:
|
|
return redirect(url_for('main.login'))
|
|
|
|
return render_template('modules/warehouse/reports.html')
|
|
|
|
|
|
@warehouse_bp.route('/test-barcode', methods=['GET'])
|
|
def test_barcode():
|
|
"""Test barcode printing functionality"""
|
|
if 'user_id' not in session:
|
|
return redirect(url_for('main.login'))
|
|
|
|
return render_template('modules/warehouse/test_barcode.html')
|