from datetime import date, timedelta from operator import or_ from typing import Any from fastapi import APIRouter, Depends, Security from sqlalchemy.sql.expression import func, select from ...core.config import settings from ...core.security import get_current_active_user as get_user from ...db.session import SessionFuture from ...models.inventory import Inventory from ...models.kot import Kot from ...models.product import Product from ...models.product_version import ProductVersion from ...models.voucher import Voucher from ...models.voucher_type import VoucherType from ...schemas.user_token import UserToken from . import check_audit_permission, report_finish_date, report_start_date router = APIRouter() @router.get("") def beer_consumption( start_date: date = Depends(report_start_date), finish_date: date = Depends(report_finish_date), r: bool | None = True, h: bool | None = True, st: bool | None = True, n: bool | None = True, user: UserToken = Security(get_user, scopes=["beer-sale-report"]), ): check_audit_permission(start_date, user.permissions) day = func.date_trunc( "day", Voucher.date + timedelta(minutes=settings.NEW_DAY_OFFSET_MINUTES - settings.TIMEZONE_OFFSET_MINUTES) ).label("day") sum_ = func.sum(Inventory.quantity * ProductVersion.quantity).label("sum") query = ( select(day, ProductVersion.name, sum_) .join(Voucher.kots) .join(Kot.inventories) .join(Inventory.product) .join(Product.versions) .where( day >= start_date, day <= finish_date, or_( ProductVersion.valid_from == None, # noqa: E711 ProductVersion.valid_from <= day, ), or_( ProductVersion.valid_till == None, # noqa: E711 ProductVersion.valid_till >= day, ), ) ) if h is False and r is not False: query = query.where(Inventory.is_happy_hour == h) if r is False and h is not False: query = query.where(Inventory.is_happy_hour != r) vt = [] if h is True or r is True: vt.append(VoucherType.REGULAR_BILL) if st is True: vt.append(VoucherType.STAFF) if n is True: vt.append(VoucherType.NO_CHARGE) with SessionFuture() as db: list_ = db.execute( query.where(Voucher.voucher_type.in_(vt)) .group_by(day, ProductVersion.name) .having(sum_ != 0) .order_by(day, ProductVersion.name) ).all() headers = [] data: list[Any] = [] for date_, name, quantity in list_: if name not in headers: headers.append(name) old = [d for d in data if d["date"] == date_.strftime("%d-%b-%Y")] if len(old): old[0][name] = quantity else: data.append({"date": date_.strftime("%d-%b-%Y"), name: quantity}) return { "startDate": start_date.strftime("%d-%b-%Y"), "finishDate": finish_date.strftime("%d-%b-%Y"), "regular": r, "happy": h, "staff": st, "nc": n, "headers": headers, "data": data, }