barker/barker/barker/routers/reports/sale_report.py

142 lines
5.3 KiB
Python

import uuid
from datetime import date, datetime, time, timedelta
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.product import Product
from ...models.product_version import ProductVersion
from ...models.sale_category import SaleCategory
from ...models.settle_option import SettleOption
from ...models.settlement import Settlement
from ...models.voucher import Voucher
from ...models.voucher_type import VoucherType
from ...printing.sale_report import print_sale_report
from ...schemas.sale_report import SaleReport, SaleReportItem
from ...schemas.user import UserLink
from ...schemas.user_token import UserToken
from . import check_audit_permission, report_finish_date, report_start_date
from .tax_report import get_tax
router = APIRouter()
@router.get("", response_model=SaleReport)
def get_sale_report(
start_date: date = Depends(report_start_date),
finish_date: date = Depends(report_finish_date),
user: UserToken = Security(get_user, scopes=["sale-report"]),
) -> SaleReport:
check_audit_permission(start_date, user.permissions)
with SessionFuture() as db:
return SaleReport(
startDate=start_date,
finishDate=finish_date,
amounts=(
get_sale(start_date, finish_date, db)
+ [SaleReportItem(name="--", amount=0)]
+ get_settlements(start_date, finish_date, db)
+ [SaleReportItem(name="--", amount=0)]
+ [SaleReportItem(name=i.name, amount=i.amount) for i in get_tax(start_date, finish_date, db)]
),
user=UserLink(id=user.id_, name=user.name),
)
def get_sale(s: date, f: date, db: Session) -> list[SaleReportItem]:
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(SaleCategory.name, func.sum(Inventory.net))
.join(Inventory.kot)
.join(Kot.voucher)
.join(Inventory.product)
.join(Product.versions)
.join(ProductVersion.sale_category)
.where(
Voucher.date >= start_date,
Voucher.date <= finish_date,
Voucher.voucher_type == VoucherType.REGULAR_BILL,
~Voucher.settlements.any(Settlement.settled == SettleOption.UNSETTLED()),
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)
.order_by(SaleCategory.name)
).all()
total = 0
info = []
for gt, am in list_:
total += am
info.append(SaleReportItem(name=gt, amount=am))
return info + [SaleReportItem(name="Total Settled", amount=total)]
def get_settlements(s: date, f: date, db: Session) -> list[SaleReportItem]:
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
)
list_ = db.execute(
select(SettleOption.name, func.sum(Settlement.amount))
.join(Voucher.settlements)
.join(Settlement.settle_option)
.where(Voucher.date >= start_date, Voucher.date <= finish_date)
.group_by(SettleOption.name)
.order_by(SettleOption.name)
).all()
total = 0
info = []
for gt, am in list_:
total += am
info.append(SaleReportItem(name=gt, amount=am))
return info + [SaleReportItem(name="Total", amount=total)]
@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=["sale-report"]),
) -> bool:
check_audit_permission(start_date, user.permissions)
with SessionFuture() as db:
report = SaleReport(
startDate=start_date,
finishDate=finish_date,
amounts=(
get_sale(start_date, finish_date, db)
+ [SaleReportItem(name="--", amount=0)]
+ get_settlements(start_date, finish_date, db)
+ [SaleReportItem(name="--", amount=0)]
+ [SaleReportItem(name=i.name, amount=i.amount) for i in get_tax(start_date, finish_date, db)]
),
user=UserLink(id=user.id_, name=user.name),
)
print_sale_report(report, device_id, db)
return True