2020-05-11 22:22:25 +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
|
|
|
|
from sqlalchemy.orm import Session, joinedload
|
2012-05-01 21:40:01 +00:00
|
|
|
from sqlalchemy.sql.expression import func
|
|
|
|
|
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 CostCentre, Product
|
|
|
|
from ...models.voucher import Inventory, Journal, Voucher, VoucherType
|
|
|
|
from ...schemas.auth import UserToken
|
|
|
|
|
2012-05-01 21:40:01 +00:00
|
|
|
|
2020-05-08 04:52:25 +00:00
|
|
|
router = APIRouter()
|
2012-10-16 09:32:36 +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 08:08:13 +00:00
|
|
|
@router.get("", response_model=schemas.ProductLedger)
|
2020-05-11 22:22:25 +00:00
|
|
|
def show_blank(
|
2020-10-07 15:18:43 +00:00
|
|
|
request: Request,
|
|
|
|
user: UserToken = Security(get_user, scopes=["product-ledger"]),
|
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
|
|
|
"product": None,
|
|
|
|
"body": [],
|
|
|
|
}
|
2012-10-26 17:14:58 +00:00
|
|
|
|
|
|
|
|
2020-05-14 08:08:13 +00:00
|
|
|
@router.get("/{id_}", response_model=schemas.ProductLedger)
|
2020-05-11 22:22:25 +00:00
|
|
|
def show_data(
|
|
|
|
id_: uuid.UUID,
|
|
|
|
request: Request,
|
|
|
|
s: str = None,
|
|
|
|
f: str = None,
|
|
|
|
db: Session = Depends(get_db),
|
|
|
|
user: UserToken = Security(get_user, scopes=["product-ledger"]),
|
|
|
|
):
|
|
|
|
product = db.query(Product).filter(Product.id == id_).first()
|
2020-05-12 04:25:33 +00:00
|
|
|
start_date = s if s is not None else get_start_date(request.session)
|
|
|
|
finish_date = f if f is not None else get_finish_date(request.session)
|
2020-05-14 08:08:13 +00:00
|
|
|
body = build_report(
|
2020-10-07 15:18:43 +00:00
|
|
|
product.id,
|
|
|
|
datetime.strptime(start_date, "%d-%b-%Y"),
|
|
|
|
datetime.strptime(finish_date, "%d-%b-%Y"),
|
|
|
|
db,
|
2020-05-14 08:08:13 +00:00
|
|
|
)
|
2020-05-12 04:25:33 +00:00
|
|
|
set_period(start_date, finish_date, request.session)
|
2019-05-10 03:49:53 +00:00
|
|
|
return {
|
2019-04-06 04:13:12 +00:00
|
|
|
"startDate": start_date,
|
|
|
|
"finishDate": finish_date,
|
|
|
|
"product": {"id": product.id, "name": product.name},
|
2019-05-10 03:49:53 +00:00
|
|
|
"body": body,
|
2019-04-06 04:13:12 +00:00
|
|
|
}
|
2012-10-16 09:32:36 +00:00
|
|
|
|
|
|
|
|
2020-10-07 16:59:24 +00:00
|
|
|
def build_report(
|
|
|
|
product_id: uuid.UUID, 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
|
|
|
running_total_q, running_total_a, opening = opening_balance(
|
|
|
|
product_id, start_date, db
|
|
|
|
)
|
2019-05-10 03:49:53 +00:00
|
|
|
body.append(opening)
|
2019-04-06 04:13:12 +00:00
|
|
|
|
|
|
|
query = (
|
2020-05-11 22:22:25 +00:00
|
|
|
db.query(Voucher, Inventory, Journal)
|
2020-10-07 15:18:43 +00:00
|
|
|
.options(
|
|
|
|
joinedload(Journal.account, innerjoin=True),
|
|
|
|
joinedload(Journal.cost_centre, innerjoin=True),
|
|
|
|
)
|
2019-04-06 04:13:12 +00:00
|
|
|
.filter(Voucher.id == Inventory.voucher_id)
|
|
|
|
.filter(Voucher.id == Journal.voucher_id)
|
|
|
|
.filter(Inventory.product_id == product_id)
|
|
|
|
.filter(Journal.cost_centre_id != CostCentre.cost_centre_purchase())
|
2020-05-14 08:08:13 +00:00
|
|
|
.filter(Voucher.date >= start_date)
|
|
|
|
.filter(Voucher.date <= finish_date)
|
2019-04-06 04:13:12 +00:00
|
|
|
.order_by(Voucher.date)
|
|
|
|
.order_by(Voucher.last_edit_date)
|
|
|
|
.all()
|
|
|
|
)
|
2012-05-01 21:40:01 +00:00
|
|
|
|
|
|
|
for row in query:
|
2016-12-24 11:41:01 +00:00
|
|
|
journal_debit = row.Journal.debit * -1
|
2019-04-06 04:13:12 +00:00
|
|
|
name = (
|
|
|
|
row.Journal.cost_centre.name
|
|
|
|
if row.Voucher.type == VoucherType.by_name("Issue").id
|
|
|
|
else row.Journal.account.name
|
|
|
|
)
|
2020-05-14 08:08:13 +00:00
|
|
|
debit_q = row.Inventory.quantity if journal_debit == 1 else None
|
|
|
|
debit_a = row.Inventory.amount if journal_debit == 1 else None
|
|
|
|
credit_q = row.Inventory.quantity if journal_debit != 1 else None
|
|
|
|
credit_a = row.Inventory.amount if journal_debit != 1 else None
|
2012-05-01 21:40:01 +00:00
|
|
|
|
2019-04-06 04:13:12 +00:00
|
|
|
running_total_q += row.Inventory.quantity * journal_debit
|
|
|
|
running_total_a += row.Inventory.amount * journal_debit
|
2012-05-01 21:40:01 +00:00
|
|
|
|
2019-05-10 03:49:53 +00:00
|
|
|
body.append(
|
2019-04-06 04:13:12 +00:00
|
|
|
{
|
|
|
|
"id": row.Voucher.id,
|
|
|
|
"date": row.Voucher.date.strftime("%d-%b-%Y"),
|
|
|
|
"name": name,
|
2020-10-07 15:18:43 +00:00
|
|
|
"url": [
|
|
|
|
"/",
|
|
|
|
VoucherType.by_id(row.Voucher.type).name.replace(" ", "-").lower(),
|
|
|
|
str(row.Voucher.id),
|
|
|
|
],
|
2019-04-06 04:13:12 +00:00
|
|
|
"type": VoucherType.by_id(row.Voucher.type).name,
|
|
|
|
"narration": row.Voucher.narration,
|
2020-10-07 16:59:24 +00:00
|
|
|
"posted": row.Voucher.posted
|
|
|
|
or VoucherType.by_id(row.Voucher.type).name == "Issue",
|
2019-04-06 04:13:12 +00:00
|
|
|
"debitQuantity": debit_q,
|
|
|
|
"debitAmount": debit_a,
|
|
|
|
"creditQuantity": credit_q,
|
|
|
|
"creditAmount": credit_a,
|
|
|
|
"runningQuantity": running_total_q,
|
|
|
|
"runningAmount": running_total_a,
|
|
|
|
}
|
|
|
|
)
|
|
|
|
|
2019-05-10 03:49:53 +00:00
|
|
|
return body
|
2016-12-24 11:41:01 +00:00
|
|
|
|
|
|
|
|
2020-05-14 08:08:13 +00:00
|
|
|
def opening_balance(product_id: uuid.UUID, start_date: date, db: Session):
|
2019-04-06 04:13:12 +00:00
|
|
|
quantity, amount = (
|
2020-10-07 15:18:43 +00:00
|
|
|
db.query(
|
|
|
|
func.sum(Inventory.quantity * Journal.debit),
|
|
|
|
func.sum(Inventory.amount * Journal.debit),
|
|
|
|
)
|
2019-04-15 05:32:54 +00:00
|
|
|
.join(Inventory.voucher)
|
|
|
|
.join(Voucher.journals)
|
2019-04-06 04:13:12 +00:00
|
|
|
.filter(Voucher.id == Inventory.voucher_id)
|
|
|
|
.filter(Voucher.id == Journal.voucher_id)
|
|
|
|
.filter(Inventory.product_id == product_id)
|
|
|
|
.filter(Journal.cost_centre_id == CostCentre.cost_centre_purchase())
|
2020-05-14 08:08:13 +00:00
|
|
|
.filter(Voucher.date < start_date)
|
2019-04-06 04:13:12 +00:00
|
|
|
.one()
|
|
|
|
)
|
2012-05-01 21:40:01 +00:00
|
|
|
|
2012-10-16 09:32:36 +00:00
|
|
|
if quantity and quantity > 0:
|
2016-12-24 11:41:01 +00:00
|
|
|
debit_quantity = quantity
|
|
|
|
debit_amount = amount
|
2012-10-17 18:48:20 +00:00
|
|
|
else:
|
2020-05-14 08:08:13 +00:00
|
|
|
debit_quantity = None
|
|
|
|
debit_amount = None
|
2012-05-01 21:40:01 +00:00
|
|
|
|
|
|
|
if quantity is None:
|
|
|
|
quantity = 0
|
|
|
|
amount = 0
|
2012-10-16 09:32:36 +00:00
|
|
|
|
2019-04-06 04:13:12 +00:00
|
|
|
return (
|
|
|
|
quantity,
|
|
|
|
amount,
|
|
|
|
{
|
2020-05-14 08:08:13 +00:00
|
|
|
"id": None,
|
|
|
|
"date": start_date.strftime("%d-%b-%Y"),
|
2019-04-06 04:13:12 +00:00
|
|
|
"name": "Opening Balance",
|
2020-05-14 08:08:13 +00:00
|
|
|
"url": [],
|
2019-04-06 04:13:12 +00:00
|
|
|
"type": "Opening Balance",
|
|
|
|
"narration": "",
|
|
|
|
"posted": True,
|
|
|
|
"debitQuantity": debit_quantity,
|
|
|
|
"debitAmount": debit_amount,
|
|
|
|
"creditQuantity": 0,
|
|
|
|
"creditAmount": 0,
|
|
|
|
"runningQuantity": quantity,
|
|
|
|
"runningAmount": amount,
|
|
|
|
},
|
|
|
|
)
|