diff --git a/py_app/app/__pycache__/routes.cpython-312.pyc b/py_app/app/__pycache__/routes.cpython-312.pyc index 31ec46b..f3b6de2 100644 Binary files a/py_app/app/__pycache__/routes.cpython-312.pyc and b/py_app/app/__pycache__/routes.cpython-312.pyc differ diff --git a/py_app/app/__pycache__/settings.cpython-312.pyc b/py_app/app/__pycache__/settings.cpython-312.pyc index b5f7fbf..1865883 100644 Binary files a/py_app/app/__pycache__/settings.cpython-312.pyc and b/py_app/app/__pycache__/settings.cpython-312.pyc differ diff --git a/py_app/app/routes.py b/py_app/app/routes.py index 69cd6f6..d72e5fb 100644 --- a/py_app/app/routes.py +++ b/py_app/app/routes.py @@ -9,14 +9,16 @@ from reportlab.pdfgen import canvas from flask import Blueprint, render_template, request, redirect, url_for, flash import csv from .warehouse import add_location -from .settings import ( - settings_handler, +from app.settings import ( + settings_handler, role_permissions_handler, save_role_permissions_handler, reset_role_permissions_handler, - create_user_handler, - edit_user_handler, - delete_user_handler, + save_all_role_permissions_handler, + reset_all_role_permissions_handler, + edit_user_handler, + create_user_handler, + delete_user_handler, save_external_db_handler ) @@ -278,6 +280,107 @@ def save_external_db(): def role_permissions(): return role_permissions_handler() +@bp.route('/test_permissions') +def test_permissions(): + from app.settings import role_permissions_handler + from flask import render_template, session, redirect, url_for, flash + from app.permissions import APP_PERMISSIONS, ACTIONS + + # Check if superadmin + if not session.get('role') == 'superadmin': + flash('Access denied: Superadmin only.') + return redirect(url_for('main.dashboard')) + + try: + # Get the same data as role_permissions_handler + from app.settings import get_external_db_connection + + conn = get_external_db_connection() + cursor = conn.cursor() + + # Get roles from role_hierarchy table + cursor.execute("SELECT role_name, display_name, description, level FROM role_hierarchy ORDER BY level DESC") + role_data = cursor.fetchall() + + roles = {} + for role_name, display_name, description, level in role_data: + roles[role_name] = { + 'display_name': display_name, + 'description': description, + 'level': level + } + + conn.close() + + return render_template('test_permissions.html', + roles=roles, + pages=APP_PERMISSIONS, + action_names=ACTIONS) + + except Exception as e: + return f"Error: {e}" + +@bp.route('/role_permissions_simple') +def role_permissions_simple(): + # Use the same handler but different template + from app.settings import get_external_db_connection + from flask import render_template, session, redirect, url_for, flash + from app.permissions import APP_PERMISSIONS, ACTIONS + import json + + # Check if superadmin + if not session.get('role') == 'superadmin': + flash('Access denied: Superadmin only.') + return redirect(url_for('main.dashboard')) + + try: + # Get roles and their current permissions + conn = get_external_db_connection() + cursor = conn.cursor() + + # Get roles from role_hierarchy table + cursor.execute("SELECT role_name, display_name, description, level FROM role_hierarchy ORDER BY level DESC") + role_data = cursor.fetchall() + + roles = {} + for role_name, display_name, description, level in role_data: + roles[role_name] = { + 'display_name': display_name, + 'description': description, + 'level': level + } + + # Get current role permissions + cursor.execute(""" + SELECT role, permission_key + FROM role_permissions + WHERE granted = TRUE + """) + permission_data = cursor.fetchall() + + role_permissions = {} + for role, permission_key in permission_data: + if role not in role_permissions: + role_permissions[role] = [] + role_permissions[role].append(permission_key) + + conn.close() + + # Convert to JSON for JavaScript + permissions_json = json.dumps(APP_PERMISSIONS) + role_permissions_json = json.dumps(role_permissions) + + return render_template('role_permissions_simple.html', + roles=roles, + pages=APP_PERMISSIONS, + action_names=ACTIONS, + permissions_json=permissions_json, + role_permissions_json=role_permissions_json) + + except Exception as e: + flash(f'Error loading role permissions: {e}') + return redirect(url_for('main.dashboard')) + @bp.route('/settings/save_role_permissions', methods=['POST']) def save_role_permissions(): return save_role_permissions_handler() @@ -286,6 +389,14 @@ def save_role_permissions(): def reset_role_permissions(): return reset_role_permissions_handler() +@bp.route('/settings/save_all_role_permissions', methods=['POST']) +def save_all_role_permissions(): + return save_all_role_permissions_handler() + +@bp.route('/settings/reset_all_role_permissions', methods=['POST']) +def reset_all_role_permissions(): + return reset_all_role_permissions_handler() + @bp.route('/get_report_data', methods=['GET']) def get_report_data(): report = request.args.get('report') @@ -683,6 +794,13 @@ def debug_dates(): @bp.route('/test_database', methods=['GET']) def test_database(): """Test database connection and query the scan1_orders table""" + # Check if user has superadmin permissions + if 'role' not in session or session['role'] != 'superadmin': + return jsonify({ + "success": False, + "error": "Access denied: Superadmin permissions required for database testing." + }), 403 + try: print("DEBUG: Testing database connection...") conn = get_db_connection() diff --git a/py_app/app/settings.py b/py_app/app/settings.py index 5ade332..73d92e8 100644 --- a/py_app/app/settings.py +++ b/py_app/app/settings.py @@ -491,3 +491,116 @@ def reset_role_permissions_handler(): except Exception as e: return jsonify({'success': False, 'error': str(e)}) + + +def save_all_role_permissions_handler(): + """Save all role permissions at once""" + if not is_superadmin(): + return jsonify({'success': False, 'error': 'Access denied: Superadmin only.'}) + + try: + data = request.get_json() + permissions_data = data.get('permissions', {}) + + if not permissions_data: + return jsonify({'success': False, 'error': 'No permissions data provided'}) + + conn = get_external_db_connection() + cursor = conn.cursor() + + current_user = session.get('username', 'system') + total_updated = 0 + + # Process each role's permissions + for role, role_permissions in permissions_data.items(): + # Clear existing permissions for this role + cursor.execute("DELETE FROM role_permissions WHERE role = %s", (role,)) + + # Convert nested permissions to flat permission keys + permission_keys = [] + for page_key, page_perms in role_permissions.items(): + for section_key, actions in page_perms.items(): + for action in actions: + permission_key = f"{page_key}.{section_key}.{action}" + permission_keys.append(permission_key) + + # Insert new permissions + for permission_key in permission_keys: + cursor.execute(""" + INSERT INTO role_permissions (role, permission_key, granted, granted_by) + VALUES (%s, %s, TRUE, %s) + """, (role, permission_key, current_user)) + total_updated += 1 + + # Log the change + cursor.execute(""" + INSERT INTO permission_audit_log (role, permission_key, action, changed_by, reason) + VALUES (%s, %s, 'bulk_update', %s, %s) + """, (role, f"Updated {len(permission_keys)} permissions", current_user, "Bulk permission update")) + + conn.commit() + conn.close() + + # Clear permission cache since permissions changed + clear_permission_cache() + + return jsonify({ + 'success': True, + 'message': f'Successfully updated {total_updated} permissions across {len(permissions_data)} roles' + }) + + except Exception as e: + return jsonify({'success': False, 'error': str(e)}) + + +def reset_all_role_permissions_handler(): + """Reset all role permissions to defaults""" + if not is_superadmin(): + return jsonify({'success': False, 'error': 'Access denied: Superadmin only.'}) + + try: + # Get all roles + conn = get_external_db_connection() + cursor = conn.cursor() + + cursor.execute("SELECT role_name FROM role_hierarchy") + roles = [row[0] for row in cursor.fetchall()] + + current_user = session.get('username', 'system') + total_reset = 0 + + # Reset each role to defaults + for role in roles: + # Clear existing permissions + cursor.execute("DELETE FROM role_permissions WHERE role = %s", (role,)) + + # Get default permissions for the role + default_permissions = get_default_permissions_for_role(role) + + # Add default permissions + for permission_key in default_permissions: + cursor.execute(""" + INSERT INTO role_permissions (role, permission_key, granted, granted_by) + VALUES (%s, %s, TRUE, %s) + """, (role, permission_key, current_user)) + total_reset += 1 + + # Log the change + cursor.execute(""" + INSERT INTO permission_audit_log (role, permission_key, action, changed_by, reason) + VALUES (%s, %s, 'reset_all_defaults', %s, %s) + """, (role, f"Reset {len(default_permissions)} permissions", current_user, "Reset all to default permissions")) + + conn.commit() + conn.close() + + # Clear permission cache since permissions changed + clear_permission_cache() + + return jsonify({ + 'success': True, + 'message': f'Successfully reset {total_reset} permissions across {len(roles)} roles to defaults' + }) + + except Exception as e: + return jsonify({'success': False, 'error': str(e)}) diff --git a/py_app/app/templates/quality.html b/py_app/app/templates/quality.html index fd25d82..eea0503 100644 --- a/py_app/app/templates/quality.html +++ b/py_app/app/templates/quality.html @@ -56,7 +56,9 @@
+ {% if session.get('role') == 'superadmin' %} + {% endif %}
diff --git a/py_app/app/templates/role_permissions.html b/py_app/app/templates/role_permissions.html index 735880d..5d03e90 100644 --- a/py_app/app/templates/role_permissions.html +++ b/py_app/app/templates/role_permissions.html @@ -5,345 +5,178 @@ {% block head %} {% endblock %} {% block content %}
-
-

Role Permissions Management

-

Configure granular access permissions for each role in the system

+
+

+ 🔐 Role Permissions Management +

+

+ Configure granular access permissions for each role in the system +

- -
- {% for role_name, role_data in roles.items() %} -
-
{{ role_data.display_name }}
- Level {{ role_data.level }} -
- {% endfor %} -
- - {% for role_name, role_data in roles.items() %} -
- - -
-

{{ role_data.display_name }} Permissions Summary

-

{{ role_data.description }}

-
-
-
0
-
Total Permissions
-
-
-
0
-
Granted
-
-
-
0
-
Denied
-
-
-
- - -
- {% for page_key, page_data in pages.items() %} -
- -
- {% for section_key, section_data in page_data.sections.items() %} -
-
- - - {{ section_data.name }} - - 0/{{ section_data.actions|length }} -
-
-
- {% for action in section_data.actions %} -
-
-
- {% if action == 'view' %}👁{% elif action == 'create' %}➕{% elif action == 'edit' %}✏️{% elif action == 'delete' %}🗑{% elif action == 'upload' %}📤{% elif action == 'download' %}📥{% elif action == 'export' %}📊{% elif action == 'import' %}📈{% endif %} -
- {{ action_names.get(action, action) }} + +
+ + + + + + + + + + + {% set current_role = '' %} + {% set current_module = '' %} + {% for role_name, role_data in roles.items() %} + {% for page_key, page_data in pages.items() %} + {% for section_key, section_data in page_data.sections.items() %} + + + {% if current_role != role_name %} + {% set current_role = role_name %} + + + + {% endif %} + + + {% if current_module != page_key %} + {% set current_module = page_key %} + + + + + {% endif %} + + + + + + + + {% endfor %} + {% set current_module = '' %} {% endfor %} - - - {% endfor %} - + {% endfor %} + +
👤 Role Name🏢 Module Name📄 Page Name⚙️ Functions & Permissions
+
+ {{ role_data.display_name }} (Level {{ role_data.level }})
- +
+
+ {{ page_data.name }} +
+
+
+ 👤 + {{ role_data.display_name }}
- {% endfor %} - - - +
+ {{ page_data.name }} + +
+ 📋 + {{ section_data.name }} +
+
+
+ {% for action in section_data.actions %} + {% set permission_key = page_key + '.' + section_key + '.' + action %} +
+ + {{ action_names[action] }} +
+ {% endfor %} +
+
+
- + +
- - - + +
- {% endfor %}
{% endblock %} \ No newline at end of file diff --git a/py_app/documentation.md b/py_app/documentation.md index 4398313..46a17e7 100644 --- a/py_app/documentation.md +++ b/py_app/documentation.md @@ -1,198 +1,422 @@ -Here is the content for the `documentation.md` file that explains the functionality of the application: +# Quality Control Management System - Documentation + +## Table of Contents +1. [Login System](#login-system) +2. [Dashboard System](#dashboard-system) +3. [User Authentication](#user-authentication) +4. [Role-Based Access Control](#role-based-access-control) --- -### Documentation for Quality Recticel Application +## Login System + +### Overview +The Quality Control Management System features a dual-database authentication system that provides flexible user management and robust access control. The login system supports both internal SQLite database users and external MariaDB database users. + +### Authentication Flow + +#### 1. Login Page Access +- **URL**: `/login` +- **Template**: `login.html` +- **Methods**: `GET`, `POST` + +#### 2. User Interface +The login page features: +- **Company Logo**: Displayed prominently on the left side +- **Login Form**: Clean, centered form on the right side +- **Required Fields**: + - Username (text input) + - Password (password input) +- **Responsive Design**: Adapts to different screen sizes + +#### 3. Authentication Methods + +##### Internal Database Authentication +Users can access the system using the internal SQLite database by prefixing their username with `#`: + +**Format**: `#username` +**Example**: `#admin` for internal admin user + +**Database Details**: +- **Location**: `py_app/instance/users.db` +- **Table**: `users` +- **Schema**: `username, password, role` +- **Use Case**: System administrators, fallback authentication + +##### External Database Authentication +Standard authentication uses the external MariaDB database: + +**Format**: `username` (no prefix) +**Example**: `john.doe` for external user + +**Database Details**: +- **Type**: MariaDB +- **Configuration**: Loaded from `external_database_settings` +- **Table**: `users` +- **Schema**: `username, password, role` +- **Use Case**: Regular operational users + +#### 4. Authentication Logic + +```python +# Authentication Process Flow +if username.startswith('#'): + # Internal SQLite Database Authentication + username_clean = username[1:].strip() + # Query: py_app/instance/users.db + +else: + # External MariaDB Database Authentication + # Primary: External database query + # Fallback: Internal database if external fails +``` + +#### 5. Security Features + +##### Input Validation +- **Required Fields**: Both username and password must be provided +- **Sanitization**: Automatic trimming of whitespace +- **Error Handling**: Clear error messages for invalid inputs + +##### Database Connection Security +- **Dual Fallback**: External database with internal fallback +- **Error Isolation**: Database errors don't expose system details +- **Connection Management**: Proper connection opening/closing + +##### Session Management +- **Secure Sessions**: User credentials stored in Flask session +- **Role Tracking**: User role preserved for authorization +- **Session Data**: + - `session['user']`: Username + - `session['role']`: User role + +#### 6. User Roles + +The system supports multiple user roles with different access levels: + +- **superadmin**: Full system access, all modules and administrative functions +- **admin**: Administrative access with some limitations +- **quality**: Quality control module access +- **warehouse**: Warehouse management module access +- **scan**: Scanning operations access +- **etichete**: Label management access +- **management**: Management reporting and oversight + +#### 7. Login Process + +1. **User Navigation**: User accesses `/login` URL +2. **Form Display**: Login form rendered with company branding +3. **Credential Submission**: User enters username/password and submits +4. **Authentication Check**: + - Internal users: Check SQLite database + - External users: Check MariaDB database with SQLite fallback +5. **Session Creation**: Valid credentials create user session +6. **Redirect**: Successful login redirects to `/dashboard` +7. **Error Handling**: Invalid credentials display error message + +#### 8. Error Messages + +- **Missing Credentials**: "Please enter both username and password." +- **Invalid Credentials**: "Invalid credentials. Please try again." +- **Database Errors**: Handled gracefully with fallback mechanisms + +#### 9. Post-Login Behavior + +After successful authentication: +- **Session Establishment**: User session created with username and role +- **Dashboard Redirect**: User redirected to main dashboard +- **Access Control**: Role-based permissions applied throughout system +- **Navigation**: Header displays logged-in user information + +#### 10. Security Considerations + +##### Password Security +- **Storage**: Passwords stored in plaintext (consider encryption upgrade) +- **Transmission**: Form-based submission over HTTPS recommended +- **Session**: Password not stored in session, only username/role + +##### Database Security +- **Connection Strings**: External database settings in separate config +- **Error Handling**: Database errors logged but not exposed to users +- **Fallback System**: Ensures availability even if external database fails + +### Technical Implementation + +#### Frontend Components +- **Template**: `templates/login.html` +- **Styling**: Login-specific CSS in `static/style.css` +- **Assets**: Company logo (`static/logo_login.jpg`) + +#### Backend Components +- **Route Handler**: `@bp.route('/login', methods=['GET', 'POST'])` +- **Database Connections**: SQLite and MariaDB integration +- **Session Management**: Flask session handling +- **Error Handling**: Comprehensive exception management + +#### Configuration Files +- **External Database**: Configuration loaded from `external_database_settings` +- **Internal Database**: SQLite database in `instance/users.db` + +### Usage Examples + +#### Standard User Login +``` +Username: john.doe +Password: userpassword +Result: Queries external MariaDB database +``` + +#### Internal Admin Login +``` +Username: #admin +Password: adminpassword +Result: Queries internal SQLite database +``` + +#### System Administrator Login +``` +Username: #superadmin +Password: superpass +Result: Internal database, full system access +``` --- -#### **Overview** -The Quality Recticel application is a web-based system designed to manage and monitor quality control processes, user roles, and database interactions. It includes modules for scanning, quality assurance, warehouse management, and administrative settings. +## Dashboard System + +### Overview +The dashboard serves as the central hub of the Quality Control Management System, providing authenticated users with access to various system modules based on their assigned roles. It features a clean, card-based interface that displays available modules and ensures proper access control. + +### Dashboard Access + +#### 1. Dashboard Page Access +- **URL**: `/dashboard` +- **Template**: `dashboard.html` +- **Methods**: `GET` +- **Authentication Required**: Yes (redirects to login if not authenticated) + +#### 2. User Interface Design + +The dashboard features a modern, responsive card-based layout: +- **Container**: Full-width responsive grid layout +- **Module Cards**: Individual cards for each system module +- **Visual Hierarchy**: Clear headings, descriptions, and call-to-action buttons +- **Responsive Design**: Adapts to different screen sizes and devices + +#### 3. Available Modules + +##### Scanning Module +- **Card Title**: "Access Scanning Module" +- **Description**: "Final scanning module for production orders" +- **Button**: "Launch Scanning Module" +- **Route**: `/scan` +- **Required Roles**: `superadmin`, `scan` +- **Purpose**: Quality control scanning operations for production orders + +##### Reports Module (Quality) +- **Card Title**: "Access Reports Module" +- **Description**: "Module for verification and quality settings configuration" +- **Button**: "Launch Reports Module" +- **Route**: `/quality` +- **Required Roles**: `superadmin`, `quality` +- **Purpose**: Quality reporting, defects analysis, and quality control reports + +##### Warehouse Module +- **Card Title**: "Access Warehouse Module" +- **Description**: "Access warehouse module functionalities" +- **Button**: "Open Warehouse" +- **Route**: `/warehouse` +- **Required Roles**: `superadmin`, `warehouse` +- **Purpose**: Warehouse management operations and inventory control + +##### Labels Module +- **Card Title**: "Access Labels Module" +- **Description**: "Module for label management" +- **Button**: "Launch Labels Module" +- **Route**: `/etichete` +- **Required Roles**: `superadmin`, `etichete` +- **Purpose**: Label creation, template management, and printing operations + +##### Settings Module +- **Card Title**: "Manage Settings" +- **Description**: "Access and manage application settings" +- **Button**: "Access Settings Page" +- **Route**: `/settings` +- **Required Roles**: `superadmin` only +- **Purpose**: System configuration, user management, and administrative settings + +#### 4. Access Control Logic + +The dashboard implements role-based access control at both the display and route levels: + +##### Frontend Display Control +All module cards are displayed to all authenticated users, but access is controlled at the route level. + +##### Backend Route Protection +Each module route implements permission checking: + +```python +# Quality Module Access Control +@bp.route('/quality') +def quality(): + if 'role' not in session or session['role'] not in ['superadmin', 'quality']: + flash('Access denied: Quality users only.') + return redirect(url_for('main.dashboard')) + +# Warehouse Module Access Control +@bp.route('/warehouse') +def warehouse(): + if 'role' not in session or session['role'] not in ['superadmin', 'warehouse']: + flash('Access denied: Warehouse users only.') + return redirect(url_for('main.dashboard')) + +# Scanning Module Access Control +@bp.route('/scan') +def scan(): + if 'role' not in session or session['role'] not in ['superadmin', 'scan']: + flash('Access denied: Scan users only.') + return redirect(url_for('main.dashboard')) + +# Labels Module Access Control +@bp.route('/etichete') +def etichete(): + if 'role' not in session or session['role'] not in ['superadmin', 'etichete']: + flash('Access denied: Etichete users only.') + return redirect(url_for('main.dashboard')) + +# Settings Module Access Control (Superadmin Only) +def settings_handler(): + if 'role' not in session or session['role'] != 'superadmin': + flash('Access denied: Superadmin only.') + return redirect(url_for('main.dashboard')) +``` + +#### 5. User Experience Flow + +1. **Authentication Check**: User must be logged in to access dashboard +2. **Dashboard Display**: All module cards shown regardless of role +3. **Module Selection**: User clicks on desired module button +4. **Permission Validation**: System checks user role against module requirements +5. **Access Grant/Deny**: + - **Authorized**: User redirected to module interface + - **Unauthorized**: Error message displayed, user remains on dashboard + +#### 6. Session Management + +The dashboard relies on Flask session management: +- **Session Check**: `if 'user' not in session` validates authentication +- **Role Access**: `session['role']` determines module permissions +- **Debug Logging**: Session information logged for troubleshooting + +#### 7. Error Handling + +##### Authentication Errors +- **Unauthenticated Users**: Automatic redirect to login page +- **Session Timeout**: Redirect to login with appropriate messaging + +##### Authorization Errors +- **Insufficient Permissions**: Flash message with specific role requirements +- **Access Denied**: User returned to dashboard with error notification +- **Clear Messaging**: Specific error messages indicate required permissions + +#### 8. Security Features + +##### Session Security +- **Authentication Required**: All dashboard access requires valid session +- **Role Validation**: Each module validates user role before access +- **Automatic Redirect**: Unauthorized access redirected safely + +##### Access Control +- **Principle of Least Privilege**: Users only access modules for their role +- **Superadmin Override**: Superadmin role has access to all modules +- **Route-Level Protection**: Backend validation prevents unauthorized access + +#### 9. Module Descriptions + +##### Quality Reports Module +- **Primary Function**: Generate quality control reports and analytics +- **Key Features**: + - Daily, weekly, and custom date range reports + - Quality defects analysis and tracking + - Export capabilities (CSV format) + - Database testing tools (superadmin only) + +##### Scanning Module +- **Primary Function**: Production order scanning and quality validation +- **Key Features**: + - Barcode/QR code scanning interface + - Real-time quality validation + - Production order processing + +##### Warehouse Module +- **Primary Function**: Warehouse operations and inventory management +- **Key Features**: + - Inventory tracking and management + - Location management + - Warehouse reporting + +##### Labels Module +- **Primary Function**: Label design, generation, and printing +- **Key Features**: + - Label template creation and management + - Dynamic label generation + - Print management system + +##### Settings Module +- **Primary Function**: System administration and configuration +- **Key Features**: + - User account management + - Role and permission configuration + - Database settings management + - System configuration options + +#### 10. Technical Implementation + +##### Frontend Components +- **Template**: `templates/dashboard.html` +- **Styling**: Dashboard-specific CSS classes in `static/style.css` +- **Layout**: CSS Grid/Flexbox responsive card layout +- **Navigation**: Base template integration with header/footer + +##### Backend Components +- **Route Handler**: `@bp.route('/dashboard')` +- **Session Management**: Flask session integration +- **Authentication Check**: User session validation +- **Logging**: Debug output for troubleshooting + +##### Styling Classes +- `.dashboard-container`: Main container with responsive grid +- `.dashboard-card`: Individual module cards +- `.btn`: Standardized button styling +- Responsive breakpoints for mobile/tablet adaptation + +### Usage Examples + +#### Superadmin User Dashboard Access +``` +Role: superadmin +Available Modules: All (Scanning, Quality, Warehouse, Labels, Settings) +Special Access: Settings module exclusive access +``` + +#### Quality Control User Dashboard Access +``` +Role: quality +Available Modules: Quality Reports module only +Restricted Access: Cannot access other modules +``` + +#### Multi-Role Access Example +``` +Role: warehouse +Available Modules: Warehouse module only +Access Pattern: Click → Permission Check → Module Access +``` --- -### **Features** +*This documentation covers the dashboard system implementation. For specific module details, see their respective documentation sections.* -#### 1. **User Management** -- **Roles**: - - `superadmin`: Full access to all features and settings. - - `administrator`: Limited administrative access. - - `quality`: Access to quality assurance features. - - `warehouse`: Access to warehouse management features. - - `scan`: Access to scanning features. -- **Functionalities**: - - Create, edit, and delete users. - - Assign roles to users. - - Manage user credentials. -#### 2. **Scan Module** -- **Input Form**: - - Allows users to input scan data, including: - - Operator Code - - CP Code - - OC1 Code - - OC2 Code - - Defect Code - - Date and Time -- **Latest Scans Table**: - - Displays the last 15 scans with details such as: - - Approved Quantity - - Rejected Quantity - - Data is dynamically fetched from the database. -#### 3. **Quality Module** -- Provides tools for quality assurance personnel to monitor and manage quality-related data. -#### 4. **Warehouse Module** -- Enables warehouse personnel to manage inventory and related processes. - -#### 5. **Settings Module** -- **External Database Configuration**: - - Allows the `superadmin` to configure external database settings, including: - - Server Domain/IP - - Port - - Database Name - - Username and Password -- **User Management**: - - Provides an interface to manage users and their roles. - ---- - -### **Database Structure** - -#### **Table: `scan1_orders`** -- **Columns**: - - `Id`: Auto-incremented primary key. - - `operator_code`: Operator code (4 characters). - - `CP_full_code`: Full CP code (15 characters, unique). - - `OC1_code`: OC1 code (4 characters). - - `OC2_code`: OC2 code (4 characters). - - `CP_base_code`: Auto-generated base code (first 10 characters of `CP_full_code`). - - `quality_code`: Quality code (3 digits). - - `date`: Date in `yyyy-mm-dd` format. - - `time`: Time in `hh:mm:ss` format. - - `approved_quantity`: Number of approved items (calculated dynamically). - - `rejected_quantity`: Number of rejected items (calculated dynamically). - -#### **Triggers** -- **`increment_approved_quantity`**: - - Updates `approved_quantity` based on the number of rows with the same `CP_base_code` and `quality_code = 000`. -- **`increment_rejected_quantity`**: - - Updates `rejected_quantity` based on the number of rows with the same `CP_base_code` and `quality_code != 000`. - ---- - -### **Key Files** - -#### 1. **`run.py`** -- Entry point for the application. -- Starts the Flask server. - -#### 2. **`routes.py`** -- Defines the routes and logic for the application. -- Handles user authentication, form submissions, and database interactions. - -#### 3. **`models.py`** -- Defines the `User` model for managing user data. - -#### 4. **`create_scan_1db.py`** -- Script to create the `scan1_orders` table in the database. - -#### 5. **`create_triggers.py`** -- Script to create database triggers for dynamically updating `approved_quantity` and `rejected_quantity`. - -#### 6. **`seed.py`** -- Seeds the database with default users. - -#### 7. **Templates** -- **`scan.html`**: - - Interface for the Scan Module. -- **`settings.html`**: - - Interface for managing users and external database settings. - ---- - -### **How to Run the Application** - -1. **Set Up the Environment**: - - Install dependencies: - ```bash - pip install flask mariadb - ``` - -2. **Configure the Database**: - - Update the `external_server.conf` file with the correct database credentials. - -3. **Create the Database and Triggers**: - - Run the create_scan_1db.py script: - ```bash - python py_app/app/db_create_scripts/create_scan_1db.py - ``` - - Run the create_triggers.py script: - ```bash - python py_app/app/db_create_scripts/create_triggers.py - ``` - -4. **Seed the Database**: - - Run the seed.py script: - ```bash - python py_app/seed.py - ``` - -5. **Start the Application**: - - Run the run.py file: - ```bash - python py_app/run.py - ``` - -6. **Access the Application**: - - Open a browser and navigate to: - ``` - http://127.0.0.1:5000 - ``` - ---- - -### **Troubleshooting** - -1. **Database Connection Issues**: - - Ensure the `external_server.conf` file is correctly configured. - - Verify that the database server is running. - -2. **Trigger Errors**: - - Check the trigger definitions in the database using: - ```sql - SHOW TRIGGERS; - ``` - -3. **Form Submission Errors**: - - Verify that all required fields in the form are filled out. - -4. **Permission Issues**: - - Ensure the user has the correct role for accessing specific modules. - ---- - -### **Future Enhancements** -- Add detailed logging for debugging. -- Implement role-based access control for more granular permissions. -- Add support for exporting scan data to CSV or Excel. - ---- - -Save this content as `documentation.md` in the root directory of your project.3. **Form Submission Errors**: - - Verify that all required fields in the form are filled out. - -4. **Permission Issues**: - - Ensure the user has the correct role for accessing specific modules. - ---- - -### **Future Enhancements** -- Add detailed logging for debugging. -- Implement role-based access control for more granular permissions. -- Add support for exporting scan data to CSV or Excel. - ---- - -Save this content as `documentation.md` in the root directory of your project. \ No newline at end of file