Files
eamco_office_api/app/delivery_status/views.py

155 lines
6.2 KiB
Python
Executable File

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)