2020-10-07 15:18:43 +00:00
|
|
|
from datetime import date, datetime
|
2018-05-25 13:49:00 +00:00
|
|
|
|
2020-10-07 15:18:43 +00:00
|
|
|
import brewman.schemas.reports as schemas
|
|
|
|
|
|
|
|
from fastapi import APIRouter, Depends, Request, Security
|
2020-05-11 21:27:48 +00:00
|
|
|
from sqlalchemy.orm import Session
|
2020-10-07 15:18:43 +00:00
|
|
|
from sqlalchemy.sql.expression import desc, func
|
2012-05-01 21:40:01 +00:00
|
|
|
|
2020-05-11 21:27:48 +00:00
|
|
|
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
|
2020-05-11 21:27:48 +00:00
|
|
|
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, get_opening_stock
|
|
|
|
from ...schemas.auth import UserToken
|
|
|
|
|
2012-10-17 10:53:55 +00:00
|
|
|
|
2020-05-08 04:52:25 +00:00
|
|
|
router = APIRouter()
|
2012-10-17 10:53:55 +00:00
|
|
|
|
|
|
|
|
2020-05-11 21:27:48 +00:00
|
|
|
# Dependency
|
|
|
|
def get_db() -> Session:
|
|
|
|
try:
|
|
|
|
db = SessionLocal()
|
|
|
|
yield db
|
|
|
|
finally:
|
|
|
|
db.close()
|
|
|
|
|
|
|
|
|
2020-05-14 08:19:40 +00:00
|
|
|
@router.get("", response_model=schemas.ProfitLoss)
|
2020-05-11 21:27:48 +00:00
|
|
|
def report_blank(
|
2020-10-07 15:18:43 +00:00
|
|
|
request: Request,
|
|
|
|
user: UserToken = Security(get_user, scopes=["profit-&-loss"]),
|
2020-05-11 21:27:48 +00:00
|
|
|
):
|
2019-05-10 03:49:53 +00:00
|
|
|
return {
|
2020-05-12 04:25:33 +00:00
|
|
|
"startDate": get_start_date(request.session),
|
|
|
|
"finishDate": get_finish_date(request.session),
|
2019-05-10 03:49:53 +00:00
|
|
|
"body": [],
|
2020-05-14 08:19:40 +00:00
|
|
|
"footer": None,
|
2019-05-10 03:49:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-05-14 08:19:40 +00:00
|
|
|
@router.get("/{start}/{finish}", response_model=schemas.ProfitLoss)
|
2020-05-11 21:27:48 +00:00
|
|
|
def report_data(
|
|
|
|
start: str,
|
|
|
|
finish: str,
|
|
|
|
request: Request,
|
|
|
|
db: Session = Depends(get_db),
|
|
|
|
user: UserToken = Security(get_user, scopes=["profit-&-loss"]),
|
|
|
|
):
|
2020-10-07 16:59:24 +00:00
|
|
|
body, footer = build_profit_loss(
|
|
|
|
datetime.strptime(start, "%d-%b-%Y"), datetime.strptime(finish, "%d-%b-%Y"), db
|
|
|
|
)
|
2020-05-12 04:25:33 +00:00
|
|
|
set_period(start, finish, request.session)
|
2019-05-10 03:49:53 +00:00
|
|
|
return {
|
2020-05-11 21:27:48 +00:00
|
|
|
"startDate": start,
|
|
|
|
"finishDate": finish,
|
2019-05-10 03:49:53 +00:00
|
|
|
"body": body,
|
|
|
|
"footer": footer,
|
|
|
|
}
|
2012-10-17 10:53:55 +00:00
|
|
|
|
|
|
|
|
2020-05-14 08:19:40 +00:00
|
|
|
def build_profit_loss(start_date: date, finish_date: date, db: Session):
|
2018-07-07 11:01:44 +00:00
|
|
|
profit_type_list = [i.id for i in AccountType.list() if i.balance_sheet == False]
|
2012-10-17 18:37:32 +00:00
|
|
|
report = []
|
2019-05-10 03:49:53 +00:00
|
|
|
groups = {}
|
2012-05-01 21:40:01 +00:00
|
|
|
|
2012-10-17 18:37:32 +00:00
|
|
|
amount_sum = func.sum(Journal.amount * Journal.debit)
|
2019-04-06 04:13:12 +00:00
|
|
|
query = (
|
2020-05-11 21:27:48 +00:00
|
|
|
db.query(AccountBase, amount_sum)
|
2019-04-06 04:13:12 +00:00
|
|
|
.join(Journal.voucher)
|
|
|
|
.join(Journal.account)
|
|
|
|
.filter(Voucher.date >= start_date)
|
|
|
|
.filter(Voucher.date <= finish_date)
|
|
|
|
.filter(Voucher.type != VoucherType.by_name("Issue").id)
|
|
|
|
.filter(AccountBase.type.in_(profit_type_list))
|
|
|
|
.group_by(AccountBase)
|
|
|
|
.order_by(AccountBase.type)
|
|
|
|
.order_by(desc(func.abs(amount_sum)))
|
|
|
|
.all()
|
|
|
|
)
|
2012-05-01 21:40:01 +00:00
|
|
|
|
|
|
|
# Get opening / closing stock
|
2020-05-11 21:27:48 +00:00
|
|
|
opening_stock = get_opening_stock(start_date, db)
|
|
|
|
closing_stock = get_closing_stock(finish_date, db)
|
2012-10-17 18:37:32 +00:00
|
|
|
total_amount = (opening_stock - closing_stock) * -1
|
2013-09-27 22:11:57 +00:00
|
|
|
|
2020-10-07 16:59:24 +00:00
|
|
|
report.append(
|
|
|
|
{"name": "Opening Stock", "amount": opening_stock * -1, "order": 200001}
|
|
|
|
)
|
2020-05-14 08:19:40 +00:00
|
|
|
report.append({"name": "Closing Stock", "amount": closing_stock, "order": 290000})
|
2018-07-07 11:01:44 +00:00
|
|
|
purchase_group = AccountType.by_id(2)
|
2019-04-06 04:13:12 +00:00
|
|
|
groups[purchase_group.id] = {
|
|
|
|
"group": purchase_group.name,
|
|
|
|
"total": total_amount,
|
|
|
|
"order": purchase_group.order,
|
|
|
|
}
|
2013-09-27 22:11:57 +00:00
|
|
|
|
2012-10-17 18:37:32 +00:00
|
|
|
counter = 0
|
2018-07-07 11:01:44 +00:00
|
|
|
for account, amount in query:
|
2012-10-17 18:37:32 +00:00
|
|
|
# Add Items
|
2013-09-27 22:11:57 +00:00
|
|
|
amount *= -1
|
2018-07-07 11:01:44 +00:00
|
|
|
account_type = AccountType.by_id(account.type)
|
2012-10-17 18:37:32 +00:00
|
|
|
total_amount += amount
|
2013-09-27 22:11:57 +00:00
|
|
|
|
2012-05-01 21:40:01 +00:00
|
|
|
if amount != 0:
|
2020-05-14 08:19:40 +00:00
|
|
|
counter += 10
|
2019-04-06 04:13:12 +00:00
|
|
|
report.append(
|
2020-10-07 15:18:43 +00:00
|
|
|
{
|
|
|
|
"name": account.name,
|
|
|
|
"amount": amount,
|
|
|
|
"order": account_type.order + counter,
|
|
|
|
}
|
2019-04-06 04:13:12 +00:00
|
|
|
)
|
2018-07-07 11:01:44 +00:00
|
|
|
if account_type.id in groups:
|
2019-04-06 04:13:12 +00:00
|
|
|
groups[account_type.id]["total"] += amount
|
2012-10-17 18:37:32 +00:00
|
|
|
else:
|
2019-04-06 04:13:12 +00:00
|
|
|
groups[account_type.id] = {
|
|
|
|
"group": account_type.name,
|
|
|
|
"total": amount,
|
|
|
|
"order": account_type.order,
|
|
|
|
}
|
2012-10-17 18:37:32 +00:00
|
|
|
|
|
|
|
# Add Subtotals
|
|
|
|
for item in groups.values():
|
|
|
|
report.append(item)
|
|
|
|
|
2012-05-01 21:40:01 +00:00
|
|
|
# Add Net
|
2019-05-10 03:49:53 +00:00
|
|
|
footer = {
|
2019-04-06 04:13:12 +00:00
|
|
|
"group": "Net Profit" if total_amount > 0 else "Net Loss",
|
|
|
|
"total": total_amount,
|
2020-05-14 08:19:40 +00:00
|
|
|
"order": 1000000,
|
2019-04-06 04:13:12 +00:00
|
|
|
}
|
2012-05-01 21:40:01 +00:00
|
|
|
|
2019-04-06 04:13:12 +00:00
|
|
|
return sorted(report, key=lambda d: d["order"]), footer
|
2012-05-01 21:40:01 +00:00
|
|
|
|
|
|
|
|
2020-05-11 21:27:48 +00:00
|
|
|
def get_accumulated_profit(finish_date, db):
|
2018-07-07 11:01:44 +00:00
|
|
|
type_list = [i.id for i in AccountType.list() if i.balance_sheet is False]
|
2012-05-01 21:40:01 +00:00
|
|
|
|
2019-04-06 04:13:12 +00:00
|
|
|
accumulated_profit = (
|
2020-05-11 21:27:48 +00:00
|
|
|
db.query(func.sum(Journal.amount * Journal.debit))
|
2019-04-06 04:13:12 +00:00
|
|
|
.join(Journal.voucher)
|
|
|
|
.join(Journal.account)
|
|
|
|
.filter(Voucher.date <= finish_date)
|
|
|
|
.filter(Voucher.type != VoucherType.by_name("Issue").id)
|
|
|
|
.filter(AccountBase.type.in_(type_list))
|
2016-12-24 11:41:01 +00:00
|
|
|
.scalar()
|
2019-04-06 04:13:12 +00:00
|
|
|
)
|
2013-09-27 22:11:57 +00:00
|
|
|
return 0 if accumulated_profit is None else accumulated_profit
|