Added custom serializer to Decimal for all Models to output as number and not string.

This should mitigate all hacks earlier and reverted the earlier hacks.
This commit is contained in:
2023-08-16 22:29:22 +05:30
parent c26f433182
commit b1ca758e9d
35 changed files with 142 additions and 154 deletions

View File

@ -1,3 +1,13 @@
from decimal import Decimal
from typing import Annotated
from pydantic import PlainSerializer
def to_camel(string: str) -> str:
first, *others = string.split("_")
return "".join([first] + [word.capitalize() for word in others])
# Custom serializer to serialize decimal as float and not as string as is the default behaviour in Pydantic V2
Daf = Annotated[Decimal, PlainSerializer(lambda x: float(x), return_type=float, when_used="unless-none")]

View File

@ -1,11 +1,11 @@
from decimal import Decimal
from brewman.schemas import to_camel
from pydantic import BaseModel, ConfigDict
from . import Daf
class AttendanceType(BaseModel):
id_: int
name: str | None = None
value: Decimal | None = None
value: Daf | None = None
model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True)

View File

@ -1,9 +1,9 @@
from decimal import Decimal
from pydantic import BaseModel
from . import Daf
# TODO: Add config
class AccountBalance(BaseModel):
date_: Decimal
total: Decimal
date_: Daf
total: Daf

View File

@ -1,5 +1,4 @@
from datetime import date, datetime
from decimal import Decimal
from pydantic import (
BaseModel,
@ -9,14 +8,14 @@ from pydantic import (
field_validator,
)
from . import to_camel
from . import Daf, to_camel
class BalanceSheetItem(BaseModel):
name: str | None = None
group: str | None = None
amount: Decimal | None = None
sub_amount: Decimal | None = None
amount: Daf | None = None
sub_amount: Daf | None = None
order: int
model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True)

View File

@ -1,18 +1,18 @@
import uuid
from decimal import Decimal
from brewman.schemas import to_camel
from brewman.schemas.product import ProductLink
from pydantic import BaseModel, ConfigDict
from . import Daf
class Batch(BaseModel):
id_: uuid.UUID | None = None
name: str
sku: ProductLink
quantity_remaining: Decimal
rate: Decimal
tax: Decimal
discount: Decimal
quantity_remaining: Daf
rate: Daf
tax: Daf
discount: Daf
model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True)

View File

@ -1,7 +1,6 @@
import uuid
from datetime import date, datetime
from decimal import Decimal
from pydantic import (
BaseModel,
@ -11,15 +10,15 @@ from pydantic import (
field_validator,
)
from . import to_camel
from . import Daf, to_camel
class BatchIntegrityItem(BaseModel):
date_: date
type_: str
url: list[str]
quantity: Decimal
price: Decimal
quantity: Daf
price: Daf
model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True)
@field_validator("date_", mode="before")
@ -38,9 +37,9 @@ class BatchIntegrity(BaseModel):
id_: uuid.UUID
product: str
date_: date
price: Decimal
showing: Decimal
actual: Decimal
price: Daf
showing: Daf
actual: Daf
details: list[BatchIntegrityItem]
model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True)

View File

@ -1,5 +1,4 @@
from datetime import date, datetime
from decimal import Decimal
from pydantic import (
BaseModel,
@ -9,13 +8,13 @@ from pydantic import (
field_validator,
)
from . import to_camel
from . import Daf, to_camel
class CashFlowItem(BaseModel):
name: str
url: list[str] | None = None
amount: Decimal
amount: Daf
model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True)

View File

@ -11,7 +11,7 @@ from pydantic import (
field_validator,
)
from . import to_camel
from . import Daf, to_camel
from .cost_centre import CostCentreLink
from .product import ProductLink
from .user_link import UserLink
@ -21,29 +21,29 @@ class ClosingStockItem(BaseModel):
id_: uuid.UUID | None = None
product: ProductLink
group: str
quantity: Decimal
amount: Decimal
physical: Decimal
quantity: Daf
amount: Daf
physical: Daf
cost_centre: CostCentreLink | None = None
model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True)
@field_validator("quantity", mode="before")
@classmethod
def parse_quantity(cls, value: Decimal | float) -> Decimal:
def parse_quantity(cls, value: Daf | float) -> Daf:
if isinstance(value, float):
return Decimal(round(value, 2))
return round(value, 2)
@field_validator("amount", mode="before")
@classmethod
def parse_amount(cls, value: Decimal | float) -> Decimal:
def parse_amount(cls, value: Daf | float) -> Daf:
if isinstance(value, float):
return Decimal(round(value, 2))
return round(value, 2)
@field_validator("physical", mode="before")
@classmethod
def parse_physical(cls, value: Decimal | float) -> Decimal:
def parse_physical(cls, value: Daf | float) -> Daf:
if isinstance(value, float):
return Decimal(round(value, 2))
return round(value, 2)

View File

@ -1,7 +1,6 @@
import uuid
from datetime import date, datetime
from decimal import Decimal
from pydantic import (
BaseModel,
@ -11,7 +10,7 @@ from pydantic import (
field_validator,
)
from . import to_camel
from . import Daf, to_camel
class DaybookItem(BaseModel):
@ -21,9 +20,9 @@ class DaybookItem(BaseModel):
type_: str
narration: str
debit_text: str | None = None
debit_amount: Decimal | None = None
debit_amount: Daf | None = None
credit_text: str | None = None
credit_amount: Decimal | None = None
credit_amount: Daf | None = None
posted: bool
model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True)

View File

@ -1,7 +1,6 @@
import uuid
from datetime import date, datetime
from decimal import Decimal
from pydantic import (
BaseModel,
@ -13,7 +12,7 @@ from pydantic import (
model_validator,
)
from . import to_camel
from . import Daf, to_camel
from .account import AccountBase
from .cost_centre import CostCentreLink
@ -21,7 +20,7 @@ from .cost_centre import CostCentreLink
class EmployeeIn(AccountBase):
designation: str
salary: int = Field(ge=0)
points: Decimal = Field(ge=0, lt=1000)
points: Daf = Field(ge=0, lt=1000)
joining_date: date
leaving_date: date | None = None
model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True)

View File

@ -1,7 +1,6 @@
import uuid
from datetime import date, datetime
from decimal import Decimal
from pydantic import (
BaseModel,
@ -11,7 +10,7 @@ from pydantic import (
field_validator,
)
from . import to_camel
from . import Daf, to_camel
from .user_link import UserLink
@ -24,7 +23,7 @@ class Entries(BaseModel):
narration: str
debit_names: list[str]
credit_names: list[str]
amount: Decimal
amount: Daf
creation_date: datetime
last_edit_date: datetime
user: UserLink

View File

@ -1,16 +1,16 @@
import uuid
from decimal import Decimal
from brewman.schemas import to_camel
from pydantic import BaseModel, ConfigDict, Field
from . import Daf
class Incentive(BaseModel):
employee_id: uuid.UUID
name: str
designation: str
department: str
days_worked: Decimal = Field(ge=0)
points: Decimal = Field(ge=0)
days_worked: Daf = Field(ge=0)
points: Daf = Field(ge=0)
model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True)

View File

@ -2,12 +2,11 @@ import json
import uuid
from datetime import date, datetime
from decimal import Decimal
from fastapi import Form
from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator
from . import to_camel
from . import Daf, to_camel
from .account import AccountLink
from .cost_centre import CostCentreLink
from .employee_benefit import EmployeeBenefit
@ -109,5 +108,5 @@ class IncentiveEmployee(BaseModel):
employee_id: uuid.UUID
cost_centre_id: uuid.UUID
journal: Journal | None = None
days_worked: Decimal = Field(ge=0)
points: Decimal = Field(ge=0)
days_worked: Daf = Field(ge=0)
points: Daf = Field(ge=0)

View File

@ -1,18 +1,18 @@
import uuid
from decimal import Decimal
from brewman.schemas import to_camel
from brewman.schemas.batch import Batch
from pydantic import BaseModel, ConfigDict, Field
from . import Daf
class Inventory(BaseModel):
id_: uuid.UUID | None = None
batch: Batch
quantity: Decimal = Field(ge=0)
rate: Decimal = Field(ge=0)
tax: Decimal = Field(ge=0, le=5)
discount: Decimal = Field(ge=0, le=1)
amount: Decimal | None = None
quantity: Daf = Field(ge=0)
rate: Daf = Field(ge=0)
tax: Daf = Field(ge=0, le=5)
discount: Daf = Field(ge=0, le=1)
amount: Daf | None = None
model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True)

View File

@ -1,14 +1,14 @@
import uuid
from decimal import Decimal
from brewman.schemas import to_camel
from pydantic import BaseModel, ConfigDict
from . import Daf
class IssueGridItem(BaseModel):
id_: uuid.UUID
amount: Decimal
amount: Daf
source: str
destination: str
model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True)

View File

@ -1,17 +1,17 @@
import uuid
from decimal import Decimal
from brewman.schemas import to_camel
from brewman.schemas.account import AccountLink
from brewman.schemas.cost_centre import CostCentreLink
from pydantic import BaseModel, ConfigDict, Field
from . import Daf
class Journal(BaseModel):
id_: uuid.UUID | None = None
debit: int = Field(ge=-1, le=1)
amount: Decimal = Field(ge=0)
amount: Daf = Field(ge=0)
account: AccountLink
cost_centre: CostCentreLink | None = None
model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True)

View File

@ -1,7 +1,6 @@
import uuid
from datetime import date, datetime
from decimal import Decimal
from pydantic import (
BaseModel,
@ -11,7 +10,7 @@ from pydantic import (
field_validator,
)
from . import to_camel
from . import Daf, to_camel
from .account import AccountLink
@ -22,8 +21,8 @@ class LedgerItem(BaseModel):
url: list[str]
type_: str
narration: str
debit: Decimal
credit: Decimal
debit: Daf
credit: Daf
posted: bool
model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True)

View File

@ -1,5 +1,4 @@
from datetime import date, datetime
from decimal import Decimal
from pydantic import (
BaseModel,
@ -9,14 +8,14 @@ from pydantic import (
field_validator,
)
from . import to_camel
from . import Daf, to_camel
class NetTransactionsItem(BaseModel):
type_: str
name: str
debit: Decimal | None = None
credit: Decimal | None = None
debit: Daf | None = None
credit: Daf | None = None
model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True)

View File

@ -1,5 +1,4 @@
from datetime import date, datetime
from decimal import Decimal
from pydantic import (
BaseModel,
@ -9,7 +8,7 @@ from pydantic import (
field_validator,
)
from . import to_camel
from . import Daf, to_camel
class NonContractPurchase(BaseModel):
@ -17,8 +16,8 @@ class NonContractPurchase(BaseModel):
vendor: str
product: str
url: list[str]
contract_price: Decimal
purchase_price: Decimal
contract_price: Daf
purchase_price: Daf
model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True)
@field_validator("date_", mode="before")

View File

@ -1,7 +1,6 @@
import uuid
from datetime import date, datetime
from decimal import Decimal
from pydantic import (
BaseModel,
@ -11,7 +10,7 @@ from pydantic import (
field_validator,
)
from . import to_camel
from . import Daf, to_camel
from .product import ProductLink
@ -22,14 +21,14 @@ class ProductLedgerItem(BaseModel):
url: list[str]
type_: str
narration: str
debit_quantity: Decimal | None = None
debit_amount: Decimal | None = None
debit_quantity: Daf | None = None
debit_amount: Daf | None = None
debit_unit: str | None = None
credit_quantity: Decimal | None = None
credit_amount: Decimal | None = None
credit_quantity: Daf | None = None
credit_amount: Daf | None = None
credit_unit: str | None = None
running_quantity: Decimal
running_amount: Decimal
running_quantity: Daf
running_amount: Daf
posted: bool
model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True)

View File

@ -1,16 +1,16 @@
import uuid
from decimal import Decimal
from brewman.schemas import to_camel
from pydantic import BaseModel, ConfigDict, Field
from . import Daf
class ProductSku(BaseModel):
id_: uuid.UUID = Field(...)
name: str
fraction_units: str
cost_price: Decimal
sale_price: Decimal
cost_price: Daf
sale_price: Daf
is_rate_contracted: bool
model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True)

View File

@ -1,5 +1,4 @@
from datetime import date, datetime
from decimal import Decimal
from pydantic import (
BaseModel,
@ -9,14 +8,14 @@ from pydantic import (
field_validator,
)
from . import to_camel
from . import Daf, to_camel
class ProfitLossItem(BaseModel):
group: str | None = None
name: str | None = None
amount: Decimal | None = None
total: Decimal | None = None
amount: Daf | None = None
total: Daf | None = None
order: int
model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True)

View File

@ -1,5 +1,4 @@
from datetime import date, datetime
from decimal import Decimal
from pydantic import (
BaseModel,
@ -9,7 +8,7 @@ from pydantic import (
field_validator,
)
from . import to_camel
from . import Daf, to_camel
class PurchaseEntriesItem(BaseModel):
@ -17,11 +16,11 @@ class PurchaseEntriesItem(BaseModel):
url: list[str]
supplier: str
product: str
quantity: Decimal
rate: Decimal
tax: Decimal
discount: Decimal
amount: Decimal
quantity: Daf
rate: Daf
tax: Daf
discount: Daf
amount: Daf
@field_validator("date_", mode="before")
@classmethod

View File

@ -1,5 +1,4 @@
from datetime import date, datetime
from decimal import Decimal
from pydantic import (
BaseModel,
@ -9,14 +8,14 @@ from pydantic import (
field_validator,
)
from . import to_camel
from . import Daf, to_camel
class PurchasesItem(BaseModel):
name: str
quantity: Decimal
rate: Decimal
amount: Decimal
quantity: Daf
rate: Daf
amount: Daf
url: list[str]
model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True)

View File

@ -1,14 +1,14 @@
import uuid
from decimal import Decimal
from brewman.schemas import to_camel
from brewman.schemas.product import ProductLink
from pydantic import BaseModel, ConfigDict, Field
from . import Daf
class RateContractItem(BaseModel):
id_: uuid.UUID | None = None
sku: ProductLink
price: Decimal = Field(ge=0)
price: Daf = Field(ge=0)
model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True)

View File

@ -1,7 +1,6 @@
import uuid
from datetime import date, datetime
from decimal import Decimal
from pydantic import (
BaseModel,
@ -11,20 +10,20 @@ from pydantic import (
field_validator,
)
from . import to_camel
from . import Daf, to_camel
class RawMaterialCostItem(BaseModel):
name: str | None = None
issue: Decimal | None = None
sale: Decimal | None = None
rmc: Decimal | None = None
issue: Daf | None = None
sale: Daf | None = None
rmc: Daf | None = None
url: list[str] | None = None
group: str | None = None
quantity: Decimal | None = None
net: Decimal | None = None
gross: Decimal | None = None
quantity: Daf | None = None
net: Daf | None = None
gross: Daf | None = None
order: int
heading: bool | None = None

View File

@ -1,7 +1,6 @@
import uuid
from datetime import date, datetime
from decimal import Decimal
from pydantic import (
BaseModel,
@ -11,7 +10,7 @@ from pydantic import (
field_validator,
)
from . import to_camel
from . import Daf, to_camel
from .product import ProductLink
from .recipe_item import RecipeItem
@ -23,7 +22,7 @@ class RecipeIn(BaseModel):
instructions: str
garnishing: str
plating: str
recipe_yield: Decimal
recipe_yield: Daf
notes: str
items: list[RecipeItem]

View File

@ -1,15 +1,15 @@
import uuid
from decimal import Decimal
from brewman.schemas import to_camel
from brewman.schemas.product import ProductLink
from pydantic import BaseModel, ConfigDict
from . import Daf
class RecipeItem(BaseModel):
id_: uuid.UUID | None = None
product: ProductLink
quantity: Decimal
quantity: Daf
description: str
model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True)

View File

@ -1,7 +1,6 @@
import uuid
from datetime import date, datetime
from decimal import Decimal
from pydantic import (
BaseModel,
@ -11,7 +10,7 @@ from pydantic import (
field_validator,
)
from . import to_camel
from . import Daf, to_camel
from .account import AccountLink
@ -22,8 +21,8 @@ class ReconcileItem(BaseModel):
url: list[str]
type_: str
narration: str
debit: Decimal
credit: Decimal
debit: Daf
credit: Daf
posted: bool
is_reconciled: bool
reconcile_date: date | None = None

View File

@ -1,17 +1,15 @@
import uuid
from decimal import Decimal
from pydantic import BaseModel, ConfigDict, Field
from . import to_camel
from . import Daf, to_camel
class StockKeepingUnit(BaseModel):
id_: uuid.UUID | None = None
units: str = Field(..., min_length=1)
fraction: Decimal = Field(ge=1, default=1)
product_yield: Decimal = Field(gt=0, le=1, default=1)
cost_price: Decimal = Field(ge=0, default=0)
sale_price: Decimal = Field(ge=0, default=0)
fraction: Daf = Field(ge=1, default=1)
product_yield: Daf = Field(gt=0, le=1, default=1)
cost_price: Daf = Field(ge=0, default=0)
sale_price: Daf = Field(ge=0, default=0)
model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True)

View File

@ -1,7 +1,6 @@
import uuid
from datetime import date, datetime
from decimal import Decimal
from pydantic import (
BaseModel,
@ -11,17 +10,17 @@ from pydantic import (
field_validator,
)
from . import to_camel
from . import Daf, to_camel
class StockMovementItem(BaseModel):
id_: uuid.UUID
group: str
name: str
opening: Decimal
purchase: Decimal
issue: Decimal
closing: Decimal
opening: Daf
purchase: Daf
issue: Daf
closing: Daf
url: list[str]
model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True)

View File

@ -1,5 +1,4 @@
from datetime import date, datetime
from decimal import Decimal
from pydantic import (
BaseModel,
@ -9,14 +8,14 @@ from pydantic import (
field_validator,
)
from . import to_camel
from . import Daf, to_camel
class TrialBalanceItem(BaseModel):
type_: str | None = None
name: str | None = None
debit: Decimal | None = None
credit: Decimal | None = None
debit: Daf | None = None
credit: Daf | None = None
model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True)

View File

@ -2,7 +2,6 @@ import json
import uuid
from datetime import date, datetime
from decimal import Decimal
from fastapi import Form
from pydantic import (
@ -13,7 +12,7 @@ from pydantic import (
field_validator,
)
from . import to_camel
from . import Daf, to_camel
from .account import AccountLink
from .batch import Batch # noqa: F401
from .cost_centre import CostCentreLink
@ -66,7 +65,7 @@ class Voucher(VoucherIn):
source: CostCentreLink | None = None
destination: CostCentreLink | None = None
incentives: list[Incentive]
incentive: Decimal | None = None
incentive: Daf | None = None
employee_benefits: list[EmployeeBenefit]
files: list[ImageUpload]
model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True)

View File

@ -193,10 +193,10 @@ export class IssueComponent implements OnInit, AfterViewInit, OnDestroy {
this.voucher.inventories.push(
new Inventory({
quantity,
rate: +this.batch.rate,
tax: +this.batch.tax,
discount: +this.batch.discount,
amount: quantity * +this.batch.rate * (1 + +this.batch.tax) * (1 - +this.batch.discount),
rate: this.batch.rate,
tax: this.batch.tax,
discount: this.batch.discount,
amount: quantity * this.batch.rate * (1 + this.batch.tax) * (1 - this.batch.discount),
batch: this.batch,
}),
);

View File

@ -95,13 +95,13 @@ export class LedgerComponent implements OnInit, AfterViewInit {
this.running = 0;
this.info.body.forEach((item) => {
if (item.type !== 'Opening Balance') {
this.debit += +item.debit;
this.credit += +item.credit;
this.debit += item.debit;
this.credit += item.credit;
if (item.posted) {
this.running += +item.debit - +item.credit;
this.running += item.debit - item.credit;
}
} else {
this.running += +item.debit - +item.credit;
this.running += item.debit - item.credit;
}
item.running = this.running;
});