diff --git a/.idea/do-tracker.iml b/.idea/do-tracker.iml new file mode 100644 index 0000000..613796a --- /dev/null +++ b/.idea/do-tracker.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..ad44661 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..75b4fb6 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 0000000..5a62a7f --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,143 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1748942798494 + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/__init__.py b/app/__init__.py index bee6b70..f34c5e2 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -1,20 +1,25 @@ from flask import Flask from flask_sqlalchemy import SQLAlchemy -from flask_login import LoginManager +##from flask_login import LoginManager db = SQLAlchemy() -login_manager = LoginManager() +#login_manager = LoginManager() def create_app(): app = Flask(__name__) - app.config['SECRET_KEY'] = 'devkey' # Change this for production + app.config['SECRET_KEY'] = 'devkey' # Change this later app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///do_tracker.db' app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False db.init_app(app) - login_manager.init_app(app) +# login_manager.init_app(app) from .routes import main as main_blueprint app.register_blueprint(main_blueprint) + from .auth import auth as auth_blueprint + app.register_blueprint(auth_blueprint) + + from . import models # <-- 🔥 this is what was missing + return app diff --git a/app/auth.py b/app/auth.py index e69de29..1e26838 100644 --- a/app/auth.py +++ b/app/auth.py @@ -0,0 +1,26 @@ +from flask import Blueprint, render_template, redirect, request, session, url_for, flash +from .models import Store +from . import db + +auth = Blueprint('auth', __name__) + +@auth.route('/login', methods=['GET', 'POST']) +def login(): + if request.method == 'POST': + store_id = request.form.get('store_id') + password = request.form.get('password') + store = Store.query.filter_by(id=store_id, password=password).first() + if store: + session['store_id'] = store.id + session['store_name'] = store.name + flash(f"Logged in as {store.name}", "success") + return redirect(url_for('main.store_dashboard')) + else: + flash("Invalid store ID or password", "danger") + return render_template('login.html') + +@auth.route('/logout') +def logout(): + session.clear() + flash("Logged out successfully", "info") + return redirect(url_for('auth.login')) diff --git a/app/models.py b/app/models.py index e69de29..4214b47 100644 --- a/app/models.py +++ b/app/models.py @@ -0,0 +1,28 @@ +from datetime import datetime +from . import db + +class Store(db.Model): + id = db.Column(db.Integer, primary_key=True) # Store number like 210 + name = db.Column(db.String(100), nullable=False) + password = db.Column(db.String(128), nullable=False) # plaintext for now (hash later) + +class DeliveryOrder(db.Model): + id = db.Column(db.Integer, primary_key=True) + do_number = db.Column(db.String(50), unique=True, nullable=False) + delivery_number = db.Column(db.String(50), nullable=False) + final_location = db.Column(db.Integer, db.ForeignKey('store.id'), nullable=False) + created_by = db.Column(db.String(100), nullable=False) + status = db.Column(db.String(50), default='Ready for Collection') + created_at = db.Column(db.DateTime, default=datetime.utcnow) + collected_by = db.Column(db.String(100), nullable=True) + + movements = db.relationship('Movement', backref='delivery_order', cascade='all, delete-orphan') + +class Movement(db.Model): + id = db.Column(db.Integer, primary_key=True) + do_id = db.Column(db.Integer, db.ForeignKey('delivery_order.id'), nullable=False) + branch_id = db.Column(db.Integer, db.ForeignKey('store.id'), nullable=False) + arrived_at = db.Column(db.DateTime, default=datetime.utcnow) + departed_at = db.Column(db.DateTime, nullable=True) + handled_by = db.Column(db.String(100), nullable=False) + comment = db.Column(db.Text, nullable=True) diff --git a/app/routes.py b/app/routes.py index 111a3a7..671e56c 100644 --- a/app/routes.py +++ b/app/routes.py @@ -1,7 +1,31 @@ -from flask import Blueprint +from flask import Blueprint, render_template, redirect, url_for, session, flash +from .models import DeliveryOrder main = Blueprint('main', __name__) -@main.route("/") + +@main.route('/') def home(): - return "

DO Tracker Online

Welcome to the system.

" + return """ +

DO Tracker Online

+

Login as Store

+

Store Dashboard

+ """ + + +@main.route('/store') +def store_dashboard(): + if 'store_id' not in session: + flash("You must be logged in to access the store dashboard.", "warning") + return redirect(url_for('auth.login')) + + store_name = session.get('store_name') + + return f""" +

Welcome, {store_name}

+

Logout

+ + """ diff --git a/app/templates/login.html b/app/templates/login.html new file mode 100644 index 0000000..f22807a --- /dev/null +++ b/app/templates/login.html @@ -0,0 +1,21 @@ + + + + Store Login + + +

Store Login

+
+
+
+
+

+ +
+ {% with messages = get_flashed_messages(with_categories=true) %} + {% for category, message in messages %} +

{{ message }}

+ {% endfor %} + {% endwith %} + +