Files
brewman/brewman/routers/reports/product_ledger.py
T
tanshu fe74ef44bf Moving to FastAPI
Config is not properly working with .env file as of now
Cost Centre is mostly working, going to work on Accounts now
2020-05-08 10:22:25 +05:30

154 lines
5.1 KiB
Python

import datetime
from sqlalchemy.orm import joinedload
from sqlalchemy.sql.expression import func
from brewman.models.master import Product, CostCentre
from brewman.models.validation_exception import ValidationError
from brewman.models.voucher import Voucher, Journal, VoucherType, Inventory
from brewman.routers import to_uuid
from brewman.routers.services.session import (
session_period_set,
session_period_start,
session_period_finish,
)
from brewman.routers.services.voucher import get_edit_url
from fastapi import APIRouter
router = APIRouter()
@router.get("/api/product-ledger") # "Product Ledger"
def show_blank(request):
return {
"startDate": session_period_start(request),
"finishDate": session_period_finish(request),
"product": None,
"body": [],
}
@router.get("/api/product-ledger/{id}") # "Product Ledger"
def show_data(request):
id_ = to_uuid(request.matchdict["id"])
if id_ is None:
raise ValidationError("Invalid Product")
product = request.dbsession.query(Product).filter(Product.id == id_).first()
start_date = request.GET.get("s", session_period_start(request))
finish_date = request.GET.get("f", session_period_finish(request))
body = build_report(product.id, start_date, finish_date, request)
session_period_set(start_date, finish_date, request)
return {
"startDate": start_date,
"finishDate": finish_date,
"product": {"id": product.id, "name": product.name},
"body": body,
}
def build_report(product_id, start_date, finish_date, request):
body = []
running_total_q, running_total_a, opening = opening_balance(
product_id, start_date, request.dbsession
)
body.append(opening)
query = (
request.dbsession.query(Voucher, Inventory, Journal)
.options(
joinedload(Journal.account, innerjoin=True),
joinedload(Journal.cost_centre, innerjoin=True),
)
.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())
.filter(Voucher.date >= datetime.datetime.strptime(start_date, "%d-%b-%Y"))
.filter(Voucher.date <= datetime.datetime.strptime(finish_date, "%d-%b-%Y"))
.order_by(Voucher.date)
.order_by(Voucher.last_edit_date)
.all()
)
for row in query:
journal_debit = row.Journal.debit * -1
name = (
row.Journal.cost_centre.name
if row.Voucher.type == VoucherType.by_name("Issue").id
else row.Journal.account.name
)
debit_q = row.Inventory.quantity if journal_debit == 1 else 0
debit_a = row.Inventory.amount if journal_debit == 1 else 0
credit_q = row.Inventory.quantity if journal_debit != 1 else 0
credit_a = row.Inventory.amount if journal_debit != 1 else 0
running_total_q += row.Inventory.quantity * journal_debit
running_total_a += row.Inventory.amount * journal_debit
body.append(
{
"id": row.Voucher.id,
"date": row.Voucher.date.strftime("%d-%b-%Y"),
"name": name,
"url": get_edit_url(row.Voucher, request),
"type": VoucherType.by_id(row.Voucher.type).name,
"narration": row.Voucher.narration,
"posted": row.Voucher.posted
or VoucherType.by_id(row.Voucher.type).name == "Issue",
"debitQuantity": debit_q,
"debitAmount": debit_a,
"creditQuantity": credit_q,
"creditAmount": credit_a,
"runningQuantity": running_total_q,
"runningAmount": running_total_a,
}
)
return body
def opening_balance(product_id, start_date, dbsession):
quantity, amount = (
dbsession.query(
func.sum(Inventory.quantity * Journal.debit),
func.sum(Inventory.amount * Journal.debit),
)
.join(Inventory.voucher)
.join(Voucher.journals)
.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())
.filter(Voucher.date < datetime.datetime.strptime(start_date, "%d-%b-%Y"))
.one()
)
if quantity and quantity > 0:
debit_quantity = quantity
debit_amount = amount
else:
debit_quantity = ""
debit_amount = ""
if quantity is None:
quantity = 0
amount = 0
return (
quantity,
amount,
{
"date": start_date,
"name": "Opening Balance",
"type": "Opening Balance",
"narration": "",
"posted": True,
"debitQuantity": debit_quantity,
"debitAmount": debit_amount,
"creditQuantity": 0,
"creditAmount": 0,
"runningQuantity": quantity,
"runningAmount": amount,
},
)