Product Ledger Done!!
This commit is contained in:
@ -1,4 +1,4 @@
|
||||
import datetime
|
||||
from datetime import datetime, date
|
||||
import uuid
|
||||
|
||||
from fastapi import APIRouter, Depends, Security, Request
|
||||
@ -10,6 +10,7 @@ from ...core.security import get_current_active_user as get_user
|
||||
from ...db.session import SessionLocal
|
||||
from brewman.models.master import Product, CostCentre
|
||||
from brewman.models.voucher import Voucher, Journal, VoucherType, Inventory
|
||||
import brewman.schemas.reports as schemas
|
||||
from ...core.session import (
|
||||
set_period,
|
||||
get_start_date,
|
||||
@ -28,10 +29,9 @@ def get_db() -> Session:
|
||||
db.close()
|
||||
|
||||
|
||||
@router.get("")
|
||||
@router.get("", response_model=schemas.ProductLedger)
|
||||
def show_blank(
|
||||
request: Request,
|
||||
user: UserToken = Security(get_user, scopes=["product-ledger"]),
|
||||
request: Request, user: UserToken = Security(get_user, scopes=["product-ledger"]),
|
||||
):
|
||||
return {
|
||||
"startDate": get_start_date(request.session),
|
||||
@ -41,7 +41,7 @@ def show_blank(
|
||||
}
|
||||
|
||||
|
||||
@router.get("/{id}")
|
||||
@router.get("/{id_}", response_model=schemas.ProductLedger)
|
||||
def show_data(
|
||||
id_: uuid.UUID,
|
||||
request: Request,
|
||||
@ -53,7 +53,12 @@ def show_data(
|
||||
product = db.query(Product).filter(Product.id == id_).first()
|
||||
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)
|
||||
body = build_report(product.id, start_date, finish_date, db)
|
||||
body = build_report(
|
||||
product.id,
|
||||
datetime.strptime(start_date, "%d-%b-%Y"),
|
||||
datetime.strptime(finish_date, "%d-%b-%Y"),
|
||||
db,
|
||||
)
|
||||
set_period(start_date, finish_date, request.session)
|
||||
return {
|
||||
"startDate": start_date,
|
||||
@ -63,7 +68,9 @@ def show_data(
|
||||
}
|
||||
|
||||
|
||||
def build_report(product_id, start_date, finish_date, db):
|
||||
def build_report(
|
||||
product_id: uuid.UUID, start_date: date, finish_date: date, db: Session
|
||||
):
|
||||
body = []
|
||||
running_total_q, running_total_a, opening = opening_balance(
|
||||
product_id, start_date, db
|
||||
@ -80,8 +87,8 @@ def build_report(product_id, start_date, finish_date, db):
|
||||
.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"))
|
||||
.filter(Voucher.date >= start_date)
|
||||
.filter(Voucher.date <= finish_date)
|
||||
.order_by(Voucher.date)
|
||||
.order_by(Voucher.last_edit_date)
|
||||
.all()
|
||||
@ -94,10 +101,10 @@ def build_report(product_id, start_date, finish_date, db):
|
||||
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
|
||||
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
|
||||
|
||||
running_total_q += row.Inventory.quantity * journal_debit
|
||||
running_total_a += row.Inventory.amount * journal_debit
|
||||
@ -107,6 +114,11 @@ def build_report(product_id, start_date, finish_date, db):
|
||||
"id": row.Voucher.id,
|
||||
"date": row.Voucher.date.strftime("%d-%b-%Y"),
|
||||
"name": name,
|
||||
"url": [
|
||||
"/",
|
||||
VoucherType.by_id(row.Voucher.type).name.replace(" ", "-").lower(),
|
||||
str(row.Voucher.id),
|
||||
],
|
||||
"type": VoucherType.by_id(row.Voucher.type).name,
|
||||
"narration": row.Voucher.narration,
|
||||
"posted": row.Voucher.posted
|
||||
@ -123,7 +135,7 @@ def build_report(product_id, start_date, finish_date, db):
|
||||
return body
|
||||
|
||||
|
||||
def opening_balance(product_id, start_date, db):
|
||||
def opening_balance(product_id: uuid.UUID, start_date: date, db: Session):
|
||||
quantity, amount = (
|
||||
db.query(
|
||||
func.sum(Inventory.quantity * Journal.debit),
|
||||
@ -135,7 +147,7 @@ def opening_balance(product_id, start_date, db):
|
||||
.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 < start_date)
|
||||
.one()
|
||||
)
|
||||
|
||||
@ -143,8 +155,8 @@ def opening_balance(product_id, start_date, db):
|
||||
debit_quantity = quantity
|
||||
debit_amount = amount
|
||||
else:
|
||||
debit_quantity = ""
|
||||
debit_amount = ""
|
||||
debit_quantity = None
|
||||
debit_amount = None
|
||||
|
||||
if quantity is None:
|
||||
quantity = 0
|
||||
@ -154,8 +166,10 @@ def opening_balance(product_id, start_date, db):
|
||||
quantity,
|
||||
amount,
|
||||
{
|
||||
"date": start_date,
|
||||
"id": None,
|
||||
"date": start_date.strftime("%d-%b-%Y"),
|
||||
"name": "Opening Balance",
|
||||
"url": [],
|
||||
"type": "Opening Balance",
|
||||
"narration": "",
|
||||
"posted": True,
|
||||
|
||||
@ -40,6 +40,14 @@ class ProductGroupLink(BaseModel):
|
||||
fields = {'id_': 'id'}
|
||||
|
||||
|
||||
class ProductLink(BaseModel):
|
||||
id_: uuid.UUID = Field(...)
|
||||
name: Optional[str]
|
||||
|
||||
class Config:
|
||||
fields = {'id_': 'id'}
|
||||
|
||||
|
||||
class ProductIn(BaseModel):
|
||||
name: str = Field(..., min_length=1)
|
||||
units: str
|
||||
|
||||
@ -4,7 +4,7 @@ from typing import List, Optional
|
||||
from datetime import datetime, date
|
||||
from pydantic import BaseModel, Field, validator
|
||||
|
||||
from brewman.schemas.master import AccountLink
|
||||
from brewman.schemas.master import AccountLink, ProductLink
|
||||
|
||||
|
||||
def to_camel(string: str) -> str:
|
||||
@ -270,3 +270,61 @@ class NetTransactions(BaseModel):
|
||||
value,
|
||||
"%d-%b-%Y"
|
||||
).date()
|
||||
|
||||
|
||||
class ProductLedgerItem(BaseModel):
|
||||
id_: Optional[uuid.UUID]
|
||||
date_: date
|
||||
name: str
|
||||
url: List[str]
|
||||
type_: str
|
||||
narration: str
|
||||
debit_quantity: Optional[Decimal] = Field(multiple_of=0.01)
|
||||
debit_amount: Optional[Decimal] = Field(multiple_of=0.01)
|
||||
credit_quantity: Optional[Decimal] = Field(multiple_of=0.01)
|
||||
credit_amount: Optional[Decimal] = Field(multiple_of=0.01)
|
||||
running_quantity: Decimal = Field(multiple_of=0.01)
|
||||
running_amount: Decimal = Field(multiple_of=0.01)
|
||||
posted: bool
|
||||
|
||||
@validator("date_", pre=True)
|
||||
def parse_date(cls, value):
|
||||
return datetime.strptime(
|
||||
value,
|
||||
"%d-%b-%Y"
|
||||
).date()
|
||||
|
||||
class Config:
|
||||
anystr_strip_whitespace = True
|
||||
alias_generator = to_camel
|
||||
json_encoders = {
|
||||
date: lambda v: v.strftime("%d-%b-%Y")
|
||||
}
|
||||
|
||||
|
||||
class ProductLedger(BaseModel):
|
||||
start_date: date
|
||||
finish_date: date
|
||||
product: Optional[ProductLink]
|
||||
body: List[ProductLedgerItem]
|
||||
|
||||
class Config:
|
||||
anystr_strip_whitespace = True
|
||||
alias_generator = to_camel
|
||||
json_encoders = {
|
||||
date: lambda v: v.strftime("%d-%b-%Y")
|
||||
}
|
||||
|
||||
@validator("start_date", pre=True)
|
||||
def parse_start_date(cls, value):
|
||||
return datetime.strptime(
|
||||
value,
|
||||
"%d-%b-%Y"
|
||||
).date()
|
||||
|
||||
@validator("finish_date", pre=True)
|
||||
def parse_finish_date(cls, value):
|
||||
return datetime.strptime(
|
||||
value,
|
||||
"%d-%b-%Y"
|
||||
).date()
|
||||
|
||||
Reference in New Issue
Block a user