barker/barker/barker/routers/reports/product_sale_report.py

106 lines
3.3 KiB
Python

from datetime import date, timedelta
from fastapi import APIRouter, Depends, Security
from sqlalchemy import func, or_
from sqlalchemy.orm import Session
from ...core.config import settings
from ...core.security import get_current_active_user as get_user
from ...db.session import SessionLocal
from ...models.inventory import Inventory
from ...models.kot import Kot
from ...models.menu_category import MenuCategory
from ...models.product_version import ProductVersion
from ...models.sale_category import SaleCategory
from ...models.voucher import Voucher
from ...models.voucher_type import VoucherType
from ...schemas import to_camel
from ...schemas.user_token import UserToken
from . import check_audit_permission, report_finish_date, report_start_date
router = APIRouter()
# Dependency
def get_db() -> Session:
try:
db = SessionLocal()
yield db
finally:
db.close()
@router.get("")
def product_sale_report_view(
start_date: date = Depends(report_start_date),
finish_date: date = Depends(report_finish_date),
db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["product-sale-report"]),
):
check_audit_permission(start_date, user.permissions)
return {
"startDate": start_date.strftime("%d-%b-%Y"),
"finishDate": finish_date.strftime("%d-%b-%Y"),
"amounts": product_sale_report(start_date, finish_date, db),
}
def product_sale_report(s: date, f: date, db: Session):
start_date = s + timedelta(minutes=settings.NEW_DAY_OFFSET_MINUTES)
finish_date = f + timedelta(days=1, minutes=settings.NEW_DAY_OFFSET_MINUTES)
day = func.date_trunc("day", Voucher.date - timedelta(minutes=settings.NEW_DAY_OFFSET_MINUTES)).label("day")
list_ = (
db.query(
ProductVersion.product_id,
ProductVersion.full_name,
Voucher.voucher_type,
Inventory.is_happy_hour,
func.sum(Inventory.quantity),
)
.join(Inventory.kot)
.join(Kot.voucher)
.join(Inventory.product)
.join(ProductVersion.sale_category)
.join(ProductVersion.menu_category)
.filter(
Voucher.date >= start_date,
Voucher.date <= finish_date,
or_(
ProductVersion.valid_from == None, # noqa: E711
ProductVersion.valid_from <= day,
),
or_(
ProductVersion.valid_till == None, # noqa: E711
ProductVersion.valid_till >= day,
),
)
.group_by(
SaleCategory.name,
MenuCategory.name,
ProductVersion.product_id,
ProductVersion.full_name,
Voucher.voucher_type,
Inventory.is_happy_hour,
)
.order_by(SaleCategory.name, MenuCategory.name)
.all()
)
info = []
for id_, name, type_, hh, quantity in list_:
type_ = to_camel(VoucherType(type_).name)
old = [i for i in info if i["id"] == id_ and i["isHappyHour"] == hh]
if len(old):
old[0][type_] = quantity
else:
info.append(
{
"id": id_,
"name": "H H " + name if hh else name,
"isHappyHour": hh,
type_: quantity,
}
)
return info