Major Refactor
This commit is contained in:
@@ -5,45 +5,53 @@ from app import db, bcrypt
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
from app.classes.auth import Auth_User
|
from app.classes.auth import Auth_User
|
||||||
|
from app.classes.employee import Employee_Employee
|
||||||
|
|
||||||
@auth.route("/whoami", methods=["GET"])
|
@auth.route("/whoami", methods=["GET"])
|
||||||
def check_session():
|
def check_session():
|
||||||
"""
|
"""
|
||||||
Checks auth token to ensure user is authenticated
|
Checks auth token and returns user and associated employee data.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
api_key = request.headers.get('Authorization')
|
api_key = request.headers.get('Authorization')
|
||||||
if not api_key:
|
if not api_key:
|
||||||
return jsonify({"error": "True"}), 200
|
return jsonify({"ok": False, "error": "Authorization header missing"}), 401
|
||||||
else:
|
|
||||||
api_key = api_key.replace('bearer ', '', 1)
|
# Clean up the token
|
||||||
api_key = api_key.replace('"', '')
|
api_key = api_key.replace('bearer ', '', 1).strip('"')
|
||||||
|
|
||||||
user_exists = (db.session
|
user = db.session.query(Auth_User).filter(Auth_User.api_key == api_key).first()
|
||||||
.query(Auth_User)
|
|
||||||
.filter(Auth_User.api_key == api_key)
|
if not user:
|
||||||
.first())
|
return jsonify({"ok": False, "error": "Invalid token"}), 401
|
||||||
if not user_exists:
|
|
||||||
return jsonify({"error": True}), 200
|
# --- THIS IS THE CRITICAL FIX ---
|
||||||
else:
|
# Now that we have the user, find the corresponding employee record.
|
||||||
user = db.session\
|
# This assumes your Employee model has a 'user_id' field linking to the Auth_User 'id'.
|
||||||
.query(Auth_User)\
|
employee = db.session.query(Employee_Employee).filter(Employee_Employee.user_id == user.id).first()
|
||||||
.filter(Auth_User.api_key == api_key)\
|
|
||||||
.first()
|
# It's possible a user exists without an employee record, so we handle that case.
|
||||||
|
if not employee:
|
||||||
return jsonify({
|
return jsonify({"ok": False, "error": "User found, but no associated employee record"}), 404
|
||||||
"ok": True,
|
|
||||||
'user': {
|
# Now, build the complete response with both user and employee data.
|
||||||
'user_name': user.username,
|
return jsonify({
|
||||||
'user_id': user.id,
|
"ok": True,
|
||||||
'user_email': user.email,
|
'user': {
|
||||||
'user_admin': user.admin_role,
|
'user_name': user.username,
|
||||||
'token': user.api_key,
|
'user_id': user.id,
|
||||||
'confirmed': user.confirmed
|
'user_email': user.email,
|
||||||
},
|
'user_admin': user.admin_role,
|
||||||
'token': user.api_key
|
'token': user.api_key,
|
||||||
}), 200
|
'confirmed': user.confirmed
|
||||||
|
},
|
||||||
|
# ADD THE EMPLOYEE OBJECT TO THE RESPONSE
|
||||||
|
'employee': {
|
||||||
|
'id': employee.id,
|
||||||
|
'employee_first_name': employee.employee_first_name,
|
||||||
|
'employee_last_name': employee.employee_last_name,
|
||||||
|
# Add any other employee fields you might need on the frontend
|
||||||
|
}
|
||||||
|
}), 200
|
||||||
|
|
||||||
|
|
||||||
@auth.route("/amiconfirmed", methods=["GET"])
|
@auth.route("/amiconfirmed", methods=["GET"])
|
||||||
|
|||||||
@@ -547,71 +547,57 @@ def customer_automatic_assignment(customer_id):
|
|||||||
"ok": True,
|
"ok": True,
|
||||||
'status': status
|
'status': status
|
||||||
}), 200
|
}), 200
|
||||||
|
|
||||||
|
|
||||||
@customer.route("/edit/tank/<int:customer_id>", methods=["PUT"])
|
@customer.route("/edit/tank/<int:customer_id>", methods=["PUT"])
|
||||||
@login_required
|
@login_required
|
||||||
def edit_customer_tank(customer_id):
|
def edit_customer_tank(customer_id):
|
||||||
"""
|
"""
|
||||||
|
Safely edits or creates tank and description details for a customer.
|
||||||
"""
|
"""
|
||||||
get_customer = (db.session
|
get_customer = db.session.query(Customer_Customer).filter(Customer_Customer.id == customer_id).one_or_none()
|
||||||
.query(Customer_Customer)
|
if not get_customer:
|
||||||
.filter(Customer_Customer.id == customer_id)
|
return jsonify({"ok": False, "error": "Customer not found"}), 404
|
||||||
.first())
|
|
||||||
get_customer_description = (db.session
|
|
||||||
.query(Customer_Description)
|
|
||||||
.filter(Customer_Description.customer_id == customer_id)
|
|
||||||
.first())
|
|
||||||
get_customer_tank = (db.session
|
|
||||||
.query(Customer_Tank_Inspection)
|
|
||||||
.filter(Customer_Tank_Inspection.customer_id == customer_id)
|
|
||||||
.first())
|
|
||||||
|
|
||||||
response_tank_status = request.json["tank_status"]
|
get_customer_description = db.session.query(Customer_Description).filter(Customer_Description.customer_id == customer_id).first()
|
||||||
|
if not get_customer_description:
|
||||||
|
get_customer_description = Customer_Description(customer_id=customer_id)
|
||||||
|
db.session.add(get_customer_description)
|
||||||
|
|
||||||
if response_tank_status == 'true':
|
get_customer_tank = db.session.query(Customer_Tank_Inspection).filter(Customer_Tank_Inspection.customer_id == customer_id).first()
|
||||||
get_customer_tank.tank_status = True
|
if not get_customer_tank:
|
||||||
|
get_customer_tank = Customer_Tank_Inspection(customer_id=customer_id)
|
||||||
|
db.session.add(get_customer_tank)
|
||||||
|
|
||||||
elif response_tank_status == 'false':
|
data = request.get_json()
|
||||||
get_customer_tank.outside_or_inside = False
|
|
||||||
else:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
if 'tank_status' in data:
|
||||||
|
get_customer_tank.tank_status = data["tank_status"]
|
||||||
|
|
||||||
|
if 'outside_or_inside' in data:
|
||||||
|
get_customer_tank.outside_or_inside = data["outside_or_inside"]
|
||||||
|
|
||||||
response_outside_or_inside = request.json["outside_or_inside"]
|
response_last_tank_inspection = data.get("last_tank_inspection", None)
|
||||||
if response_outside_or_inside == 'true':
|
response_tank_size = data.get("tank_size", 0)
|
||||||
get_customer_tank.outside_or_inside = True
|
|
||||||
|
# --- FIX APPLIED HERE ---
|
||||||
elif response_outside_or_inside == 'false':
|
# 1. Get the value from the request. Default to 0 if it's missing.
|
||||||
get_customer_tank.outside_or_inside = False
|
response_customer_fill_location = data.get("fill_location", 0)
|
||||||
else:
|
|
||||||
pass
|
# 2. Add a safety check: if the frontend sent an empty string, convert it to 0.
|
||||||
|
if response_customer_fill_location == "":
|
||||||
response_last_tank_inspection = request.json["last_tank_inspection"]
|
response_customer_fill_location = 0
|
||||||
response_tank_size = request.json["tank_size"]
|
|
||||||
response_customer_fill_location = request.json["fill_location"]
|
|
||||||
|
|
||||||
|
|
||||||
get_customer_tank.last_tank_inspection = response_last_tank_inspection
|
get_customer_tank.last_tank_inspection = response_last_tank_inspection
|
||||||
get_customer_tank.tank_size = response_tank_size
|
get_customer_tank.tank_size = response_tank_size
|
||||||
|
|
||||||
|
|
||||||
get_customer_description.fill_location = response_customer_fill_location
|
get_customer_description.fill_location = response_customer_fill_location
|
||||||
|
|
||||||
if get_customer.customer_automatic == 1:
|
if get_customer.customer_automatic == 1:
|
||||||
get_auto_info = (db.session
|
get_auto_info = db.session.query(Auto_Delivery).filter(Auto_Delivery.customer_id == customer_id).first()
|
||||||
.query(Auto_Delivery)
|
if get_auto_info:
|
||||||
.filter(Auto_Delivery.customer_id == customer_id)
|
get_auto_info.tank_size = response_tank_size
|
||||||
.first())
|
db.session.add(get_auto_info)
|
||||||
|
|
||||||
get_auto_info.tank_size = response_tank_size
|
|
||||||
db.session.add(get_auto_info)
|
|
||||||
|
|
||||||
|
|
||||||
db.session.add(get_customer_description)
|
|
||||||
|
|
||||||
db.session.add(get_customer)
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
return jsonify({
|
return jsonify({"ok": True}), 200
|
||||||
"ok": True,
|
|
||||||
}), 200
|
|
||||||
|
|
||||||
@@ -17,116 +17,86 @@ from app.classes.promo import Promo_Promo
|
|||||||
from app.classes.stats_customer import Stats_Customer
|
from app.classes.stats_customer import Stats_Customer
|
||||||
from app.classes.auto import Tickets_Auto_Delivery, Tickets_Auto_Delivery_schema
|
from app.classes.auto import Tickets_Auto_Delivery, Tickets_Auto_Delivery_schema
|
||||||
|
|
||||||
|
|
||||||
|
# This endpoint is fine, but I've added some comments for clarity.
|
||||||
@delivery.route("/updatestatus", methods=["GET"])
|
@delivery.route("/updatestatus", methods=["GET"])
|
||||||
def move_deliveries():
|
def move_deliveries():
|
||||||
"""
|
"""
|
||||||
This will get deliveries not done
|
Batch updates delivery statuses based on their expected delivery date relative to today.
|
||||||
|
- Today's deliveries -> "Out for Delivery" (2)
|
||||||
|
- Tomorrow's deliveries -> "Scheduled for Tomorrow" (3)
|
||||||
|
- Future deliveries -> "Waiting" (0)
|
||||||
|
- Past-due deliveries -> "Pending" (9)
|
||||||
"""
|
"""
|
||||||
counter = 0
|
counter = 0
|
||||||
today = date.today()
|
today = date.today()
|
||||||
deliveries_today = (db.session
|
tomorrow = today + timedelta(days=1)
|
||||||
.query(Delivery_Delivery)
|
|
||||||
.filter(Delivery_Delivery.delivery_status != 10)
|
# Update statuses for deliveries scheduled for today
|
||||||
.filter(Delivery_Delivery.delivery_status != 5)
|
deliveries_today = db.session.query(Delivery_Delivery).filter(
|
||||||
.filter(Delivery_Delivery.delivery_status != 1)
|
Delivery_Delivery.delivery_status.notin_([1, 5, 10]), # Not cancelled, issue, or finalized
|
||||||
.filter(Delivery_Delivery.expected_delivery_date == today)
|
Delivery_Delivery.expected_delivery_date == today,
|
||||||
.all())
|
Delivery_Delivery.delivery_status != 2 # Avoid redundant updates
|
||||||
for f in deliveries_today:
|
).all()
|
||||||
if f.delivery_status != 2:
|
for delivery_item in deliveries_today:
|
||||||
f.delivery_status = 2
|
delivery_item.delivery_status = 2
|
||||||
db.session.add(f)
|
db.session.add(delivery_item)
|
||||||
counter = counter + 1
|
counter += 1
|
||||||
|
|
||||||
tomm = date.today() + timedelta(days=1)
|
# Update statuses for deliveries scheduled for tomorrow
|
||||||
deliveries_tom = (db.session
|
deliveries_tomorrow = db.session.query(Delivery_Delivery).filter(
|
||||||
.query(Delivery_Delivery)
|
Delivery_Delivery.delivery_status.notin_([1, 5, 10]),
|
||||||
.filter(Delivery_Delivery.delivery_status != 10)
|
Delivery_Delivery.expected_delivery_date == tomorrow,
|
||||||
.filter(Delivery_Delivery.delivery_status != 5)
|
Delivery_Delivery.delivery_status != 3
|
||||||
.filter(Delivery_Delivery.delivery_status != 1)
|
).all()
|
||||||
.filter(Delivery_Delivery.expected_delivery_date == tomm)
|
for delivery_item in deliveries_tomorrow:
|
||||||
.all())
|
delivery_item.delivery_status = 3
|
||||||
for g in deliveries_tom:
|
db.session.add(delivery_item)
|
||||||
if g.delivery_status != 3:
|
counter += 1
|
||||||
g.delivery_status = 3
|
|
||||||
db.session.add(g)
|
|
||||||
counter = counter + 1
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
deliveries_waiting = (db.session
|
|
||||||
.query(Delivery_Delivery)
|
|
||||||
.filter(Delivery_Delivery.delivery_status != 10)
|
|
||||||
.filter(Delivery_Delivery.delivery_status != 5)
|
|
||||||
.filter(Delivery_Delivery.delivery_status != 1)
|
|
||||||
.filter(Delivery_Delivery.expected_delivery_date != tomm)
|
|
||||||
.filter(Delivery_Delivery.expected_delivery_date > today)
|
|
||||||
.all())
|
|
||||||
for r in deliveries_waiting:
|
|
||||||
if r.delivery_status != 0:
|
|
||||||
r.delivery_status = 0
|
|
||||||
db.session.add(r)
|
|
||||||
counter = counter + 1
|
|
||||||
|
|
||||||
|
|
||||||
deliveries_pending = (db.session
|
|
||||||
.query(Delivery_Delivery)
|
|
||||||
.filter(Delivery_Delivery.delivery_status != 10)
|
|
||||||
.filter(Delivery_Delivery.delivery_status != 5)
|
|
||||||
.filter(Delivery_Delivery.delivery_status != 1)
|
|
||||||
.filter(Delivery_Delivery.expected_delivery_date < today)
|
|
||||||
.all())
|
|
||||||
for t in deliveries_pending:
|
|
||||||
if t.delivery_status != 9:
|
|
||||||
t.delivery_status = 9
|
|
||||||
db.session.add(t)
|
|
||||||
counter = counter + 1
|
|
||||||
|
|
||||||
|
# Update statuses for future deliveries (after tomorrow)
|
||||||
|
deliveries_waiting = db.session.query(Delivery_Delivery).filter(
|
||||||
|
Delivery_Delivery.delivery_status.notin_([1, 5, 10]),
|
||||||
|
Delivery_Delivery.expected_delivery_date > tomorrow,
|
||||||
|
Delivery_Delivery.delivery_status != 0
|
||||||
|
).all()
|
||||||
|
for delivery_item in deliveries_waiting:
|
||||||
|
delivery_item.delivery_status = 0
|
||||||
|
db.session.add(delivery_item)
|
||||||
|
counter += 1
|
||||||
|
|
||||||
|
# Update statuses for deliveries that are past their expected date
|
||||||
|
deliveries_pending = db.session.query(Delivery_Delivery).filter(
|
||||||
|
Delivery_Delivery.delivery_status.notin_([1, 5, 10]),
|
||||||
|
Delivery_Delivery.expected_delivery_date < today,
|
||||||
|
Delivery_Delivery.delivery_status != 9
|
||||||
|
).all()
|
||||||
|
for delivery_item in deliveries_pending:
|
||||||
|
delivery_item.delivery_status = 9
|
||||||
|
db.session.add(delivery_item)
|
||||||
|
counter += 1
|
||||||
|
|
||||||
if counter > 0:
|
if counter > 0:
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
return jsonify({
|
return jsonify({"ok": True, 'update': True}), 200
|
||||||
"ok": True,
|
|
||||||
'update': True,
|
|
||||||
}), 200
|
|
||||||
|
|
||||||
return jsonify({"ok": True}), 200
|
|
||||||
|
|
||||||
|
return jsonify({"ok": True, 'update': False}), 200
|
||||||
|
|
||||||
|
|
||||||
@delivery.route("/<int:delivery_id>", methods=["GET"])
|
@delivery.route("/<int:delivery_id>", methods=["GET"])
|
||||||
def get_a_delivery(delivery_id):
|
def get_a_delivery(delivery_id):
|
||||||
"""
|
"""
|
||||||
|
Get a single delivery's details.
|
||||||
"""
|
"""
|
||||||
get_delivery = db.session\
|
get_delivery = db.session.query(Delivery_Delivery).filter(Delivery_Delivery.id == delivery_id).first()
|
||||||
.query(Delivery_Delivery)\
|
if not get_delivery:
|
||||||
.filter(Delivery_Delivery.id == delivery_id)\
|
return jsonify({"ok": False, "error": "Delivery not found"}), 404
|
||||||
.first()
|
|
||||||
|
# Using the schema is cleaner and less error-prone than building a manual dictionary.
|
||||||
return jsonify({
|
delivery_schema = Delivery_Delivery_schema(many=False)
|
||||||
"ok": True,
|
return jsonify({"ok": True, "delivery": delivery_schema.dump(get_delivery)}), 200
|
||||||
'delivery': {
|
|
||||||
'id': get_delivery.id,
|
|
||||||
'customer_id': get_delivery.customer_id,
|
|
||||||
'delivery_expected_delivery_date': str(get_delivery.expected_delivery_date),
|
|
||||||
'delivery_asked_for_fill': get_delivery.customer_asked_for_fill,
|
|
||||||
'delivery_gallons_ordered': get_delivery.gallons_ordered,
|
|
||||||
'dispatcher_notes_taken': get_delivery.dispatcher_notes,
|
|
||||||
'delivery_prime': get_delivery.prime,
|
|
||||||
'delivery_emergency': get_delivery.emergency,
|
|
||||||
'delivery_same_day': get_delivery.same_day,
|
|
||||||
'when_ordered': str(get_delivery.when_ordered),
|
|
||||||
'customer_price': get_delivery.customer_price,
|
|
||||||
'delivery_status': get_delivery.delivery_status,
|
|
||||||
'payment_type': get_delivery.payment_type,
|
|
||||||
'payment_card_id': get_delivery.payment_card_id,
|
|
||||||
'driver_employee_id': get_delivery.driver_employee_id,
|
|
||||||
'driver_first_name': get_delivery.driver_first_name,
|
|
||||||
'driver_last_name': get_delivery.driver_last_name,
|
|
||||||
'promo_id': get_delivery.promo_id,
|
|
||||||
'promo_money_discount': get_delivery.promo_money_discount,
|
|
||||||
|
|
||||||
},
|
|
||||||
}), 200
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -173,11 +143,13 @@ def get_customer_auto_delivery(customer_id):
|
|||||||
|
|
||||||
@delivery.route("/order/<int:delivery_id>", methods=["GET"])
|
@delivery.route("/order/<int:delivery_id>", methods=["GET"])
|
||||||
def get_a_specific_delivery(delivery_id):
|
def get_a_specific_delivery(delivery_id):
|
||||||
|
"""
|
||||||
get_delivery = db.session\
|
Get a single delivery by its ID.
|
||||||
.query(Delivery_Delivery)\
|
"""
|
||||||
.filter(Delivery_Delivery.id == delivery_id)\
|
get_delivery = db.session.query(Delivery_Delivery).filter(Delivery_Delivery.id == delivery_id).first()
|
||||||
.first()
|
if not get_delivery:
|
||||||
|
return jsonify({"error": "Delivery not found"}), 404
|
||||||
|
|
||||||
delivery_schema = Delivery_Delivery_schema(many=False)
|
delivery_schema = Delivery_Delivery_schema(many=False)
|
||||||
return jsonify(delivery_schema.dump(get_delivery))
|
return jsonify(delivery_schema.dump(get_delivery))
|
||||||
|
|
||||||
@@ -492,172 +464,97 @@ def get_deliveries_today():
|
|||||||
@delivery.route("/edit/<int:delivery_id>", methods=["POST"])
|
@delivery.route("/edit/<int:delivery_id>", methods=["POST"])
|
||||||
def edit_a_delivery(delivery_id):
|
def edit_a_delivery(delivery_id):
|
||||||
"""
|
"""
|
||||||
This will edit a delivery using a delivery id
|
This will edit a delivery using a delivery id.
|
||||||
"""
|
"""
|
||||||
get_delivery = db.session \
|
data = request.json
|
||||||
.query(Delivery_Delivery) \
|
get_delivery = db.session.query(Delivery_Delivery).filter(Delivery_Delivery.id == delivery_id).first()
|
||||||
.filter(Delivery_Delivery.id == delivery_id) \
|
|
||||||
.first()
|
|
||||||
|
|
||||||
|
|
||||||
get_customer = db.session \
|
|
||||||
.query(Customer_Customer) \
|
|
||||||
.filter(Customer_Customer.id == get_delivery.customer_id) \
|
|
||||||
.first()
|
|
||||||
|
|
||||||
get_today_price = db.session\
|
|
||||||
.query(Pricing_Oil_Oil)\
|
|
||||||
.order_by(Pricing_Oil_Oil.id.desc())\
|
|
||||||
.first()
|
|
||||||
|
|
||||||
if not get_delivery:
|
if not get_delivery:
|
||||||
return jsonify({"error": False}), 200
|
return jsonify({"ok": False, "error": "Delivery not found"}), 404
|
||||||
else:
|
|
||||||
gallons_ordered = request.json["gallons_ordered"]
|
|
||||||
delivery_status = request.json["delivery_status"]
|
|
||||||
when_to_deliver = request.json["expected_delivery_date"]
|
|
||||||
when_ordered = request.json["created_delivery_date"]
|
|
||||||
customer_wants_fill = request.json["customer_asked_for_fill"]
|
|
||||||
card_payment = request.json["credit"]
|
|
||||||
cash_payment = request.json["cash"]
|
|
||||||
emergency_info = request.json["emergency"]
|
|
||||||
dispatcher_notes = request.json["dispatcher_notes_taken"]
|
|
||||||
|
|
||||||
delivery_driver_id = request.json["driver_employee_id"]
|
# --- Fetch related data ---
|
||||||
|
get_customer = db.session.query(Customer_Customer).filter(Customer_Customer.id == get_delivery.customer_id).first()
|
||||||
|
if not get_customer:
|
||||||
|
return jsonify({"ok": False, "error": "Associated customer not found"}), 404
|
||||||
|
|
||||||
get_driver = (db.session
|
get_today_price = db.session.query(Pricing_Oil_Oil).order_by(Pricing_Oil_Oil.id.desc()).first()
|
||||||
.query(Employee_Employee)
|
if not get_today_price:
|
||||||
.filter(Employee_Employee.id == delivery_driver_id)
|
return jsonify({"ok": False, "error": "Pricing information not available"}), 500
|
||||||
.first())
|
|
||||||
|
# --- Process Form Input (using .get() for safety) ---
|
||||||
|
get_delivery.gallons_ordered = data.get("gallons_ordered", get_delivery.gallons_ordered)
|
||||||
|
get_delivery.delivery_status = data.get("delivery_status", get_delivery.delivery_status)
|
||||||
|
get_delivery.expected_delivery_date = data.get("expected_delivery_date")
|
||||||
|
get_delivery.when_ordered = data.get("created_delivery_date")
|
||||||
|
get_delivery.dispatcher_notes = data.get("dispatcher_notes_taken", "")
|
||||||
|
get_delivery.payment_type = data.get("payment_type", 0)
|
||||||
|
|
||||||
|
# Convert booleans to 1 or 0 for the database
|
||||||
|
customer_wants_fill = 1 if data.get("customer_asked_for_fill") else 0
|
||||||
|
get_delivery.customer_asked_for_fill = customer_wants_fill
|
||||||
|
get_delivery.prime = 1 if data.get("prime") else 0
|
||||||
|
get_delivery.same_day = 1 if data.get("same_day") else 0
|
||||||
|
get_delivery.emergency = 1 if data.get("emergency") else 0
|
||||||
|
|
||||||
|
# --- Handle Driver Assignment ---
|
||||||
|
driver_id = data.get("driver_employee_id")
|
||||||
|
if driver_id:
|
||||||
|
get_driver = db.session.query(Employee_Employee).filter(Employee_Employee.id == driver_id).first()
|
||||||
|
if get_driver:
|
||||||
|
get_delivery.driver_employee_id = get_driver.id
|
||||||
|
get_delivery.driver_first_name = get_driver.employee_first_name
|
||||||
|
get_delivery.driver_last_name = get_driver.employee_last_name
|
||||||
|
else:
|
||||||
|
# Optionally, handle the case where the driver ID is invalid
|
||||||
|
# For now, we'll just not update the driver info.
|
||||||
|
pass
|
||||||
|
|
||||||
|
# --- Handle Promotion ---
|
||||||
|
promo_id = data.get("promo_id")
|
||||||
|
if promo_id and promo_id != 0:
|
||||||
|
get_promo = db.session.query(Promo_Promo).filter(Promo_Promo.id == promo_id).first()
|
||||||
|
if get_promo:
|
||||||
|
get_delivery.promo_id = get_promo.id
|
||||||
|
get_delivery.promo_money_discount = get_promo.money_off_delivery
|
||||||
|
else: # Clear promo if "No Promotion" is selected
|
||||||
|
get_delivery.promo_id = None
|
||||||
|
get_delivery.promo_money_discount = None
|
||||||
|
|
||||||
|
# --- Handle Credit Card Assignment ---
|
||||||
|
card_id = data.get("credit_card_id")
|
||||||
|
# Only assign card if payment type is Card (1) and a valid card_id is provided
|
||||||
|
if get_delivery.payment_type == 1 and card_id:
|
||||||
|
get_card = db.session.query(Card_Card).filter(Card_Card.id == card_id, Card_Card.user_id == get_customer.id).first()
|
||||||
|
if get_card:
|
||||||
|
get_delivery.payment_card_id = get_card.id
|
||||||
|
else: # Clear card if payment is not by card
|
||||||
|
get_delivery.payment_card_id = None
|
||||||
|
|
||||||
|
# --- Recalculate Pricing (This logic could be moved to a helper function) ---
|
||||||
|
gallons_for_calc = 250 if customer_wants_fill else int(get_delivery.gallons_ordered)
|
||||||
|
base_price = gallons_for_calc * get_today_price.price_for_customer
|
||||||
|
|
||||||
|
# Add fees
|
||||||
|
total_price = base_price
|
||||||
|
if get_delivery.prime:
|
||||||
|
total_price += get_today_price.price_prime
|
||||||
|
if get_delivery.same_day:
|
||||||
|
total_price += get_today_price.price_same_day
|
||||||
|
if get_delivery.emergency:
|
||||||
|
total_price += get_today_price.price_emergency
|
||||||
|
|
||||||
## promo
|
get_delivery.total_price = base_price # Price before fees
|
||||||
|
get_delivery.pre_charge_amount = total_price # Price including fees
|
||||||
try:
|
|
||||||
if request.json["promo_id"]:
|
|
||||||
promo_id = request.json["promo_id"]
|
|
||||||
else:
|
|
||||||
promo_id = None
|
|
||||||
except:
|
|
||||||
promo_id = None
|
|
||||||
|
|
||||||
if promo_id is not None:
|
|
||||||
get_promo_data = (db.session
|
|
||||||
.query(Promo_Promo)
|
|
||||||
.filter(Promo_Promo.id == promo_id)
|
|
||||||
.first())
|
|
||||||
promo_id_get_delivery =get_promo_data.id,
|
|
||||||
promo_money_discount_get_delivery = get_promo_data.money_off_delivery
|
|
||||||
else:
|
|
||||||
promo_id_get_delivery =None
|
|
||||||
promo_money_discount_get_delivery = None
|
|
||||||
|
|
||||||
|
# --- Commit Changes ---
|
||||||
|
db.session.add(get_delivery)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
return jsonify({
|
||||||
if request.json["credit_card_id"]:
|
"ok": True,
|
||||||
card_payment_id = request.json["credit_card_id"]
|
'message': f"Delivery {delivery_id} updated successfully.",
|
||||||
else:
|
'customer_id': get_customer.id # Keep this if the frontend uses it for navigation
|
||||||
card_payment_id = None
|
}), 200
|
||||||
|
|
||||||
|
|
||||||
if card_payment_id is not None:
|
|
||||||
get_card = (db.session
|
|
||||||
.query(Card_Card)
|
|
||||||
.filter(Card_Card.id == card_payment_id)
|
|
||||||
.filter(Card_Card.user_id == get_customer.id)
|
|
||||||
.first())
|
|
||||||
card_id_from_customer = get_card.id
|
|
||||||
else:
|
|
||||||
card_id_from_customer = None
|
|
||||||
|
|
||||||
|
|
||||||
if cash_payment is True and card_payment is False:
|
|
||||||
delivery_payment_method = 0
|
|
||||||
|
|
||||||
elif card_payment is True and cash_payment is False:
|
|
||||||
delivery_payment_method = 1
|
|
||||||
|
|
||||||
elif card_payment is True and cash_payment is True:
|
|
||||||
delivery_payment_method = 2
|
|
||||||
else:
|
|
||||||
delivery_payment_method = 3
|
|
||||||
|
|
||||||
if customer_wants_fill is True:
|
|
||||||
customer_wants_fill = 1
|
|
||||||
gallons_ordered = 250
|
|
||||||
else:
|
|
||||||
customer_wants_fill = 0
|
|
||||||
|
|
||||||
same_day_info = request.json["same_day"]
|
|
||||||
if same_day_info is True:
|
|
||||||
same_day_info = 1
|
|
||||||
else:
|
|
||||||
same_day_info = 0
|
|
||||||
|
|
||||||
if emergency_info is True:
|
|
||||||
emergency_asked = 1
|
|
||||||
else:
|
|
||||||
emergency_asked = 0
|
|
||||||
|
|
||||||
prime_info = request.json["prime"]
|
|
||||||
if prime_info is True:
|
|
||||||
prime_info = 1
|
|
||||||
else:
|
|
||||||
prime_info = 0
|
|
||||||
|
|
||||||
# Pricing
|
|
||||||
|
|
||||||
if customer_wants_fill == 1:
|
|
||||||
# Fill
|
|
||||||
precharge_amount = (250 * get_today_price.price_for_customer)
|
|
||||||
else:
|
|
||||||
# Gallons
|
|
||||||
precharge_amount = int(gallons_ordered) * get_today_price.price_for_customer
|
|
||||||
|
|
||||||
|
|
||||||
# if prime/emergency/sameday
|
|
||||||
if same_day_info == 1 and prime_info == 0:
|
|
||||||
total_precharge_amount = precharge_amount + get_today_price.price_same_day
|
|
||||||
|
|
||||||
elif prime_info == 1 and same_day_info == 0:
|
|
||||||
total_precharge_amount = precharge_amount + get_today_price.price_prime
|
|
||||||
|
|
||||||
elif emergency_asked == 1:
|
|
||||||
total_precharge_amount = precharge_amount + get_today_price.price_emergency
|
|
||||||
|
|
||||||
else:
|
|
||||||
total_precharge_amount = precharge_amount + get_today_price.price_prime + get_today_price.price_same_day
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
get_delivery.dispatcher_notes = dispatcher_notes
|
|
||||||
get_delivery.delivery_status = delivery_status
|
|
||||||
get_delivery.gallons_ordered = gallons_ordered
|
|
||||||
get_delivery.customer_asked_for_fill = customer_wants_fill
|
|
||||||
get_delivery.expected_delivery_date = when_to_deliver
|
|
||||||
get_delivery.when_ordered = when_ordered
|
|
||||||
get_delivery.prime = prime_info
|
|
||||||
get_delivery.same_day = same_day_info
|
|
||||||
get_delivery.gallons_ordered = gallons_ordered
|
|
||||||
get_delivery.payment_type = delivery_payment_method
|
|
||||||
get_delivery.payment_card_id = card_id_from_customer
|
|
||||||
get_delivery.driver_last_name = get_driver.employee_last_name
|
|
||||||
get_delivery.driver_first_name = get_driver.employee_first_name
|
|
||||||
get_delivery.driver_employee_id = get_driver.id
|
|
||||||
get_delivery.promo_id = promo_id_get_delivery
|
|
||||||
get_delivery.promo_money_discount = promo_money_discount_get_delivery
|
|
||||||
|
|
||||||
get_delivery.pre_charge_amount = total_precharge_amount
|
|
||||||
get_delivery.total_price = precharge_amount
|
|
||||||
|
|
||||||
db.session.add(get_delivery)
|
|
||||||
db.session.commit()
|
|
||||||
|
|
||||||
return jsonify({
|
|
||||||
"ok": True,
|
|
||||||
'customer': {
|
|
||||||
'user_id': get_customer.id,
|
|
||||||
},
|
|
||||||
}), 200
|
|
||||||
|
|
||||||
|
|
||||||
@delivery.route("/create/<int:user_id>", methods=["POST"])
|
@delivery.route("/create/<int:user_id>", methods=["POST"])
|
||||||
|
|||||||
@@ -99,22 +99,24 @@ def create_user_card(user_id):
|
|||||||
"""
|
"""
|
||||||
adds a card of a user
|
adds a card of a user
|
||||||
"""
|
"""
|
||||||
|
|
||||||
get_customer = (db.session
|
get_customer = (db.session
|
||||||
.query(Customer_Customer)
|
.query(Customer_Customer)
|
||||||
.filter(Customer_Customer.id == user_id)
|
.filter(Customer_Customer.id == user_id)
|
||||||
.first())
|
.first())
|
||||||
|
|
||||||
name_on_card = request.json["card_name"]
|
# --- FIX: Use .get() for safety and get the correct key 'name_on_card' ---
|
||||||
expiration_month = request.json["expiration_month"]
|
data = request.get_json()
|
||||||
expiration_year = request.json["expiration_year"]
|
name_on_card = data.get("name_on_card") # <-- CORRECT KEY
|
||||||
type_of_card = request.json["type_of_card"]
|
expiration_month = data.get("expiration_month")
|
||||||
security_number = request.json["security_number"]
|
expiration_year = data.get("expiration_year")
|
||||||
main_card = request.json["main_card"]
|
type_of_card = data.get("type_of_card")
|
||||||
zip_code = request.json["zip_code"]
|
security_number = data.get("security_number")
|
||||||
|
main_card = data.get("main_card", False)
|
||||||
card_number = request.json["card_number"]
|
zip_code = data.get("zip_code")
|
||||||
last_four = card_number[-4]
|
card_number = data.get("card_number")
|
||||||
|
|
||||||
|
# --- FIX: Correctly slice the last four digits ---
|
||||||
|
last_four = card_number[-4:] if card_number else ""
|
||||||
|
|
||||||
create_new_card = Card_Card(
|
create_new_card = Card_Card(
|
||||||
user_id=get_customer.id,
|
user_id=get_customer.id,
|
||||||
@@ -131,12 +133,10 @@ def create_user_card(user_id):
|
|||||||
)
|
)
|
||||||
db.session.add(create_new_card)
|
db.session.add(create_new_card)
|
||||||
db.session.flush()
|
db.session.flush()
|
||||||
if main_card is True:
|
|
||||||
try:
|
if main_card:
|
||||||
set_card_main(user_id=get_customer.id, card_id=create_new_card.id)
|
set_card_main(user_id=get_customer.id, card_id=create_new_card.id)
|
||||||
except:
|
|
||||||
pass
|
|
||||||
db.session.add(create_new_card)
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
return jsonify({"ok": True}), 200
|
return jsonify({"ok": True}), 200
|
||||||
@@ -176,28 +176,25 @@ def update_user_card(card_id):
|
|||||||
"""
|
"""
|
||||||
edits a card
|
edits a card
|
||||||
"""
|
"""
|
||||||
|
|
||||||
get_card = (db.session
|
get_card = (db.session
|
||||||
.query(Card_Card)
|
.query(Card_Card)
|
||||||
.filter(Card_Card.id == card_id)
|
.filter(Card_Card.id == card_id)
|
||||||
.first())
|
.first())
|
||||||
|
|
||||||
get_customer = (db.session
|
if not get_card:
|
||||||
.query(Customer_Customer)
|
return jsonify({"ok": False, "error": "Card not found"}), 404
|
||||||
.filter(Customer_Customer.id == get_card.user_id)
|
|
||||||
.first())
|
|
||||||
|
|
||||||
|
# --- FIX: Use .get() for safety and get the correct key 'name_on_card' ---
|
||||||
|
data = request.get_json()
|
||||||
|
name_on_card = data.get("name_on_card") # <-- CORRECT KEY
|
||||||
|
expiration_month = data.get("expiration_month")
|
||||||
|
expiration_year = data.get("expiration_year")
|
||||||
|
type_of_card = data.get("type_of_card")
|
||||||
|
security_number = data.get("security_number")
|
||||||
|
card_number = data.get("card_number")
|
||||||
|
main_card = data.get("main_card", False)
|
||||||
|
zip_code = data.get("zip_code")
|
||||||
|
|
||||||
name_on_card = request.json["card_name"]
|
|
||||||
expiration_month = request.json["expiration_month"]
|
|
||||||
expiration_year = request.json["expiration_year"]
|
|
||||||
type_of_card = request.json["type_of_card"]
|
|
||||||
security_number = request.json["security_number"]
|
|
||||||
card_number = request.json["card_number"]
|
|
||||||
main_card = request.json["main_card"]
|
|
||||||
zip_code = request.json["zip_code"]
|
|
||||||
|
|
||||||
get_card.user_id = get_customer.id
|
|
||||||
get_card.card_number = card_number
|
get_card.card_number = card_number
|
||||||
get_card.name_on_card = name_on_card
|
get_card.name_on_card = name_on_card
|
||||||
get_card.expiration_month = expiration_month
|
get_card.expiration_month = expiration_month
|
||||||
@@ -206,9 +203,13 @@ def update_user_card(card_id):
|
|||||||
get_card.security_number = security_number
|
get_card.security_number = security_number
|
||||||
get_card.main_card = main_card
|
get_card.main_card = main_card
|
||||||
get_card.zip_code = zip_code
|
get_card.zip_code = zip_code
|
||||||
|
|
||||||
|
# --- FIX: Correctly slice the last four digits on edit ---
|
||||||
|
if card_number:
|
||||||
|
get_card.last_four_digits = card_number[-4:]
|
||||||
|
|
||||||
if main_card is True:
|
if main_card:
|
||||||
set_card_main(user_id=get_customer.id, card_id=get_card.id)
|
set_card_main(user_id=get_card.user_id, card_id=get_card.id)
|
||||||
|
|
||||||
db.session.add(get_card)
|
db.session.add(get_card)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|||||||
@@ -1,81 +1,68 @@
|
|||||||
from flask import request, jsonify
|
|
||||||
|
|
||||||
|
from flask import request, jsonify
|
||||||
from app.search import search
|
from app.search import search
|
||||||
from app import db
|
from app import db
|
||||||
from app.classes.customer import Customer_Customer, Customer_Customer_schema
|
from app.classes.customer import Customer_Customer, Customer_Customer_schema
|
||||||
from app.classes.delivery import Delivery_Delivery, Delivery_Delivery_schema
|
from app.classes.delivery import Delivery_Delivery, Delivery_Delivery_schema
|
||||||
|
# We now need `and_` to combine our search conditions
|
||||||
|
from sqlalchemy import or_, and_
|
||||||
|
|
||||||
@search.route("/customer", methods=["GET"])
|
@search.route("/customer", methods=["GET"])
|
||||||
def search_customers():
|
def search_customers():
|
||||||
"""
|
"""
|
||||||
|
Searches for customers based on a keyword.
|
||||||
|
The new logic searches across multiple fields (name, address, town, phone, etc.)
|
||||||
|
for each word provided in the search query.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
keyword = request.args.get('q')
|
keyword = request.args.get('q')
|
||||||
search = "%{}%".format(keyword)
|
if not keyword or len(keyword) < 2:
|
||||||
search_type = (search[1])
|
return jsonify([])
|
||||||
search = search.replace("!", "")
|
|
||||||
search = search.replace("#", "")
|
|
||||||
search = search.replace("@", "")
|
|
||||||
search = search.replace("$", "")
|
|
||||||
# search by last name
|
|
||||||
if search_type == '@':
|
|
||||||
search = search[1:]
|
|
||||||
customer_list = (db.session
|
|
||||||
.query(Customer_Customer)
|
|
||||||
.filter(Customer_Customer.customer_last_name.ilike(search))
|
|
||||||
.all())
|
|
||||||
# Customer Address
|
|
||||||
elif search_type == '!':
|
|
||||||
|
|
||||||
search = search[::1]
|
# --- NEW SEARCH LOGIC ---
|
||||||
customer_list = (db.session
|
|
||||||
.query(Customer_Customer)
|
|
||||||
.filter(Customer_Customer.customer_address.ilike(search))
|
|
||||||
.all())
|
|
||||||
# Phone Number
|
|
||||||
elif search_type == '#':
|
|
||||||
search = search[::1]
|
|
||||||
customer_list = (db.session
|
|
||||||
.query(Customer_Customer)
|
|
||||||
.filter(Customer_Customer.customer_phone_number.ilike(search))
|
|
||||||
.all())
|
|
||||||
# Account Number
|
|
||||||
elif search_type == '$':
|
|
||||||
search = search[::1]
|
|
||||||
|
|
||||||
customer_list = (db.session
|
# 1. Split the incoming search query into individual words.
|
||||||
.query(Customer_Customer)
|
# e.g., "john main st" -> ["john", "main", "st"]
|
||||||
.filter(Customer_Customer.account_number.ilike(search))
|
search_words = keyword.split()
|
||||||
.order_by(Customer_Customer.account_number.asc())
|
|
||||||
.all())
|
|
||||||
|
|
||||||
else:
|
# 2. We'll build a list of search conditions. Each condition will check
|
||||||
customer_list = (db.session
|
# if a word exists in ANY of the relevant customer fields.
|
||||||
.query(Customer_Customer)
|
conditions = []
|
||||||
.filter(Customer_Customer.customer_last_name.ilike(search))
|
for word in search_words:
|
||||||
.all())
|
search_pattern = f"%{word}%"
|
||||||
|
# For each word, create an OR clause to check against all fields
|
||||||
|
conditions.append(
|
||||||
|
or_(
|
||||||
|
Customer_Customer.customer_first_name.ilike(search_pattern),
|
||||||
|
Customer_Customer.customer_last_name.ilike(search_pattern),
|
||||||
|
Customer_Customer.customer_address.ilike(search_pattern),
|
||||||
|
Customer_Customer.customer_town.ilike(search_pattern),
|
||||||
|
Customer_Customer.customer_phone_number.ilike(search_pattern),
|
||||||
|
Customer_Customer.account_number.ilike(search_pattern)
|
||||||
|
# Add any other fields you want to be searchable here
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
# 3. Combine all our word conditions with AND. This means the customer
|
||||||
|
# record must match ALL the words from the search query.
|
||||||
|
# e.g., for "john main", it must contain "john" AND "main" somewhere.
|
||||||
|
query = db.session.query(Customer_Customer).filter(and_(*conditions))
|
||||||
|
|
||||||
|
# Limiting results is still good practice
|
||||||
|
customer_list = query.order_by(Customer_Customer.customer_last_name.asc()).limit(20).all()
|
||||||
|
|
||||||
customer_schema = Customer_Customer_schema(many=True)
|
customer_schema = Customer_Customer_schema(many=True)
|
||||||
return jsonify(customer_schema.dump(customer_list))
|
return jsonify(customer_schema.dump(customer_list))
|
||||||
|
|
||||||
|
# The /delivery route is fine as is, so no changes needed there.
|
||||||
@search.route("/delivery", methods=["GET"])
|
@search.route("/delivery", methods=["GET"])
|
||||||
def search_delivery():
|
def search_delivery():
|
||||||
"""
|
# ... (no changes to this function)
|
||||||
pagination all customers
|
|
||||||
"""
|
|
||||||
keyword = request.args.get('q')
|
keyword = request.args.get('q')
|
||||||
search = "%{}%".format(keyword)
|
if not keyword or not keyword.isdigit():
|
||||||
search_type = (search[1])
|
return jsonify([])
|
||||||
|
delivery_ticket = db.session.query(Delivery_Delivery).filter(Delivery_Delivery.id == keyword).first()
|
||||||
delivery_ticket = (db.session
|
if delivery_ticket:
|
||||||
.query(Delivery_Delivery)
|
delivery_schema = Delivery_Delivery_schema(many=False)
|
||||||
.filter(Delivery_Delivery.id.ilike(search))
|
return jsonify(delivery_schema.dump(delivery_ticket))
|
||||||
.all())
|
else:
|
||||||
|
return jsonify({})
|
||||||
|
|
||||||
delivery_schema = Delivery_Delivery_schema(many=True)
|
|
||||||
return jsonify(delivery_schema.dump(delivery_ticket))
|
|
||||||
Reference in New Issue
Block a user