Major Refactor

This commit is contained in:
2025-09-01 16:42:59 -04:00
parent 9a2f9a6564
commit d250e136c3
5 changed files with 310 additions and 431 deletions

View File

@@ -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)
api_key = api_key.replace('"', '')
user_exists = (db.session # Clean up the token
.query(Auth_User) api_key = api_key.replace('bearer ', '', 1).strip('"')
.filter(Auth_User.api_key == api_key)
.first())
if not user_exists:
return jsonify({"error": True}), 200
else:
user = db.session\
.query(Auth_User)\
.filter(Auth_User.api_key == api_key)\
.first()
return jsonify({ user = db.session.query(Auth_User).filter(Auth_User.api_key == api_key).first()
"ok": True,
'user': { if not user:
'user_name': user.username, return jsonify({"ok": False, "error": "Invalid token"}), 401
'user_id': user.id,
'user_email': user.email, # --- THIS IS THE CRITICAL FIX ---
'user_admin': user.admin_role, # Now that we have the user, find the corresponding employee record.
'token': user.api_key, # This assumes your Employee model has a 'user_id' field linking to the Auth_User 'id'.
'confirmed': user.confirmed employee = db.session.query(Employee_Employee).filter(Employee_Employee.user_id == user.id).first()
},
'token': user.api_key # It's possible a user exists without an employee record, so we handle that case.
}), 200 if not employee:
return jsonify({"ok": False, "error": "User found, but no associated employee record"}), 404
# Now, build the complete response with both user and employee data.
return jsonify({
"ok": True,
'user': {
'user_name': user.username,
'user_id': user.id,
'user_email': user.email,
'user_admin': user.admin_role,
'token': user.api_key,
'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"])

View File

@@ -548,70 +548,56 @@ def customer_automatic_assignment(customer_id):
'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"]
response_outside_or_inside = request.json["outside_or_inside"] if 'outside_or_inside' in data:
if response_outside_or_inside == 'true': get_customer_tank.outside_or_inside = data["outside_or_inside"]
get_customer_tank.outside_or_inside = True
elif response_outside_or_inside == 'false': response_last_tank_inspection = data.get("last_tank_inspection", None)
get_customer_tank.outside_or_inside = False response_tank_size = data.get("tank_size", 0)
else:
pass
response_last_tank_inspection = request.json["last_tank_inspection"] # --- FIX APPLIED HERE ---
response_tank_size = request.json["tank_size"] # 1. Get the value from the request. Default to 0 if it's missing.
response_customer_fill_location = request.json["fill_location"] response_customer_fill_location = data.get("fill_location", 0)
# 2. Add a safety check: if the frontend sent an empty string, convert it to 0.
if response_customer_fill_location == "":
response_customer_fill_location = 0
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

View File

@@ -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)
.filter(Delivery_Delivery.delivery_status != 5)
.filter(Delivery_Delivery.delivery_status != 1)
.filter(Delivery_Delivery.expected_delivery_date == today)
.all())
for f in deliveries_today:
if f.delivery_status != 2:
f.delivery_status = 2
db.session.add(f)
counter = counter + 1
tomm = date.today() + timedelta(days=1) # Update statuses for deliveries scheduled for today
deliveries_tom = (db.session deliveries_today = db.session.query(Delivery_Delivery).filter(
.query(Delivery_Delivery) Delivery_Delivery.delivery_status.notin_([1, 5, 10]), # Not cancelled, issue, or finalized
.filter(Delivery_Delivery.delivery_status != 10) Delivery_Delivery.expected_delivery_date == today,
.filter(Delivery_Delivery.delivery_status != 5) Delivery_Delivery.delivery_status != 2 # Avoid redundant updates
.filter(Delivery_Delivery.delivery_status != 1) ).all()
.filter(Delivery_Delivery.expected_delivery_date == tomm) for delivery_item in deliveries_today:
.all()) delivery_item.delivery_status = 2
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
# Update statuses for deliveries scheduled for tomorrow
deliveries_tomorrow = db.session.query(Delivery_Delivery).filter(
Delivery_Delivery.delivery_status.notin_([1, 5, 10]),
Delivery_Delivery.expected_delivery_date == tomorrow,
Delivery_Delivery.delivery_status != 3
).all()
for delivery_item in deliveries_tomorrow:
delivery_item.delivery_status = 3
db.session.add(delivery_item)
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
deliveries_waiting = (db.session # Update statuses for deliveries that are past their expected date
.query(Delivery_Delivery) deliveries_pending = db.session.query(Delivery_Delivery).filter(
.filter(Delivery_Delivery.delivery_status != 10) Delivery_Delivery.delivery_status.notin_([1, 5, 10]),
.filter(Delivery_Delivery.delivery_status != 5) Delivery_Delivery.expected_delivery_date < today,
.filter(Delivery_Delivery.delivery_status != 1) Delivery_Delivery.delivery_status != 9
.filter(Delivery_Delivery.expected_delivery_date != tomm) ).all()
.filter(Delivery_Delivery.expected_delivery_date > today) for delivery_item in deliveries_pending:
.all()) delivery_item.delivery_status = 9
for r in deliveries_waiting: db.session.add(delivery_item)
if r.delivery_status != 0: counter += 1
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
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.
delivery_schema = Delivery_Delivery_schema(many=False)
return jsonify({"ok": True, "delivery": delivery_schema.dump(get_delivery)}), 200
return jsonify({
"ok": True,
'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 a single delivery by its ID.
"""
get_delivery = db.session.query(Delivery_Delivery).filter(Delivery_Delivery.id == delivery_id).first()
if not get_delivery:
return jsonify({"error": "Delivery not found"}), 404
get_delivery = db.session\
.query(Delivery_Delivery)\
.filter(Delivery_Delivery.id == delivery_id)\
.first()
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())
## promo # --- 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)
try: # Convert booleans to 1 or 0 for the database
if request.json["promo_id"]: customer_wants_fill = 1 if data.get("customer_asked_for_fill") else 0
promo_id = request.json["promo_id"] get_delivery.customer_asked_for_fill = customer_wants_fill
else: get_delivery.prime = 1 if data.get("prime") else 0
promo_id = None get_delivery.same_day = 1 if data.get("same_day") else 0
except: get_delivery.emergency = 1 if data.get("emergency") else 0
promo_id = None
if promo_id is not None: # --- Handle Driver Assignment ---
get_promo_data = (db.session driver_id = data.get("driver_employee_id")
.query(Promo_Promo) if driver_id:
.filter(Promo_Promo.id == promo_id) get_driver = db.session.query(Employee_Employee).filter(Employee_Employee.id == driver_id).first()
.first()) if get_driver:
promo_id_get_delivery =get_promo_data.id, get_delivery.driver_employee_id = get_driver.id
promo_money_discount_get_delivery = get_promo_data.money_off_delivery get_delivery.driver_first_name = get_driver.employee_first_name
get_delivery.driver_last_name = get_driver.employee_last_name
else: else:
promo_id_get_delivery =None # Optionally, handle the case where the driver ID is invalid
promo_money_discount_get_delivery = None # 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
if request.json["credit_card_id"]: # --- Recalculate Pricing (This logic could be moved to a helper function) ---
card_payment_id = request.json["credit_card_id"] gallons_for_calc = 250 if customer_wants_fill else int(get_delivery.gallons_ordered)
else: base_price = gallons_for_calc * get_today_price.price_for_customer
card_payment_id = None
# 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
if card_payment_id is not None: get_delivery.total_price = base_price # Price before fees
get_card = (db.session get_delivery.pre_charge_amount = total_price # Price including fees
.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
# --- Commit Changes ---
db.session.add(get_delivery)
db.session.commit()
if cash_payment is True and card_payment is False: return jsonify({
delivery_payment_method = 0 "ok": True,
'message': f"Delivery {delivery_id} updated successfully.",
elif card_payment is True and cash_payment is False: 'customer_id': get_customer.id # Keep this if the frontend uses it for navigation
delivery_payment_method = 1 }), 200
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"])

View File

@@ -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)
zip_code = data.get("zip_code")
card_number = data.get("card_number")
card_number = request.json["card_number"] # --- FIX: Correctly slice the last four digits ---
last_four = card_number[-4] 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
@@ -207,8 +204,12 @@ def update_user_card(card_id):
get_card.main_card = main_card get_card.main_card = main_card
get_card.zip_code = zip_code get_card.zip_code = zip_code
if main_card is True: # --- FIX: Correctly slice the last four digits on edit ---
set_card_main(user_id=get_customer.id, card_id=get_card.id) if card_number:
get_card.last_four_digits = card_number[-4:]
if main_card:
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()

View File

@@ -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))