import logging import base64 import json from flask import request from flask_login import current_user, logout_user, login_user, login_required from app.admin import admin from app import db from app.common.responses import error_response, success_response from datetime import datetime from app.classes.pricing import ( Pricing_Oil_Oil, Pricing_Oil_Oil_schema) from app.classes.admin import Admin_Company, Admin_Company_schema, Call, Admin_Settings, Admin_Settings_schema from app.common.decorators import admin_required, login_required as custom_login_required logger = logging.getLogger(__name__) @admin.route("/oil/create", methods=["POST"]) @admin_required def create_oil_price(): """ Changes the price for oil deliveries """ logger.info("POST /admin/oil/create - Creating new oil price") now = datetime.utcnow() price_from_supplier = request.json["price_from_supplier"] price_for_customer = request.json["price_for_customer"] price_for_employee = request.json["price_for_employee"] # Legacy single-tier pricing (for backward compatibility, use tier1 values) price_same_day_tier1 = request.json.get("price_same_day_tier1", 0) price_prime_tier1 = request.json.get("price_prime_tier1", 0) price_emergency_tier1 = request.json.get("price_emergency_tier1", 0) # Get all tier pricing price_same_day_tier2 = request.json.get("price_same_day_tier2", 0) price_same_day_tier3 = request.json.get("price_same_day_tier3", 0) price_same_day_tier4 = request.json.get("price_same_day_tier4", 0) price_same_day_tier5 = request.json.get("price_same_day_tier5", 0) price_prime_tier2 = request.json.get("price_prime_tier2", 0) price_prime_tier3 = request.json.get("price_prime_tier3", 0) price_prime_tier4 = request.json.get("price_prime_tier4", 0) price_prime_tier5 = request.json.get("price_prime_tier5", 0) price_emergency_tier2 = request.json.get("price_emergency_tier2", 0) price_emergency_tier3 = request.json.get("price_emergency_tier3", 0) price_emergency_tier4 = request.json.get("price_emergency_tier4", 0) price_emergency_tier5 = request.json.get("price_emergency_tier5", 0) new_admin_oil_price = Pricing_Oil_Oil( price_from_supplier=price_from_supplier, price_for_customer=price_for_customer, price_for_employee=price_for_employee, # Legacy columns (use tier1 for backward compatibility) price_same_day=price_same_day_tier1, price_prime=price_prime_tier1, price_emergency=price_emergency_tier1, # Tier pricing price_same_day_tier1=price_same_day_tier1, price_same_day_tier2=price_same_day_tier2, price_same_day_tier3=price_same_day_tier3, price_same_day_tier4=price_same_day_tier4, price_same_day_tier5=price_same_day_tier5, price_prime_tier1=price_prime_tier1, price_prime_tier2=price_prime_tier2, price_prime_tier3=price_prime_tier3, price_prime_tier4=price_prime_tier4, price_prime_tier5=price_prime_tier5, price_emergency_tier1=price_emergency_tier1, price_emergency_tier2=price_emergency_tier2, price_emergency_tier3=price_emergency_tier3, price_emergency_tier4=price_emergency_tier4, price_emergency_tier5=price_emergency_tier5, date=now, ) # new_admin_oil_price = Pricing_Oil_Oil( # price_from_supplier=price_from_supplier, # price_for_customer=price_for_customer, # price_for_employee=price_for_employee, # price_same_day=price_same_day, # price_prime=price_prime, # date=now, # ) db.session.add(new_admin_oil_price) db.session.commit() return success_response({'price': new_admin_oil_price.id}) @admin.route("/oil/get", methods=["GET"]) @admin_required def get_oil_price(): """ gets oil prices """ logger.info("GET /admin/oil/get - Fetching current oil prices") get_oil_prices = (db.session .query(Pricing_Oil_Oil) .order_by(Pricing_Oil_Oil.date.desc()) .first()) price_schema = Pricing_Oil_Oil_schema(many=False) return success_response({"price": price_schema.dump(get_oil_prices)}) @admin.route("/company/", methods=["GET"]) @admin_required def get_company(company_id): logger.info(f"GET /admin/company/{company_id} - Fetching company data") get_data_company = (db.session .query(Admin_Company) .first()) company_schema = Admin_Company_schema(many=False) return success_response({"company": company_schema.dump(get_data_company)}) @admin.route("/voip_routing", methods=["GET"]) @admin_required def get_voip_routing(): """ Gets the current VOIP routing (latest Call record's current_phone) """ logger.info("GET /admin/voip_routing - Fetching current VoIP routing") latest_call = (db.session .query(Call) .order_by(Call.created_at.desc()) .first()) if latest_call: return success_response({"current_phone": latest_call.current_phone}) else: return error_response("No VoIP routing found", 404) # ============================================ # Admin Settings Endpoints # ============================================ DEFAULT_QUICK_CALLS = json.dumps([ {"name": "WB Hill Tank Springfield", "phone": "(413) 525-3678"}, {"name": "LW Tank Uxbridge", "phone": "(508) 234-6000"}, {"name": "Trask Tank Worcester", "phone": "(508) 791-5064"}, {"name": "David Mechanic", "phone": "(774) 239-3776"}, {"name": "Spring Rebuilders", "phone": "(508) 799-9342"}, ]) def _get_or_create_settings(): """Get the singleton settings row, creating it with defaults on first access.""" settings = db.session.query(Admin_Settings).first() if not settings: settings = Admin_Settings( company_name='Auburn Oil', link_facebook='https://www.facebook.com/auburnoil', link_google='https://www.google.com/search?client=firefox-b-1-d&sca_esv=02c44965d6d4b280&sca_upv=1&cs=1&output=search&kgmid=/g/11wcbqrx5l&q=Auburn+Oil&shndl=30&shem=lsde&source=sh/x/loc/act/m1/1&kgs=52995d809762cd61', link_website='https://auburnoil.com', link_google_review='https://g.page/r/CZHnPQ85LsMUEBM/review', quick_calls=DEFAULT_QUICK_CALLS, show_automatics=True, show_stats=True, show_service=True, show_ticker=True, default_theme='ocean', ) db.session.add(settings) db.session.commit() return settings @admin.route("/settings", methods=["GET"]) @custom_login_required def get_settings(): """Get admin settings (any logged-in user can read).""" logger.info("GET /admin/settings") settings = _get_or_create_settings() schema = Admin_Settings_schema(many=False) return success_response({"settings": schema.dump(settings)}) @admin.route("/settings", methods=["PUT"]) @admin_required def update_settings(): """Update admin settings (admin only). Does not update logo.""" logger.info("PUT /admin/settings") settings = _get_or_create_settings() data = request.json allowed_fields = [ 'company_name', 'link_facebook', 'link_google', 'link_website', 'link_google_review', 'quick_calls', 'show_automatics', 'show_stats', 'show_service', 'show_ticker', 'default_theme', ] for field in allowed_fields: if field in data: value = data[field] if field == 'quick_calls' and isinstance(value, list): value = json.dumps(value) setattr(settings, field, value) settings.updated_at = datetime.utcnow() db.session.commit() schema = Admin_Settings_schema(many=False) return success_response({"settings": schema.dump(settings)}) @admin.route("/settings/logo", methods=["POST"]) @admin_required def upload_logo(): """Upload a logo image (admin only). Max 2MB.""" logger.info("POST /admin/settings/logo") if 'logo' not in request.files: return error_response("No file provided", 400) file = request.files['logo'] if file.filename == '': return error_response("No file selected", 400) # 2MB limit file_data = file.read() if len(file_data) > 2 * 1024 * 1024: return error_response("File too large. Maximum size is 2MB.", 400) mime_type = file.content_type or 'image/png' encoded = base64.b64encode(file_data).decode('utf-8') settings = _get_or_create_settings() settings.logo_base64 = encoded settings.logo_mime_type = mime_type settings.updated_at = datetime.utcnow() db.session.commit() schema = Admin_Settings_schema(many=False) return success_response({"settings": schema.dump(settings)}) @admin.route("/settings/logo", methods=["DELETE"]) @admin_required def delete_logo(): """Delete the custom logo (admin only).""" logger.info("DELETE /admin/settings/logo") settings = _get_or_create_settings() settings.logo_base64 = None settings.logo_mime_type = None settings.updated_at = datetime.utcnow() db.session.commit() schema = Admin_Settings_schema(many=False) return success_response({"settings": schema.dump(settings)})