brewman/brewman/brewman/routers/reports/balance_sheet.py

131 lines
4.0 KiB
Python
Raw Normal View History

2020-10-07 15:18:43 +00:00
from datetime import date, datetime
2020-10-07 15:18:43 +00:00
import brewman.schemas.reports as schemas
from fastapi import APIRouter, Depends, Request, Security
from sqlalchemy.orm import Session
2020-10-07 15:18:43 +00:00
from sqlalchemy.sql.expression import desc, func
from ...core.security import get_current_active_user as get_user
2020-10-07 15:18:43 +00:00
from ...core.session import get_finish_date, get_start_date, set_period
from ...db.session import SessionLocal
2020-10-07 15:18:43 +00:00
from ...models.master import AccountBase, AccountType
from ...models.voucher import Journal, Voucher, VoucherType
from ...routers.reports.closing_stock import get_closing_stock
from ...routers.reports.profit_loss import get_accumulated_profit
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.BalanceSheet)
def report_blank(
2020-10-07 15:18:43 +00:00
request: Request,
user: UserToken = Security(get_user, scopes=["balance-sheet"]),
):
return {"date": get_finish_date(request.session), "body": [], "footer": None}
@router.get("/{date_}", response_model=schemas.BalanceSheet)
def report_data(
date_: str,
2020-05-12 06:23:20 +00:00
request: Request,
db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["balance-sheet"]),
):
body, footer = build_balance_sheet(datetime.strptime(date_, "%d-%b-%Y"), db)
set_period(get_start_date(request.session), date_, request.session)
return {"date": date_, "body": body, "footer": footer}
def build_balance_sheet(date_: date, db: Session):
type_list = [i.id for i in AccountType.list() if i.balance_sheet]
report = []
groups = dict()
# Add Net Profit / Loss
closing_stock = round(get_closing_stock(date_, db), 2)
net_profit = round(get_accumulated_profit(date_, db), 2) - closing_stock
total_amount = net_profit
report.append(
2020-10-07 15:18:43 +00:00
{
"name": "Net Loss" if net_profit >= 0 else "Net Profit",
"subAmount": round(net_profit, 2),
"order": 79000,
}
)
capital_group = AccountType.by_id(5)
groups[capital_group.id] = {
"group": capital_group.name,
"amount": round(total_amount, 2),
"order": capital_group.order,
}
total_amount += closing_stock
2020-10-07 16:59:24 +00:00
report.append(
{"name": "Closing Stock", "subAmount": round(closing_stock, 2), "order": 20001}
)
asset_group = AccountType.by_id(4)
groups[asset_group.id] = {
"group": asset_group.name,
"amount": round(closing_stock, 2),
"order": asset_group.order,
}
amount_sum = func.sum(Journal.amount * Journal.debit)
query = (
db.query(AccountBase, amount_sum)
.join(Journal.voucher)
.join(Journal.account)
.filter(Voucher.date <= date_)
.filter(Voucher.type != VoucherType.by_name("Issue").id)
.filter(AccountBase.type.in_(type_list))
.group_by(AccountBase)
.order_by(AccountBase.type)
.order_by(desc(func.abs(amount_sum)))
.all()
)
counter = 0
for account, amount in query:
# Add Items
account_type = AccountType.by_id(account.type)
total_amount += amount
if amount != 0:
counter += 1
report.append(
2020-10-07 15:18:43 +00:00
{
"name": account.name,
"subAmount": round(amount, 2),
"order": account_type.order + counter,
}
)
if account_type.id in groups:
2020-10-07 16:59:24 +00:00
groups[account_type.id]["amount"] = round(
groups[account_type.id]["amount"] + amount, 2
)
else:
groups[account_type.id] = {
"group": account_type.name,
"amount": round(amount, 2),
"order": account_type.order,
}
# Add Subtotals
for item in groups.values():
report.append(item)
footer = {"name": "Total", "amount": round(total_amount, 2), "order": 100000}
return sorted(report, key=lambda d: d["order"]), footer