2012-10-22 13:53:58 +00:00
|
|
|
import uuid
|
2018-05-25 13:49:00 +00:00
|
|
|
|
2020-10-07 15:18:43 +00:00
|
|
|
from datetime import date, datetime
|
|
|
|
|
|
|
|
import brewman.schemas.reports as schemas
|
|
|
|
|
|
|
|
from fastapi import APIRouter, Depends, Request, Security
|
2020-05-11 22:22:25 +00:00
|
|
|
from sqlalchemy.orm import Session
|
2020-10-07 15:18:43 +00:00
|
|
|
from sqlalchemy.sql.expression import case, func
|
2012-10-22 13:53:58 +00:00
|
|
|
|
2020-05-11 22:22:25 +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 22:22:25 +00:00
|
|
|
from ...db.session import SessionLocal
|
2020-10-07 15:18:43 +00:00
|
|
|
from ...models.master import AccountBase, CostCentre, Product, ProductGroup
|
|
|
|
from ...models.voucher import Inventory, Journal, Voucher
|
|
|
|
from ...schemas.auth import UserToken
|
|
|
|
|
2012-10-22 13:53:58 +00:00
|
|
|
|
2020-05-08 04:52:25 +00:00
|
|
|
router = APIRouter()
|
2012-10-22 13:53:58 +00:00
|
|
|
|
|
|
|
|
2020-05-11 22:22:25 +00:00
|
|
|
# Dependency
|
|
|
|
def get_db() -> Session:
|
|
|
|
try:
|
|
|
|
db = SessionLocal()
|
|
|
|
yield db
|
|
|
|
finally:
|
|
|
|
db.close()
|
|
|
|
|
|
|
|
|
2020-05-14 10:13:20 +00:00
|
|
|
@router.get("", response_model=schemas.RawMaterialCost)
|
2020-05-11 22:22:25 +00:00
|
|
|
def report_blank(
|
2020-10-07 15:18:43 +00:00
|
|
|
request: Request,
|
|
|
|
user: UserToken = Security(get_user, scopes=["raw-material-cost"]),
|
2020-05-11 22:22:25 +00:00
|
|
|
):
|
2019-04-06 04:13:12 +00:00
|
|
|
return {
|
2020-05-12 04:25:33 +00:00
|
|
|
"startDate": get_start_date(request.session),
|
|
|
|
"finishDate": get_finish_date(request.session),
|
2019-04-06 04:13:12 +00:00
|
|
|
"body": [],
|
2020-05-14 10:13:20 +00:00
|
|
|
"footer": None,
|
2019-04-06 04:13:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-05-14 10:13:20 +00:00
|
|
|
@router.get("/data", response_model=schemas.RawMaterialCost)
|
2020-05-11 22:22:25 +00:00
|
|
|
def report_data(
|
|
|
|
request: Request,
|
|
|
|
s: str = None,
|
|
|
|
f: str = None,
|
|
|
|
db: Session = Depends(get_db),
|
|
|
|
user: UserToken = Security(get_user, scopes=["raw-material-cost"]),
|
|
|
|
):
|
2020-10-07 16:59:24 +00:00
|
|
|
body, footer = build_report(
|
|
|
|
datetime.strptime(s, "%d-%b-%Y"), datetime.strptime(f, "%d-%b-%Y"), db
|
|
|
|
)
|
2020-05-12 04:25:33 +00:00
|
|
|
set_period(s, f, request.session)
|
2019-05-10 03:49:53 +00:00
|
|
|
return {
|
2020-05-11 22:22:25 +00:00
|
|
|
"startDate": s,
|
|
|
|
"finishDate": f,
|
2019-05-10 03:49:53 +00:00
|
|
|
"body": body,
|
|
|
|
"footer": footer,
|
|
|
|
}
|
2012-10-22 13:53:58 +00:00
|
|
|
|
|
|
|
|
2020-05-14 10:13:20 +00:00
|
|
|
@router.get("/{id_}", response_model=schemas.RawMaterialCost)
|
2020-05-11 22:22:25 +00:00
|
|
|
def report_id(
|
|
|
|
id_: uuid.UUID,
|
|
|
|
request: Request,
|
|
|
|
s: str = None,
|
|
|
|
f: str = None,
|
|
|
|
db: Session = Depends(get_db),
|
|
|
|
user: UserToken = Security(get_user, scopes=["raw-material-cost"]),
|
|
|
|
):
|
2020-10-07 16:59:24 +00:00
|
|
|
body = build_report_id(
|
|
|
|
id_, datetime.strptime(s, "%d-%b-%Y"), datetime.strptime(f, "%d-%b-%Y"), db
|
|
|
|
)
|
2020-05-12 04:25:33 +00:00
|
|
|
set_period(s, f, request.session)
|
2019-05-10 03:49:53 +00:00
|
|
|
return {
|
|
|
|
"id": id_,
|
2020-05-11 22:22:25 +00:00
|
|
|
"startDate": s,
|
|
|
|
"finishDate": f,
|
2019-05-10 03:49:53 +00:00
|
|
|
"body": body,
|
2019-04-06 04:13:12 +00:00
|
|
|
}
|
|
|
|
|
2019-05-10 03:49:53 +00:00
|
|
|
|
2020-05-14 10:13:20 +00:00
|
|
|
def build_report(start_date: date, finish_date: date, db: Session):
|
2019-05-10 03:49:53 +00:00
|
|
|
body = []
|
2020-10-07 16:59:24 +00:00
|
|
|
sum_issue = func.sum(
|
|
|
|
case([(AccountBase.type == 2, Journal.signed_amount)], else_=0)
|
|
|
|
).label("issue")
|
|
|
|
sum_sale = func.sum(
|
|
|
|
case([(AccountBase.type == 3, Journal.signed_amount * -1)], else_=0)
|
|
|
|
).label("sale")
|
2019-04-06 04:13:12 +00:00
|
|
|
|
|
|
|
query = (
|
2020-05-11 22:22:25 +00:00
|
|
|
db.query(CostCentre, sum_issue, sum_sale)
|
2019-04-06 04:13:12 +00:00
|
|
|
.join(CostCentre.journals)
|
|
|
|
.join(Journal.voucher)
|
|
|
|
.join(Journal.account)
|
2020-05-14 10:13:20 +00:00
|
|
|
.filter(Voucher.date >= start_date)
|
|
|
|
.filter(Voucher.date <= finish_date)
|
2019-04-06 04:13:12 +00:00
|
|
|
.filter(Journal.cost_centre_id != CostCentre.cost_centre_purchase())
|
|
|
|
.filter(AccountBase.type.in_([2, 3]))
|
|
|
|
.group_by(CostCentre)
|
|
|
|
.order_by(sum_sale.desc())
|
|
|
|
.all()
|
|
|
|
)
|
2012-10-22 13:53:58 +00:00
|
|
|
|
|
|
|
issues = 0
|
|
|
|
sales = 0
|
2015-02-12 12:12:46 +00:00
|
|
|
for cost_centre, issue, sale in query:
|
2012-10-22 13:53:58 +00:00
|
|
|
issues += issue
|
|
|
|
sales += sale
|
|
|
|
rmc = 0 if sale == 0 else issue / sale
|
2019-05-10 03:49:53 +00:00
|
|
|
body.append(
|
2019-04-06 04:13:12 +00:00
|
|
|
{
|
|
|
|
"name": cost_centre.name,
|
|
|
|
"issue": issue,
|
|
|
|
"sale": sale,
|
|
|
|
"rmc": rmc,
|
2020-05-31 09:11:11 +00:00
|
|
|
"url": ["/", "raw-material-cost", str(cost_centre.id)],
|
2019-04-06 04:13:12 +00:00
|
|
|
}
|
|
|
|
)
|
2012-10-22 13:53:58 +00:00
|
|
|
|
|
|
|
rmc = 0 if sales == 0 else issues / sales
|
2019-05-10 03:49:53 +00:00
|
|
|
return body, {"name": "Total", "issue": issues, "sale": sales, "rmc": rmc}
|
2012-10-22 13:53:58 +00:00
|
|
|
|
2019-04-06 04:13:12 +00:00
|
|
|
|
2020-10-07 16:59:24 +00:00
|
|
|
def build_report_id(
|
|
|
|
cost_centre_id: uuid.UUID, start_date: date, finish_date: date, db: Session
|
|
|
|
):
|
2019-04-06 04:13:12 +00:00
|
|
|
sum_quantity = func.sum(Inventory.quantity * Journal.debit).label("quantity")
|
|
|
|
sum_net = func.sum(Inventory.rate * Inventory.quantity * Journal.debit).label("net")
|
|
|
|
sum_gross = func.sum(Inventory.amount * Journal.debit).label("gross")
|
|
|
|
|
|
|
|
query = (
|
2020-05-11 22:22:25 +00:00
|
|
|
db.query(Product, sum_quantity, sum_net, sum_gross)
|
2019-04-06 04:13:12 +00:00
|
|
|
.join(Product.inventories)
|
|
|
|
.join(Inventory.voucher)
|
|
|
|
.join(Voucher.journals)
|
|
|
|
.join(Product.product_group)
|
2020-05-14 10:13:20 +00:00
|
|
|
.filter(Voucher.date >= start_date)
|
|
|
|
.filter(Voucher.date <= finish_date)
|
2019-04-06 04:13:12 +00:00
|
|
|
.filter(Voucher.type == 3)
|
|
|
|
.filter(Journal.cost_centre_id == cost_centre_id)
|
|
|
|
.group_by(Product)
|
|
|
|
.group_by(Journal.debit)
|
|
|
|
.group_by(ProductGroup.name)
|
|
|
|
.order_by(ProductGroup.name)
|
|
|
|
.order_by(sum_net.desc())
|
|
|
|
.all()
|
|
|
|
)
|
2012-10-22 13:53:58 +00:00
|
|
|
|
|
|
|
groups = {}
|
|
|
|
counter = 0
|
2019-05-10 03:49:53 +00:00
|
|
|
list_ = []
|
2012-10-22 13:53:58 +00:00
|
|
|
for product, quantity, net, gross in query:
|
|
|
|
if product.product_group_id in groups:
|
|
|
|
group = groups[product.product_group_id]
|
2019-04-06 04:13:12 +00:00
|
|
|
group["net"] += net
|
|
|
|
group["gross"] += gross
|
2012-10-22 13:53:58 +00:00
|
|
|
else:
|
|
|
|
counter += 500
|
2019-04-06 04:13:12 +00:00
|
|
|
group = {
|
|
|
|
"group": product.product_group.name,
|
|
|
|
"net": net,
|
|
|
|
"gross": gross,
|
|
|
|
"order": counter,
|
|
|
|
"heading": True,
|
|
|
|
}
|
2012-10-22 13:53:58 +00:00
|
|
|
groups[product.product_group_id] = group
|
|
|
|
counter += 1
|
2019-05-10 03:49:53 +00:00
|
|
|
list_.append(
|
2019-04-06 04:13:12 +00:00
|
|
|
{
|
|
|
|
"name": product.full_name,
|
|
|
|
"quantity": quantity,
|
|
|
|
"net": net,
|
|
|
|
"gross": gross,
|
|
|
|
"order": counter,
|
|
|
|
"heading": False,
|
|
|
|
}
|
|
|
|
)
|
2012-10-22 13:53:58 +00:00
|
|
|
|
|
|
|
for item in groups.values():
|
2019-05-10 03:49:53 +00:00
|
|
|
list_.append(item)
|
2012-10-22 13:53:58 +00:00
|
|
|
|
2019-05-10 03:49:53 +00:00
|
|
|
return sorted(list_, key=lambda d: d["order"])
|