barker/barker/barker/routers/reports/bill_settlement_report.py

103 lines
3.6 KiB
Python

from datetime import date, datetime, time, timedelta
from typing import List
from fastapi import APIRouter, Depends, Security
from sqlalchemy import 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.reporting_level import ReportingLevel
from ...models.reprint import Reprint
from ...models.settle_option import SettleOption
from ...models.settlement import Settlement
from ...models.voucher import Voucher
from ...schemas.bill_settlement_report import BillSettlement, BillSettlementItem
from ...schemas.user_token import UserToken
from . import check_audit_permission, report_finish_date, report_start_date
router = APIRouter()
@router.get("", response_model=BillSettlement)
def bill_details(
start_date: date = Depends(report_start_date),
finish_date: date = Depends(report_finish_date),
user: UserToken = Security(get_user, scopes=["bill-settlement-report"]),
) -> BillSettlement:
check_audit_permission(start_date, user.permissions)
with SessionFuture() as db:
return BillSettlement(
startDate=start_date,
finishDate=finish_date,
amounts=settlements(start_date, finish_date, db) + reprints(start_date, finish_date, db),
)
def settlements(s: date, f: date, db: Session) -> List[BillSettlementItem]:
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
)
vouchers = (
db.execute(
select(Voucher)
.join(Voucher.settlements)
.join(Settlement.settle_option)
.where(Voucher.date >= start_date, Voucher.date <= finish_date)
.order_by(Voucher.voucher_type)
.order_by(Voucher.bill_id)
)
.unique()
.scalars()
.all()
)
report = []
for item in vouchers:
for so in (
so for so in item.settlements if so.settle_option.reporting_level >= ReportingLevel.Aggregate
): # Only unsettled roundoff and amount is skipped
if so.settle_option.has_reason:
details = f"{so.settle_option.name}: {item.reason}"
else:
details = so.settle_option.name
report.append(
BillSettlementItem(
date=item.date,
billId=item.full_bill_id,
settlement=details,
amount=round(so.amount, 2),
)
)
for i in report:
print(i.json())
return report
def reprints(s: date, f: date, db: Session) -> List[BillSettlementItem]:
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
)
return [
BillSettlementItem(
date=item.date,
billId=item.voucher.full_bill_id,
settlement=f"Reprinted by {item.user.name}",
amount=round(
next(s.amount for s in item.voucher.settlements if s.settled == SettleOption.AMOUNT()) * -1,
2,
),
)
for item in db.execute(select(Reprint).where(Reprint.date >= start_date, Reprint.date <= finish_date))
.scalars()
.all()
]