import logging from decimal import Decimal from app.info import info from app import db from app.common.responses import error_response, success_response from app.classes.pricing import Pricing_Oil_Oil, Pricing_Oil_Oil_schema from app.classes.admin import Admin_Company from app.classes.delivery import Delivery_Delivery from app.classes.service import Service_Service from app.classes.ticker import Ticker_Price, Ticker_Price_Schema from app.classes.competitor import CompanyPrice from flask_login import login_required logger = logging.getLogger(__name__) from datetime import datetime, timedelta from flask import request @info.route("/price/oil/tiers", methods=["GET"]) @login_required def get_pricing_tiers(): logger.info("GET /info/price/oil/tiers - Fetching oil pricing tiers") get_price_query = (db.session .query(Pricing_Oil_Oil) .order_by(Pricing_Oil_Oil.date.desc()) .first()) if not get_price_query: return error_response("No pricing data available", 404) # Get the single price per gallon from the database, e.g., Decimal('2.92') price_per_gallon = get_price_query.price_for_customer # Define the specific gallon amounts you want to display totals for gallon_tiers = [100, 125, 150, 175, 200, 220] # Calculate the total price for each gallon amount by multiplication pricing_totals = { gallons: price_per_gallon * gallons for gallons in gallon_tiers } # Return the dictionary of totals return success_response({"pricing_tiers": pricing_totals}) @info.route("/price/oil", methods=["GET"]) @login_required def get_oil_price_today(): logger.info("GET /info/price/oil - Fetching current oil prices") get_price_query = (db.session .query(Pricing_Oil_Oil) .order_by(Pricing_Oil_Oil.date.desc()) .first()) return success_response({ 'price_from_supplier': get_price_query.price_from_supplier, 'price_for_customer': get_price_query.price_for_customer, 'price_for_employee': get_price_query.price_for_employee, 'price_same_day': get_price_query.price_same_day, 'price_prime': get_price_query.price_prime, 'price_emergency': get_price_query.price_emergency, }) @info.route("/price/oil/table", methods=["GET"]) @login_required def get_pricing(): logger.info("GET /info/price/oil/table - Fetching oil pricing table") get_price_query = (db.session .query(Pricing_Oil_Oil) .order_by(Pricing_Oil_Oil.date.desc()) .first()) delivery_schema = Pricing_Oil_Oil_schema(many=False) return success_response({"pricing": delivery_schema.dump(get_price_query)}) @info.route("/company", methods=["GET"]) @login_required def get_company(): logger.info("GET /info/company - Fetching company information") get_data_company = (db.session .query(Admin_Company) .first()) return success_response({ 'name': get_data_company.company_name, 'telephone': get_data_company.company_phone_number, }) @info.route("/price/ticker", methods=["GET"]) @login_required def get_ticker_prices(): """Get latest stock/commodity ticker prices.""" logger.info("GET /info/price/ticker - Fetching ticker prices") # We want the latest price for each symbol # HO=F, CL=F, RB=F target_symbols = ["HO=F", "CL=F", "RB=F"] results = {} # 1. Fetch Market Tickers for symbol in target_symbols: latest = (db.session.query(Ticker_Price) .filter(Ticker_Price.symbol == symbol) .order_by(Ticker_Price.timestamp.desc()) .first()) if latest: results[symbol] = latest.to_dict() # 2. Fetch Competitor Prices # Focusing on LMT Oil and Charlton Oil as requested, but fetching others too for completeness competitors = [ "LMT OIL", "CHARLTON OIL", "LEBLANC OIL", "ALS OIL", "VALUE OIL", "DADDY'S OIL" ] for comp_name in competitors: latest_comp = (db.session.query(CompanyPrice) .filter(CompanyPrice.company_name.ilike(f"%{comp_name}%")) .order_by(CompanyPrice.scrape_date.desc()) .first()) if latest_comp: # Map to Ticker format for uniform frontend handling if possible, or distinct # For simplicity, we'll just add them to the dictionary. # Convert name to a key like 'LMT' or keep full name key = comp_name.replace(" OIL", "").replace("'S", "").replace(" ", "") results[key] = { "symbol": comp_name, # Use full name as symbol/label "price": float(latest_comp.price_decimal), "currency": "USD", "change": 0.0, # We'd need history to calc this, skipping for now "percent_change": 0.0, "timestamp": latest_comp.scrape_date.isoformat() } return success_response({"tickers": results}) @info.route("/price/ticker/history", methods=["GET"]) @login_required def get_ticker_history(): """ Get historical ticker prices for charting. Query Params: days (int): Number of days to look back (default 30) Returns: List of daily price points for each ticker. """ try: days = int(request.args.get('days', 30)) except ValueError: days = 30 logger.info(f"GET /info/price/ticker/history - Fetching history for {days} days") start_date = datetime.utcnow() - timedelta(days=days) # Fetch all records since start_date # We want to group by date and symbol, taking the last price of the day records = (db.session.query(Ticker_Price) .filter(Ticker_Price.timestamp >= start_date) .order_by(Ticker_Price.timestamp.asc()) .all()) # Organize data structure for Chart.js # { date: { symbol: price, symbol2: price } } daily_data = {} target_symbols = ["HO=F", "CL=F", "RB=F"] for record in records: if record.symbol not in target_symbols: continue date_str = record.timestamp.strftime('%Y-%m-%d') if date_str not in daily_data: daily_data[date_str] = {} # This acts as "last value for the day" since we ordered by asc timestamp daily_data[date_str][record.symbol] = float(record.price_decimal) # Convert to list for frontend # [ { date: '2023-01-01', prices: { 'HO=F': 2.5, ... } }, ... ] result = [] for date_str in sorted(daily_data.keys()): result.append({ "date": date_str, "prices": daily_data[date_str] }) return success_response({"history": result})