from flask import request, jsonify from app.service import service from app import db from datetime import datetime, date from app.classes.customer import (Customer_Customer) from app.classes.service import (Service_Service, Service_Service_schema ) # --- NEW ENDPOINT TO GET ALL SERVICE CALLS FOR THE MASTER CALENDAR --- @service.route("/all", methods=["GET"]) def get_all_service_calls(): """ Fetches ALL service calls from the database and formats them for FullCalendar. """ # 1. Query all service records, without filtering by customer all_services = Service_Service.query.all() # 2. Reuse the same formatting logic (colors, titles, etc.) color_map = { 0: {"backgroundColor": "blue", "textColor": "white"}, 1: {"backgroundColor": "red", "textColor": "white"}, 2: {"backgroundColor": "green", "textColor": "white"}, 3: {"backgroundColor": "yellow", "textColor": "black"}, 4: {"backgroundColor": "black", "textColor": "white"} } service_type_map = {0: 'Tune-up', 1: 'No Heat', 2: 'Fix', 3: 'Tank Install', 4: 'Other'} calendar_events = [] for service_record in all_services: service_type_text = service_type_map.get(service_record.type_service_call, 'Service') # The title now includes the customer name, which is crucial for a master calendar event_title = f"{service_type_text}: {service_record.customer_name}" event_colors = color_map.get(service_record.type_service_call, {"backgroundColor": "gray", "textColor": "white"}) # Use the schema to correctly format the date to a string serialized_record = Service_Service_schema().dump(service_record) event_data = { "id": service_record.id, "title": event_title, "start": serialized_record.get('scheduled_date'), # Use the reliable formatted date "end": None, "extendedProps": { "description": service_record.description, "type_service_call": service_record.type_service_call, }, "backgroundColor": event_colors.get("backgroundColor"), "textColor": event_colors.get("textColor"), "borderColor": event_colors.get("backgroundColor") } calendar_events.append(event_data) return jsonify(calendar_events), 200 # --- YOUR OTHER EXISTING ROUTES (no changes needed below) --- @service.route("/upcoming", methods=["GET"]) def get_upcoming_service_calls(): # ... (no changes) now = datetime.now() upcoming_services = (Service_Service.query.filter(Service_Service.scheduled_date >= now).order_by(Service_Service.scheduled_date.asc()).limit(100).all()) service_schema = Service_Service_schema(many=True) result = service_schema.dump(upcoming_services) return jsonify(result), 200 @service.route("/create", methods=["POST"]) def create_service_call(): data = request.get_json() if not data: return jsonify({"error": "No data provided"}), 400 cus_id=data.get('customer_id') get_customer = (db.session.query(Customer_Customer).filter(Customer_Customer.id == cus_id).first()) if not get_customer: return jsonify({"error": f"Customer with id {cus_id} not found."}), 404 # --- FIX: Use fromisoformat to parse the FULL timestamp string (e.g., "2025-08-26T14:00:00") --- # This correctly preserves the time sent from the frontend. scheduled_datetime_str = data.get('expected_delivery_date') scheduled_datetime_obj = datetime.fromisoformat(scheduled_datetime_str) new_service_call = Service_Service( customer_id=get_customer.id, customer_name=get_customer.customer_first_name + ' ' + get_customer.customer_last_name, customer_address=get_customer.customer_address, customer_town=get_customer.customer_town, customer_state=get_customer.customer_state, customer_zip=get_customer.customer_zip, type_service_call=data.get('type_service_call'), when_ordered=datetime.utcnow(), scheduled_date=scheduled_datetime_obj, # Save the full datetime object description=data.get('description'), ) db.session.add(new_service_call) db.session.commit() return jsonify({ "ok": True, "id": new_service_call.id }), 201 @service.route("/update/", methods=["PUT"]) def update_service_call(id): service_record = Service_Service.query.get_or_404(id) data = request.get_json() if not data: return jsonify({"error": "No data provided"}), 400 # --- FIX: Also use fromisoformat here to correctly update with time --- scheduled_datetime_str = data.get('scheduled_date') if scheduled_datetime_str: service_record.scheduled_date = datetime.fromisoformat(scheduled_datetime_str) service_record.type_service_call = data.get('type_service_call', service_record.type_service_call) service_record.description = data.get('description', service_record.description) try: db.session.commit() service_schema = Service_Service_schema(many=False) return jsonify({"ok": True, "service": service_schema.dump(service_record)}), 200 except Exception as e: db.session.rollback() return jsonify({"error": str(e)}), 500 @service.route("/upcoming/count", methods=["GET"]) def get_upcoming_service_calls_count(): """ Efficiently counts the number of all future service calls from today onwards. """ # 1. Get the current time now = datetime.now() # 2. Build the query and use the database's optimized count() function try: count = ( db.session.query(Service_Service) .filter(Service_Service.scheduled_date >= now) .count() ) # 3. Return the count in a simple JSON object return jsonify({"count": count}), 200 except Exception as e: # Return an error if the query fails return jsonify({"error": str(e)}), 500 @service.route("/for-customer/", methods=["GET"]) def get_service_calls_for_customer(customer_id): """ Fetches all service calls for a specific customer, ordered by most recent first. """ # Query the database, filtering by customer_id and ordering by date service_records = ( Service_Service.query .filter_by(customer_id=customer_id) .order_by(Service_Service.scheduled_date.desc()) # .desc() for newest first .all() ) # Use the schema to convert the list of objects to JSON service_schema = Service_Service_schema(many=True) result = service_schema.dump(service_records) return jsonify(result), 200