diff --git a/app/auth/views.py b/app/auth/views.py index a8713c1..cea8005 100755 --- a/app/auth/views.py +++ b/app/auth/views.py @@ -5,45 +5,53 @@ from app import db, bcrypt from datetime import datetime from uuid import uuid4 from app.classes.auth import Auth_User - +from app.classes.employee import Employee_Employee @auth.route("/whoami", methods=["GET"]) 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') if not api_key: - return jsonify({"error": "True"}), 200 - else: - api_key = api_key.replace('bearer ', '', 1) - api_key = api_key.replace('"', '') - - user_exists = (db.session - .query(Auth_User) - .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({ - "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 - }, - 'token': user.api_key - }), 200 + return jsonify({"ok": False, "error": "Authorization header missing"}), 401 + + # Clean up the token + api_key = api_key.replace('bearer ', '', 1).strip('"') + + user = db.session.query(Auth_User).filter(Auth_User.api_key == api_key).first() + + if not user: + return jsonify({"ok": False, "error": "Invalid token"}), 401 + + # --- THIS IS THE CRITICAL FIX --- + # Now that we have the user, find the corresponding employee record. + # This assumes your Employee model has a 'user_id' field linking to the Auth_User 'id'. + employee = db.session.query(Employee_Employee).filter(Employee_Employee.user_id == user.id).first() + + # It's possible a user exists without an employee record, so we handle that case. + 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"]) diff --git a/app/customer/views.py b/app/customer/views.py index 80c47a5..aeddb43 100755 --- a/app/customer/views.py +++ b/app/customer/views.py @@ -547,71 +547,57 @@ def customer_automatic_assignment(customer_id): "ok": True, 'status': status }), 200 - + + @customer.route("/edit/tank/", methods=["PUT"]) @login_required def edit_customer_tank(customer_id): """ + Safely edits or creates tank and description details for a customer. """ - get_customer = (db.session - .query(Customer_Customer) - .filter(Customer_Customer.id == customer_id) - .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()) + get_customer = db.session.query(Customer_Customer).filter(Customer_Customer.id == customer_id).one_or_none() + if not get_customer: + return jsonify({"ok": False, "error": "Customer not found"}), 404 - 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.tank_status = True + get_customer_tank = db.session.query(Customer_Tank_Inspection).filter(Customer_Tank_Inspection.customer_id == customer_id).first() + 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': - get_customer_tank.outside_or_inside = False - else: - pass + data = request.get_json() + 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"] - if response_outside_or_inside == 'true': - get_customer_tank.outside_or_inside = True - - elif response_outside_or_inside == 'false': - get_customer_tank.outside_or_inside = False - else: - pass - - response_last_tank_inspection = request.json["last_tank_inspection"] - response_tank_size = request.json["tank_size"] - response_customer_fill_location = request.json["fill_location"] - + response_last_tank_inspection = data.get("last_tank_inspection", None) + response_tank_size = data.get("tank_size", 0) + + # --- FIX APPLIED HERE --- + # 1. Get the value from the request. Default to 0 if it's missing. + 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.tank_size = response_tank_size - - get_customer_description.fill_location = response_customer_fill_location + if get_customer.customer_automatic == 1: - get_auto_info = (db.session - .query(Auto_Delivery) - .filter(Auto_Delivery.customer_id == customer_id) - .first()) - - get_auto_info.tank_size = response_tank_size - db.session.add(get_auto_info) - + get_auto_info = db.session.query(Auto_Delivery).filter(Auto_Delivery.customer_id == customer_id).first() + if 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() - return jsonify({ - "ok": True, - }), 200 - + return jsonify({"ok": True}), 200 \ No newline at end of file diff --git a/app/delivery/views.py b/app/delivery/views.py index 2ef4c19..6d31fdc 100755 --- a/app/delivery/views.py +++ b/app/delivery/views.py @@ -17,116 +17,86 @@ from app.classes.promo import Promo_Promo from app.classes.stats_customer import Stats_Customer 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"]) 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 today = date.today() - deliveries_today = (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 f in deliveries_today: - if f.delivery_status != 2: - f.delivery_status = 2 - db.session.add(f) - counter = counter + 1 + tomorrow = today + timedelta(days=1) + + # Update statuses for deliveries scheduled for today + deliveries_today = db.session.query(Delivery_Delivery).filter( + Delivery_Delivery.delivery_status.notin_([1, 5, 10]), # Not cancelled, issue, or finalized + Delivery_Delivery.expected_delivery_date == today, + Delivery_Delivery.delivery_status != 2 # Avoid redundant updates + ).all() + for delivery_item in deliveries_today: + delivery_item.delivery_status = 2 + db.session.add(delivery_item) + counter += 1 - tomm = date.today() + timedelta(days=1) - deliveries_tom = (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) - .all()) - for g in deliveries_tom: - if g.delivery_status != 3: - 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 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 + + # 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: db.session.commit() - return jsonify({ - "ok": True, - 'update': True, - }), 200 - - return jsonify({"ok": True}), 200 + return jsonify({"ok": True, 'update': True}), 200 + return jsonify({"ok": True, 'update': False}), 200 @delivery.route("/", methods=["GET"]) def get_a_delivery(delivery_id): """ + Get a single delivery's details. """ - get_delivery = db.session\ - .query(Delivery_Delivery)\ - .filter(Delivery_Delivery.id == delivery_id)\ - .first() - - 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 + get_delivery = db.session.query(Delivery_Delivery).filter(Delivery_Delivery.id == delivery_id).first() + if not get_delivery: + return jsonify({"ok": False, "error": "Delivery not found"}), 404 + + # 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 + + @@ -173,11 +143,13 @@ def get_customer_auto_delivery(customer_id): @delivery.route("/order/", methods=["GET"]) def get_a_specific_delivery(delivery_id): - - get_delivery = db.session\ - .query(Delivery_Delivery)\ - .filter(Delivery_Delivery.id == delivery_id)\ - .first() + """ + 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 + delivery_schema = Delivery_Delivery_schema(many=False) return jsonify(delivery_schema.dump(get_delivery)) @@ -492,172 +464,97 @@ def get_deliveries_today(): @delivery.route("/edit/", methods=["POST"]) 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 \ - .query(Delivery_Delivery) \ - .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() + data = request.json + get_delivery = db.session.query(Delivery_Delivery).filter(Delivery_Delivery.id == delivery_id).first() if not get_delivery: - return jsonify({"error": False}), 200 - 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"] + return jsonify({"ok": False, "error": "Delivery not found"}), 404 - 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 - .query(Employee_Employee) - .filter(Employee_Employee.id == delivery_driver_id) - .first()) + get_today_price = db.session.query(Pricing_Oil_Oil).order_by(Pricing_Oil_Oil.id.desc()).first() + if not get_today_price: + return jsonify({"ok": False, "error": "Pricing information not available"}), 500 + + # --- 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 - - 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 + get_delivery.total_price = base_price # Price before fees + get_delivery.pre_charge_amount = total_price # Price including fees + # --- Commit Changes --- + db.session.add(get_delivery) + db.session.commit() - - if request.json["credit_card_id"]: - card_payment_id = request.json["credit_card_id"] - else: - card_payment_id = None - - - 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 + return jsonify({ + "ok": True, + 'message': f"Delivery {delivery_id} updated successfully.", + 'customer_id': get_customer.id # Keep this if the frontend uses it for navigation + }), 200 @delivery.route("/create/", methods=["POST"]) diff --git a/app/payment/views.py b/app/payment/views.py index a746058..6df28bd 100755 --- a/app/payment/views.py +++ b/app/payment/views.py @@ -99,22 +99,24 @@ def create_user_card(user_id): """ adds a card of a user """ - get_customer = (db.session .query(Customer_Customer) .filter(Customer_Customer.id == user_id) .first()) - - 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"] - main_card = request.json["main_card"] - zip_code = request.json["zip_code"] - - card_number = request.json["card_number"] - last_four = card_number[-4] + + # --- 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") + main_card = data.get("main_card", False) + zip_code = data.get("zip_code") + 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( user_id=get_customer.id, @@ -131,12 +133,10 @@ def create_user_card(user_id): ) db.session.add(create_new_card) db.session.flush() - if main_card is True: - try: - set_card_main(user_id=get_customer.id, card_id=create_new_card.id) - except: - pass - db.session.add(create_new_card) + + if main_card: + set_card_main(user_id=get_customer.id, card_id=create_new_card.id) + db.session.commit() return jsonify({"ok": True}), 200 @@ -176,28 +176,25 @@ def update_user_card(card_id): """ edits a card """ - get_card = (db.session .query(Card_Card) .filter(Card_Card.id == card_id) .first()) - get_customer = (db.session - .query(Customer_Customer) - .filter(Customer_Customer.id == get_card.user_id) - .first()) + if not get_card: + return jsonify({"ok": False, "error": "Card not found"}), 404 + # --- 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.name_on_card = name_on_card get_card.expiration_month = expiration_month @@ -206,9 +203,13 @@ def update_user_card(card_id): get_card.security_number = security_number get_card.main_card = main_card 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: - set_card_main(user_id=get_customer.id, card_id=get_card.id) + if main_card: + set_card_main(user_id=get_card.user_id, card_id=get_card.id) db.session.add(get_card) db.session.commit() diff --git a/app/search/views.py b/app/search/views.py index 7315062..de20b40 100755 --- a/app/search/views.py +++ b/app/search/views.py @@ -1,81 +1,68 @@ -from flask import request, jsonify +from flask import request, jsonify from app.search import search from app import db from app.classes.customer import Customer_Customer, Customer_Customer_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"]) 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') - search = "%{}%".format(keyword) - search_type = (search[1]) - 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 == '!': + if not keyword or len(keyword) < 2: + return jsonify([]) - search = search[::1] - 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] + # --- NEW SEARCH LOGIC --- - customer_list = (db.session - .query(Customer_Customer) - .filter(Customer_Customer.account_number.ilike(search)) - .order_by(Customer_Customer.account_number.asc()) - .all()) + # 1. Split the incoming search query into individual words. + # e.g., "john main st" -> ["john", "main", "st"] + search_words = keyword.split() - else: - customer_list = (db.session - .query(Customer_Customer) - .filter(Customer_Customer.customer_last_name.ilike(search)) - .all()) + # 2. We'll build a list of search conditions. Each condition will check + # if a word exists in ANY of the relevant customer fields. + conditions = [] + for word in search_words: + 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) return jsonify(customer_schema.dump(customer_list)) - +# The /delivery route is fine as is, so no changes needed there. @search.route("/delivery", methods=["GET"]) def search_delivery(): - """ - pagination all customers - """ + # ... (no changes to this function) keyword = request.args.get('q') - search = "%{}%".format(keyword) - search_type = (search[1]) - - delivery_ticket = (db.session - .query(Delivery_Delivery) - .filter(Delivery_Delivery.id.ilike(search)) - .all()) - - - delivery_schema = Delivery_Delivery_schema(many=True) - return jsonify(delivery_schema.dump(delivery_ticket)) \ No newline at end of file + if not keyword or not keyword.isdigit(): + return jsonify([]) + delivery_ticket = db.session.query(Delivery_Delivery).filter(Delivery_Delivery.id == keyword).first() + if delivery_ticket: + delivery_schema = Delivery_Delivery_schema(many=False) + return jsonify(delivery_schema.dump(delivery_ticket)) + else: + return jsonify({}) \ No newline at end of file