import uuid from datetime import date, datetime, time, timedelta from typing import Any from fastapi import APIRouter, Cookie, Depends, Security from sqlalchemy import func, or_, select 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 SessionFuture from ...models.inventory import Inventory from ...models.kot import Kot from ...models.menu_category import MenuCategory from ...models.product import Product from ...models.product_version import ProductVersion from ...models.sale_category import SaleCategory from ...models.voucher import Voucher from ...models.voucher_type import VoucherType from ...printing.product_sale_report import print_product_sale_report from ...schemas import to_camel from ...schemas.user_token import UserToken from . import check_audit_permission, report_finish_date, report_start_date router = APIRouter() @router.get("") def product_sale_report_view( start_date: date = Depends(report_start_date), finish_date: date = Depends(report_finish_date), user: UserToken = Security(get_user, scopes=["product-sale-report"]), ): check_audit_permission(start_date, user.permissions) with SessionFuture() as db: 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 = datetime.combine(s, time()) + timedelta( minutes=settings.NEW_DAY_OFFSET_MINUTES - settings.TIMEZONE_OFFSET_MINUTES ) finish_date = datetime.combine(f, time()) + timedelta( days=1, minutes=settings.NEW_DAY_OFFSET_MINUTES - settings.TIMEZONE_OFFSET_MINUTES ) day = func.date_trunc("day", Voucher.date - timedelta(minutes=settings.NEW_DAY_OFFSET_MINUTES)).label("day") list_ = db.execute( select( ProductVersion.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(Product.versions) .join(ProductVersion.sale_category) .join(ProductVersion.menu_category) .where( 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.id, ProductVersion.full_name, Voucher.voucher_type, Inventory.is_happy_hour, ) .order_by(SaleCategory.name, MenuCategory.name, ProductVersion.full_name) ).all() info: list[Any] = [] 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): if type_ not in old[0]: old[0][type_] = 0 old[0][type_] += quantity else: info.append( { "id": id_, "name": "H H " + name if hh else name, "isHappyHour": hh, type_: quantity, } ) return info @router.get("/print", response_model=bool) def print_report( start_date: date = Depends(report_start_date), finish_date: date = Depends(report_finish_date), device_id: uuid.UUID = Cookie(None), user: UserToken = Security(get_user, scopes=["product-sale-report"]), ) -> bool: check_audit_permission(start_date, user.permissions) with SessionFuture() as db: report = { "userName": user.name, "startDate": start_date.strftime("%d-%b-%Y"), "finishDate": finish_date.strftime("%d-%b-%Y"), "amounts": product_sale_report(start_date, finish_date, db), } print_product_sale_report(report, device_id, db) return True