diff --git a/py_app/app/__init__.py b/py_app/app/__init__.py index f9429e8..0458074 100644 --- a/py_app/app/__init__.py +++ b/py_app/app/__init__.py @@ -1,5 +1,6 @@ from flask import Flask from flask_sqlalchemy import SQLAlchemy +from datetime import datetime db = SQLAlchemy() @@ -14,6 +15,9 @@ def create_app(): from .routes import bp app.register_blueprint(bp) + # Add 'now' function to Jinja2 globals + app.jinja_env.globals['now'] = datetime.now + with app.app_context(): db.create_all() # Create database tables if they don't exist diff --git a/py_app/app/__pycache__/__init__.cpython-311.pyc b/py_app/app/__pycache__/__init__.cpython-311.pyc index 7db3f91..790d919 100644 Binary files a/py_app/app/__pycache__/__init__.cpython-311.pyc and b/py_app/app/__pycache__/__init__.cpython-311.pyc differ diff --git a/py_app/app/__pycache__/routes.cpython-311.pyc b/py_app/app/__pycache__/routes.cpython-311.pyc index bd42740..ea20127 100644 Binary files a/py_app/app/__pycache__/routes.cpython-311.pyc and b/py_app/app/__pycache__/routes.cpython-311.pyc differ diff --git a/py_app/app/routes.py b/py_app/app/routes.py index a964cee..9d96574 100644 --- a/py_app/app/routes.py +++ b/py_app/app/routes.py @@ -1,10 +1,34 @@ import os +import pyodbc from flask import Blueprint, render_template, redirect, url_for, request, flash, session, current_app from .models import User from . import db bp = Blueprint('main', __name__) +def get_db_connection(): + """Reads the external_server.conf file and returns a database connection.""" + settings_file = os.path.join(current_app.instance_path, 'external_server.conf') + if not os.path.exists(settings_file): + raise FileNotFoundError("The external_server.conf file is missing in the instance folder.") + + # Read settings from the configuration file + settings = {} + with open(settings_file, 'r') as f: + for line in f: + key, value = line.strip().split('=', 1) + settings[key] = value + + # Create a database connection string + connection_string = ( + f"DRIVER={{ODBC Driver 17 for SQL Server}};" + f"SERVER={settings['server_domain']},{settings['port']};" + f"DATABASE={settings['database_name']};" + f"UID={settings['username']};" + f"PWD={settings['password']};" + ) + return pyodbc.connect(connection_string) + @bp.route('/login', methods=['GET', 'POST']) def login(): if request.method == 'POST': @@ -59,12 +83,48 @@ def warehouse(): return redirect(url_for('main.dashboard')) return render_template('warehouse.html') -@bp.route('/scan') +@bp.route('/scan', methods=['GET', 'POST']) 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')) - return render_template('scan.html') + + 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: + conn = get_db_connection() + cursor = conn.cursor() + cursor.execute( + "INSERT INTO scanare (operator_code, cp_code, oc1_code, oc2_code, defect_code, date, time, quantity) " + "VALUES (?, ?, ?, ?, ?, ?, ?, ?)", + operator_code, cp_code, oc1_code, oc2_code, defect_code, date, time, 1 + ) + conn.commit() + conn.close() + flash('Scan data saved successfully.') + except Exception as e: + flash(f"Error saving scan data: {e}") + + # Fetch the latest scan data for display + scan_data = [] + try: + conn = get_db_connection() + cursor = conn.cursor() + cursor.execute("SELECT TOP 14 * FROM scanare ORDER BY id DESC") + scan_data = cursor.fetchall() + conn.close() + except Exception as e: + flash(f"Error fetching scan data: {e}") + + return render_template('scan.html', scan_data=scan_data) @bp.route('/logout') def logout(): diff --git a/py_app/app/static/style.css b/py_app/app/static/style.css index 019630f..ec47f52 100644 --- a/py_app/app/static/style.css +++ b/py_app/app/static/style.css @@ -6,8 +6,8 @@ body { } .container { - width: 100%; - margin: auto; + width: 95%; + margin: 15px auto; /* Add 15px top margin */ overflow: hidden; padding: 0; /* Remove padding */ background: none; /* Remove white background */ @@ -443,18 +443,19 @@ body.dark-mode .popup-content { .form-centered { display: flex; flex-direction: column; - align-items: center; /* Center the input fields */ + align-items: center; + margin-bottom: 20px; } .form-centered label { - width: 75%; /* Align labels with the input fields */ + width: 100%; text-align: left; margin-bottom: 5px; font-weight: bold; } .form-centered input { - width: 75%; /* Set input fields to 75% of the card width */ + width: 80%; padding: 10px; margin-bottom: 15px; font-size: 1em; @@ -462,19 +463,44 @@ body.dark-mode .popup-content { border-radius: 5px; } -.form-centered button { - width: 50%; /* Center the button and reduce its width */ - padding: 10px; - font-size: 1em; - background-color: #007bff; - color: #fff; - border: none; - border-radius: 5px; - cursor: pointer; +.scan-table { + width: 100%; + border-collapse: collapse; + margin-top: 20px; } -.form-centered button:hover { - background-color: #0056b3; +.scan-table th, .scan-table td { + border: 1px solid #ddd; + padding: 8px; + text-align: center; +} + +.scan-table th { + background-color: #f4f4f4; + font-weight: bold; +} + +/* Dark mode styles for the scan table */ +body.dark-mode .scan-table { + background-color: #1e1e1e; /* Dark background for the table */ + color: #fff; /* Light text for better contrast */ +} + +body.dark-mode .scan-table th { + background-color: #333; /* Darker background for table headers */ + color: #fff; /* Light text for headers */ +} + +body.dark-mode .scan-table td { + color: #ddd; /* Slightly lighter text for table cells */ +} + +body.dark-mode .scan-table tr:nth-child(even) { + background-color: #2a2a2a; /* Slightly lighter background for even rows */ +} + +body.dark-mode .scan-table tr:nth-child(odd) { + background-color: #1e1e1e; /* Match the table background for odd rows */ } /* Container for the cards */ @@ -487,9 +513,66 @@ body.dark-mode .popup-content { max-width: 1200px; /* Optional: Limit the maximum width of the container */ } +/* Container for the scan page */ +.scan-container { + display: flex; + flex-wrap: wrap; /* Allow wrapping on smaller screens */ + gap: 20px; /* Add 20px spacing between the cards */ + margin: 20px auto; /* Center the container vertically and horizontally */ + justify-content: center; /* Center the cards horizontally */ + align-items: stretch; /* Make all cards the same height */ +} + +/* Input Form Card */ +.scan-form-card { + flex: 0 0 500px; /* Fixed width of 500px */ + max-width: 500px; + background: #fff; + border-radius: 5px; + padding: 20px; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); + display: flex; + flex-direction: column; /* Ensure content inside the card is vertically aligned */ +} + +/* Latest Scans Card */ +.scan-table-card { + flex: 2 1 1000px; /* Take up twice the space compared to other cards */ + max-width: 1000px; /* Ensure the card doesn't exceed 1000px in width */ + background: #fff; + border-radius: 5px; + padding: 20px; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); + overflow-x: auto; /* Allow horizontal scrolling for the table */ + display: flex; + flex-direction: column; /* Ensure content inside the card is vertically aligned */ +} + +/* Table styles */ +.scan-table { + width: 100%; + border-collapse: collapse; + margin-top: 20px; +} + +.scan-table th, .scan-table td { + border: 1px solid #ddd; + padding: 8px; + text-align: center; +} + +.scan-table th { + background-color: #f4f4f4; + font-weight: bold; +} + /* Media query for smaller screens */ @media (max-width: 768px) { .card { flex: 1 1 100%; /* Make cards take full width on smaller screens */ } + + .scan-form-card, .scan-table-card { + flex: 1 1 100%; /* Make both cards take full width on smaller screens */ + } } \ No newline at end of file diff --git a/py_app/app/templates/dashboard.html b/py_app/app/templates/dashboard.html index ba00a1f..8d36521 100644 --- a/py_app/app/templates/dashboard.html +++ b/py_app/app/templates/dashboard.html @@ -3,9 +3,17 @@ {% block title %}Dashboard{% endblock %} {% block content %} -
-

Manage Settings

-

Access and manage application settings.

- Access Settings Page +
+
+

Accesare modul scanare

+

Modul de scanare finala a comenzilor de productie

+ Lansare modul de scanare +
+ +
+

Manage Settings

+

Access and manage application settings.

+ Access Settings Page +
{% endblock %} \ No newline at end of file diff --git a/py_app/app/templates/scan.html b/py_app/app/templates/scan.html index 06a0a89..42e5e81 100644 --- a/py_app/app/templates/scan.html +++ b/py_app/app/templates/scan.html @@ -1,6 +1,69 @@ {% extends "base.html" %} {% block title %}Scan Module{% endblock %} {% block content %} -

Scan Module

-

Welcome to the Scan Module.

+
+ +
+

Scan Input

+
+ + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+

Latest Scans

+ + + + + + + + + + + + + + + + {% for row in scan_data %} + + + + + + + + + + + + {% endfor %} + +
IDOperator CodeCP CodeOC1 CodeOC2 CodeDefect CodeDateTimeQuantity
{{ row.id }}{{ row.operator_code }}{{ row.cp_code }}{{ row.oc1_code }}{{ row.oc2_code }}{{ row.defect_code }}{{ row.date }}{{ row.time }}{{ row.quantity }}
+
+
{% endblock %} \ No newline at end of file diff --git a/py_app/requirements.txt b/py_app/requirements.txt index ad4356b..c9148f2 100644 --- a/py_app/requirements.txt +++ b/py_app/requirements.txt @@ -3,3 +3,4 @@ Flask-SSLify==0.1.5 Werkzeug==2.2.2 gunicorn==20.1.0 flask-sqlalchemy==2.5.1 +pyodbc==4.0.0 \ No newline at end of file