119 lines
3.3 KiB
Python
119 lines
3.3 KiB
Python
import datetime
|
|
|
|
from fastapi import APIRouter, Depends, Security, Request
|
|
from sqlalchemy.orm import Session
|
|
from sqlalchemy.sql.expression import func
|
|
|
|
from ...schemas.auth import UserToken
|
|
from ...core.security import get_current_active_user as get_user
|
|
from ...db.session import SessionLocal
|
|
from brewman.models.master import Product, CostCentre
|
|
from brewman.models.voucher import Voucher, Journal, Inventory
|
|
from brewman.routers.services.session import (
|
|
session_period_set,
|
|
session_period_start,
|
|
session_period_finish,
|
|
)
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
# Dependency
|
|
def get_db() -> Session:
|
|
try:
|
|
db = SessionLocal()
|
|
yield db
|
|
finally:
|
|
db.close()
|
|
|
|
|
|
@router.get("") # "Closing Stock"
|
|
def report_blank(
|
|
request: Request,
|
|
user: UserToken = Security(get_user, scopes=["closing-stock"]),
|
|
):
|
|
return {"date": session_period_finish(request.session), "body": []}
|
|
|
|
|
|
@router.get("/{date}")
|
|
def report_data(
|
|
date: str,
|
|
request: Request,
|
|
db: Session = Depends(get_db),
|
|
user: UserToken = Security(get_user, scopes=["closing-stock"]),
|
|
):
|
|
session_period_set(session_period_start(request.session), date, request.session)
|
|
return {"date": date, "body": build_report(date, db)}
|
|
|
|
|
|
def build_report(date, db):
|
|
date = datetime.datetime.strptime(date, "%d-%b-%Y")
|
|
amount_sum = func.sum(
|
|
Journal.debit * Inventory.quantity * Inventory.rate * (1 + Inventory.tax)
|
|
).label("amount")
|
|
quantity_sum = func.sum(Journal.debit * Inventory.quantity).label("quantity")
|
|
query = (
|
|
db.query(Product, quantity_sum, amount_sum)
|
|
.join(Product.inventories)
|
|
.join(Inventory.voucher)
|
|
.join(Voucher.journals)
|
|
.filter(Voucher.date <= date)
|
|
.filter(Journal.cost_centre_id == CostCentre.cost_centre_purchase())
|
|
.group_by(Product)
|
|
.order_by(amount_sum.desc())
|
|
.all()
|
|
)
|
|
|
|
body = []
|
|
for product, quantity, amount in query:
|
|
if quantity != 0 and amount != 0:
|
|
body.append(
|
|
{
|
|
"product": product.full_name,
|
|
"group": product.product_group.name,
|
|
"quantity": quantity,
|
|
"amount": amount,
|
|
}
|
|
)
|
|
return body
|
|
|
|
|
|
def get_opening_stock(start_date, db):
|
|
opening_stock = (
|
|
db.query(
|
|
func.sum(
|
|
Inventory.quantity
|
|
* Inventory.rate
|
|
* (1 + Inventory.tax)
|
|
* Journal.debit
|
|
)
|
|
)
|
|
.join(Journal.voucher)
|
|
.join(Journal.account)
|
|
.join(Voucher.inventories)
|
|
.filter(Voucher.date < start_date)
|
|
.filter(Journal.cost_centre_id == CostCentre.cost_centre_purchase())
|
|
.scalar()
|
|
)
|
|
return 0 if opening_stock is None else opening_stock
|
|
|
|
|
|
def get_closing_stock(finish_date, db):
|
|
closing_stock = (
|
|
db.query(
|
|
func.sum(
|
|
Inventory.quantity
|
|
* Inventory.rate
|
|
* (1 + Inventory.tax)
|
|
* Journal.debit
|
|
)
|
|
)
|
|
.join(Journal.voucher)
|
|
.join(Journal.account)
|
|
.join(Voucher.inventories)
|
|
.filter(Voucher.date <= finish_date)
|
|
.filter(Journal.cost_centre_id == CostCentre.cost_centre_purchase())
|
|
.scalar()
|
|
)
|
|
return 0 if closing_stock is None else closing_stock
|