97 lines
3.2 KiB
Python
97 lines
3.2 KiB
Python
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,
|
|
}
|