brewman/brewman/brewman/routers/reports/purchases.py

98 lines
2.8 KiB
Python

import datetime
import brewman.schemas.reports as schemas
from fastapi import APIRouter, Depends, Request, Security
from sqlalchemy.orm import Session
from sqlalchemy.sql.expression import desc, 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 CostCentre, Product
from ...models.voucher import Inventory, 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.Purchases)
def report_blank(
request: Request,
user: UserToken = Security(get_user, scopes=["purchases"]),
):
return schemas.Purchases(
startDate=get_start_date(request.session),
finishDate=get_finish_date(request.session),
body=[],
footer=None,
)
@router.get("/{start}/{finish}", response_model=schemas.Purchases)
def report_data(
start: str,
finish: str,
request: Request,
db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["purchases"]),
):
body, footer = build_report(start, finish, db)
set_period(start, finish, request.session)
return schemas.Purchases(
startDate=start,
finishDate=finish,
body=body,
footer=footer,
)
def build_report(start_date, finish_date, db):
body = []
quantity_sum = func.sum(Journal.debit * Inventory.quantity).label("quantity")
amount_sum = func.sum(
Journal.debit * Inventory.quantity * Inventory.rate * (1 + Inventory.tax)
).label("amount")
query = (
db.query(Product, quantity_sum, amount_sum)
.join(Product.inventories)
.join(Inventory.voucher)
.join(Voucher.journals)
.filter(Voucher.date >= datetime.datetime.strptime(start_date, "%d-%b-%Y"))
.filter(Voucher.date <= datetime.datetime.strptime(finish_date, "%d-%b-%Y"))
.filter(Voucher.type != VoucherType.by_name("Issue").id)
.filter(Journal.cost_centre_id == CostCentre.cost_centre_purchase())
.group_by(Product)
.order_by(desc(amount_sum))
.all()
)
total_amount = 0
for product, quantity, amount in query:
rate = amount / quantity if quantity != 0 else 0
total_amount += amount
row = schemas.PurchasesItem(
name=product.full_name,
quantity=quantity,
rate=rate,
amount=amount,
url=["/", "product-ledger", str(product.id)],
)
body.append(row)
return (
body,
schemas.PurchasesItem(
name="Total", quantity=0, rate=0, url=[], amount=total_amount
),
)