import logging from datetime import date, timedelta from app.delivery_status import deliverystatus from app import db from app.common.responses import error_response, success_response from sqlalchemy import func, case from app.classes.delivery import (Delivery_Delivery, Delivery_Delivery_schema, ) from app.classes.service import Service_Service from app.classes.auto import Auto_Delivery from app.classes.transactions import Transaction from datetime import date, timedelta, datetime from zoneinfo import ZoneInfo logger = logging.getLogger(__name__) # --- NEW EFFICIENT ENDPOINT --- @deliverystatus.route("/stats/sidebar-counts", methods=["GET"]) def get_sidebar_counts(): """ Efficiently gets all counts needed for the navigation sidebar in a single request. This combines logic from all the individual /count/* endpoints. """ logger.info("GET /deliverystatus/stats/sidebar-counts - Fetching sidebar counts") try: eastern = ZoneInfo("America/New_York") now_local = datetime.now(eastern).replace(tzinfo=None) # naive local time today_date = datetime.now(eastern).date() # local date # Replicate the logic from each of your /count/* endpoints today_count = db.session.query(Delivery_Delivery).filter(Delivery_Delivery.delivery_status == 2).count() tomorrow_count = db.session.query(Delivery_Delivery).filter(Delivery_Delivery.delivery_status == 3).count() waiting_count = db.session.query(Delivery_Delivery).filter(Delivery_Delivery.delivery_status == 0).count() pending_count = db.session.query(Delivery_Delivery).filter(Delivery_Delivery.delivery_status == 9).count() automatic_count = db.session.query(Auto_Delivery).filter(Auto_Delivery.estimated_gallons_left <= 80).count() start_of_today = datetime.combine(today_date, datetime.min.time()) start_of_tomorrow = datetime.combine(today_date + timedelta(days=1), datetime.min.time()) today_service_count = db.session.query(Service_Service).filter( Service_Service.scheduled_date >= start_of_today, Service_Service.scheduled_date < start_of_tomorrow ).count() # Upcoming service calls start from tomorrow, not today upcoming_service_count = db.session.query(Service_Service).filter(Service_Service.scheduled_date >= start_of_tomorrow).count() transaction_count = db.session.query(Transaction).filter(Transaction.transaction_type == 0).count() return success_response({ "counts": { "today": today_count, "tomorrow": tomorrow_count, "waiting": waiting_count, "pending": pending_count, "automatic": automatic_count, "upcoming_service": upcoming_service_count, "today_service": today_service_count, "transaction": transaction_count, } }) except Exception as e: return error_response(str(e), 500) @deliverystatus.route("/tomorrow-totals", methods=["GET"]) def get_tomorrow_totals(): """ Get total gallons by town for tomorrow's deliveries, including grand total. """ logger.info("GET /deliverystatus/tomorrow-totals - Fetching tomorrow delivery totals") try: deliveries = db.session.query( Delivery_Delivery.customer_town, func.sum( case( (Delivery_Delivery.customer_asked_for_fill == 1, 250), else_=Delivery_Delivery.gallons_ordered ) ).label('total_gallons') ).filter(Delivery_Delivery.delivery_status == 3).group_by(Delivery_Delivery.customer_town).order_by(Delivery_Delivery.customer_town).all() totals = [{'town': d.customer_town, 'gallons': int(d.total_gallons)} for d in deliveries] grand_total = sum(d.total_gallons for d in deliveries) return success_response({ 'totals': totals, 'grand_total': int(grand_total) }) except Exception as e: return error_response(str(e), 500) @deliverystatus.route("/today-totals", methods=["GET"]) def get_today_totals(): """ Get total gallons by town for today's deliveries, including grand total. """ logger.info("GET /deliverystatus/today-totals - Fetching today delivery totals") try: deliveries = db.session.query( Delivery_Delivery.customer_town, func.sum( case( (Delivery_Delivery.customer_asked_for_fill == 1, 250), else_=Delivery_Delivery.gallons_ordered ) ).label('total_gallons') ).filter(Delivery_Delivery.delivery_status == 2).group_by(Delivery_Delivery.customer_town).order_by(Delivery_Delivery.customer_town).all() totals = [{'town': d.customer_town, 'gallons': int(d.total_gallons)} for d in deliveries] grand_total = sum(d.total_gallons for d in deliveries) return success_response({ 'totals': totals, 'grand_total': int(grand_total) }) except Exception as e: return error_response(str(e), 500) @deliverystatus.route("/waiting-totals", methods=["GET"]) def get_waiting_totals(): """ Get total gallons by town for waiting deliveries, including grand total. """ logger.info("GET /deliverystatus/waiting-totals - Fetching waiting delivery totals") try: deliveries = db.session.query( Delivery_Delivery.customer_town, func.sum( case( (Delivery_Delivery.customer_asked_for_fill == 1, 250), else_=Delivery_Delivery.gallons_ordered ) ).label('total_gallons') ).filter(Delivery_Delivery.delivery_status == 0).group_by(Delivery_Delivery.customer_town).order_by(Delivery_Delivery.customer_town).all() totals = [{'town': d.customer_town, 'gallons': int(d.total_gallons)} for d in deliveries] grand_total = sum(d.total_gallons for d in deliveries) return success_response({ 'totals': totals, 'grand_total': int(grand_total) }) except Exception as e: return error_response(str(e), 500)