intrgrating suggestions after betta 1

This commit is contained in:
2025-09-08 18:06:00 +03:00
parent eb262451ad
commit 106045d72a
34 changed files with 1549 additions and 146 deletions

View File

@@ -9,6 +9,7 @@ import os
from datetime import timezone
from models.user import Users
from utils.welcome_email import WelcomeMessage
auth_bp = Blueprint("auth", __name__)
@@ -30,8 +31,10 @@ def register():
password_hash = generate_password_hash(password)
users.insert_user(name, email, password_hash)
return jsonify({"message": "User registered successfully!"}), 201
welcome_message = WelcomeMessage(name, email)
welcome_message.send_email()
return jsonify({"message": "User registered successfully!"}), 201
@auth_bp.route("/login", methods=["POST"])
def login():
@@ -46,6 +49,9 @@ def login():
user = users.get_user_by_email(email)
if not user or not check_password_hash(user["password_hash"], password):
return jsonify({"error": "Invalid credentials"}), 401
if user["active"] != 1:
return jsonify({"error": "Inactive user"}), 401
otp_code = str(random.randint(100000, 999999))
expiration = datetime.datetime.now(timezone.utc) + datetime.timedelta(minutes=10)
@@ -188,7 +194,8 @@ def me():
"terms": user["terms"],
"first_order_number": user["first_order_number"],
"created_at": user["created_at"],
"user_role": user["user_role"]
"user_role": user["user_role"],
"temporary_password": user["temporary_password"]
}), 200
@@ -201,4 +208,17 @@ def validate_token():
user = users.get_user_by_id(user_id)
if not user:
return jsonify({"error": "User not found"}), 404
return jsonify({"message": "Token is valid"}), 200
return jsonify({"message": "Token is valid"}), 200
@auth_bp.route("/temporary_password", methods=["POST"])
@jwt_required()
def change_passwd():
data = request.get_json()
if not data:
return jsonify({"error": "Password not found"}), 404
users = Users()
user_id = get_jwt_identity()
new_password_hash = generate_password_hash(data['password'])
users.update_user_password(user_id, new_password_hash)
users.update_temp_pass(user_id)
return jsonify({"message": "Password has been updated successfully."}), 200

View File

@@ -1,5 +1,6 @@
from flask import Blueprint, request, jsonify
from models.client import Clients
from models.user import Users
from flask_jwt_extended import jwt_required, get_jwt_identity
@@ -10,6 +11,10 @@ clients_bp = Blueprint("clients", __name__, url_prefix="/clients")
def list_clients():
clients_db = Clients()
user_id = get_jwt_identity()
users = Users()
user = users.get_user_by_id(user_id)
if user['user_role'] == 'company_user':
user_id = user['company_id']
clients = clients_db.get_all_by_user(user_id)
return jsonify(clients), 200
@@ -19,6 +24,10 @@ def create_client():
clients_db = Clients()
user_id = get_jwt_identity()
data = request.get_json()
users = Users()
user = users.get_user_by_id(user_id)
if user['user_role'] == 'company_user':
user_id = user['company_id']
client_id = clients_db.create(
user_id=user_id,
name=data["name"],

View File

@@ -0,0 +1,118 @@
from flask import Blueprint, request, jsonify
from models.user import Users
from utils.welcome_email import WelcomeMessage
from werkzeug.security import generate_password_hash, check_password_hash
from flask_jwt_extended import jwt_required, get_jwt_identity
from models.company_users import CompanyUsers
company_user_bp = Blueprint("company_user", __name__, url_prefix="/company_user")
@company_user_bp.route('/access/<int:id>', methods=["GET"])
@jwt_required()
def get_access(id):
company_user_id = id
if not company_user_id:
return jsonify({"error":"Missing required fields"}), 400
company_users = CompanyUsers()
access = company_users.get_access_by_company_user_id(company_user_id)
return jsonify(access)
@company_user_bp.route("/register_company_user", methods=["POST"])
@jwt_required()
def register_company_user():
users = Users()
data = request.get_json()
name = data.get("name")
email = data.get("email")
company_id = data.get("company_id")
password = data.get("password")
if not name or not email or not password or not company_id:
return jsonify({"error": "Missing required fields"}), 400
existing_user = users.get_user_by_email(email)
if existing_user:
return jsonify({"error": "User already exists"}), 409
password_hash = generate_password_hash(password)
company_user_id = users.insert_company_user(name, email, password_hash, company_id)
welcome_message = WelcomeMessage(name, email)
welcome_message.send_email()
return jsonify({"message": "User registered successfully!", "company_user_id":company_user_id}), 201
@company_user_bp.route('/access', methods=["POST"])
@jwt_required()
def create_access():
data = request.get_json()
company_user_id = data.get('company_user_id')
orders_in = data.get("orders_in")
orders_out = data.get("orders_out")
addresses = data.get("addresses")
clients = data.get("clients")
transporters = data.get("transporters")
report = data.get("report")
company_users = CompanyUsers()
# Use explicit None checks so that False/0 values are allowed
if (
company_user_id is None or
orders_in is None or
orders_out is None or
addresses is None or
clients is None or
transporters is None or
report is None
):
return jsonify({"error": "Missing required fields"}), 400
access_data = {
'company_user_id': company_user_id,
'clients': clients,
'transporters': transporters,
'destinations': addresses,
'orders_in': orders_in,
'orders_out': orders_out,
'report': report
}
company_users.insert_company_user_access(access_data)
return jsonify({"message": "Company User access inserted!"})
@company_user_bp.route('/update_access', methods=["PUT"])
@jwt_required()
def update_access():
data = request.get_json()
company_user_id = data.get('company_user_id')
orders_in = data.get("orders_in")
orders_out = data.get("orders_out")
addresses = data.get("addresses")
clients = data.get("clients")
transporters = data.get("transporters")
report = data.get("report")
company_users = CompanyUsers()
# Use explicit None checks so that False/0 values are allowed
if (
company_user_id is None or
orders_in is None or
orders_out is None or
addresses is None or
clients is None or
transporters is None or
report is None
):
return jsonify({"error": "Missing required fields"}), 400
access_data = {
'company_user_id': company_user_id,
'clients': clients,
'transporters': transporters,
'destinations': addresses,
'orders_in': orders_in,
'orders_out': orders_out,
'report': report
}
company_users.update_company_user_access(access_data)
return jsonify({"message": "Company User access updated!"})

View File

@@ -2,6 +2,7 @@ from flask import Blueprint, request, jsonify
from models.destinations import Destinations
from flask_jwt_extended import jwt_required, get_jwt_identity
from utils.maps import AdressCoordinates
from models.user import Users
destinations_bp = Blueprint("destinations", __name__, url_prefix="/destinations")
@@ -10,6 +11,10 @@ destinations_bp = Blueprint("destinations", __name__, url_prefix="/destinations"
def list_destinations():
destinations_db = Destinations()
user_id = get_jwt_identity()
users = Users()
user = users.get_user_by_id(user_id)
if user['user_role'] == 'company_user':
user_id = user['company_id']
destinations = destinations_db.get_all_by_user(user_id)
return jsonify([dict(d) for d in destinations]), 200
@@ -18,6 +23,10 @@ def list_destinations():
def create_destination():
destinations_db = Destinations()
user_id = get_jwt_identity()
users = Users()
user = users.get_user_by_id(user_id)
if user['user_role'] == 'company_user':
user_id = user['company_id']
data = request.get_json()
destination_id = destinations_db.create(user_id, data.get("name"), data.get("address"))
# coordinates = AdressCoordinates(data.get("address"))
@@ -33,6 +42,10 @@ def create_destination():
def update_destination(id):
destinations_db = Destinations()
user_id = get_jwt_identity()
users = Users()
user = users.get_user_by_id(user_id)
if user['user_role'] == 'company_user':
user_id = user['company_id']
data = request.get_json()
destinations_db.update(id, user_id, data.get("name"), data.get("address"))
coordinates = AdressCoordinates(data.get("address"))

View File

@@ -17,6 +17,10 @@ orders_bp = Blueprint("orders", __name__, url_prefix="/orders")
@jwt_required()
def create_order_route():
user_id = get_jwt_identity()
users = Users()
user = users.get_user_by_id(user_id)
if user['user_role'] == 'company_user':
user_id = user['company_id']
orders = OrdersOut()
incoming_data = request.json
#here we need to first implement the order pdf
@@ -83,6 +87,10 @@ def update_order_route(order_id):
orders = OrdersOut()
data = request.json
user_id = get_jwt_identity()
users = Users()
user = users.get_user_by_id(user_id)
if user['user_role'] == 'company_user':
user_id = user['company_id']
order = orders.get_order_by_id(order_id)
if not order:
return jsonify({"error": "Order not found"}), 404
@@ -150,6 +158,10 @@ def update_order_route(order_id):
def delete_order_route(order_id):
orders = OrdersOut()
user_id = get_jwt_identity()
users = Users()
user = users.get_user_by_id(user_id)
if user['user_role'] == 'company_user':
user_id = user['company_id']
order = orders.get_order_by_id(order_id)
if not order:
return jsonify({"error": "Order not found"}), 404
@@ -168,6 +180,10 @@ def delete_order_route(order_id):
def list_orders():
orders = OrdersOut()
user_id = get_jwt_identity()
users = Users()
user = users.get_user_by_id(user_id)
if user['user_role'] == 'company_user':
user_id = user['company_id']
try:
user_orders = orders.get_orders_by_user(user_id)
#result = [{"id": order["id"], "order_number": order["order_number"]} for order in user_orders]
@@ -180,6 +196,10 @@ def list_orders():
def get_order(order_id):
orders = OrdersOut()
user_id = get_jwt_identity()
users = Users()
user = users.get_user_by_id(user_id)
if user['user_role'] == 'company_user':
user_id = user['company_id']
order = orders.get_order_by_id(order_id)
points = orders.get_order_points_by_order(order['id'])
loading_points = []
@@ -251,6 +271,10 @@ def cancel_order(order_id):
orders = OrdersOut()
order = orders.get_order_by_id(order_id)
user_id = get_jwt_identity()
users = Users()
user = users.get_user_by_id(user_id)
if user['user_role'] == 'company_user':
user_id = user['company_id']
pdf_name = f'order_{user_id}_{order['order_number']}.pdf'
cancel_order_pdf(pdf_name)
orders.cancel_order(order_id)

View File

@@ -1,9 +1,12 @@
from flask import Blueprint, request, jsonify
from flask import Blueprint, request, jsonify, abort
from flask_jwt_extended import jwt_required, get_jwt_identity
from models.order_in import OrdersIn
from models.transporters import Transporters
from models.user import Users
from datetime import datetime
import os
from flask import send_from_directory
import mimetypes
orders_in_bp = Blueprint("orders_in", __name__, url_prefix="/orders_in")
@@ -11,6 +14,10 @@ orders_in_bp = Blueprint("orders_in", __name__, url_prefix="/orders_in")
@jwt_required()
def create_order_in_route():
user_id = get_jwt_identity()
users = Users()
user = users.get_user_by_id(user_id)
if user['user_role'] == 'company_user':
user_id = user['company_id']
orders = OrdersIn()
incoming_data = request.json
try:
@@ -25,7 +32,10 @@ def create_order_in_route():
'track_reg_number': incoming_data["track_reg_number"],
'trailer_reg_number': incoming_data["trailer_reg_number"],
'products_description': incoming_data["products_description"],
'file': incoming_data['file'],
'expenses': incoming_data['expenses']
}
#print(order_data)
order_id = orders.create_order(order_data)
for address in incoming_data["loading_addresses"]:
@@ -60,6 +70,10 @@ def update_order_route(order_id):
orders = OrdersIn()
data = request.json
user_id = get_jwt_identity()
users = Users()
user = users.get_user_by_id(user_id)
if user['user_role'] == 'company_user':
user_id = user['company_id']
order = orders.get_order_by_id(order_id)
if not order:
return jsonify({"error": "Order in not found"}), 404
@@ -77,6 +91,8 @@ def update_order_route(order_id):
"track_reg_number": data.get("track_reg_number", order["track_reg_number"]),
"trailer_reg_number": data.get("trailer_reg_number", order["trailer_reg_number"]),
"products_description": data.get("products_description", order["products_description"]),
'file': data.get("file", order["file"]),
'expenses': data.get("expenses", order["expenses"]),
"user_id":user_id
})
@@ -113,6 +129,10 @@ def update_order_route(order_id):
def delete_order_route(order_id):
orders = OrdersIn()
user_id = get_jwt_identity()
users = Users()
user = users.get_user_by_id(user_id)
if user['user_role'] == 'company_user':
user_id = user['company_id']
order = orders.get_order_by_id(order_id)
if not order:
return jsonify({"error": "Order in not found"}), 404
@@ -131,6 +151,10 @@ def delete_order_route(order_id):
def list_orders():
orders = OrdersIn()
user_id = get_jwt_identity()
users = Users()
user = users.get_user_by_id(user_id)
if user['user_role'] == 'company_user':
user_id = user['company_id']
try:
user_orders = orders.get_orders_by_user(user_id)
#result = [{"id": order["id"], "order_number": order["order_number"]} for order in user_orders]
@@ -143,6 +167,10 @@ def list_orders():
def get_order(order_id):
orders = OrdersIn()
user_id = get_jwt_identity()
users = Users()
user = users.get_user_by_id(user_id)
if user['user_role'] == 'company_user':
user_id = user['company_id']
order = orders.get_order_by_id(order_id)
points = orders.get_order_points_by_order(order['id'])
loading_points = []
@@ -160,4 +188,26 @@ def get_order(order_id):
print(f'{type(order["user_id"])} {type(user_id)}')
if order["user_id"] != int(user_id):
return jsonify({"error": "Unauthorized"}), 403
return jsonify(order), 200
return jsonify(order), 200
@orders_in_bp.route("/files/<path:filename>", methods=["GET"])
#@jwt_required()
def serve_order_pdf(filename):
try:
# Directory containing uploaded client files
uploads_dir = os.path.abspath(
os.path.join(os.path.dirname(__file__), "..", "..", "client", "uploads")
)
# Security: prevent path traversal and ensure file exists
abs_file_path = os.path.abspath(os.path.join(uploads_dir, filename))
if not abs_file_path.startswith(uploads_dir + os.sep):
abort(404)
if not os.path.isfile(abs_file_path):
abort(404)
guessed_type = mimetypes.guess_type(filename)[0] or "application/octet-stream"
# send_from_directory expects the directory and the filename relative to it
return send_from_directory(uploads_dir, filename, mimetype=guessed_type, as_attachment=False)
except Exception as e:
print(e)
return jsonify({"error": "File not found"}), 404

View File

@@ -2,6 +2,7 @@ from flask import Blueprint, request, jsonify
from flask_jwt_extended import jwt_required, get_jwt_identity
from models.order_out import OrdersOut # Your plain SQL model
from datetime import datetime
from models.user import Users
report_bp = Blueprint("report", __name__, url_prefix="/report")
@@ -10,6 +11,10 @@ report_bp = Blueprint("report", __name__, url_prefix="/report")
def get_profit_report():
try:
user_id = get_jwt_identity()
users = Users()
user = users.get_user_by_id(user_id)
if user['user_role'] == 'company_user':
user_id = user['company_id']
# Get filters from query params
date_from = request.args.get("date_from")
date_to = request.args.get("date_to")

View File

@@ -11,6 +11,10 @@ subscription_bp = Blueprint("subscription", __name__, url_prefix="/subscription"
@jwt_required()
def get_subscription():
user_id = get_jwt_identity()
users = Users()
user = users.get_user_by_id(user_id)
if user['user_role'] == 'company_user':
user_id = user['company_id']
subscription_model = Subscription()
subscriptions = subscription_model.get_by_user_id(user_id)
return jsonify(subscriptions), 200

View File

@@ -1,6 +1,7 @@
from flask import Blueprint, request, jsonify
from flask_jwt_extended import jwt_required, get_jwt_identity
from models.transporters import Transporters
from models.user import Users
transporters_bp = Blueprint("transporters", __name__, url_prefix="/transporters")
@@ -8,6 +9,10 @@ transporters_bp = Blueprint("transporters", __name__, url_prefix="/transporters"
@jwt_required()
def list_transporters():
user_id = get_jwt_identity()
users = Users()
user = users.get_user_by_id(user_id)
if user['user_role'] == 'company_user':
user_id = user['company_id']
transporters_db = Transporters()
transporters = transporters_db.get_all_transporters_by_user(user_id)
return jsonify(transporters), 200
@@ -18,6 +23,10 @@ def create_transporter():
transporters_db = Transporters()
data = request.get_json()
user_id = get_jwt_identity()
users = Users()
user = users.get_user_by_id(user_id)
if user['user_role'] == 'company_user':
user_id = user['company_id']
transporter_id = transporters_db.create_transporter(
user_id=user_id,
name=data.get("name"),
@@ -36,6 +45,10 @@ def create_transporter():
def update_transporter(transporter_id):
transporters_db = Transporters()
user_id = get_jwt_identity()
users = Users()
user = users.get_user_by_id(user_id)
if user['user_role'] == 'company_user':
user_id = user['company_id']
data = request.get_json()
transporter = transporters_db.get_transporter_by_id(transporter_id)
if not transporter:
@@ -58,6 +71,10 @@ def update_transporter(transporter_id):
def delete_transporter(transporter_id):
transporters_db = Transporters()
user_id = get_jwt_identity()
users = Users()
user = users.get_user_by_id(user_id)
if user['user_role'] == 'company_user':
user_id = user['company_id']
transporter = transporters_db.get_transporter_by_id(transporter_id)
if not transporter:
return jsonify({"error": "Transporter not found"}), 404