73 lines
2.0 KiB
Python
73 lines
2.0 KiB
Python
from datetime import date, datetime
|
|
|
|
import brewman.schemas.reports as schemas
|
|
|
|
from fastapi import APIRouter, Depends, Request, Security
|
|
from sqlalchemy.orm import Session
|
|
from sqlalchemy.sql.expression import func
|
|
|
|
from ...core.security import get_current_active_user as get_user
|
|
from ...core.session import get_finish_date, get_start_date, set_period
|
|
from ...db.session import SessionLocal
|
|
from ...models.master import AccountBase
|
|
from ...models.voucher import Journal, Voucher, VoucherType
|
|
from ...schemas.auth import UserToken
|
|
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
# Dependency
|
|
def get_db() -> Session:
|
|
try:
|
|
db = SessionLocal()
|
|
yield db
|
|
finally:
|
|
db.close()
|
|
|
|
|
|
@router.get("", response_model=schemas.TrialBalance)
|
|
def report_blank(
|
|
request: Request,
|
|
user: UserToken = Security(get_user, scopes=["trial-balance"]),
|
|
):
|
|
return {"date": get_finish_date(request.session), "body": []}
|
|
|
|
|
|
@router.get("/{date_}", response_model=schemas.TrialBalance)
|
|
def report_data(
|
|
date_: str,
|
|
request: Request,
|
|
db: Session = Depends(get_db),
|
|
user: UserToken = Security(get_user, scopes=["trial-balance"]),
|
|
):
|
|
set_period(get_start_date(request.session), date_, request.session)
|
|
return {
|
|
"date": date_,
|
|
"body": build_report(datetime.strptime(date_, "%d-%b-%Y"), db),
|
|
}
|
|
|
|
|
|
def build_report(date_: date, db: Session):
|
|
amount_sum = func.sum(Journal.amount * Journal.debit).label("amount")
|
|
query = (
|
|
db.query(AccountBase, amount_sum)
|
|
.join(Journal.voucher)
|
|
.join(Journal.account)
|
|
.filter(Voucher.date <= date_)
|
|
.filter(Voucher.type != VoucherType.by_name("Issue").id)
|
|
.group_by(AccountBase)
|
|
.order_by(AccountBase.type)
|
|
.order_by(func.abs(amount_sum).desc())
|
|
.all()
|
|
)
|
|
|
|
body = []
|
|
for account, amount in query:
|
|
if amount != 0:
|
|
tag = "debit" if amount > 0 else "credit"
|
|
body.append(
|
|
{"type": account.type_object.name, "name": account.name, tag: amount}
|
|
)
|
|
return body
|