barker/barker/barker/routers/reports/cashier_report.py

172 lines
6.1 KiB
Python
Raw Normal View History

import uuid
from datetime import date, datetime, time, timedelta
from typing import Dict, List
from fastapi import APIRouter, Cookie, Depends, Security
from sqlalchemy import distinct, select
2020-06-17 04:27:41 +00:00
from sqlalchemy.orm import Session, joinedload
2020-06-17 04:27:41 +00:00
from ...core.config import settings
from ...core.security import get_current_active_user as get_user
from ...db.session import SessionFuture
from ...models.reporting_level import ReportingLevel
from ...models.settlement import Settlement
from ...models.user import User
from ...models.voucher import Voucher
from ...printing.cashier_report import print_cashier_report
from ...schemas.cashier_report import (
CashierReport,
InfoItem,
NameAmount,
SettleOptionSchema,
)
from ...schemas.user import UserLink
from ...schemas.user_token import UserToken
from . import check_audit_permission, report_finish_date, report_start_date
2020-06-17 04:27:41 +00:00
router = APIRouter()
@router.get("/active", response_model=List[UserLink])
2020-06-17 04:27:41 +00:00
def active_cashiers(
start_date: date = Depends(report_start_date),
finish_date: date = Depends(report_finish_date),
2020-06-17 04:27:41 +00:00
user: UserToken = Security(get_user, scopes=["cashier-report"]),
) -> List[UserLink]:
check_audit_permission(start_date, user.permissions)
with SessionFuture() as db:
return get_active_cashiers(start_date, finish_date, db)
2019-08-19 10:28:02 +00:00
def get_active_cashiers(start_date: date, finish_date: date, db: Session) -> List[UserLink]:
start_datetime = datetime.combine(start_date, time()) + timedelta(
minutes=settings.TIMEZONE_OFFSET_MINUTES - settings.NEW_DAY_OFFSET_MINUTES
)
finish_datetime = datetime.combine(finish_date, time()) + timedelta(
days=1, minutes=settings.TIMEZONE_OFFSET_MINUTES - settings.NEW_DAY_OFFSET_MINUTES
)
2020-06-17 04:27:41 +00:00
users = (
db.execute(
select(User)
.where(
User.id.in_(
select(distinct(Voucher.user_id)).where(
Voucher.date >= start_datetime,
Voucher.date <= finish_datetime,
)
2020-06-17 04:27:41 +00:00
)
)
.order_by(User.name)
2020-06-17 04:27:41 +00:00
)
.scalars()
2020-06-17 04:27:41 +00:00
.all()
)
return [UserLink(id=u.id, name=u.name) for u in users]
2019-08-19 10:28:02 +00:00
@router.get("/{id_}", response_model=CashierReport)
2020-06-17 04:27:41 +00:00
def show_id(
id_: uuid.UUID,
start_date: date = Depends(report_start_date),
finish_date: date = Depends(report_finish_date),
2020-06-17 04:27:41 +00:00
user: UserToken = Security(get_user, scopes=["cashier-report"]),
) -> CashierReport:
check_audit_permission(start_date, user.permissions)
user_link = UserLink(id=user.id_, name=user.name)
with SessionFuture() as db:
return get_id(id_, start_date, finish_date, user_link, db)
def get_id(id_: uuid.UUID, start_date: date, finish_date: date, user: UserLink, db: Session) -> CashierReport:
cashier: str = db.execute(select(User.name).where(User.id == id_)).scalar_one()
start_datetime = datetime.combine(start_date, time()) + timedelta(
minutes=settings.TIMEZONE_OFFSET_MINUTES - settings.NEW_DAY_OFFSET_MINUTES
)
finish_datetime = datetime.combine(finish_date, time()) + timedelta(
days=1, minutes=settings.TIMEZONE_OFFSET_MINUTES - settings.NEW_DAY_OFFSET_MINUTES
)
2019-08-19 10:28:02 +00:00
vouchers = (
db.execute(
select(Voucher)
.join(Voucher.settlements)
.join(Settlement.settle_option)
.options(
joinedload(Voucher.settlements, innerjoin=True).joinedload(Settlement.settle_option, innerjoin=True)
)
.where(
Voucher.date >= start_datetime,
Voucher.date <= finish_datetime,
Voucher.user_id == id_,
)
.order_by(Voucher.voucher_type)
.order_by(Voucher.bill_id)
2020-06-17 04:27:41 +00:00
)
.unique()
.scalars()
2019-08-19 10:28:02 +00:00
.all()
)
info: Dict[SettleOptionSchema, List[InfoItem]] = {}
2019-08-19 10:28:02 +00:00
amounts = {}
for item in vouchers:
for so in (
so for so in item.settlements if so.settle_option.reporting_level >= ReportingLevel.Aggregate
): # Only Roundoff and Amount is skipped
if so.settle_option.name not in info:
info[so.settle_option.name] = []
2019-08-19 10:28:02 +00:00
amounts[so.settle_option.name] = 0
amounts[so.settle_option.name] += so.amount
if so.settle_option.reporting_level == ReportingLevel.Detailed: # Only additionally Cash is skipped
info[so.settle_option.name].append(
InfoItem(
date=item.date,
billId=item.full_bill_id,
customer=item.customer.name if item.customer is not None else "",
amount=so.amount,
)
)
return CashierReport(
startDate=start_date,
finishDate=finish_date,
cashier=UserLink(id=id_, name=cashier),
cashiers=", ".join(x.name for x in get_active_cashiers(start_date, finish_date, db)),
amounts=[NameAmount(name=key, amount=value) for key, value in amounts.items()],
info=info,
user=user,
)
2020-06-17 04:27:41 +00:00
@router.get("/print/{id_}", response_model=bool)
def print_report(
id_: uuid.UUID,
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=["cashier-report"]),
) -> bool:
check_audit_permission(start_date, user.permissions)
with SessionFuture() as db:
report = get_id(id_, start_date, finish_date, UserLink(id=user.id_, name=user.name), db)
print_cashier_report(report, device_id, db)
return True
@router.get("", response_model=CashierReport)
2020-06-17 04:27:41 +00:00
def show_blank(
start_date: date = Depends(report_start_date),
finish_date: date = Depends(report_finish_date),
2020-06-17 04:27:41 +00:00
user: UserToken = Security(get_user, scopes=["cashier-report"]),
) -> CashierReport:
check_audit_permission(start_date, user.permissions)
return CashierReport(
startDate=start_date,
finishDate=finish_date,
cashier=UserLink(id=None),
cashiers="",
amounts=[],
info=[],
user=UserLink(id=user.id_),
)