188 lines
6.4 KiB
Python
188 lines
6.4 KiB
Python
"""
|
|
Quality Module Routes
|
|
"""
|
|
from flask import Blueprint, render_template, session, redirect, url_for, request, jsonify, flash
|
|
from app.modules.quality.quality import (
|
|
ensure_scanfg_orders_table,
|
|
save_fg_scan,
|
|
get_latest_scans,
|
|
get_fg_report,
|
|
get_daily_statistics,
|
|
get_cp_statistics
|
|
)
|
|
import logging
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
quality_bp = Blueprint('quality', __name__, url_prefix='/quality')
|
|
|
|
|
|
@quality_bp.route('/', methods=['GET'])
|
|
def quality_index():
|
|
"""Quality module main page"""
|
|
if 'user_id' not in session:
|
|
return redirect(url_for('main.login'))
|
|
|
|
return render_template('modules/quality/index.html')
|
|
|
|
|
|
@quality_bp.route('/inspections', methods=['GET'])
|
|
def inspections():
|
|
"""View and manage quality inspections"""
|
|
if 'user_id' not in session:
|
|
return redirect(url_for('main.login'))
|
|
|
|
return render_template('modules/quality/inspections.html')
|
|
|
|
|
|
@quality_bp.route('/reports', methods=['GET'])
|
|
def quality_reports():
|
|
"""Quality reports page - displays FG scan reports"""
|
|
if 'user_id' not in session:
|
|
return redirect(url_for('main.login'))
|
|
|
|
# Ensure scanfg_orders table exists
|
|
ensure_scanfg_orders_table()
|
|
|
|
return render_template('modules/quality/fg_reports.html')
|
|
|
|
|
|
@quality_bp.route('/fg_scan', methods=['GET', 'POST'])
|
|
def fg_scan():
|
|
"""Finish goods scan page - POST saves scan data, GET displays form and latest scans"""
|
|
if 'user_id' not in session:
|
|
return redirect(url_for('main.login'))
|
|
|
|
# Ensure scanfg_orders table exists
|
|
ensure_scanfg_orders_table()
|
|
|
|
if request.method == 'POST':
|
|
# Handle form submission
|
|
operator_code = request.form.get('operator_code')
|
|
cp_code = request.form.get('cp_code')
|
|
oc1_code = request.form.get('oc1_code')
|
|
oc2_code = request.form.get('oc2_code')
|
|
defect_code = request.form.get('defect_code')
|
|
date = request.form.get('date')
|
|
time = request.form.get('time')
|
|
|
|
try:
|
|
# Save the scan using business logic function
|
|
success, approved_count, rejected_count = save_fg_scan(
|
|
operator_code, cp_code, oc1_code, oc2_code, defect_code, date, time
|
|
)
|
|
|
|
# Flash appropriate message based on defect code
|
|
if int(defect_code) == 0 or defect_code == '000':
|
|
flash(f'✅ APPROVED scan recorded for {cp_code}. Total approved: {approved_count}')
|
|
else:
|
|
flash(f'❌ REJECTED scan recorded for {cp_code} (defect: {defect_code}). Total rejected: {rejected_count}')
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error saving finish goods scan data: {e}")
|
|
flash(f"Error saving scan data: {str(e)}", 'error')
|
|
|
|
# Check if this is an AJAX request (for scan-to-boxes feature)
|
|
if request.headers.get('X-Requested-With') == 'XMLHttpRequest' or request.accept_mimetypes.best == 'application/json':
|
|
# For AJAX requests, return JSON response without redirect
|
|
return jsonify({'success': True, 'message': 'Scan recorded successfully'})
|
|
|
|
# For normal form submissions, redirect to prevent form resubmission (POST-Redirect-GET pattern)
|
|
return redirect(url_for('quality.fg_scan'))
|
|
|
|
# GET request - Fetch and display latest scans
|
|
try:
|
|
scan_groups = get_latest_scans(limit=25)
|
|
except Exception as e:
|
|
logger.error(f"Error fetching latest scans: {e}")
|
|
flash(f"Error fetching scan data: {str(e)}", 'error')
|
|
scan_groups = []
|
|
|
|
return render_template('modules/quality/fg_scan.html', scan_groups=scan_groups)
|
|
|
|
|
|
# API Routes for AJAX requests
|
|
|
|
@quality_bp.route('/api/fg_report', methods=['POST'])
|
|
def api_fg_report():
|
|
"""
|
|
API endpoint for generating FG reports via AJAX
|
|
|
|
Expected JSON body:
|
|
{
|
|
'report_type': 'daily|select-day|date-range|5-day|defects-today|defects-date|defects-range|defects-5day|all',
|
|
'filter_date': 'YYYY-MM-DD' (optional, for select-day/defects-date),
|
|
'start_date': 'YYYY-MM-DD' (optional, for date-range/defects-range),
|
|
'end_date': 'YYYY-MM-DD' (optional, for date-range/defects-range)
|
|
}
|
|
"""
|
|
if 'user_id' not in session:
|
|
return jsonify({'success': False, 'message': 'Unauthorized'}), 401
|
|
|
|
try:
|
|
data = request.get_json()
|
|
report_type = data.get('report_type')
|
|
filter_date = data.get('filter_date')
|
|
start_date = data.get('start_date')
|
|
end_date = data.get('end_date')
|
|
|
|
# Validate report type
|
|
valid_types = ['daily', 'select-day', 'date-range', '5-day', 'defects-today',
|
|
'defects-date', 'defects-range', 'defects-5day', 'all']
|
|
|
|
if report_type not in valid_types:
|
|
return jsonify({'success': False, 'message': 'Invalid report type'}), 400
|
|
|
|
# Generate report
|
|
result = get_fg_report(report_type, filter_date, start_date, end_date)
|
|
|
|
return jsonify(result)
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error in API fg_report: {e}")
|
|
return jsonify({
|
|
'success': False,
|
|
'message': f'Error processing report: {str(e)}'
|
|
}), 500
|
|
|
|
|
|
@quality_bp.route('/api/daily_stats', methods=['GET'])
|
|
def api_daily_stats():
|
|
"""API endpoint for today's statistics"""
|
|
if 'user_id' not in session:
|
|
return jsonify({'success': False, 'message': 'Unauthorized'}), 401
|
|
|
|
try:
|
|
stats = get_daily_statistics()
|
|
return jsonify({
|
|
'success': True,
|
|
'data': stats
|
|
})
|
|
except Exception as e:
|
|
logger.error(f"Error in API daily_stats: {e}")
|
|
return jsonify({
|
|
'success': False,
|
|
'message': f'Error fetching statistics: {str(e)}'
|
|
}), 500
|
|
|
|
|
|
@quality_bp.route('/api/cp_stats/<cp_code>', methods=['GET'])
|
|
def api_cp_stats(cp_code):
|
|
"""API endpoint for CP code statistics"""
|
|
if 'user_id' not in session:
|
|
return jsonify({'success': False, 'message': 'Unauthorized'}), 401
|
|
|
|
try:
|
|
stats = get_cp_statistics(cp_code)
|
|
return jsonify({
|
|
'success': True,
|
|
'data': stats
|
|
})
|
|
except Exception as e:
|
|
logger.error(f"Error in API cp_stats: {e}")
|
|
return jsonify({
|
|
'success': False,
|
|
'message': f'Error fetching CP statistics: {str(e)}'
|
|
}), 500
|
|
|