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

154 lines
5.4 KiB
Python

import uuid
from datetime import date, datetime, time, timedelta
from typing import List
from fastapi import APIRouter, Cookie, Depends, HTTPException, Security, status
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.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 report_finish_date, report_start_date
from .tax_report import get_tax
router = APIRouter()
# Dependency
def get_db() -> Session:
try:
db = SessionLocal()
yield db
finally:
db.close()
@router.get("", response_model=SaleReport)
def get_sale_analysis(
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=["sale-report"]),
) -> SaleReport:
today = (datetime.now() + timedelta(minutes=settings.TIMEZONE_OFFSET_MINUTES)).date()
if (today - start_date).days > 5 and "audit" not in user.permissions:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="Accounts Audit",
)
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)
finish_date = datetime.combine(f, time()) + 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(SaleCategory.name, func.sum(Inventory.net))
.join(Inventory.kot)
.join(Kot.voucher)
.join(Inventory.product)
.join(ProductVersion.sale_category)
.filter(
Voucher.date >= start_date,
Voucher.date <= finish_date,
Voucher.voucher_type == VoucherType.REGULAR_BILL,
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)
finish_date = datetime.combine(f, time()) + timedelta(days=1, minutes=settings.NEW_DAY_OFFSET_MINUTES)
list_ = (
db.query(SettleOption.name, func.sum(Settlement.amount))
.join(Voucher.settlements)
.join(Settlement.settle_option)
.filter(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),
db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["discount-report"]),
) -> bool:
today = (datetime.now() + timedelta(minutes=settings.TIMEZONE_OFFSET_MINUTES)).date()
if (today - start_date).days > 5 and "audit" not in user.permissions:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="Accounts Audit",
)
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