Files
quality_app-v2/app/__init__.py
Quality App Developer e1f3302c6b Implement boxes management module with auto-numbered box creation
- 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
2026-01-26 22:08:31 +02:00

188 lines
5.5 KiB
Python

"""
Quality App v2 - Flask Application Factory
Robust, modular application with login, dashboard, and multiple modules
"""
from flask import Flask
from datetime import datetime, timedelta
import os
import logging
from logging.handlers import RotatingFileHandler
def create_app(config=None):
"""
Application factory function
Creates and configures the Flask application
"""
app = Flask(__name__)
# Load configuration
if config is None:
from app.config import Config
config = Config
app.config.from_object(config)
# Setup logging
setup_logging(app)
logger = logging.getLogger(__name__)
logger.info("=" * 80)
logger.info("Flask App Initialization Started")
logger.info("=" * 80)
# Configure session
app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(hours=8)
app.config['SESSION_COOKIE_SECURE'] = False # Set True in production with HTTPS
app.config['SESSION_COOKIE_HTTPONLY'] = True
app.config['SESSION_COOKIE_SAMESITE'] = 'Lax'
# Initialize database connection
logger.info("Initializing database connection...")
from app.database import init_db, close_db
init_db(app)
app.teardown_appcontext(close_db)
# Register blueprints
logger.info("Registering blueprints...")
register_blueprints(app)
# Register error handlers
logger.info("Registering error handlers...")
register_error_handlers(app)
# Add template globals
app.jinja_env.globals['now'] = datetime.now
# Add context processor for app name
@app.context_processor
def inject_app_settings():
"""Inject app settings into all templates"""
try:
from app.database import get_db
conn = get_db()
cursor = conn.cursor()
cursor.execute(
"SELECT setting_value FROM application_settings WHERE setting_key = %s",
('app_name',)
)
result = cursor.fetchone()
cursor.close()
app_name = result[0] if result else 'Quality App v2'
except:
app_name = 'Quality App v2'
return {'app_name': app_name}
# Add before_request handlers
register_request_handlers(app)
# Initialize backup scheduler
logger.info("Initializing backup scheduler...")
try:
from app.scheduler import init_scheduler
init_scheduler(app)
except Exception as e:
logger.error(f"Failed to initialize backup scheduler: {e}")
logger.info("=" * 80)
logger.info("Flask App Initialization Completed Successfully")
logger.info("=" * 80)
return app
def setup_logging(app):
"""Configure application logging"""
log_dir = app.config.get('LOG_DIR', '/app/data/logs')
# Create log directory if it doesn't exist
if not os.path.exists(log_dir):
os.makedirs(log_dir, exist_ok=True)
# Configure rotating file handler
log_file = os.path.join(log_dir, 'app.log')
handler = RotatingFileHandler(
log_file,
maxBytes=10485760, # 10MB
backupCount=10
)
# Create formatter
formatter = logging.Formatter(
'%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
handler.setFormatter(formatter)
# Set logging level
log_level = app.config.get('LOG_LEVEL', 'INFO')
handler.setLevel(getattr(logging, log_level))
# Add handler to app logger
app.logger.addHandler(handler)
app.logger.setLevel(getattr(logging, log_level))
def register_blueprints(app):
"""Register application blueprints"""
from app.routes import main_bp
from app.modules.quality.routes import quality_bp
from app.modules.settings.routes import settings_bp
from app.modules.warehouse.routes import warehouse_bp
from app.modules.warehouse.boxes_routes import boxes_bp
app.register_blueprint(main_bp)
app.register_blueprint(quality_bp, url_prefix='/quality')
app.register_blueprint(settings_bp, url_prefix='/settings')
app.register_blueprint(warehouse_bp, url_prefix='/warehouse')
app.register_blueprint(boxes_bp)
app.logger.info("Blueprints registered: main, quality, settings, warehouse, boxes")
def register_error_handlers(app):
"""Register error handlers"""
@app.errorhandler(404)
def page_not_found(e):
from flask import render_template
return render_template('errors/404.html'), 404
@app.errorhandler(500)
def internal_error(e):
from flask import render_template
app.logger.error(f"Internal error: {e}")
return render_template('errors/500.html'), 500
@app.errorhandler(403)
def forbidden(e):
from flask import render_template
return render_template('errors/403.html'), 403
def register_request_handlers(app):
"""Register before/after request handlers"""
@app.before_request
def before_request():
"""Handle pre-request logic"""
from flask import session, request, redirect, url_for
# Skip authentication check for login and static files
if request.endpoint and (
request.endpoint in ['static', 'main.login', 'main.index'] or
request.path.startswith('/static/')
):
return None
# Check if user is logged in
if 'user_id' not in session:
return redirect(url_for('main.login'))
return None
@app.after_request
def after_request(response):
"""Handle post-request logic"""
return response