diff --git a/brewman/.pre-commit-config.yaml b/brewman/.pre-commit-config.yaml index 911249e5..4fffe303 100644 --- a/brewman/.pre-commit-config.yaml +++ b/brewman/.pre-commit-config.yaml @@ -27,3 +27,11 @@ repos: - id: check-yaml - id: check-added-large-files - id: debug-statements + +- repo: https://github.com/astral-sh/ruff-pre-commit + # Ruff version. + rev: v0.0.280 + hooks: + - id: ruff + # To autofix, enable this + # args: [ --fix, --exit-non-zero-on-fix ] \ No newline at end of file diff --git a/brewman/alembic/versions/12262aadbc08_recipe_templates.py b/brewman/alembic/versions/12262aadbc08_recipe_templates.py index 1ead19e5..fdf4c2e9 100644 --- a/brewman/alembic/versions/12262aadbc08_recipe_templates.py +++ b/brewman/alembic/versions/12262aadbc08_recipe_templates.py @@ -7,7 +7,6 @@ Create Date: 2023-04-14 07:50:22.110724 """ from alembic import op import sqlalchemy as sa -from sqlalchemy.dialects import postgresql # revision identifiers, used by Alembic. revision = '12262aadbc08' diff --git a/brewman/brewman/core/config.py b/brewman/brewman/core/config.py index ead7858a..6d2c431a 100644 --- a/brewman/brewman/core/config.py +++ b/brewman/brewman/core/config.py @@ -1,9 +1,8 @@ import secrets -from typing import Any - from dotenv import load_dotenv -from pydantic import BaseSettings, PostgresDsn, validator +from pydantic import PostgresDsn, model_validator +from pydantic_settings import BaseSettings, SettingsConfigDict class Settings(BaseSettings): @@ -22,24 +21,22 @@ class Settings(BaseSettings): POSTGRES_DB: str = "" SQLALCHEMY_DATABASE_URI: str | None = None - @validator("SQLALCHEMY_DATABASE_URI", pre=True) - def assemble_db_connection(cls, v: str | None, values: dict[str, Any]) -> Any: - if isinstance(v, str): - return v - return PostgresDsn.build( + @model_validator(mode="after") + def assemble_db_connection(self) -> "Settings": + if isinstance(self.SQLALCHEMY_DATABASE_URI, str): + return self + self.SQLALCHEMY_DATABASE_URI = PostgresDsn.build( scheme="postgresql", - user=values.get("POSTGRES_USER"), - password=values.get("POSTGRES_PASSWORD"), - host=values.get("POSTGRES_SERVER"), - path=f"/{values.get('POSTGRES_DB') or ''}", + username=self.POSTGRES_USER, + password=self.POSTGRES_PASSWORD, + host=self.POSTGRES_SERVER, + path=f"/{self.POSTGRES_DB or ''}", ) + return self ALEMBIC_LOG_LEVEL: str = "INFO" ALEMBIC_SQLALCHEMY_LOG_LEVEL: str = "WARN" - - class Config: - case_sensitive = True - env_file = ".env" + model_config = SettingsConfigDict(case_sensitive=True, env_file=".env") load_dotenv() diff --git a/brewman/brewman/core/security.py b/brewman/brewman/core/security.py index ccc69a3e..22609fd7 100644 --- a/brewman/brewman/core/security.py +++ b/brewman/brewman/core/security.py @@ -38,7 +38,7 @@ def f7(seq): return [x for x in seq if not (x in seen or seen_add(x))] -def create_access_token(*, data: dict, expires_delta: timedelta = None): +def create_access_token(*, data: dict, expires_delta: timedelta | None = None) -> str: to_encode = data.copy() if expires_delta: expire = datetime.utcnow() + expires_delta @@ -92,7 +92,7 @@ async def get_current_user( ) try: payload = jwt.decode(token, settings.SECRET_KEY, algorithms=[settings.ALGORITHM]) - username: str = payload.get("sub") + username: str = payload.get("sub") or "" if username is None: raise credentials_exception token_scopes = payload.get("scopes", []) diff --git a/brewman/brewman/core/session.py b/brewman/brewman/core/session.py index 244e8831..5d69c787 100644 --- a/brewman/brewman/core/session.py +++ b/brewman/brewman/core/session.py @@ -23,7 +23,7 @@ def get_finish_date(session: dict) -> str: return session["finish"] # type: ignore[no-any-return] -def set_period(start: str | date, finish: str | date, session: dict) -> None: +def set_period(start: str | date | None, finish: str | date | None, session: dict) -> None: if start is not None: session["start"] = start if isinstance(start, str) else start.strftime("%d-%b-%Y") if finish is not None: diff --git a/brewman/brewman/main.py b/brewman/brewman/main.py index e1bd64a7..5d5e9922 100644 --- a/brewman/brewman/main.py +++ b/brewman/brewman/main.py @@ -132,5 +132,5 @@ app.include_router(db_integrity.router, prefix="/api/db-integrity", tags=["manag app.include_router(rebase.router, prefix="/api/rebase", tags=["management"]) -def init(): +def init() -> None: uvicorn.run(app, host=settings.HOST, port=settings.PORT) diff --git a/brewman/brewman/models/account_base.py b/brewman/brewman/models/account_base.py index 47983a94..19fa31ce 100644 --- a/brewman/brewman/models/account_base.py +++ b/brewman/brewman/models/account_base.py @@ -99,15 +99,15 @@ class AccountBase: @classmethod def cash_in_hand(cls) -> AccountLink: - return AccountLink(id=uuid.UUID("ed2341bb-80b8-9649-90db-f9aaca183bb3"), name="Cash in Hand") + return AccountLink(id_=uuid.UUID("ed2341bb-80b8-9649-90db-f9aaca183bb3"), name="Cash in Hand") @classmethod def local_purchase(cls) -> AccountLink: - return AccountLink(id=uuid.UUID("d2b75912-505f-2548-9093-466dfff6a0f9"), name="Local Purchase") + return AccountLink(id_=uuid.UUID("d2b75912-505f-2548-9093-466dfff6a0f9"), name="Local Purchase") @classmethod - def salary(cls) -> AccountLink: - return AccountLink(id=uuid.UUID("5c2b54d0-c174-004d-a0d5-92cdaadcefa7"), name="Staff Salary") + def salary_acc(cls) -> AccountLink: + return AccountLink(id_=uuid.UUID("5c2b54d0-c174-004d-a0d5-92cdaadcefa7"), name="Staff Salary") @classmethod def salary_id(cls) -> uuid.UUID: @@ -115,7 +115,7 @@ class AccountBase: @classmethod def incentive(cls) -> AccountLink: - return AccountLink(id=uuid.UUID("b7eff754-e8ba-e047-ab06-9132c15c7640"), name="Incentives") + return AccountLink(id_=uuid.UUID("b7eff754-e8ba-e047-ab06-9132c15c7640"), name="Incentives") @classmethod def incentive_id(cls) -> uuid.UUID: diff --git a/brewman/brewman/models/attendance.py b/brewman/brewman/models/attendance.py index 7dbbaf53..314a014a 100644 --- a/brewman/brewman/models/attendance.py +++ b/brewman/brewman/models/attendance.py @@ -1,6 +1,6 @@ -import datetime import uuid +from datetime import date, datetime from decimal import Decimal from typing import TYPE_CHECKING @@ -32,10 +32,10 @@ class Attendance: __tablename__ = "attendances" id: Mapped[uuid.UUID] = mapped_column(Uuid, primary_key=True, insert_default=uuid.uuid4) employee_id: Mapped[uuid.UUID] = mapped_column(Uuid, ForeignKey("employees.id"), nullable=False) - date: Mapped[datetime.date] = mapped_column(Date, nullable=False) + date_: Mapped[date] = mapped_column("date", Date, nullable=False) attendance_type: Mapped[int] = mapped_column(Integer, nullable=False) amount: Mapped[Decimal] = mapped_column(Numeric(precision=5, scale=2), nullable=False) - creation_date: Mapped[datetime.datetime] = mapped_column(DateTime(), nullable=False) + creation_date: Mapped[datetime] = mapped_column(DateTime(), nullable=False) user_id: Mapped[uuid.UUID] = mapped_column(Uuid, ForeignKey("users.id"), nullable=False) is_valid: Mapped[bool] = mapped_column(Boolean, nullable=False) @@ -54,20 +54,20 @@ class Attendance: def __init__( self, employee_id: uuid.UUID, - date: datetime.date, + date_: date, attendance_type: int, user_id: uuid.UUID, amount: Decimal = Decimal(0), - creation_date: datetime.datetime | None = None, + creation_date: datetime | None = None, is_valid: bool = True, id_: uuid.UUID | None = None, ): self.employee_id = employee_id - self.date = date + self.date_ = date_ self.attendance_type = attendance_type self.user_id = user_id self.amount = amount - self.creation_date = creation_date or datetime.datetime.utcnow() + self.creation_date = creation_date or datetime.utcnow() self.is_valid = is_valid if id_ is not None: self.id = id_ @@ -76,7 +76,7 @@ class Attendance: old = ( db.execute( select(Attendance) - .filter(Attendance.date == self.date) + .filter(Attendance.date_ == self.date_) .filter(Attendance.employee_id == self.employee_id) .filter(Attendance.is_valid == True) # noqa: E712 ) diff --git a/brewman/brewman/models/cost_centre.py b/brewman/brewman/models/cost_centre.py index 6b732f64..36bd6bd8 100644 --- a/brewman/brewman/models/cost_centre.py +++ b/brewman/brewman/models/cost_centre.py @@ -51,4 +51,4 @@ class CostCentre: @classmethod def overall(cls) -> CostCentreLink: - return CostCentreLink(id=uuid.UUID("36f59436-522a-0746-ae94-e0f746bf6c0d"), name="Overall") + return CostCentreLink(id_=uuid.UUID("36f59436-522a-0746-ae94-e0f746bf6c0d"), name="Overall") diff --git a/brewman/brewman/models/fingerprint.py b/brewman/brewman/models/fingerprint.py index 22408635..2634c1d2 100644 --- a/brewman/brewman/models/fingerprint.py +++ b/brewman/brewman/models/fingerprint.py @@ -19,12 +19,12 @@ class Fingerprint: id: Mapped[uuid.UUID] = mapped_column(Uuid, primary_key=True, insert_default=uuid.uuid4) employee_id: Mapped[uuid.UUID] = mapped_column(Uuid, ForeignKey("employees.id"), nullable=False) - date: Mapped[datetime] = mapped_column(DateTime, nullable=False) + date_: Mapped[datetime] = mapped_column(DateTime, nullable=False) employee: Mapped["Employee"] = relationship("Employee", back_populates="fingerprints") - def __init__(self, employee_id: uuid.UUID, date: datetime, id_: uuid.UUID | None = None) -> None: + def __init__(self, employee_id: uuid.UUID, date_: datetime, id_: uuid.UUID | None = None) -> None: self.employee_id = employee_id - self.date = date + self.date = date_ if id_ is not None: self.id = id_ diff --git a/brewman/brewman/models/inventory.py b/brewman/brewman/models/inventory.py index 256dc176..44156280 100644 --- a/brewman/brewman/models/inventory.py +++ b/brewman/brewman/models/inventory.py @@ -3,7 +3,15 @@ import uuid from decimal import Decimal from typing import TYPE_CHECKING -from sqlalchemy import ForeignKey, Numeric, UniqueConstraint, Uuid +from sqlalchemy import ( + DECIMAL, + ColumnElement, + ForeignKey, + Numeric, + UniqueConstraint, + Uuid, + type_coerce, +) from sqlalchemy.ext.hybrid import hybrid_property from sqlalchemy.orm import Mapped, mapped_column, relationship @@ -59,6 +67,7 @@ class Inventory: def amount(self) -> Decimal: return self.quantity * self.rate * (1 + self.tax) * (1 - self.discount) - @amount.expression # type: ignore[no-redef] - def amount(cls) -> Decimal: - return cls.quantity * cls.rate * (1 + cls.tax) * (1 - cls.discount) + @amount.inplace.expression + @classmethod + def _amount_expression(cls) -> ColumnElement[Decimal]: + return type_coerce(cls.quantity * cls.rate * (1 + cls.tax) * (1 - cls.discount), Decimal) diff --git a/brewman/brewman/models/journal.py b/brewman/brewman/models/journal.py index ca42a193..e3687304 100644 --- a/brewman/brewman/models/journal.py +++ b/brewman/brewman/models/journal.py @@ -3,7 +3,7 @@ import uuid from decimal import Decimal from typing import TYPE_CHECKING -from sqlalchemy import ForeignKey, Integer, Numeric, Uuid +from sqlalchemy import ColumnElement, ForeignKey, Integer, Numeric, Uuid, type_coerce from sqlalchemy.ext.hybrid import hybrid_property from sqlalchemy.orm import Mapped, mapped_column, relationship @@ -50,8 +50,8 @@ class Journal: @signed_amount.inplace.expression @classmethod - def _signed_amount_expression(cls): - return cls.debit * cls.amount + def _signed_amount_expression(cls) -> ColumnElement[Decimal]: + return type_coerce(cls.debit * cls.amount, Decimal) def __init__( self, diff --git a/brewman/brewman/models/rate_contract.py b/brewman/brewman/models/rate_contract.py index a356abe7..941d69e6 100644 --- a/brewman/brewman/models/rate_contract.py +++ b/brewman/brewman/models/rate_contract.py @@ -1,6 +1,6 @@ -import datetime import uuid +from datetime import date, datetime from typing import TYPE_CHECKING from sqlalchemy import Date, DateTime, ForeignKey, Unicode, Uuid @@ -20,15 +20,15 @@ class RateContract: __tablename__ = "rate_contracts" id: Mapped[uuid.UUID] = mapped_column(Uuid, primary_key=True, insert_default=uuid.uuid4) - date: Mapped[datetime.date] = mapped_column(Date, nullable=False, index=True) + date_: Mapped[date] = mapped_column("date", Date, nullable=False, index=True) vendor_id: Mapped[uuid.UUID] = mapped_column(Uuid, ForeignKey("accounts.id"), nullable=False) - valid_from: Mapped[datetime.date | None] = mapped_column(Date(), nullable=True) - valid_till: Mapped[datetime.date | None] = mapped_column(Date(), nullable=True) + valid_from: Mapped[date | None] = mapped_column(Date(), nullable=True) + valid_till: Mapped[date | None] = mapped_column(Date(), nullable=True) narration: Mapped[str] = mapped_column(Unicode, nullable=False) user_id: Mapped[uuid.UUID] = mapped_column(Uuid, ForeignKey("users.id"), nullable=False) - creation_date: Mapped[datetime.datetime] = mapped_column(DateTime(), nullable=False) - last_edit_date: Mapped[datetime.datetime] = mapped_column(DateTime(), nullable=False) + creation_date: Mapped[datetime] = mapped_column(DateTime(), nullable=False) + last_edit_date: Mapped[datetime] = mapped_column(DateTime(), nullable=False) user: Mapped["User"] = relationship("User") vendor: Mapped["AccountBase"] = relationship("AccountBase", back_populates="rate_contracts") @@ -36,23 +36,23 @@ class RateContract: def __init__( self, - date: datetime.date, + date_: date, vendor_id: uuid.UUID, - valid_from: datetime.date | None, - valid_till: datetime.date | None, + valid_from: date | None, + valid_till: date | None, user_id: uuid.UUID, narration: str = "", - creation_date: datetime.datetime | None = None, - last_edit_date: datetime.datetime | None = None, + creation_date: datetime | None = None, + last_edit_date: datetime | None = None, id_: uuid.UUID | None = None, ): - self.date = date + self.date_ = date_ self.vendor_id = vendor_id self.valid_from = valid_from self.valid_till = valid_till self.narration = narration self.user_id = user_id - self.creation_date = creation_date or datetime.datetime.utcnow() - self.last_edit_date = last_edit_date or datetime.datetime.utcnow() + self.creation_date = creation_date or datetime.utcnow() + self.last_edit_date = last_edit_date or datetime.utcnow() if id_ is not None: self.id = id_ diff --git a/brewman/brewman/models/recipe.py b/brewman/brewman/models/recipe.py index 40a85fa2..6abc200e 100644 --- a/brewman/brewman/models/recipe.py +++ b/brewman/brewman/models/recipe.py @@ -1,8 +1,8 @@ from __future__ import annotations -import datetime import uuid +from datetime import date from decimal import Decimal from typing import TYPE_CHECKING @@ -26,7 +26,7 @@ class Recipe: id: Mapped[uuid.UUID] = mapped_column(Uuid, primary_key=True, insert_default=uuid.uuid4) sku_id: Mapped[uuid.UUID] = mapped_column(Uuid, ForeignKey("stock_keeping_units.id"), nullable=False) - date: Mapped[datetime.date] = mapped_column(Date, nullable=False, index=True) + date_: Mapped[date] = mapped_column("date", Date, nullable=False, index=True) source: Mapped[str] = mapped_column(Text, nullable=False) instructions: Mapped[str] = mapped_column(Text, nullable=False) garnishing: Mapped[str] = mapped_column(Text, nullable=False) diff --git a/brewman/brewman/models/recipe_template.py b/brewman/brewman/models/recipe_template.py index 9a57e638..93e14139 100644 --- a/brewman/brewman/models/recipe_template.py +++ b/brewman/brewman/models/recipe_template.py @@ -2,7 +2,7 @@ from __future__ import annotations import uuid -from datetime import datetime +from datetime import date from sqlalchemy import Boolean, Date, Index, Unicode, Uuid from sqlalchemy.orm import Mapped, mapped_column @@ -16,7 +16,7 @@ class RecipeTemplate: id: Mapped[uuid.UUID] = mapped_column(Uuid, primary_key=True, insert_default=uuid.uuid4) name: Mapped[str] = mapped_column(Unicode, unique=True, nullable=False) - date: Mapped[datetime.date] = mapped_column(Date, nullable=False) + date_: Mapped[date] = mapped_column("date", Date, nullable=False) text: Mapped[str] = mapped_column(Unicode, nullable=False) selected: Mapped[bool] = mapped_column(Boolean, nullable=False) diff --git a/brewman/brewman/models/tag.py b/brewman/brewman/models/tag.py index cc697965..a528f7e0 100644 --- a/brewman/brewman/models/tag.py +++ b/brewman/brewman/models/tag.py @@ -21,5 +21,5 @@ class Tag: name: Mapped[str] = mapped_column(Unicode, unique=True, nullable=False) recipes: Mapped[list["Recipe"]] = relationship( - "Recipe", secondary=RecipeTag.__table__, order_by="Recipe.date", back_populates="tags" + "Recipe", secondary=RecipeTag.__table__, order_by="Recipe.date_", back_populates="tags" ) diff --git a/brewman/brewman/models/user.py b/brewman/brewman/models/user.py index b69cd3de..1bd8f901 100644 --- a/brewman/brewman/models/user.py +++ b/brewman/brewman/models/user.py @@ -36,19 +36,13 @@ class User: login_history: Mapped[list[LoginHistory]] = relationship(order_by=desc(LoginHistory.date), back_populates="user") vouchers: Mapped[list[Voucher]] = relationship("Voucher", foreign_keys="Voucher.user_id", back_populates="user") - def _get_password(self) -> str: - return self._password - - def _set_password(self, password: str) -> None: - self._password = encrypt(password) - @hybrid_property def password(self) -> str: return self._password @password.inplace.setter - def _password_setter(self, password: str) -> None: - self._password = encrypt(password) + def _password_setter(self, value: str) -> None: + self._password = encrypt(value) def __init__(self, name: str, password: str, locked_out: bool, id_: uuid.UUID | None = None) -> None: self.name = name diff --git a/brewman/brewman/models/voucher.py b/brewman/brewman/models/voucher.py index e27e1f10..69f05174 100644 --- a/brewman/brewman/models/voucher.py +++ b/brewman/brewman/models/voucher.py @@ -1,6 +1,6 @@ -import datetime import uuid +from datetime import date, datetime from typing import TYPE_CHECKING, Optional from sqlalchemy import Boolean, Date, DateTime, Enum, ForeignKey, Unicode, Uuid @@ -23,13 +23,13 @@ class Voucher: __tablename__ = "vouchers" id: Mapped[uuid.UUID] = mapped_column(Uuid, primary_key=True, insert_default=uuid.uuid4) - date: Mapped[datetime.date] = mapped_column(Date, nullable=False, index=True) + date_: Mapped[date] = mapped_column("date", Date, nullable=False, index=True) narration: Mapped[str] = mapped_column(Unicode, nullable=False) is_reconciled: Mapped[bool] = mapped_column(Boolean, nullable=False) - reconcile_date: Mapped[datetime.date] = mapped_column(Date, nullable=False) + reconcile_date: Mapped[date] = mapped_column(Date, nullable=False) is_starred: Mapped[bool] = mapped_column(Boolean, nullable=False) - creation_date: Mapped[datetime.datetime] = mapped_column(DateTime(), nullable=False) - last_edit_date: Mapped[datetime.datetime] = mapped_column(DateTime(), nullable=False) + creation_date: Mapped[datetime] = mapped_column(DateTime(), nullable=False) + last_edit_date: Mapped[datetime] = mapped_column(DateTime(), nullable=False) voucher_type: Mapped[VoucherType] = mapped_column(Enum(VoucherType), nullable=False) user_id: Mapped[uuid.UUID] = mapped_column(Uuid, ForeignKey("users.id"), nullable=False) posted: Mapped[bool] = mapped_column("is_posted", Boolean, nullable=False) @@ -54,26 +54,26 @@ class Voucher: def __init__( self, - date: datetime.date, + date_: date, voucher_type: VoucherType, user_id: uuid.UUID, narration: str = "", is_starred: bool = False, posted: bool = False, is_reconciled: bool = False, - reconcile_date: datetime.date | None = None, + reconcile_date: date | None = None, poster_id: uuid.UUID | None = None, - creation_date: datetime.datetime | None = None, - last_edit_date: datetime.datetime | None = None, + creation_date: datetime | None = None, + last_edit_date: datetime | None = None, ): - self.date = date + self.date_ = date_ self.is_reconciled = is_reconciled - self.reconcile_date = reconcile_date or date + self.reconcile_date = reconcile_date or date_ self.is_starred = is_starred if is_starred is not None else False self.narration = narration self.posted = posted - self.creation_date = creation_date or datetime.datetime.utcnow() - self.last_edit_date = last_edit_date or datetime.datetime.utcnow() + self.creation_date = creation_date or datetime.utcnow() + self.last_edit_date = last_edit_date or datetime.utcnow() self.voucher_type = voucher_type self.user_id = user_id if poster_id is not None: diff --git a/brewman/brewman/routers/__init__.py b/brewman/brewman/routers/__init__.py index ae17816d..f2764333 100644 --- a/brewman/brewman/routers/__init__.py +++ b/brewman/brewman/routers/__init__.py @@ -1,4 +1,5 @@ from datetime import date, timedelta +from typing import Sequence from sqlalchemy import or_, select from sqlalchemy.orm import Session @@ -15,12 +16,12 @@ from ..schemas.settings import ( def get_lock_info( - voucher_dates: list[date], voucher_type: VoucherType, account_types: list[int], db: Session + voucher_dates: Sequence[date], voucher_type: VoucherType, account_types: Sequence[int], db: Session ) -> tuple[bool, str]: date_ = date.today() start: date | None finish: date | None - data: list = ( + data: list[dict] = list( db.execute( select(DbSetting.data).where( DbSetting.setting_type == SettingType.VOUCHER_LOCK, @@ -37,14 +38,14 @@ def get_lock_info( .scalars() .all() ) - data = sorted(data, key=lambda d: d["index"], reverse=True) # type: ignore[no-any-return] + data = sorted(data, key=lambda d: d["index"], reverse=True) # type: ignore[index] for it in data: li: LockInformation = LockInformation( - voucherTypes=[VoucherTypesSelected(id=vt["id_"], name=vt["name"]) for vt in it["voucher_types"]], - accountTypes=[AccountTypesSelected(id=at["id_"], name=at["name"]) for at in it["account_types"]], - start=LockDate(days=it["start"]["days"], date=it["start"]["date_"]), - finish=LockDate(days=it["finish"]["days"], date=it["finish"]["date_"]), - index=it["index"], + voucher_types=[VoucherTypesSelected(id_=vt["id_"], name=vt["name"]) for vt in it["voucher_types"]], # type: ignore[index] + account_types=[AccountTypesSelected(id_=at["id_"], name=at["name"]) for at in it["account_types"]], # type: ignore[index] + start=LockDate(days=it["start"]["days"], date_=it["start"]["date_"]), # type: ignore[index] + finish=LockDate(days=it["finish"]["days"], date_=it["finish"]["date_"]), # type: ignore[index] + index=it["index"], # type: ignore[index] ) # Data format if len(li.voucher_types) != 0 and voucher_type not in [vt.id_ for vt in li.voucher_types]: diff --git a/brewman/brewman/routers/account.py b/brewman/brewman/routers/account.py index 6219a6a3..1685d940 100644 --- a/brewman/brewman/routers/account.py +++ b/brewman/brewman/routers/account.py @@ -147,10 +147,10 @@ async def show_term( query_ = query_.order_by(AccountBase.name) if c is not None: query_ = query_.limit(c) - data: list[AccountBase] = db.execute(query_).scalars().all() + data: list[AccountBase] = list(db.execute(query_).scalars().all()) for item in data: - list_.append(schemas.AccountLink(id=item.id, name=item.name)) + list_.append(schemas.AccountLink(id_=item.id, name=item.name)) return list_ @@ -162,7 +162,7 @@ async def show_balance( ) -> AccountBalance: date_ = None if d is None or d == "" else datetime.strptime(d, "%d-%b-%Y") with SessionFuture() as db: - return AccountBalance(date=balance(id_, date_, db), total=balance(id_, None, db)) + return AccountBalance(date_=balance(id_, date_, db), total=balance(id_, None, db)) @router.get("/{id_}", response_model=schemas.Account) @@ -182,7 +182,7 @@ def balance(id_: uuid.UUID, date_: date | None, db: Session) -> Decimal: bal = select(func.sum(Journal.amount * Journal.debit)).join(Journal.voucher) if date_ is not None: - bal = bal.where(Voucher.date <= date_) + bal = bal.where(Voucher.date_ <= date_) bal = bal.where(Voucher.voucher_type != VoucherType.ISSUE).where(Journal.account_id == id_) result: Decimal | None = db.execute(bal).scalar_one_or_none() @@ -191,16 +191,16 @@ def balance(id_: uuid.UUID, date_: date | None, db: Session) -> Decimal: def account_info(item: Account) -> schemas.Account: return schemas.Account( - id=item.id, + id_=item.id, code=item.code, name=item.name, - type=item.type_id, - isActive=item.is_active, - isReconcilable=item.is_reconcilable, - isStarred=item.is_starred, - isFixture=item.is_fixture, - costCentre=schemas.CostCentreLink( - id=item.cost_centre_id, + type_=item.type_id, + is_active=item.is_active, + is_reconcilable=item.is_reconcilable, + is_starred=item.is_starred, + is_fixture=item.is_fixture, + cost_centre=schemas.CostCentreLink( + id_=item.cost_centre_id, name=item.cost_centre.name, ), ) @@ -209,18 +209,18 @@ def account_info(item: Account) -> schemas.Account: def account_blank(db: Session) -> schemas.AccountBlank: return schemas.AccountBlank( name="", - type=db.execute(select(AccountType.id).where(AccountType.name == "Creditors")).scalar_one(), - isActive=True, - isReconcilable=False, - isStarred=False, - costCentre=CostCentre.overall(), - isFixture=False, + type_=db.execute(select(AccountType.id).where(AccountType.name == "Creditors")).scalar_one(), + is_active=True, + is_reconcilable=False, + is_starred=False, + cost_centre=CostCentre.overall(), + is_fixture=False, ) def delete_with_data(account: Account, db: Session) -> None: suspense_account = db.execute(select(Account).where(Account.id == Account.suspense())).scalar_one() - query: list[Voucher] = ( + query: list[Voucher] = list( db.execute( select(Voucher) .options(joinedload(Voucher.journals, innerjoin=True).joinedload(Journal.account, innerjoin=True)) diff --git a/brewman/brewman/routers/account_types.py b/brewman/brewman/routers/account_types.py index 853f9b17..503a74cd 100644 --- a/brewman/brewman/routers/account_types.py +++ b/brewman/brewman/routers/account_types.py @@ -16,5 +16,5 @@ router = APIRouter() def account_type_list(user: UserToken = Depends(get_user)) -> list[schemas.AccountType]: with SessionFuture() as db: return [ - schemas.AccountType(id=item.id, name=item.name) for item in db.execute(select(AccountType)).scalars().all() + schemas.AccountType(id_=item.id, name=item.name) for item in db.execute(select(AccountType)).scalars().all() ] diff --git a/brewman/brewman/routers/attendance.py b/brewman/brewman/routers/attendance.py index 5c8699cd..4d24c404 100644 --- a/brewman/brewman/routers/attendance.py +++ b/brewman/brewman/routers/attendance.py @@ -24,7 +24,7 @@ router = APIRouter() def attendance_blank( request: Request, user: UserToken = Security(get_user, scopes=["attendance"]) ) -> schemas.Attendance: - return schemas.Attendance(date=get_date(request.session), body=[]) + return schemas.Attendance(date_=get_date(request.session), body=[]) # type: ignore[arg-type] @router.get("/{date_}", response_model=schemas.Attendance) @@ -36,7 +36,7 @@ def attendance_date( set_date(date_, request.session) with SessionFuture() as db: return schemas.Attendance( - date=date_, + date_=date_, # type: ignore[arg-type] body=attendance_date_report(datetime.strptime(date_, "%d-%b-%Y"), db), ) @@ -64,7 +64,7 @@ def attendance_date_report(date_: date, db: Session) -> list[schemas.AttendanceI db.execute( select(Attendance).where( Attendance.employee_id == item.id, - Attendance.date == date_, + Attendance.date_ == date_, Attendance.is_valid == True, # noqa: E712 ) ) @@ -72,20 +72,20 @@ def attendance_date_report(date_: date, db: Session) -> list[schemas.AttendanceI .one_or_none() ) - att = 0 if att is None else att.attendance_type + at_type = 0 if att is None else att.attendance_type prints, hours_worked, full_day = get_prints(item.id, date_, db) body.append( schemas.AttendanceItem( - id=item.id, + id_=item.id, code=item.code, name=item.name, designation=item.designation, department=item.cost_centre.name, - attendanceType=schemas.AttendanceType(id=att), + attendance_type=schemas.AttendanceType(id_=at_type), prints=prints, - hoursWorked=hours_worked, - fullDay=full_day, + hours_worked=hours_worked, + full_day=full_day, ) ) return body @@ -104,13 +104,13 @@ def save( if item.attendance_type.id_ != 0: attendance = Attendance( employee_id=item.id_, - date=att_date, + date_=att_date, attendance_type=item.attendance_type.id_, user_id=user.id_, ) attendance.create(db) db.commit() - return schemas.Attendance(date=date_, body=attendance_date_report(att_date, db)) + return schemas.Attendance(date_=date_, body=attendance_date_report(att_date, db)) # type: ignore[arg-type] except SQLAlchemyError as e: raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, diff --git a/brewman/brewman/routers/attendance_report.py b/brewman/brewman/routers/attendance_report.py index b302be9c..b1489dc5 100644 --- a/brewman/brewman/routers/attendance_report.py +++ b/brewman/brewman/routers/attendance_report.py @@ -74,15 +74,15 @@ def attendance_record(start_date: date, finish_date: date, output: io.StringIO, db.execute( select(Attendance).where( Attendance.employee_id == employee.id, - Attendance.date == date_, + Attendance.date_ == date_, Attendance.is_valid == True, # noqa: E712 ) ) .scalars() .one_or_none() ) - att = not_set if att is None else AttendanceType.by_id(att.attendance_type) - row_display.append(att.name) - row_value.append(att.value) + at_type = not_set if att is None else AttendanceType.by_id(att.attendance_type) + row_display.append(at_type.name) + row_value.append(at_type.value) writer.writerow(row_display) writer.writerow(row_value) diff --git a/brewman/brewman/routers/attendance_types.py b/brewman/brewman/routers/attendance_types.py index 12d94298..0bd1e54b 100644 --- a/brewman/brewman/routers/attendance_types.py +++ b/brewman/brewman/routers/attendance_types.py @@ -15,5 +15,5 @@ async def show_list(user: UserToken = Depends(get_user)) -> list[schemas.Attenda list_ = AttendanceType.list() attendance_types: list[schemas.AttendanceType] = [] for item in list_: - attendance_types.append(schemas.AttendanceType(id=item.id, name=item.name, value=item.value)) + attendance_types.append(schemas.AttendanceType(id_=item.id, name=item.name, value=item.value)) return attendance_types diff --git a/brewman/brewman/routers/batch.py b/brewman/brewman/routers/batch.py index 084f8d8b..a3e4f2d4 100644 --- a/brewman/brewman/routers/batch.py +++ b/brewman/brewman/routers/batch.py @@ -45,14 +45,14 @@ def batch_term( ) list_.append( schemas.Batch( - id=item.id, + id_=item.id, name=text, - quantityRemaining=round(item.quantity_remaining, 2), + quantity_remaining=round(item.quantity_remaining, 2), rate=round(item.rate, 2), tax=round(item.tax, 5), discount=round(item.discount, 5), sku=schemas.ProductLink( - id=item.sku.id, + id_=item.sku.id, name=f"{item.sku.product.name} ({item.sku.units})", ), ) diff --git a/brewman/brewman/routers/batch_integrity.py b/brewman/brewman/routers/batch_integrity.py index 227be3c1..802588d9 100644 --- a/brewman/brewman/routers/batch_integrity.py +++ b/brewman/brewman/routers/batch_integrity.py @@ -1,5 +1,7 @@ import uuid +from decimal import Decimal + import brewman.schemas.batch_integrity as schemas from fastapi import APIRouter, Security @@ -45,7 +47,7 @@ def negative_batches(db: Session) -> list[schemas.BatchIntegrity]: .where( Journal.cost_centre_id == CostCentre.cost_centre_purchase(), ) - .group_by(Batch, Product.name) + .group_by(Batch, Product.name) # type: ignore .having(Batch.quantity_remaining != inv_sum) ).all() @@ -56,9 +58,9 @@ def negative_batches(db: Session) -> list[schemas.BatchIntegrity]: else: issue.append( schemas.BatchIntegrity( - id=batch.id, + id_=batch.id, product=product, - date=batch.name, + date_=batch.name, showing=batch.quantity_remaining, actual=quantity, price=batch.rate, @@ -70,7 +72,7 @@ def negative_batches(db: Session) -> list[schemas.BatchIntegrity]: def batch_details(batch_id: uuid.UUID, db: Session) -> list[schemas.BatchIntegrityItem]: list_ = db.execute( - select(Voucher.id, Voucher.date, Voucher.voucher_type, Inventory.quantity, Inventory.rate) + select(Voucher.id, Voucher.date_, Voucher.voucher_type, Inventory.quantity, Inventory.rate) .join(Inventory.voucher) .join(Voucher.journals) .where( @@ -80,8 +82,8 @@ def batch_details(batch_id: uuid.UUID, db: Session) -> list[schemas.BatchIntegri ).all() return [ schemas.BatchIntegrityItem( - date=date_, - type=type_.name.replace("_", " ").title(), + date_=date_, + type_=type_.name.replace("_", " ").title(), url=["/", type_.name.replace("_", "-").lower(), str(id_)], quantity=quantity, price=rate, @@ -98,7 +100,7 @@ def batch_dates(db: Session) -> list[schemas.BatchIntegrity]: .join(StockKeepingUnit.product) .join(Batch.inventories) .join(Inventory.voucher) - .where(Voucher.date < Batch.name) + .where(Voucher.date_ < Batch.name) .options( contains_eager(Batch.sku).contains_eager(StockKeepingUnit.product), contains_eager(Batch.inventories).contains_eager(Inventory.voucher), @@ -113,16 +115,16 @@ def batch_dates(db: Session) -> list[schemas.BatchIntegrity]: for batch in list_: issue.append( schemas.BatchIntegrity( - id=batch.id, + id_=batch.id, product=batch.sku.product.name, - date=batch.name, + date_=batch.name, showing=batch.quantity_remaining, - actual=0, + actual=Decimal(0), price=batch.rate, details=[ schemas.BatchIntegrityItem( - date=inv.voucher.date, - type=inv.voucher.voucher_type.name.replace("_", " ").title(), + date_=inv.voucher.date_, + type_=inv.voucher.voucher_type.name.replace("_", " ").title(), quantity=inv.quantity, price=inv.rate, url=[ @@ -153,11 +155,11 @@ def fix_batch_prices(db: Session) -> None: for batch in list_: for inv in batch.inventories: - refresh_voucher(inv.voucher_id, inv.product_id, db) + refresh_voucher(inv.voucher_id, inv.batch_id, db) def fix_single_batch_prices(batch_id: uuid.UUID, db: Session) -> None: - list_ = ( + list_: list[uuid.UUID] = list( db.execute( select(distinct(Inventory.voucher_id)) .join(Inventory.batch) diff --git a/brewman/brewman/routers/client.py b/brewman/brewman/routers/client.py index b659b08c..ec4bd44e 100644 --- a/brewman/brewman/routers/client.py +++ b/brewman/brewman/routers/client.py @@ -65,14 +65,14 @@ async def show_list( for item in list_: clients.append( schemas.ClientList( - id=item.id, + id_=item.id, code=item.code, name=item.name, enabled=item.enabled, otp=item.otp, - creationDate=item.creation_date, - lastUser=item.login_history[0].user.name if len(item.login_history) else "None", - lastDate=item.login_history[0].date if len(item.login_history) else None, + creation_date=item.creation_date, + last_user=item.login_history[0].user.name if len(item.login_history) else "None", + last_date=item.login_history[0].date if len(item.login_history) else None, ) ) return clients @@ -86,10 +86,10 @@ def show_id( with SessionFuture() as db: item: Client = db.execute(select(Client).where(Client.id == id_)).scalar_one() return schemas.Client( - id=item.id, + id_=item.id, code=item.code, name=item.name, enabled=item.enabled, otp=item.otp, - creationDate=item.creation_date, + creation_date=item.creation_date, ) diff --git a/brewman/brewman/routers/cost_centre.py b/brewman/brewman/routers/cost_centre.py index 7649bec9..eba630ff 100644 --- a/brewman/brewman/routers/cost_centre.py +++ b/brewman/brewman/routers/cost_centre.py @@ -112,14 +112,14 @@ def show_id( def cost_centre_info(item: CostCentre) -> schemas.CostCentre: return schemas.CostCentre( - id=item.id, + id_=item.id, name=item.name, - isFixture=item.is_fixture, + is_fixture=item.is_fixture, ) def cost_centre_blank() -> schemas.CostCentreBlank: return schemas.CostCentreBlank( name="", - isFixture=False, + is_fixture=False, ) diff --git a/brewman/brewman/routers/credit_salary.py b/brewman/brewman/routers/credit_salary.py index 0b5f6396..849fc76d 100644 --- a/brewman/brewman/routers/credit_salary.py +++ b/brewman/brewman/routers/credit_salary.py @@ -33,7 +33,7 @@ def credit_salary( finish_date = get_last_day(month_) with SessionFuture() as db: voucher = Voucher( - date=finish_date, + date_=finish_date, narration="Auto Generated Salary Entry", user_id=user.id_, voucher_type=VoucherType.JOURNAL, @@ -67,8 +67,8 @@ def salary_journals(start_date: date, finish_date: date, db: Session) -> list[Jo db.execute( select(Attendance).where( Attendance.employee_id == employee.id, - Attendance.date >= start_date, - Attendance.date <= finish_date, + Attendance.date_ >= start_date, + Attendance.date_ <= finish_date, Attendance.is_valid == True, # noqa: E712 ) ) diff --git a/brewman/brewman/routers/db_image.py b/brewman/brewman/routers/db_image.py index 178366d3..87b2e1de 100644 --- a/brewman/brewman/routers/db_image.py +++ b/brewman/brewman/routers/db_image.py @@ -21,10 +21,10 @@ def db_image(id_: uuid.UUID, type_: str) -> StreamingResponse: with SessionFuture() as db: item = db.execute(select(DbImage).where(DbImage.id == id_)).scalar_one() if type_ == "thumbnail": - item = BytesIO(item.thumbnail) + img = BytesIO(item.thumbnail) else: - item = BytesIO(item.image) - return StreamingResponse(item, media_type="image/jpeg") + img = BytesIO(item.image) + return StreamingResponse(img, media_type="image/jpeg") def save_files(voucher_id: uuid.UUID, i: list[bytes], t: list[bytes], db: Session) -> None: diff --git a/brewman/brewman/routers/db_integrity.py b/brewman/brewman/routers/db_integrity.py index 45ab911d..e32cba4f 100644 --- a/brewman/brewman/routers/db_integrity.py +++ b/brewman/brewman/routers/db_integrity.py @@ -19,14 +19,14 @@ def post_check_db(user: UserToken = Security(get_user)) -> AttendanceCount: if duplicate_attendances > 0: fix_duplicate_attendances(db) db.commit() - return AttendanceCount(attendanceCount=duplicate_attendances) + return AttendanceCount(attendance_count=duplicate_attendances) def get_duplicate_attendances(db: Session) -> int: - sub_query = select( + sub_query = select( # type: ignore[var-annotated] over( - distinct(func.first_value(Attendance.id)), - partition_by=[Attendance.employee_id, Attendance.date], + distinct(func.first_value(Attendance.id)), # type: ignore[arg-type] + partition_by=[Attendance.employee_id, Attendance.date_], ) ).where( Attendance.is_valid == True # noqa: E712 @@ -43,12 +43,12 @@ def fix_duplicate_attendances(db: Session) -> None: sub = ( select( over( - distinct(func.first_value(Attendance.id)), - partition_by=[Attendance.employee_id, Attendance.date], + distinct(func.first_value(Attendance.id)), # type: ignore[arg-type] + partition_by=[Attendance.employee_id, Attendance.date_], order_by=desc(Attendance.creation_date), ) ) .where(Attendance.is_valid == True) # noqa: E712 .subquery() ) - db.execute(delete(Attendance).where(~Attendance.id.in_(sub), Attendance.is_valid == True)) # noqa: E712 + db.execute(delete(Attendance).where(~Attendance.id.in_(sub), Attendance.is_valid == True)) # type: ignore[arg-type] # noqa: E712 diff --git a/brewman/brewman/routers/employee.py b/brewman/brewman/routers/employee.py index c9abda80..b222f60c 100644 --- a/brewman/brewman/routers/employee.py +++ b/brewman/brewman/routers/employee.py @@ -1,6 +1,8 @@ import uuid from datetime import datetime +from decimal import Decimal +from typing import Sequence import brewman.schemas.employee as schemas @@ -142,16 +144,16 @@ async def show_term( query_ = query_.order_by(Employee.name) if c is not None: query_ = query_.limit(c) - data: list[Employee] = db.execute(query_).scalars().all() + data: Sequence[Employee] = db.execute(query_).scalars().all() for item in data: list_.append( schemas.EmployeeLink( - id=item.id, + id_=item.id, name=item.name, designation=item.designation, - costCentre=schemas.CostCentreLink( - id=item.cost_centre.id, + cost_centre=schemas.CostCentreLink( + id_=item.cost_centre.id, name=item.cost_centre.name, ), ) @@ -171,35 +173,35 @@ def show_id( def employee_info(employee: Employee) -> schemas.Employee: return schemas.Employee( - id=employee.id, + id_=employee.id, code=employee.code, name=employee.name, - isActive=employee.is_active, - isStarred=employee.is_starred, + is_active=employee.is_active, + is_starred=employee.is_starred, designation=employee.designation, salary=employee.salary, points=employee.points, - joiningDate=employee.joining_date, - leavingDate=None if employee.is_active else employee.leaving_date, - costCentre=schemas.CostCentreLink( - id=employee.cost_centre_id, + joining_date=employee.joining_date, + leaving_date=None if employee.is_active else employee.leaving_date, + cost_centre=schemas.CostCentreLink( + id_=employee.cost_centre_id, name=employee.cost_centre.name, ), - isFixture=employee.is_fixture, + is_fixture=employee.is_fixture, ) def employee_blank() -> schemas.EmployeeBlank: return schemas.EmployeeBlank( name="", - isStarred=False, - isActive=True, - costCentre=CostCentre.overall(), + is_starred=False, + is_active=True, + cost_centre=CostCentre.overall(), designation="", salary=0, - points=0, - joiningDate=datetime.today(), - leavingDate=None, + points=Decimal(0), + joining_date=datetime.today(), + leaving_date=None, ) diff --git a/brewman/brewman/routers/employee_attendance.py b/brewman/brewman/routers/employee_attendance.py index 4b778d48..144e5997 100644 --- a/brewman/brewman/routers/employee_attendance.py +++ b/brewman/brewman/routers/employee_attendance.py @@ -27,8 +27,8 @@ def show_blank( user: UserToken = Security(get_user, scopes=["attendance"]), ) -> schemas.EmployeeAttendance: return schemas.EmployeeAttendance( - startDate=get_start_date(request.session), - finishDate=get_finish_date(request.session), + start_date=get_start_date(request.session), # type: ignore[arg-type] + finish_date=get_finish_date(request.session), # type: ignore[arg-type] employee=None, body=[], ) @@ -48,12 +48,12 @@ def employee_attendance_report( finish_date = datetime.strptime(f or get_finish_date(request.session), "%d-%b-%Y").date() start_date = employee.joining_date if employee.joining_date > start_date else start_date finish_date = ( - employee.leaving_date if not employee.is_active and employee.leaving_date < finish_date else finish_date # type: ignore[assignment] + employee.leaving_date if not employee.is_active and employee.leaving_date < finish_date else finish_date # type: ignore[assignment, operator] ) info = schemas.EmployeeAttendance( - startDate=start_date, - finishDate=finish_date, - employee=schemas.AccountLink(id=employee.id, name=employee.name), + start_date=start_date, + finish_date=finish_date, + employee=schemas.AccountLink(id_=employee.id, name=employee.name), body=employee_attendance(employee, start_date, finish_date, db), ) return info @@ -68,7 +68,7 @@ def employee_attendance( db.execute( select(Attendance).where( Attendance.employee_id == employee.id, - Attendance.date == item, + Attendance.date_ == item, Attendance.is_valid == True, # noqa: E712 ) ) @@ -76,15 +76,15 @@ def employee_attendance( .one_or_none() ) - att = 0 if att is None else att.attendance_type + at_type = 0 if att is None else att.attendance_type prints, hours_worked, full_day = get_prints(employee.id, item, db) list_.append( schemas.EmployeeAttendanceItem( - date=item.strftime("%d-%b-%Y"), - attendanceType={"id": att}, + date_=item.strftime("%d-%b-%Y"), # type: ignore + attendance_type=schemas.AttendanceType(id_=at_type), prints=prints, - hoursWorked=hours_worked, - fullDay=full_day, + hours_worked=hours_worked, + full_day=full_day, ) ) return list_ @@ -103,7 +103,7 @@ def save_employee_attendance( if attendance_type != 0: attendance = Attendance( employee_id=employee.id, - date=item.date_, + date_=item.date_, attendance_type=attendance_type, user_id=user.id_, ) @@ -112,8 +112,8 @@ def save_employee_attendance( start_date = min(i.date_ for i in data.body) finish_date = max(i.date_ for i in data.body) return schemas.EmployeeAttendance( - startDate=start_date, - finishDate=finish_date, - employee={"id": employee.id, "name": employee.name}, + start_date=start_date, + finish_date=finish_date, + employee=schemas.AccountLink(id_=employee.id, name=employee.name), body=employee_attendance(employee, start_date, finish_date, db), ) diff --git a/brewman/brewman/routers/employee_benefit.py b/brewman/brewman/routers/employee_benefit.py index 9f707372..11c98e0d 100644 --- a/brewman/brewman/routers/employee_benefit.py +++ b/brewman/brewman/routers/employee_benefit.py @@ -62,7 +62,7 @@ def save_route( def save(data: schema_in.EmployeeBenefitIn, date_: date, user: UserToken, db: Session) -> Voucher: - account_types = ( + account_types: list[int] = list( db.execute( select(distinct(AccountBase.type_id)).where( AccountBase.id.in_([dj.employee.id_ for dj in data.employee_benefits]) @@ -78,7 +78,7 @@ def save(data: schema_in.EmployeeBenefitIn, date_: date, user: UserToken, db: Se detail=message, ) voucher = Voucher( - date=date_, + date_=date_, narration=data.narration, is_starred=data.is_starred, user_id=user.id_, @@ -160,13 +160,13 @@ def update_route( days_in_month = dt.day with SessionFuture() as db: item: Voucher = update_voucher(id_, data, user, db) - if dt != item.date: + if dt != item.date_: raise HTTPException( status_code=status.HTTP_423_LOCKED, detail="Date Cannot be changed for Employee Benefit voucher!", ) exp, total = update_employee_benefits(item, data.employee_benefits, days_in_month, db) - update_journals(item, exp, total) + update_journals(item, Decimal(exp), Decimal(total)) check_journals_are_valid(item) update_files(item.id, data.files, i, t, db) db.commit() @@ -181,7 +181,7 @@ def update_route( def update_voucher(id_: uuid.UUID, data: schema_in.EmployeeBenefitIn, user: UserToken, db: Session) -> Voucher: voucher: Voucher = db.execute(select(Voucher).where(Voucher.id == id_)).scalar_one() - account_types = ( + account_types: list[int] = list( db.execute( select(distinct(AccountBase.type_id)).where( AccountBase.id.in_( @@ -192,7 +192,7 @@ def update_voucher(id_: uuid.UUID, data: schema_in.EmployeeBenefitIn, user: User .scalars() .all() ) - allowed, message = get_lock_info([voucher.date, data.date_], voucher.voucher_type, account_types, db) + allowed, message = get_lock_info([voucher.date_, data.date_], voucher.voucher_type, account_types, db) if not allowed: raise HTTPException( status_code=status.HTTP_423_LOCKED, @@ -228,7 +228,7 @@ def update_employee_benefits( return exp + new_exp, total + new_total -def update_journals(voucher: Voucher, exp: int, total: int) -> None: +def update_journals(voucher: Voucher, exp: Decimal, total: Decimal) -> None: journal = next(i for i in voucher.journals if i.account_id == AccountBase.esi_pf_expense()) journal.amount = exp journal = next(i for i in voucher.journals if i.account_id == AccountBase.esi_pf_payable()) @@ -256,7 +256,7 @@ def show_blank( request: Request, user: UserToken = Security(get_user, scopes=["employee-benefit"]), ) -> output.Voucher: - additional_info = BlankVoucherInfo(date=get_date(request.session), type=VoucherType.EMPLOYEE_BENEFIT) + additional_info = BlankVoucherInfo(date_=get_date(request.session), type_=VoucherType.EMPLOYEE_BENEFIT) # type: ignore[arg-type] with SessionFuture() as db: return blank_voucher(additional_info, db) diff --git a/brewman/brewman/routers/fingerprint.py b/brewman/brewman/routers/fingerprint.py index 975f83e6..c25852d7 100644 --- a/brewman/brewman/routers/fingerprint.py +++ b/brewman/brewman/routers/fingerprint.py @@ -36,7 +36,7 @@ def upload_prints( for id_, code in db.execute(select(Employee.id, Employee.code)).all(): employees[code] = id_ file_data = read_file(fingerprints) - prints = [d for d in fp(file_data, employees) if start <= d.date.date() <= finish] + prints = [d for d in fp(file_data, employees) if start <= d.date_.date() <= finish] paged_data = [prints[i : i + 100] for i in range(0, len(prints), 100)] for i, page in enumerate(paged_data): print(f"Processing page {i} of {len(paged_data)}") @@ -93,9 +93,9 @@ def fp(file_data: StringIO, employees: dict[int, uuid.UUID]) -> list[schemas.Fin if employee_code in employees.keys(): fingerprints.append( schemas.Fingerprint( - id=uuid.uuid4(), + id_=uuid.uuid4(), employee_id=employees[employee_code], - date=date_, + date_=date_, ) ) except ValueError: diff --git a/brewman/brewman/routers/incentive.py b/brewman/brewman/routers/incentive.py index 59a9b71d..6a3fc8f1 100644 --- a/brewman/brewman/routers/incentive.py +++ b/brewman/brewman/routers/incentive.py @@ -61,7 +61,7 @@ def save_route( def save(data: schema_in.IncentiveIn, user: UserToken, db: Session) -> Voucher: - account_types = ( + account_types: list[int] = list( db.execute( select(distinct(AccountBase.type_id)).where(AccountBase.id.in_([dj.employee_id for dj in data.incentives])) ) @@ -75,7 +75,7 @@ def save(data: schema_in.IncentiveIn, user: UserToken, db: Session) -> Voucher: detail=message, ) voucher = Voucher( - date=data.date_, + date_=data.date_, narration=data.narration, is_starred=data.is_starred, user_id=user.id_, @@ -141,7 +141,7 @@ def update_route( def update_voucher(id_: uuid.UUID, data: schema_in.IncentiveIn, user: UserToken, db: Session) -> Voucher: voucher: Voucher = db.execute(select(Voucher).where(Voucher.id == id_)).scalar_one() - account_types = ( + account_types: list[int] = list( db.execute( select(distinct(AccountBase.type_id)).where( AccountBase.id.in_( @@ -152,7 +152,7 @@ def update_voucher(id_: uuid.UUID, data: schema_in.IncentiveIn, user: UserToken, .scalars() .all() ) - allowed, message = get_lock_info([voucher.date, data.date_], voucher.voucher_type, account_types, db) + allowed, message = get_lock_info([voucher.date_, data.date_], voucher.voucher_type, account_types, db) if not allowed: raise HTTPException( status_code=status.HTTP_423_LOCKED, @@ -179,11 +179,11 @@ def update_incentives( item_amount = round(employee.points * employee.days_worked * point_value) item.days_worked = employee.days_worked item.points = employee.points - item.journal.amount = item_amount + item.journal.amount = Decimal(item_amount) total_amount += item_amount journal = next(j for j in voucher.journals if j.account_id == Account.incentive_id()) - journal.amount = total_amount + journal.amount = Decimal(total_amount) @router.get("/{id_}", response_model=output.Voucher) @@ -208,7 +208,7 @@ def show_blank( d: str | None = None, user: UserToken = Security(get_user, scopes=["incentive"]), ) -> output.Voucher: - additional_info = BlankVoucherInfo(date=d or get_date(request.session), type=VoucherType.INCENTIVE) + additional_info = BlankVoucherInfo(date_=d or get_date(request.session), type_=VoucherType.INCENTIVE) # type: ignore[arg-type] with SessionFuture() as db: return blank_voucher(additional_info, db) @@ -221,7 +221,7 @@ def get_employees( db: Session, ) -> list[schema_in.IncentiveEmployee]: details = [] - employees = ( + employees = list( db.execute( select(Employee) .where(Employee.joining_date <= finish_date, or_(Employee.is_active, Employee.leaving_date >= start_date)) @@ -238,15 +238,15 @@ def get_employees( db.execute( select(Attendance).where( Attendance.employee_id == employee.id, - Attendance.date >= start_date, - Attendance.date <= finish_date, + Attendance.date_ >= start_date, + Attendance.date_ <= finish_date, Attendance.is_valid == True, # noqa: E712 ) ) .scalars() .all() ) - att = sum(AttendanceType.by_id(x.attendance_type).value for x in attendances) + att = sum(AttendanceType.by_id(x.attendance_type).value for x in attendances) or Decimal(0) points = next(x for x in incentives if x.employee_id == employee.id).points details.append( schema_in.IncentiveEmployee( @@ -267,9 +267,9 @@ def balance(date_: date, voucher_id: uuid.UUID | None, db: Session) -> Decimal: Journal.account_id == Account.incentive_id(), Voucher.voucher_type != VoucherType.ISSUE, or_( - Voucher.date <= date_, + Voucher.date_ <= date_, and_( - Voucher.date == date_, + Voucher.date_ == date_, Voucher.voucher_type != VoucherType.INCENTIVE, ), ), diff --git a/brewman/brewman/routers/issue.py b/brewman/brewman/routers/issue.py index f8b16dd6..2723bb3b 100644 --- a/brewman/brewman/routers/issue.py +++ b/brewman/brewman/routers/issue.py @@ -74,7 +74,7 @@ def save(data: schema_in.IssueIn, user: UserToken, db: Session) -> tuple[Voucher .join(Product.skus) .where(StockKeepingUnit.id.in_([i.batch.sku.id_ for i in data.inventories])) ) - account_types = ( + account_types: list[int] = list( db.execute(select(distinct(AccountBase.type_id)).where(AccountBase.id.in_(product_accounts))).scalars().all() ) allowed, message = get_lock_info([data.date_], VoucherType[data.type_.replace(" ", "_").upper()], account_types, db) @@ -84,7 +84,7 @@ def save(data: schema_in.IssueIn, user: UserToken, db: Session) -> tuple[Voucher detail=message, ) voucher = Voucher( - date=data.date_, + date_=data.date_, narration=data.narration, is_starred=data.is_starred, user_id=user.id_, @@ -121,7 +121,7 @@ def save_inventories( status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=f"{batch.sku.product.name} ({batch.sku.units}) stock is {batch.quantity_remaining}", ) - if batch.name > voucher.date: + if batch.name > voucher.date_: raise HTTPException( status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=f"{batch.sku.product.name} ({batch.sku.units}) " @@ -210,7 +210,7 @@ def update_voucher( .join(Product.skus) .where(StockKeepingUnit.id.in_([i.batch.sku.id_ for i in data.inventories])) ) - account_types = ( + account_types: list[int] = list( db.execute( select(distinct(AccountBase.type_id)).where( or_( @@ -222,14 +222,14 @@ def update_voucher( .scalars() .all() ) - allowed, message = get_lock_info([voucher.date, data.date_], voucher.voucher_type, account_types, db) + allowed, message = get_lock_info([voucher.date_, data.date_], voucher.voucher_type, account_types, db) if not allowed: raise HTTPException( status_code=status.HTTP_423_LOCKED, detail=message, ) check_voucher_edit_allowed(voucher, user) - voucher.date = data.date_ + voucher.date_ = data.date_ voucher.is_starred = data.is_starred voucher.narration = data.narration voucher.user_id = user.id_ @@ -288,7 +288,7 @@ def update_inventories( detail=f"Maximum quantity available for " f"{batch.sku.product.name} ({batch.sku.units}) is {batch_quantity}", ) - if item.batch.name > voucher.date: + if item.batch.name > voucher.date_: raise HTTPException( status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=f"Batch of {batch.sku.product.name} ({batch.sku.units}) was purchased after the issue date", @@ -386,10 +386,10 @@ def show_blank( user: UserToken = Security(get_user, scopes=["issue"]), ) -> output.Voucher: date_ = date or get_date(request.session) - additional_info = BlankVoucherInfo(date=date_, type=VoucherType.ISSUE) + additional_info = BlankVoucherInfo(date_=date_, type_=VoucherType.ISSUE) # type: ignore[arg-type] if source: - additional_info.source = CostCentreLink(id=source, name="") + additional_info.source = CostCentreLink(id_=source, name="") if destination: - additional_info.destination = CostCentreLink(id=destination, name="") + additional_info.destination = CostCentreLink(id_=destination, name="") with SessionFuture() as db: return blank_voucher(additional_info, db) diff --git a/brewman/brewman/routers/issue_grid.py b/brewman/brewman/routers/issue_grid.py index ae2f30c6..f54a7c3c 100644 --- a/brewman/brewman/routers/issue_grid.py +++ b/brewman/brewman/routers/issue_grid.py @@ -31,7 +31,7 @@ def get_grid(date_: date, db: Session) -> list[IssueGridItem]: db.execute( select(Voucher) .join(Voucher.journals) - .where(Voucher.date == date_, Voucher.voucher_type == VoucherType.ISSUE) + .where(Voucher.date_ == date_, Voucher.voucher_type == VoucherType.ISSUE) .order_by(Voucher.creation_date) ) .unique() @@ -43,7 +43,7 @@ def get_grid(date_: date, db: Session) -> list[IssueGridItem]: amount = voucher.journals[0].amount list_.append( IssueGridItem( - id=str(voucher.id), + id_=voucher.id, amount=amount, source=next(j.cost_centre.name for j in voucher.journals if j.debit == -1), destination=next(j.cost_centre.name for j in voucher.journals if j.debit == 1), diff --git a/brewman/brewman/routers/journal.py b/brewman/brewman/routers/journal.py index 0c2f1dfa..b4d5a551 100644 --- a/brewman/brewman/routers/journal.py +++ b/brewman/brewman/routers/journal.py @@ -55,7 +55,7 @@ def save_route( def save(data: schema_in.JournalIn, user: UserToken, db: Session) -> Voucher: - account_types = ( + account_types: list[int] = list( db.execute( select(distinct(AccountBase.type_id)).where(AccountBase.id.in_([dj.account.id_ for dj in data.journals])) ) @@ -69,7 +69,7 @@ def save(data: schema_in.JournalIn, user: UserToken, db: Session) -> Voucher: detail=message, ) voucher = Voucher( - date=data.date_, + date_=data.date_, narration=data.narration, is_starred=data.is_starred, user_id=user.id_, @@ -119,7 +119,7 @@ def update_route( def update_voucher(id_: uuid.UUID, data: schema_in.JournalIn, user: UserToken, db: Session) -> Voucher: voucher: Voucher = db.execute(select(Voucher).where(Voucher.id == id_)).scalar_one() - account_types = ( + account_types: list[int] = list( db.execute( select(distinct(AccountBase.type_id)).where( AccountBase.id.in_( @@ -130,7 +130,7 @@ def update_voucher(id_: uuid.UUID, data: schema_in.JournalIn, user: UserToken, d .scalars() .all() ) - allowed, message = get_lock_info([voucher.date, data.date_], voucher.voucher_type, account_types, db) + allowed, message = get_lock_info([voucher.date_, data.date_], voucher.voucher_type, account_types, db) if not allowed: raise HTTPException( status_code=status.HTTP_423_LOCKED, @@ -138,7 +138,7 @@ def update_voucher(id_: uuid.UUID, data: schema_in.JournalIn, user: UserToken, d ) check_voucher_edit_allowed(voucher, user) - voucher.date = data.date_ + voucher.date_ = data.date_ voucher.is_starred = data.is_starred voucher.narration = data.narration voucher.user_id = user.id_ @@ -199,8 +199,8 @@ def show_blank( else: type_ = VoucherType.JOURNAL - additional_info = BlankVoucherInfo(date=get_date(request.session), type=type_) + additional_info = BlankVoucherInfo(date_=get_date(request.session), type_=type_) # type: ignore[arg-type] if a: - additional_info.account = AccountLink(id=a) + additional_info.account = AccountLink(id_=a) with SessionFuture() as db: return blank_voucher(additional_info, db) diff --git a/brewman/brewman/routers/lock_information.py b/brewman/brewman/routers/lock_information.py index 42254ddc..29d87e87 100644 --- a/brewman/brewman/routers/lock_information.py +++ b/brewman/brewman/routers/lock_information.py @@ -70,26 +70,26 @@ def get_info(db: Session) -> list[LockInformation]: data = db.execute(select(DbSetting.data).where(DbSetting.setting_type == SettingType.VOUCHER_LOCK)).scalars().all() return [ LockInformation( - id=item["id_"], - validFrom=item["valid_from"], - validTill=item["valid_till"], - voucherTypes=[ + id_=item["id_"], + valid_from=item["valid_from"], + valid_till=item["valid_till"], + voucher_types=[ VoucherTypesSelected( - id=vt["id_"], + id_=vt["id_"], name=VoucherType(vt["id_"]).name.replace("_", " ").title(), ) for vt in item["voucher_types"] ], - accountTypes=[ + account_types=[ AccountTypesSelected( - id=at["id_"], + id_=at["id_"], name=db.execute(select(AccountType.name).where(AccountType.id == at["id_"])).scalar_one(), ) for at in item["account_types"] ], - start=LockDate(days=item["start"]["days"], date=item["start"]["date_"]), - finish=LockDate(days=item["finish"]["days"], date=item["finish"]["date_"]), + start=LockDate(days=item["start"]["days"], date_=item["start"]["date_"]), + finish=LockDate(days=item["finish"]["days"], date_=item["finish"]["date_"]), index=item["index"], ) - for item in sorted(data, key=lambda d: d["index"], reverse=True) # type: ignore[no-any-return] + for item in sorted(data, key=lambda d: d["index"], reverse=True) ] diff --git a/brewman/brewman/routers/period.py b/brewman/brewman/routers/period.py index 71955f49..e2ba8791 100644 --- a/brewman/brewman/routers/period.py +++ b/brewman/brewman/routers/period.py @@ -93,14 +93,14 @@ def show_id( def period_info(item: Period) -> schemas.Period: return schemas.Period( - id=item.id, - validFrom=item.valid_from, - validTill=item.valid_till, + id_=item.id, + valid_from=item.valid_from, + valid_till=item.valid_till, ) def period_blank(request: Request) -> schemas.PeriodIn: return schemas.PeriodIn( - validFrom=get_start_date(request.session), - validTill=get_finish_date(request.session), + valid_from=get_start_date(request.session), # type: ignore[arg-type] + valid_till=get_finish_date(request.session), # type: ignore[arg-type] ) diff --git a/brewman/brewman/routers/product.py b/brewman/brewman/routers/product.py index 74c468ff..894995b4 100644 --- a/brewman/brewman/routers/product.py +++ b/brewman/brewman/routers/product.py @@ -105,7 +105,7 @@ def update_route( sku.cost_price = round(new_data_sku.cost_price, 2) sku.sale_price = round(new_data_sku.sale_price, 2) else: - count: Decimal = db.execute(select(func.count()).where(Batch.sku_id == sku.id)).scalar_one() + count: int = db.execute(select(func.count()).where(Batch.sku_id == sku.id)).scalar_one() if count > 0: raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, @@ -145,7 +145,7 @@ def delete_route( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"{item.name} is a fixture and cannot be edited or deleted.", ) - count: Decimal = db.execute( + count: int = db.execute( select(func.count()).join(StockKeepingUnit.batches).where(StockKeepingUnit.product_id == id_) ).scalar_one() if count > 0: @@ -217,12 +217,12 @@ async def show_term_sku( rc_price = get_rc_price(item.id, d, v, db) list_.append( ProductSku( - id=sku.id, + id_=sku.id, name=f"{item.name} ({sku.units})", - fractionUnits=item.fraction_units, - costPrice=sku.cost_price if rc_price is None else rc_price, - salePrice=sku.sale_price, - isRateContracted=False if rc_price is None else True, + fraction_units=item.fraction_units, + cost_price=sku.cost_price if rc_price is None else rc_price, + sale_price=sku.sale_price, + is_rate_contracted=False if rc_price is None else True, ) ) return list_ @@ -251,12 +251,12 @@ async def show_term_product( for item in db.execute(query_).unique().scalars().all(): list_.append( ProductSku( - id=item.id, + id_=item.id, name=item.name, - fractionUnits=item.fraction_units, - costPrice=0, - salePrice=0, - isRateContracted=False, + fraction_units=item.fraction_units, + cost_price=Decimal(0), + sale_price=Decimal(0), + is_rate_contracted=False, ) ) return list_ @@ -274,38 +274,38 @@ def show_id( def product_info(product: Product) -> schemas.Product: return schemas.Product( - id=product.id, + id_=product.id, code=product.code, name=product.name, - fractionUnits=product.fraction_units, + fraction_units=product.fraction_units, skus=[ schemas.StockKeepingUnit( - id=sku.id, + id_=sku.id, units=sku.units, fraction=sku.fraction, - productYield=sku.product_yield, - costPrice=sku.cost_price, - salePrice=sku.sale_price, + product_yield=sku.product_yield, + cost_price=sku.cost_price, + sale_price=sku.sale_price, ) for sku in product.skus ], - isActive=product.is_active, - isFixture=product.is_fixture, - isPurchased=product.is_purchased, - isSold=product.is_sold, - productGroup=schemas.ProductGroupLink(id=product.product_group.id, name=product.product_group.name), + is_active=product.is_active, + is_fixture=product.is_fixture, + is_purchased=product.is_purchased, + is_sold=product.is_sold, + product_group=schemas.ProductGroupLink(id_=product.product_group.id, name=product.product_group.name), ) def product_blank() -> schemas.ProductBlank: return schemas.ProductBlank( name="", - fractionUnits="", + fraction_units="", skus=[], - isActive=True, - isPurchased=True, - isSold=False, - isFixture=False, + is_active=True, + is_purchased=True, + is_sold=False, + is_fixture=False, ) diff --git a/brewman/brewman/routers/product_group.py b/brewman/brewman/routers/product_group.py index 4e6580d3..2f8a024a 100644 --- a/brewman/brewman/routers/product_group.py +++ b/brewman/brewman/routers/product_group.py @@ -110,14 +110,14 @@ def show_id( def product_group_info(item: ProductGroup) -> schemas.ProductGroup: return schemas.ProductGroup( - id=item.id, + id_=item.id, name=item.name, - isFixture=item.is_fixture, + is_fixture=item.is_fixture, ) def product_group_blank() -> schemas.ProductGroupBlank: return schemas.ProductGroupBlank( name="", - isFixture=False, + is_fixture=False, ) diff --git a/brewman/brewman/routers/purchase.py b/brewman/brewman/routers/purchase.py index 4bcb14d2..7ad5f282 100644 --- a/brewman/brewman/routers/purchase.py +++ b/brewman/brewman/routers/purchase.py @@ -75,7 +75,7 @@ def save(data: schema_in.PurchaseIn, user: UserToken, db: Session) -> Voucher: .join(Product.skus) .where(StockKeepingUnit.id.in_([i.batch.sku.id_ for i in data.inventories])) ) - account_types = ( + account_types: list[int] = list( db.execute( select(distinct(AccountBase.type_id)).where( or_( @@ -94,7 +94,7 @@ def save(data: schema_in.PurchaseIn, user: UserToken, db: Session) -> Voucher: detail=message, ) voucher = Voucher( - date=data.date_, + date_=data.date_, narration=data.narration, is_starred=data.is_starred, user_id=user.id_, @@ -109,7 +109,7 @@ def save_inventories(voucher: Voucher, vendor_id: uuid.UUID, inventories: list[I sku: StockKeepingUnit = db.execute( select(StockKeepingUnit).where(StockKeepingUnit.id == item.batch.sku.id_) ).scalar_one() - rc_price = rate_contract_price(sku.id, vendor_id, voucher.date, db) + rc_price = rate_contract_price(sku.id, vendor_id, voucher.date_, db) if rc_price is not None and rc_price != item.rate: raise HTTPException( status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, @@ -119,7 +119,7 @@ def save_inventories(voucher: Voucher, vendor_id: uuid.UUID, inventories: list[I item.tax = Decimal(0) item.discount = Decimal(0) batch = Batch( - name=voucher.date, + name=voucher.date_, sku=sku, quantity_remaining=item.quantity, rate=item.rate, @@ -143,7 +143,7 @@ def save_inventories(voucher: Voucher, vendor_id: uuid.UUID, inventories: list[I def save_journals(voucher: Voucher, ven: schema_in.AccountLink, db: Session) -> None: vendor = db.execute(select(AccountBase).where(AccountBase.id == ven.id_)).scalar_one() journals: dict[uuid.UUID, Journal] = {} - amount = 0 + amount = Decimal(0) for i_item in voucher.inventories: account_id, cc_id = db.execute( select(AccountBase.id, AccountBase.cost_centre_id) @@ -165,7 +165,7 @@ def save_journals(voucher: Voucher, ven: schema_in.AccountLink, db: Session) -> debit=-1, cost_centre_id=vendor.cost_centre_id, account_id=vendor.id, - amount=amount, # type: ignore[arg-type] + amount=amount, ) for item in journals.values(): voucher.journals.append(item) @@ -206,7 +206,7 @@ def update_voucher(id_: uuid.UUID, data: schema_in.PurchaseIn, user: UserToken, .join(Product.skus) .where(StockKeepingUnit.id.in_([i.batch.sku.id_ for i in data.inventories])) ) - account_types = ( + account_types: list[int] = list( db.execute( select(distinct(AccountBase.type_id)).where( or_( @@ -218,7 +218,7 @@ def update_voucher(id_: uuid.UUID, data: schema_in.PurchaseIn, user: UserToken, .scalars() .all() ) - allowed, message = get_lock_info([voucher.date, data.date_], voucher.voucher_type, account_types, db) + allowed, message = get_lock_info([voucher.date_, data.date_], voucher.voucher_type, account_types, db) if not allowed: raise HTTPException( status_code=status.HTTP_423_LOCKED, @@ -226,7 +226,7 @@ def update_voucher(id_: uuid.UUID, data: schema_in.PurchaseIn, user: UserToken, ) check_voucher_edit_allowed(voucher, user) - voucher.date = data.date_ + voucher.date_ = data.date_ voucher.is_starred = data.is_starred voucher.narration = data.narration voucher.user_id = user.id_ @@ -248,8 +248,8 @@ def update_inventory(voucher: Voucher, vendor_id: uuid.UUID, inventories: list[I sku: StockKeepingUnit = db.execute( select(StockKeepingUnit).where(StockKeepingUnit.id == item.batch.sku.id) ).scalar_one() - rc_price = rate_contract_price(sku.id, vendor_id, voucher.date, db) - if batch_has_older_vouchers(item.batch_id, voucher.date, voucher.id, db): + rc_price = rate_contract_price(sku.id, vendor_id, voucher.date_, db) + if batch_has_older_vouchers(item.batch_id, voucher.date_, voucher.id, db): raise HTTPException( status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=f"{item.batch.sku.product.name} has older vouchers", @@ -269,7 +269,7 @@ def update_inventory(voucher: Voucher, vendor_id: uuid.UUID, inventories: list[I ) item.batch.quantity_remaining = new_inventory.quantity - quantity_consumed item.quantity = new_inventory.quantity - item.batch.name = voucher.date + item.batch.name = voucher.date_ item.rate = new_inventory.rate item.batch.rate = new_inventory.rate item.discount = new_inventory.discount @@ -314,7 +314,7 @@ def update_journals(voucher: Voucher, ven: schema_in.AccountLink, db: Session) - debit=1, cost_centre_id=cc_id, account_id=account_id, - amount=i_item.amount, # type: ignore[arg-type] + amount=i_item.amount, ) journals[vendor.id] = Journal( debit=-1, @@ -359,7 +359,7 @@ def show_blank( request: Request, user: UserToken = Security(get_user, scopes=["purchase"]), ) -> output.Voucher: - additional_info = BlankVoucherInfo(date=get_date(request.session), type=VoucherType.PURCHASE) + additional_info = BlankVoucherInfo(date_=get_date(request.session), type_=VoucherType.PURCHASE) # type: ignore with SessionFuture() as db: return blank_voucher(additional_info, db) @@ -380,6 +380,6 @@ def batch_has_older_vouchers(id_: uuid.UUID, date_: date, voucher_id: uuid.UUID, select(func.count()) .join(Batch.inventories) .join(Inventory.voucher) - .where(Batch.id == id_, Voucher.date < date_, Voucher.id != voucher_id) + .where(Batch.id == id_, Voucher.date_ < date_, Voucher.id != voucher_id) ).scalar_one() return count_ > 0 diff --git a/brewman/brewman/routers/purchase_return.py b/brewman/brewman/routers/purchase_return.py index 232a37b5..4e9689be 100644 --- a/brewman/brewman/routers/purchase_return.py +++ b/brewman/brewman/routers/purchase_return.py @@ -72,8 +72,8 @@ def save(data: schema_in.PurchaseIn, user: UserToken, db: Session) -> Voucher: .join(Product.skus) .where(StockKeepingUnit.id.in_([i.batch.sku.id_ for i in data.inventories])) ) - account_types = ( - db.execute( + account_types: list[int] = list( + db.execute( # ignore[assignment] select(distinct(AccountBase.type_id)).where( or_( AccountBase.id == data.vendor.id_, @@ -91,7 +91,7 @@ def save(data: schema_in.PurchaseIn, user: UserToken, db: Session) -> Voucher: detail=message, ) voucher = Voucher( - date=data.date_, + date_=data.date_, narration=data.narration, is_starred=data.is_starred, user_id=user.id_, @@ -110,7 +110,7 @@ def save_inventories(voucher: Voucher, inventories: list[InventorySchema], db: S status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=f"{batch.sku.product.name} ({batch.sku.units}) stock is {batch.quantity_remaining}", ) - if batch.name > voucher.date: + if batch.name > voucher.date_: raise HTTPException( status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=f"{batch.sku.product.name} ({batch.sku.units}) " @@ -200,7 +200,7 @@ def update_voucher(id_: uuid.UUID, data: schema_in.PurchaseIn, user: UserToken, .join(Product.skus) .where(StockKeepingUnit.id.in_([i.batch.sku.id_ for i in data.inventories])) ) - account_types = ( + account_types: list[int] = list( db.execute( select(distinct(AccountBase.type_id)).where( or_( @@ -212,14 +212,14 @@ def update_voucher(id_: uuid.UUID, data: schema_in.PurchaseIn, user: UserToken, .scalars() .all() ) - allowed, message = get_lock_info([voucher.date, data.date_], voucher.voucher_type, account_types, db) + allowed, message = get_lock_info([voucher.date_, data.date_], voucher.voucher_type, account_types, db) if not allowed: raise HTTPException( status_code=status.HTTP_423_LOCKED, detail=message, ) check_voucher_edit_allowed(voucher, user) - voucher.date = data.date_ + voucher.date_ = data.date_ voucher.is_starred = data.is_starred voucher.narration = data.narration voucher.user_id = user.id_ @@ -244,7 +244,7 @@ def update_inventory(voucher: Voucher, new_inventories: list[InventorySchema], d detail=f"Maximum quantity available for " f"{batch.sku.product.name} ({batch.sku.units}) is {batch_quantity}", ) - if batch.name > voucher.date: + if batch.name > voucher.date_: raise HTTPException( status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=f"Voucher cannot be before {item.batch.name.strftime('%d-%b-%Y')}", @@ -280,7 +280,7 @@ def update_journals(voucher: Voucher, ven: schema_in.AccountLink, db: Session) - debit=-1, cost_centre_id=cc_id, account_id=account_id, - amount=v_item.amount, # type: ignore[arg-type] + amount=v_item.amount, ) journals[vendor.id] = Journal( debit=1, @@ -325,6 +325,6 @@ def show_blank( request: Request, user: UserToken = Security(get_user, scopes=["purchase-return"]), ) -> output.Voucher: - additional_info = BlankVoucherInfo(date=get_date(request.session), type=VoucherType.PURCHASE_RETURN) + additional_info = BlankVoucherInfo(date_=get_date(request.session), type_=VoucherType.PURCHASE_RETURN) # type: ignore[arg-type] with SessionFuture() as db: return blank_voucher(additional_info, db) diff --git a/brewman/brewman/routers/rate_contract.py b/brewman/brewman/routers/rate_contract.py index 047342e0..ba07f3d6 100644 --- a/brewman/brewman/routers/rate_contract.py +++ b/brewman/brewman/routers/rate_contract.py @@ -37,7 +37,7 @@ async def save( try: with SessionFuture() as db: item = RateContract( - date=data.date_, + date_=data.date_, vendor_id=data.vendor.id_, valid_from=data.valid_from, valid_till=data.valid_till, @@ -46,8 +46,8 @@ async def save( ) db.add(item) add_items(item, data.items, db) - set_date(data.date_.strftime("%d-%b-%Y"), request.session) - set_period(data.valid_from.strftime("%d-%b-%Y"), data.valid_till.strftime("%d-%b-%Y"), request.session) + set_date(data.date_, request.session) + set_period(data.valid_from, data.valid_till, request.session) db.commit() return rate_contract_info(item) except SQLAlchemyError as e: @@ -74,15 +74,15 @@ async def update_route( try: with SessionFuture() as db: item: RateContract = db.execute(select(RateContract).where(RateContract.id == id_)).scalar_one() - item.date = data.date_ + item.date_ = data.date_ item.vendor_id = data.vendor.id_ item.valid_from = data.valid_from item.valid_till = data.valid_till item.narration = data.narration item.user_id = user.id_ update_items(item, data.items, db) - set_date(data.date_.strftime("%d-%b-%Y"), request.session) - set_period(data.valid_from.strftime("%d-%b-%Y"), data.valid_till.strftime("%d-%b-%Y"), request.session) + set_date(data.date_, request.session) + set_period(data.valid_from, data.valid_till, request.session) db.commit() return rate_contract_info(item) except SQLAlchemyError as e: @@ -134,7 +134,7 @@ async def show_list( with SessionFuture() as db: return [ rate_contract_info(item) - for item in db.execute(select(RateContract).order_by(RateContract.date)).scalars().all() + for item in db.execute(select(RateContract).order_by(RateContract.date_)).scalars().all() ] @@ -150,20 +150,20 @@ async def show_id( def rate_contract_info(item: RateContract) -> RateContractSchema: return RateContractSchema( - id=item.id, - date=item.date, - vendor=AccountLink(id=item.vendor_id, name=item.vendor.name), - validFrom=item.valid_from, - validTill=item.valid_till, + id_=item.id, + date_=item.date_, + vendor=AccountLink(id_=item.vendor_id, name=item.vendor.name), + valid_from=item.valid_from, + valid_till=item.valid_till, narration=item.narration, - creationDate=item.creation_date, - lastEditDate=item.last_edit_date, - user=UserLink(id=item.user_id, name=item.user.name), + creation_date=item.creation_date, + last_edit_date=item.last_edit_date, + user=UserLink(id_=item.user_id, name=item.user.name), items=[ RateContractItemSchema( - id=i.id, + id_=i.id, sku=ProductLink( - id=i.sku_id, name=f"{i.sku.product.name} ({i.sku.units})" if i.sku.units else i.sku.product.name + id_=i.sku_id, name=f"{i.sku.product.name} ({i.sku.units})" if i.sku.units else i.sku.product.name ), price=i.price, ) @@ -174,9 +174,9 @@ def rate_contract_info(item: RateContract) -> RateContractSchema: def rate_contract_blank(session: dict) -> RateContractBlank: return RateContractBlank( - date=get_date(session), - validFrom=get_start_date(session), - validTill=get_finish_date(session), + date_=get_date(session), # type: ignore[arg-type] + valid_from=get_start_date(session), # type: ignore[arg-type] + valid_till=get_finish_date(session), # type: ignore[arg-type] narration="", items=[], ) diff --git a/brewman/brewman/routers/rebase.py b/brewman/brewman/routers/rebase.py index e6ecc0af..e38a119b 100644 --- a/brewman/brewman/routers/rebase.py +++ b/brewman/brewman/routers/rebase.py @@ -1,3 +1,4 @@ +# mypy: disable-error-code="arg-type" import uuid from datetime import date, datetime, timedelta @@ -56,17 +57,17 @@ def rebase( db.commit() -def save_starred(date_: date, db: Session) -> list[Voucher]: +def save_starred(date_: date, db: Session) -> list[uuid.UUID]: accounts = [ i.id for i in db.execute(select(AccountBase.id).where(AccountBase.is_starred == True)).all() # noqa: E712 ] - vouchers = [] + vouchers: list[uuid.UUID] = [] query = ( db.execute( select(Voucher) .join(Voucher.journals) .join(Journal.account) - .where(Voucher.date < date_, Voucher.journals.any(Journal.account_id.in_(accounts))) + .where(Voucher.date_ < date_, Voucher.journals.any(Journal.account_id.in_(accounts))) ) .unique() .scalars() @@ -113,7 +114,7 @@ def opening_accounts(date_: date, user_id: uuid.UUID, db: Session) -> Voucher: .where( AccountBase.is_starred == False, # noqa: E712 AccountBase.id != AccountBase.suspense(), - Voucher.date < date_, + Voucher.date_ < date_, Voucher.voucher_type != VoucherType.ISSUE, ) .having(sum_func != 0) @@ -122,7 +123,7 @@ def opening_accounts(date_: date, user_id: uuid.UUID, db: Session) -> Voucher: dt = date_ - timedelta(days=1) voucher = Voucher( - date=dt, + date_=dt, narration="Opening Accounts", user_id=user_id, posted=True, @@ -158,14 +159,14 @@ def opening_batches(date_: date, user_id: uuid.UUID, db: Session) -> Voucher: .join(Batch.inventories) .join(Inventory.voucher) .join(Voucher.journals) - .where(Voucher.date < date_, Journal.cost_centre_id == CostCentre.cost_centre_purchase()) + .where(Voucher.date_ < date_, Journal.cost_centre_id == CostCentre.cost_centre_purchase()) .having(sum_func != 0) .group_by(Batch) ).all() dt = date_ - timedelta(days=1) voucher = Voucher( - date=dt, + date_=dt, narration="Opening Batches", user_id=user_id, posted=True, @@ -204,9 +205,9 @@ def opening_batches(date_: date, user_id: uuid.UUID, db: Session) -> Voucher: return voucher -def delete_data(date_: date, vouchers: list[Voucher], db: Session) -> None: +def delete_data(date_: date, vouchers: list[uuid.UUID], db: Session) -> None: sub_voucher = aliased(Voucher) - sub_query = select(sub_voucher.id).where(sub_voucher.date < date_).subquery() + sub_query = select(sub_voucher.id).where(sub_voucher.date_ < date_).subquery() db.execute( delete(Inventory).where(Inventory.voucher_id.in_(sub_query)).execution_options(synchronize_session=False) @@ -237,7 +238,7 @@ def delete_data(date_: date, vouchers: list[Voucher], db: Session) -> None: ) db.execute( delete(Voucher) - .where(Voucher.date < date_, ~Voucher.id.in_(vouchers)) + .where(Voucher.date_ < date_, ~Voucher.id.in_(vouchers)) .execution_options(synchronize_session=False) ) @@ -250,7 +251,7 @@ def cleanup_lint(date_: date, db: Session) -> None: .execution_options(synchronize_session=False) ) db.execute(delete(Fingerprint).where(Fingerprint.date < date_).execution_options(synchronize_session=False)) - db.execute(delete(Attendance).where(Attendance.date < date_).execution_options(synchronize_session=False)) + db.execute(delete(Attendance).where(Attendance.date_ < date_).execution_options(synchronize_session=False)) db.execute( delete(Employee) .where( diff --git a/brewman/brewman/routers/recipe.py b/brewman/brewman/routers/recipe.py index 0419fd75..4c7aa232 100644 --- a/brewman/brewman/routers/recipe.py +++ b/brewman/brewman/routers/recipe.py @@ -4,7 +4,9 @@ import uuid from collections import defaultdict from datetime import date +from decimal import Decimal from io import BytesIO +from typing import Sequence import brewman.schemas.recipe as schemas import brewman.schemas.recipe_item as rischemas @@ -51,7 +53,7 @@ def save( detail="Recipe has no ingredients", ) recipe = Recipe( - date=data.date_, + date_=data.date_, source=data.source, instructions=data.instructions, garnishing=data.garnishing, @@ -101,7 +103,7 @@ async def update_route( recipe.sku = sku recipe.recipe_yield = round(data.recipe_yield, 2) - recipe.date = data.date_ + recipe.date_ = data.date_ recipe.source = data.source recipe.instructions = data.instructions recipe.garnishing = data.garnishing @@ -166,7 +168,7 @@ def delete_route( ) -> None: with SessionFuture() as db: recipe: Recipe = db.execute(select(Recipe).where(Recipe.id == id_)).scalar_one() - recipe_ids: list[uuid.UUID] = ( + recipe_ids: Sequence[uuid.UUID] = ( db.execute( select(func.distinct(RecipeItem.recipe_id)).where( RecipeItem.product_id @@ -203,7 +205,7 @@ async def show_list( user: UserToken = Depends(get_user), ) -> list[schemas.Recipe]: with SessionFuture() as db: - list_: list[Recipe] = ( + list_: Sequence[Recipe] = ( db.execute( select(Recipe) .options(joinedload(Recipe.sku, innerjoin=True).joinedload(StockKeepingUnit.product, innerjoin=True)) @@ -214,16 +216,16 @@ async def show_list( ) return [ schemas.Recipe( - id=item.id, - sku=schemas.ProductLink(id=item.sku.id, name=item.sku.product.name), - date=item.date, + id_=item.id, + sku=schemas.ProductLink(id_=item.sku.id, name=item.sku.product.name), + date_=item.date_, source=item.source, instructions=item.instructions, garnishing=item.garnishing, plating=item.plating, - recipeYield=item.recipe_yield, + recipe_yield=item.recipe_yield, notes=item.notes, - productGroupId=item.sku.product.product_group_id, + product_group_id=item.sku.product.product_group_id, units=item.sku.units, items=[], ) @@ -239,7 +241,7 @@ async def show_list( # with SessionFuture() as db: # product: Product = db.execute(select(Product).join(Product.skus).where(Product.id == id_)).unique().scalar_one() # return ProductSku( -# id=id_, +# id_=id_, # name=product.name, # fractionUnits=product.fraction_units, # isRateContracted=False, @@ -278,7 +280,7 @@ def get_report( ) if p is not None: q = q.where(Recipe.sku, StockKeepingUnit.product, Product.product_group_id == p) - list_: list[Recipe] = db.execute(q).unique().scalars().all() + list_: Sequence[Recipe] = db.execute(q).unique().scalars().all() e = excel(sorted(list_, key=lambda r: r.sku.product.name)) e.seek(0) @@ -286,7 +288,7 @@ def get_report( return StreamingResponse(e, media_type="text/xlsx", headers=headers) -def excel(recipes: list[Recipe]) -> None: +def excel(recipes: list[Recipe]) -> BytesIO: wb = Workbook() wb.active.title = "Rate List" pgs = set([x.sku.product.product_group.name for x in recipes]) @@ -325,7 +327,7 @@ def excel(recipes: list[Recipe]) -> None: return virtual_workbook -def register_styles(wb: Workbook): +def register_styles(wb: Workbook) -> tuple[NamedStyle, NamedStyle, NamedStyle, NamedStyle, NamedStyle]: bd = Side(style="thin", color="000000") recipe_name = NamedStyle(name="recipe_name") @@ -371,23 +373,23 @@ def show_id( def recipe_info(recipe: Recipe) -> schemas.Recipe: return schemas.Recipe( - id=recipe.id, + id_=recipe.id, sku=schemas.ProductLink( - id=recipe.sku_id, + id_=recipe.sku_id, name=f"{recipe.sku.product.name} ({recipe.sku.units})", ), - date=recipe.date, + date_=recipe.date_, source=recipe.source, instructions=recipe.instructions, garnishing=recipe.garnishing, plating=recipe.plating, - recipeYield=recipe.recipe_yield, + recipe_yield=recipe.recipe_yield, notes="", items=[ rischemas.RecipeItem( - id=item.id, + id_=item.id, product=schemas.ProductLink( - id=item.product.id, + id_=item.product.id, name=f"{item.product.name} ({item.product.fraction_units})", ), quantity=round(item.quantity, 2), @@ -400,13 +402,12 @@ def recipe_info(recipe: Recipe) -> schemas.Recipe: def recipe_blank() -> schemas.RecipeBlank: return schemas.RecipeBlank( - date=date.today(), + date_=date.today(), source="", instructions="", garnishing="", plating="", - recipeYield=1, - isLocked=False, + recipe_yield=Decimal(1), notes="", items=[], ) diff --git a/brewman/brewman/routers/recipe_template.py b/brewman/brewman/routers/recipe_template.py index dddec3a7..0be8b59f 100644 --- a/brewman/brewman/routers/recipe_template.py +++ b/brewman/brewman/routers/recipe_template.py @@ -26,7 +26,7 @@ def save( date_ = data.date_ if data.date_ is not None else datetime.date.today() if data.selected: db.execute(update(RecipeTemplate).values(selected=False)) - item = RecipeTemplate(id=None, name=data.name, date=date_, text=data.text, selected=data.selected) + item = RecipeTemplate(id=None, name=data.name, date_=date_, text=data.text, selected=data.selected) db.add(item) db.commit() return None @@ -52,7 +52,7 @@ def update_route( item.name = data.name item.text = data.text item.selected = data.selected - item.date = date_ + item.date_ = date_ db.commit() return None except SQLAlchemyError as e: @@ -83,7 +83,7 @@ def delete_route( def show_blank( user: UserToken = Security(get_user, scopes=["recipes"]), ) -> schemas.RecipeTemplateIn: - return schemas.RecipeTemplateIn(name="", date=datetime.date.today(), text="", selected=False) + return schemas.RecipeTemplateIn(name="", date_=datetime.date.today(), text="", selected=False) @router.get("/list", response_model=list[schemas.RecipeTemplate]) @@ -93,7 +93,8 @@ async def show_list( with SessionFuture() as db: list_ = db.execute(select(RecipeTemplate).order_by(RecipeTemplate.name)).scalars().all() return [ - schemas.RecipeTemplate(id=i.id, name=i.name, date=i.date, text=i.text, selected=i.selected) for i in list_ + schemas.RecipeTemplate(id_=i.id, name=i.name, date_=i.date_, text=i.text, selected=i.selected) + for i in list_ ] @@ -105,5 +106,5 @@ def show_id( with SessionFuture() as db: item = db.execute(select(RecipeTemplate).where(RecipeTemplate.id == id_)).scalar_one() return schemas.RecipeTemplate( - id=item.id, name=item.name, date=item.date, text=item.text, selected=item.selected + id_=item.id, name=item.name, date_=item.date_, text=item.text, selected=item.selected ) diff --git a/brewman/brewman/routers/reports/balance_sheet.py b/brewman/brewman/routers/reports/balance_sheet.py index e6747fa5..84775015 100644 --- a/brewman/brewman/routers/reports/balance_sheet.py +++ b/brewman/brewman/routers/reports/balance_sheet.py @@ -29,7 +29,7 @@ def report_blank( request: Request, user: UserToken = Security(get_user, scopes=["balance-sheet"]), ) -> schemas.BalanceSheet: - return schemas.BalanceSheet(date=get_finish_date(request.session), body=[], footer=None) + return schemas.BalanceSheet(date_=get_finish_date(request.session), body=[], footer=None) @router.get("/{date_}", response_model=schemas.BalanceSheet) @@ -41,7 +41,7 @@ def report_data( with SessionFuture() as db: body, footer = build_balance_sheet(datetime.strptime(date_, "%d-%b-%Y"), db) set_period(get_start_date(request.session), date_, request.session) - return schemas.BalanceSheet(date=date_, body=body, footer=footer) + return schemas.BalanceSheet(date_=date_, body=body, footer=footer) def build_balance_sheet(date_: date, db: Session) -> tuple[list[schemas.BalanceSheetItem], schemas.BalanceSheetItem]: @@ -59,7 +59,7 @@ def build_balance_sheet(date_: date, db: Session) -> tuple[list[schemas.BalanceS name="Net Loss" if net_profit >= 0 else "Net Profit", group="", amount=Decimal(0), - subAmount=round(net_profit, 2), + sub_amount=round(net_profit, 2), order=79000, ) ) @@ -69,14 +69,14 @@ def build_balance_sheet(date_: date, db: Session) -> tuple[list[schemas.BalanceS name="", group=capital_group.name, amount=round(total_amount, 2), - subAmount=Decimal(0), + sub_amount=Decimal(0), order=capital_group.order, ) total_amount += closing_stock report.append( schemas.BalanceSheetItem( - name="Closing Stock", group="", amount=Decimal(0), subAmount=round(closing_stock, 2), order=20001 + name="Closing Stock", group="", amount=Decimal(0), sub_amount=round(closing_stock, 2), order=20001 ) ) @@ -85,7 +85,7 @@ def build_balance_sheet(date_: date, db: Session) -> tuple[list[schemas.BalanceS name="", group=asset_group.name, amount=round(closing_stock, 2), - subAmount=Decimal(0), + sub_amount=Decimal(0), order=asset_group.order, ) @@ -95,11 +95,11 @@ def build_balance_sheet(date_: date, db: Session) -> tuple[list[schemas.BalanceS .join(Journal.voucher) .join(Journal.account) .where( - Voucher.date <= date_, + Voucher.date_ <= date_, not_(Voucher.voucher_type.in_([VoucherType.ISSUE, VoucherType.CLOSING_STOCK])), AccountBase.type_id.in_(type_list), ) - .group_by(AccountBase) + .group_by(AccountBase) # type: ignore .order_by(AccountBase.type_id, desc(func.abs(amount_sum))) ).all() @@ -114,7 +114,7 @@ def build_balance_sheet(date_: date, db: Session) -> tuple[list[schemas.BalanceS name=account.name, group="", amount=Decimal(0), - subAmount=round(amount, 2), + sub_amount=round(amount, 2), order=account.type_.order + counter, ) ) @@ -125,7 +125,7 @@ def build_balance_sheet(date_: date, db: Session) -> tuple[list[schemas.BalanceS name="", group=account.type_.name, amount=round(amount, 2), - subAmount=Decimal(0), + sub_amount=Decimal(0), order=account.type_.order, ) diff --git a/brewman/brewman/routers/reports/cash_flow.py b/brewman/brewman/routers/reports/cash_flow.py index 78262246..dcfbc065 100644 --- a/brewman/brewman/routers/reports/cash_flow.py +++ b/brewman/brewman/routers/reports/cash_flow.py @@ -1,4 +1,5 @@ from datetime import date, datetime +from decimal import Decimal import brewman.schemas.cash_flow as schemas @@ -27,8 +28,8 @@ def report_blank( user: UserToken = Security(get_user, scopes=["cash-flow"]), ) -> schemas.CashFlow: return schemas.CashFlow( - startDate=get_start_date(request.session), - finishDate=get_finish_date(request.session), + start_date=get_start_date(request.session), + finish_date=get_finish_date(request.session), body=schemas.CashFlowBody(operating=[], investing=[], financing=[], details=[]), footer=[], ) @@ -47,8 +48,8 @@ def report_data( body, footer = build_report(start_date, finish_date, db) set_period(s, f, request.session) return schemas.CashFlow( - startDate=s, - finishDate=f, + start_date=s, + finish_date=f, body=body, footer=footer, ) @@ -68,8 +69,8 @@ def report_id( body, footer = build_report_id(id_, start_date, finish_date, db) set_period(s, f, request.session) return schemas.CashFlow( - startDate=s, - finishDate=f, + start_date=s, + finish_date=f, body=body, footer=footer, ) @@ -84,8 +85,8 @@ def build_report( .join(Journal.account) .where( AccountBase.type_id == select(AccountType.id).where(AccountType.name == "Cash").scalar_subquery(), - Voucher.date >= start_date, - Voucher.date <= finish_date, + Voucher.date_ >= start_date, + Voucher.date_ <= finish_date, ) ) @@ -98,11 +99,11 @@ def build_report( Voucher.id.in_(sub_query), AccountBase.type_id != select(AccountType.id).where(AccountType.name == "Cash").scalar_subquery(), ) - .group_by(AccountType) + .group_by(AccountType) # type: ignore .order_by(func.sum(Journal.signed_amount)) ).all() - total_amount = 0 + total_amount = Decimal(0) cf: schemas.CashFlowBody = schemas.CashFlowBody(operating=[], investing=[], financing=[], details=[]) dict_ = {"operating": cf.operating, "investing": cf.investing, "financing": cf.investing, "details": cf.details} for account_type, amount in query: @@ -115,27 +116,27 @@ def build_report( ) ) - opening = db.execute( + opening: Decimal = db.execute( select(func.sum(Journal.amount * Journal.debit)) .join(Journal.voucher) .join(Journal.account) .where( - Voucher.date < start_date, + Voucher.date_ < start_date, not_(Voucher.voucher_type.in_([VoucherType.ISSUE, VoucherType.CLOSING_STOCK])), AccountBase.type_id == select(AccountType.id).where(AccountType.name == "Cash"), ) - ).scalar() + ).scalar() or Decimal(0) - closing = db.execute( + closing: Decimal = db.execute( select(func.sum(Journal.amount * Journal.debit)) .join(Journal.voucher) .join(Journal.account) .where( - Voucher.date <= finish_date, + Voucher.date_ <= finish_date, not_(Voucher.voucher_type.in_([VoucherType.ISSUE, VoucherType.CLOSING_STOCK])), AccountBase.type_id == select(AccountType.id).where(AccountType.name == "Cash"), ) - ).scalar() + ).scalar() or Decimal(0) return ( cf, @@ -166,8 +167,8 @@ def build_report_id( .join(Journal.account) .where( AccountBase.type_id == select(AccountType.id).where(AccountType.name == "Cash").scalar_subquery(), - Voucher.date >= start_date, - Voucher.date <= finish_date, + Voucher.date_ >= start_date, + Voucher.date_ <= finish_date, ) ) @@ -176,11 +177,11 @@ def build_report_id( .join(Journal, Voucher.journals) .join(AccountBase, Journal.account) .where(Voucher.id.in_(sub_query), AccountBase.type_id == account_type) - .group_by(AccountBase) + .group_by(AccountBase) # type: ignore .order_by(desc(func.sum(Journal.amount))) ).all() - total_amount = 0 + total_amount = Decimal(0) for account, amount in query: total_amount += amount * -1 details.append( diff --git a/brewman/brewman/routers/reports/closing_stock.py b/brewman/brewman/routers/reports/closing_stock.py index 36dbe431..efa573f7 100644 --- a/brewman/brewman/routers/reports/closing_stock.py +++ b/brewman/brewman/routers/reports/closing_stock.py @@ -38,9 +38,9 @@ def report_blank( user: UserToken = Security(get_user, scopes=["closing-stock"]), ) -> schemas.ClosingStock: return schemas.ClosingStock( - date=get_finish_date(request.session), + date_=get_finish_date(request.session), # type: ignore posted=False, - costCentre=schemas.CostCentreLink(id=CostCentre.cost_centre_purchase()), + cost_centre=schemas.CostCentreLink(id_=CostCentre.cost_centre_purchase()), items=[], ) @@ -92,7 +92,7 @@ def post_voucher( vouchers = ( db.execute( select(Voucher.id).where( - Voucher.date == date_obj, Voucher.voucher_type == VoucherType.CLOSING_STOCK + Voucher.date_ == date_obj, Voucher.voucher_type == VoucherType.CLOSING_STOCK ) ) .scalars() @@ -117,21 +117,21 @@ def post_voucher( def full_report(date_: date, cost_centre_id: uuid.UUID, db: Session) -> schemas.ClosingStock: voucher = ( - db.execute(select(Voucher).where(Voucher.date == date_, Voucher.voucher_type == VoucherType.CLOSING_STOCK)) + db.execute(select(Voucher).where(Voucher.date_ == date_, Voucher.voucher_type == VoucherType.CLOSING_STOCK)) .scalars() .first() ) return schemas.ClosingStock( - date=date_, - costCentre=schemas.CostCentreLink(id=cost_centre_id), + date_=date_, + cost_centre=schemas.CostCentreLink(id_=cost_centre_id), items=build_report(date_, cost_centre_id, db), - creationDate=voucher.creation_date if voucher is not None else None, - lastEditDate=voucher.last_edit_date if voucher is not None else None, - user=schemas.UserLink(id=voucher.user.id, name=voucher.user.name) if voucher is not None else None, + creation_date=voucher.creation_date if voucher is not None else None, + last_edit_date=voucher.last_edit_date if voucher is not None else None, + user=schemas.UserLink(id_=voucher.user.id, name=voucher.user.name) if voucher is not None else None, posted=voucher.posted if voucher is not None else False, poster=None if voucher is None or voucher.poster is None - else schemas.UserLink(id=voucher.poster.id, name=voucher.poster.name), + else schemas.UserLink(id_=voucher.poster.id, name=voucher.poster.name), ) @@ -148,11 +148,11 @@ def build_report(date_: date, cost_centre_id: uuid.UUID, db: Session) -> list[sc .join(Voucher.journals) .options(contains_eager(StockKeepingUnit.product).contains_eager(Product.product_group)) .where( - Voucher.date <= date_, + Voucher.date_ <= date_, Journal.cost_centre_id == cost_centre_id, - or_(Voucher.voucher_type != VoucherType.CLOSING_STOCK, Voucher.date != date_), + or_(Voucher.voucher_type != VoucherType.CLOSING_STOCK, Voucher.date_ != date_), ) - .group_by(StockKeepingUnit, Product, ProductGroup) + .group_by(StockKeepingUnit, Product, ProductGroup) # type: ignore .order_by(ProductGroup.name, Product.name, StockKeepingUnit.units) ).all() @@ -171,7 +171,7 @@ def build_report(date_: date, cost_centre_id: uuid.UUID, db: Session) -> list[sc .join(Inventory.batch) .where( Voucher.voucher_type == VoucherType.CLOSING_STOCK, - Voucher.date == date_, + Voucher.date_ == date_, Journal.cost_centre_id != cost_centre_id, Voucher.id.in_(select(Journal.voucher_id).where(Journal.cost_centre_id == cost_centre_id)), ) @@ -183,16 +183,16 @@ def build_report(date_: date, cost_centre_id: uuid.UUID, db: Session) -> list[sc if quantity != 0 and amount != 0: id_ = next((p.id for p in physical_list if p.sku_id == sku.id), None) physical = next((p.quantity for p in physical_list if p.sku_id == sku.id), quantity) - cc = next((schemas.CostCentreLink(id=c) for (c, s) in ccs if s == sku.id), None) + cc = next((schemas.CostCentreLink(id_=c) for (c, s) in ccs if s == sku.id), None) body.append( schemas.ClosingStockItem( - id=id_, - product=schemas.ProductLink(id=sku.id, name=f"{sku.product.name} ({sku.units})"), + id_=id_, + product=schemas.ProductLink(id_=sku.id, name=f"{sku.product.name} ({sku.units})"), group=sku.product.product_group.name, quantity=quantity, amount=amount, physical=physical, - costCentre=cc, + cost_centre=cc, ) ) return body @@ -204,7 +204,7 @@ def get_opening_stock(date_: date, db: Session) -> Decimal: .join(Journal.voucher) .join(Journal.account) .join(Voucher.inventories) - .where(Voucher.date < date_, Journal.cost_centre_id == CostCentre.cost_centre_purchase()) + .where(Voucher.date_ < date_, Journal.cost_centre_id == CostCentre.cost_centre_purchase()) ).scalar() return Decimal(0) if opening_stock is None else opening_stock @@ -215,7 +215,7 @@ def get_closing_stock(date_: date, db: Session) -> Decimal: .join(Journal.voucher) .join(Journal.account) .join(Voucher.inventories) - .where(Voucher.date <= date_, Journal.cost_centre_id == CostCentre.cost_centre_purchase()) + .where(Voucher.date_ <= date_, Journal.cost_centre_id == CostCentre.cost_centre_purchase()) ).scalar() return Decimal(0) if closing_stock is None else closing_stock @@ -264,7 +264,7 @@ def save_route( items = [d for d in data.items if d.cost_centre is not None and d.cost_centre.id_ == dep] item = save(data.date_, items, user, db) save_inventories(item, items, db) - amount: Decimal = sum(i.amount for i in item.inventories) # type: ignore[assignment, misc] + amount: Decimal = sum(i.amount for i in item.inventories) or Decimal(0) save_journals(item, data.cost_centre.id_, dep, amount, db) check_journals_are_valid(item) db.commit() @@ -286,10 +286,10 @@ def save_cs(data: schemas.ClosingStock, db: Session) -> None: def save(date_: date, items: list[schemas.ClosingStockItem], user: UserToken, db: Session) -> Voucher: - product_accounts = ( + product_accounts: list[uuid.UUID] = list( # type: ignore select(Product.account_id).join(Product.skus).where(StockKeepingUnit.id.in_([i.product.id_ for i in items])) ) - account_types = ( + account_types: list[int] = list( db.execute(select(distinct(AccountBase.type_id)).where(AccountBase.id.in_(product_accounts))).scalars().all() ) allowed, message = get_lock_info([date_], VoucherType.CLOSING_STOCK, account_types, db) @@ -299,7 +299,7 @@ def save(date_: date, items: list[schemas.ClosingStockItem], user: UserToken, db detail=message, ) voucher = Voucher( - date=date_, + date_=date_, narration="", is_starred=False, user_id=user.id_, @@ -311,10 +311,10 @@ def save(date_: date, items: list[schemas.ClosingStockItem], user: UserToken, db def save_inventories(voucher: Voucher, items: list[schemas.ClosingStockItem], db: Session) -> None: for item in items: - batches = ( + batches = list( db.execute( select(Batch) - .where(Batch.sku_id == item.product.id_, Batch.quantity_remaining != 0, Batch.name <= voucher.date) + .where(Batch.sku_id == item.product.id_, Batch.quantity_remaining != 0, Batch.name <= voucher.date_) .order_by(Batch.name) ) .scalars() @@ -381,7 +381,7 @@ def update_cs(date_: date, cost_centre_id: uuid.UUID, items: list[schemas.Closin def delete_old_vouchers(date_: date, cost_centre_id: uuid.UUID, db: Session) -> None: vouchers = ( - db.execute(select(Voucher.id).where(Voucher.date == date_, Voucher.voucher_type == VoucherType.CLOSING_STOCK)) + db.execute(select(Voucher.id).where(Voucher.date_ == date_, Voucher.voucher_type == VoucherType.CLOSING_STOCK)) .scalars() .all() ) diff --git a/brewman/brewman/routers/reports/daybook.py b/brewman/brewman/routers/reports/daybook.py index 2a58c0f4..5feba9fe 100644 --- a/brewman/brewman/routers/reports/daybook.py +++ b/brewman/brewman/routers/reports/daybook.py @@ -1,4 +1,5 @@ from datetime import date, datetime +from decimal import Decimal import brewman.schemas.daybook as schemas @@ -24,8 +25,8 @@ def report_blank( user: UserToken = Security(get_user, scopes=["daybook"]), ) -> schemas.Daybook: return schemas.Daybook( - startDate=get_start_date(request.session), - finishDate=get_finish_date(request.session), + start_date=get_start_date(request.session), + finish_date=get_finish_date(request.session), body=[], ) @@ -42,7 +43,7 @@ def report_data( with SessionFuture() as db: body = build_report(start_date, finish_date, db) set_period(start, finish, request.session) - return schemas.Daybook(startDate=start_date, finishDate=finish_date, body=body) + return schemas.Daybook(start_date=start_date, finish_date=finish_date, body=body) def build_report(start_date: date, finish_date: date, db: Session) -> list[schemas.DaybookItem]: @@ -54,11 +55,11 @@ def build_report(start_date: date, finish_date: date, db: Session) -> list[schem .join(Voucher.journals) .join(Journal.account) .where( - Voucher.date >= start_date, - Voucher.date <= finish_date, + Voucher.date_ >= start_date, + Voucher.date_ <= finish_date, not_(Voucher.voucher_type.in_([VoucherType.ISSUE, VoucherType.CLOSING_STOCK])), ) - .order_by(Voucher.date, Voucher.last_edit_date) + .order_by(Voucher.date_, Voucher.last_edit_date) ) .unique() .scalars() @@ -66,8 +67,8 @@ def build_report(start_date: date, finish_date: date, db: Session) -> list[schem ) for voucher in query: - debit = 0 - credit = 0 + debit = Decimal(0) + credit = Decimal(0) name_debit = "" name_credit = "" for journal in voucher.journals: @@ -82,20 +83,20 @@ def build_report(start_date: date, finish_date: date, db: Session) -> list[schem body.append( schemas.DaybookItem( - id=voucher.id, - date=voucher.date.strftime("%d-%b-%Y"), + id_=voucher.id, + date_=voucher.date_, url=[ "/", voucher.voucher_type.name.replace("_", "-").lower(), str(voucher.id), ], - type=voucher.voucher_type.name.replace("_", " ").title(), + type_=voucher.voucher_type.name.replace("_", " ").title(), narration=voucher.narration, posted=voucher.posted, - debitText=name_debit, - debitAmount=debit, - creditText=name_credit, - creditAmount=credit, + debit_text=name_debit, + debit_amount=debit, + credit_text=name_credit, + credit_amount=credit, ) ) return body diff --git a/brewman/brewman/routers/reports/entries.py b/brewman/brewman/routers/reports/entries.py index 774fb3d0..6e4163c3 100644 --- a/brewman/brewman/routers/reports/entries.py +++ b/brewman/brewman/routers/reports/entries.py @@ -1,4 +1,6 @@ from datetime import date, datetime, time, timedelta +from decimal import Decimal +from typing import Sequence import brewman.schemas.entries as schemas @@ -30,7 +32,7 @@ def build_report( active_sort: str, sort_direction: str, db: Session, -) -> tuple[int, list[Voucher]]: +) -> tuple[int, Sequence[Voucher]]: query = ( select(Voucher) .join(Voucher.user) @@ -42,7 +44,7 @@ def build_report( ) ) sq = select(Voucher.id) - counts = select(count(Voucher.id)) + counts = select(count(Voucher.id)) # type: ignore[no-untyped-call] if start_date is not None: sd = datetime.combine(start_date, time(5, 30)) sq = sq.where(or_(Voucher.creation_date >= sd, Voucher.last_edit_date >= sd)) @@ -61,11 +63,11 @@ def build_report( ) if active_sort == "date": if sort_direction == "desc": - sq = sq.order_by(desc(Voucher.date), desc(Voucher.last_edit_date)) - query = query.order_by(desc(Voucher.date), desc(Voucher.last_edit_date)) + sq = sq.order_by(desc(Voucher.date_), desc(Voucher.last_edit_date)) + query = query.order_by(desc(Voucher.date_), desc(Voucher.last_edit_date)) else: - sq = sq.order_by(Voucher.date, Voucher.last_edit_date) - query = query.order_by(Voucher.date, Voucher.last_edit_date) + sq = sq.order_by(Voucher.date_, Voucher.last_edit_date) + query = query.order_by(Voucher.date_, Voucher.last_edit_date) if active_sort == "user": if sort_direction == "desc": sq = sq.order_by(desc(Voucher.last_edit_date)) @@ -100,22 +102,22 @@ def report_data( counts=counts, report=[ schemas.Entries( - id=voucher.id, - date=voucher.date, + id_=voucher.id, + date_=voucher.date_, url=[ "/", voucher.voucher_type.name.replace("_", "-").lower(), str(voucher.id), ], - type=voucher.voucher_type.name.replace("_", " ").title(), + type_=voucher.voucher_type.name.replace("_", " ").title(), posted=voucher.posted, narration=voucher.narration, - debitNames=[x.account.name for x in voucher.journals if x.debit == 1], - creditNames=[x.account.name for x in voucher.journals if x.debit != 1], - amount=sum(x.amount for x in voucher.journals if x.debit != 1), - creationDate=voucher.creation_date, - lastEditDate=voucher.last_edit_date, - user=UserLink(id=voucher.user.id, name=voucher.user.name), + debit_names=[x.account.name for x in voucher.journals if x.debit == 1], + credit_names=[x.account.name for x in voucher.journals if x.debit != 1], + amount=sum(x.amount for x in voucher.journals if x.debit != 1) or Decimal(0), + creation_date=voucher.creation_date, + last_edit_date=voucher.last_edit_date, + user=UserLink(id_=voucher.user.id, name=voucher.user.name), ) for voucher in report ], diff --git a/brewman/brewman/routers/reports/ledger.py b/brewman/brewman/routers/reports/ledger.py index 62105794..6ca87a7a 100644 --- a/brewman/brewman/routers/reports/ledger.py +++ b/brewman/brewman/routers/reports/ledger.py @@ -1,6 +1,8 @@ import datetime import uuid +from decimal import Decimal + import brewman.schemas.ledger as schemas from fastapi import APIRouter, Request, Security @@ -27,8 +29,8 @@ def show_blank( user: UserToken = Security(get_user, scopes=["ledger"]), ) -> schemas.Ledger: return schemas.Ledger( - startDate=get_start_date(request.session), - finishDate=get_finish_date(request.session), + start_date=get_start_date(request.session), + finish_date=get_finish_date(request.session), account=None, body=[], ) @@ -49,9 +51,9 @@ def show_data( body = build_report(account.id, start_date, finish_date, db) set_period(start_date, finish_date, request.session) return schemas.Ledger( - startDate=start_date, - finishDate=finish_date, - account=schemas.AccountLink(id=account.id, name=account.name), + start_date=start_date, + finish_date=finish_date, + account=schemas.AccountLink(id_=account.id, name=account.name), body=body, ) @@ -68,11 +70,11 @@ def build_report(account_id: uuid.UUID, start_date: str, finish_date: str, db: S .join(Journal.account) .where( Voucher.journals.any(Journal.account_id == account_id), - Voucher.date >= datetime.datetime.strptime(start_date, "%d-%b-%Y"), - Voucher.date <= datetime.datetime.strptime(finish_date, "%d-%b-%Y"), + Voucher.date_ >= datetime.datetime.strptime(start_date, "%d-%b-%Y"), + Voucher.date_ <= datetime.datetime.strptime(finish_date, "%d-%b-%Y"), not_(Voucher.voucher_type.in_([VoucherType.ISSUE, VoucherType.CLOSING_STOCK])), ) - .order_by(Voucher.date, Voucher.last_edit_date) + .order_by(Voucher.date_, Voucher.last_edit_date) ) .unique() .scalars() @@ -80,8 +82,8 @@ def build_report(account_id: uuid.UUID, start_date: str, finish_date: str, db: S ) for voucher in query: - debit = 0 - credit = 0 + debit = Decimal(0) + credit = Decimal(0) journal_debit = 0 name = "" for journal in voucher.journals: @@ -89,25 +91,25 @@ def build_report(account_id: uuid.UUID, start_date: str, finish_date: str, db: S journal_debit = journal.debit if journal.debit == 1: debit = journal.amount - credit = 0 + credit = Decimal(0) else: credit = journal.amount - debit = 0 + debit = Decimal(0) for journal in voucher.journals: if journal.debit != journal_debit: name += "{0} / ".format(journal.account.name) name = name[:-3] body.append( schemas.LedgerItem( - id=voucher.id, - date=voucher.date.strftime("%d-%b-%Y"), + id_=voucher.id, + date_=voucher.date_, name=name, url=[ "/", voucher.voucher_type.name.replace("_", "-").lower(), str(voucher.id), ], - type=voucher.voucher_type.name.replace("_", " ").title(), + type_=voucher.voucher_type.name.replace("_", " ").title(), narration=voucher.narration, debit=debit, credit=credit, @@ -122,23 +124,23 @@ def opening_balance(account_id: uuid.UUID, start_date: str, db: Session) -> sche select(func.sum(Journal.amount * Journal.debit)) .join(Journal.voucher) .where( - Voucher.date < datetime.datetime.strptime(start_date, "%d-%b-%Y"), + Voucher.date_ < datetime.datetime.strptime(start_date, "%d-%b-%Y"), not_(Voucher.voucher_type.in_([VoucherType.ISSUE, VoucherType.CLOSING_STOCK])), Journal.account_id == account_id, ) ).scalar() - opening = 0 if opening is None else opening + opening = Decimal(0) if opening is None else opening if opening < 0: credit = opening * -1 - debit = 0 + debit = Decimal(0) else: debit = opening - credit = 0 + credit = Decimal(0) return schemas.LedgerItem( - date=start_date, - id=None, + date_=start_date, + id_=None, name="Opening Balance", - type="Opening Balance", + type_="Opening Balance", url=[], narration="", debit=debit, diff --git a/brewman/brewman/routers/reports/net_transactions.py b/brewman/brewman/routers/reports/net_transactions.py index b8ecadcd..685b1543 100644 --- a/brewman/brewman/routers/reports/net_transactions.py +++ b/brewman/brewman/routers/reports/net_transactions.py @@ -26,8 +26,8 @@ def show_blank( user: UserToken = Security(get_user, scopes=["net-transactions"]), ) -> schemas.NetTransactions: return schemas.NetTransactions( - startDate=get_start_date(request.session), - finishDate=get_finish_date(request.session), + start_date=get_start_date(request.session), + finish_date=get_finish_date(request.session), body=[], ) @@ -42,8 +42,8 @@ def show_data( set_period(start, finish, request.session) with SessionFuture() as db: return schemas.NetTransactions( - startDate=start, - finishDate=finish, + start_date=start, + finish_date=finish, body=build_report( datetime.strptime(start, "%d-%b-%Y"), datetime.strptime(finish, "%d-%b-%Y"), @@ -59,18 +59,18 @@ def build_report(start_date: date, finish_date: date, db: Session) -> list[schem .join(Journal.voucher) .join(Journal.account) .where( - Voucher.date >= start_date, - Voucher.date <= finish_date, + Voucher.date_ >= start_date, + Voucher.date_ <= finish_date, not_(Voucher.voucher_type.in_([VoucherType.ISSUE, VoucherType.CLOSING_STOCK])), ) - .group_by(AccountBase) + .group_by(AccountBase) # type: ignore .order_by(AccountBase.type_id, desc(func.abs(amount_sum))) ).all() body = [] for account, amount in query: if amount != 0: - item = schemas.NetTransactionsItem(type=account.type_.name, name=account.name) + item = schemas.NetTransactionsItem(type_=account.type_.name, name=account.name) if amount > 0: item.debit = amount else: diff --git a/brewman/brewman/routers/reports/non_contract_purchase.py b/brewman/brewman/routers/reports/non_contract_purchase.py index 8f12ebf6..e134c881 100644 --- a/brewman/brewman/routers/reports/non_contract_purchase.py +++ b/brewman/brewman/routers/reports/non_contract_purchase.py @@ -29,7 +29,7 @@ def non_contract_purchases( def report(db: Session) -> list[schemas.NonContractPurchase]: rcs: list[RateContract] = ( - db.execute( + db.execute( # type: ignore select(RateContract) .join(RateContract.vendor) .join(RateContract.items) @@ -48,14 +48,14 @@ def report(db: Session) -> list[schemas.NonContractPurchase]: for rc in rcs: for item in rc.items: invs = db.execute( - select(Voucher.id, Voucher.date, Inventory.id, Inventory.rate) + select(Voucher.id, Voucher.date_, Inventory.id, Inventory.rate) .join(Inventory.batch) .join(Inventory.voucher) .join(Voucher.journals) .where( Batch.sku_id == item.sku_id, - Voucher.date >= rc.valid_from, - Voucher.date <= rc.valid_till, + Voucher.date_ >= rc.valid_from, + Voucher.date_ <= rc.valid_till, Voucher.voucher_type == VoucherType.PURCHASE, Journal.account_id == rc.vendor_id, Inventory.rate != item.price, @@ -69,7 +69,7 @@ def report(db: Session) -> list[schemas.NonContractPurchase]: ).one() list_.append( schemas.NonContractPurchase( - date=inv.date, + date_=inv.date_, vendor=rc.vendor.name, product=f"{p} ({u})", url=[ @@ -77,8 +77,8 @@ def report(db: Session) -> list[schemas.NonContractPurchase]: "purchase", str(inv.id), ], - contractPrice=item.price, - purchasePrice=inv.rate, + contract_price=item.price, + purchase_price=inv.rate, ) ) return list_ diff --git a/brewman/brewman/routers/reports/product_ledger.py b/brewman/brewman/routers/reports/product_ledger.py index 8dfa520f..f9faaa4a 100644 --- a/brewman/brewman/routers/reports/product_ledger.py +++ b/brewman/brewman/routers/reports/product_ledger.py @@ -32,8 +32,8 @@ def show_blank( user: UserToken = Security(get_user, scopes=["product-ledger"]), ) -> schemas.ProductLedger: return schemas.ProductLedger( - startDate=get_start_date(request.session), - finishDate=get_finish_date(request.session), + start_date=get_start_date(request.session), + finish_date=get_finish_date(request.session), product=None, body=[], ) @@ -59,9 +59,9 @@ def show_data( ) set_period(start_date, finish_date, request.session) return schemas.ProductLedger( - startDate=start_date, - finishDate=finish_date, - product=schemas.ProductLink(id=product.id, name=product.name), + start_date=start_date, + finish_date=finish_date, + product=schemas.ProductLink(id_=product.id, name=product.name), body=body, ) @@ -86,10 +86,10 @@ def build_report( .where( StockKeepingUnit.product_id == product_id, Journal.cost_centre_id != CostCentre.cost_centre_purchase(), - Voucher.date >= start_date, - Voucher.date <= finish_date, + Voucher.date_ >= start_date, + Voucher.date_ <= finish_date, ) - .order_by(Voucher.date, Voucher.last_edit_date) + .order_by(Voucher.date_, Voucher.last_edit_date) ).all() for voucher, inventory, journal, stockKeepingUnit in query: @@ -111,8 +111,8 @@ def build_report( body.append( schemas.ProductLedgerItem( - id=voucher.id, - date=voucher.date, + id_=voucher.id, + date_=voucher.date, name=name, url=[ "/", @@ -121,17 +121,17 @@ def build_report( if voucher.voucher_type != VoucherType.CLOSING_STOCK else voucher.date.strftime("%d-%b-%Y"), ], - type=voucher.voucher_type.name.replace("_", " ").title(), + type_=voucher.voucher_type.name.replace("_", " ").title(), narration=voucher.narration, posted=voucher.posted or voucher.voucher_type in [VoucherType.ISSUE, VoucherType.CLOSING_STOCK], - debitQuantity=debit_q, - debitAmount=debit_a, - debitUnit=debit_u, - creditQuantity=credit_q, - creditAmount=credit_a, - creditUnit=credit_u, - runningQuantity=running_total_q, - runningAmount=running_total_a, + debit_quantity=debit_q, + debit_amount=debit_a, + debit_unit=debit_u, + credit_quantity=credit_q, + credit_amount=credit_a, + credit_unit=credit_u, + running_quantity=running_total_q, + running_amount=running_total_a, ) ) @@ -156,34 +156,34 @@ def opening_balance( Voucher.id == Journal.voucher_id, StockKeepingUnit.product_id == product_id, Journal.cost_centre_id == CostCentre.cost_centre_purchase(), - Voucher.date < start_date, + Voucher.date_ < start_date, ) .group_by(StockKeepingUnit.units) ).all() - quantity: Decimal = sum(r.quantity for r in row) # type: ignore[assignment] - amount: Decimal = sum(r.amount for r in row) # type: ignore[assignment] + quantity: Decimal = sum(r.quantity for r in row) + amount: Decimal = sum(r.amount for r in row) return ( quantity, amount, [ schemas.ProductLedgerItem( - id=None, - date=start_date.strftime("%d-%b-%Y"), + id_=None, + date_=start_date, name="Opening Balance", url=[], - type="Opening Balance", + type_="Opening Balance", narration="", posted=True, - debitQuantity=q, - debitAmount=a, - debitUnit=u, - creditQuantity=0, - creditAmount=0, - creditUnit="", - runningQuantity=quantity, - runningAmount=amount, + debit_quantity=q, + debit_amount=a, + debit_unit=u, + credit_quantity=Decimal(0), + credit_amount=Decimal(0), + credit_unit="", + running_quantity=quantity, + running_amount=amount, ) for u, q, a in row ], diff --git a/brewman/brewman/routers/reports/profit_loss.py b/brewman/brewman/routers/reports/profit_loss.py index fa836bb9..9b9567d0 100644 --- a/brewman/brewman/routers/reports/profit_loss.py +++ b/brewman/brewman/routers/reports/profit_loss.py @@ -29,10 +29,10 @@ def report_blank( user: UserToken = Security(get_user, scopes=["profit-&-loss"]), ) -> schemas.ProfitLoss: return schemas.ProfitLoss( - startDate=get_start_date(request.session), - finishDate=get_finish_date(request.session), + start_date=get_start_date(request.session), + finish_date=get_finish_date(request.session), body=[], - footer=schemas.ProfitLossItem(group="", total=0, order=0), + footer=schemas.ProfitLossItem(group="", total=Decimal(0), order=0), ) @@ -49,8 +49,8 @@ def report_data( ) set_period(start, finish, request.session) return schemas.ProfitLoss( - startDate=start, - finishDate=finish, + start_date=start, + finish_date=finish, body=body, footer=footer, ) @@ -71,12 +71,12 @@ def build_profit_loss( .join(Journal.voucher) .join(Journal.account) .where( - Voucher.date >= start_date, - Voucher.date <= finish_date, + Voucher.date_ >= start_date, + Voucher.date_ <= finish_date, not_(Voucher.voucher_type.in_([VoucherType.ISSUE, VoucherType.CLOSING_STOCK])), AccountBase.type_id.in_(profit_type_list), ) - .group_by(AccountBase) + .group_by(AccountBase) # type: ignore .order_by(AccountBase.type_id, desc(func.abs(amount_sum))) ).all() @@ -143,7 +143,7 @@ def get_accumulated_profit(finish_date: date, db: Session) -> Decimal: .join(Journal.voucher) .join(Journal.account) .where( - Voucher.date <= finish_date, + Voucher.date_ <= finish_date, not_(Voucher.voucher_type.in_([VoucherType.ISSUE, VoucherType.CLOSING_STOCK])), AccountBase.type_id.in_(type_list), ) diff --git a/brewman/brewman/routers/reports/purchase_entries.py b/brewman/brewman/routers/reports/purchase_entries.py index ea476770..7f66ee3d 100644 --- a/brewman/brewman/routers/reports/purchase_entries.py +++ b/brewman/brewman/routers/reports/purchase_entries.py @@ -27,8 +27,8 @@ def report_blank( user: UserToken = Security(get_user, scopes=["purchase-entries"]), ) -> schemas.PurchaseEntries: return schemas.PurchaseEntries( - startDate=get_start_date(request.session), - finishDate=get_finish_date(request.session), + start_date=get_start_date(request.session), + finish_date=get_finish_date(request.session), body=[], ) @@ -45,12 +45,12 @@ def report_data( with SessionFuture() as db: body = build_report(start_date, finish_date, db) set_period(start, finish, request.session) - return schemas.PurchaseEntries(startDate=start, finishDate=finish, body=body) + return schemas.PurchaseEntries(start_date=start, finish_date=finish, body=body) def build_report(start_date: date, finish_date: date, db: Session) -> list[schemas.PurchaseEntriesItem]: body = [] - query: list[Voucher] = ( + query: list[Voucher] = list( db.execute( select(Voucher) .join(Voucher.journals) @@ -67,11 +67,11 @@ def build_report(start_date: date, finish_date: date, db: Session) -> list[schem .contains_eager(StockKeepingUnit.product), ) .where( - Voucher.date >= start_date, - Voucher.date <= finish_date, + Voucher.date_ >= start_date, + Voucher.date_ <= finish_date, Voucher.voucher_type == VoucherType.PURCHASE, ) - .order_by(Voucher.date) + .order_by(Voucher.date_) ) .unique() .scalars() @@ -82,7 +82,7 @@ def build_report(start_date: date, finish_date: date, db: Session) -> list[schem journal = next(j for j in voucher.journals if j.debit == -1) for item in voucher.inventories: row = schemas.PurchaseEntriesItem( - date=voucher.date, + date_=voucher.date_, supplier=journal.account.name, url=[ "/", diff --git a/brewman/brewman/routers/reports/purchases.py b/brewman/brewman/routers/reports/purchases.py index 370c37ea..79e2e69e 100644 --- a/brewman/brewman/routers/reports/purchases.py +++ b/brewman/brewman/routers/reports/purchases.py @@ -1,4 +1,5 @@ from datetime import datetime +from decimal import Decimal import brewman.schemas.purchases as schemas @@ -30,10 +31,10 @@ def report_blank( user: UserToken = Security(get_user, scopes=["purchases"]), ) -> schemas.Purchases: return schemas.Purchases( - startDate=get_start_date(request.session), - finishDate=get_finish_date(request.session), + start_date=get_start_date(request.session), + finish_date=get_finish_date(request.session), body=[], - footer=schemas.PurchasesItem(name="Total", quantity=0, rate=0, url=[], amount=0), + footer=schemas.PurchasesItem(name="Total", quantity=Decimal(0), rate=Decimal(0), url=[], amount=Decimal(0)), ) @@ -48,8 +49,8 @@ def report_data( body, footer = build_report(start, finish, db) set_period(start, finish, request.session) return schemas.Purchases( - startDate=start, - finishDate=finish, + start_date=start, + finish_date=finish, body=body, footer=footer, ) @@ -69,15 +70,15 @@ def build_report( .join(Batch.sku) .join(StockKeepingUnit.product) .where( - Voucher.date >= datetime.strptime(start_date, "%d-%b-%Y"), - Voucher.date <= datetime.strptime(finish_date, "%d-%b-%Y"), + Voucher.date_ >= datetime.strptime(start_date, "%d-%b-%Y"), + Voucher.date_ <= datetime.strptime(finish_date, "%d-%b-%Y"), not_(Voucher.voucher_type.in_([VoucherType.ISSUE, VoucherType.CLOSING_STOCK])), Journal.cost_centre_id == CostCentre.cost_centre_purchase(), ) - .group_by(Product) + .group_by(Product) # type: ignore .order_by(desc(amount_sum)) ).all() - total_amount = 0 + total_amount = Decimal(0) for product, quantity, amount in query: rate = amount / quantity if quantity != 0 else 0 total_amount += amount @@ -91,5 +92,5 @@ def build_report( body.append(row) return ( body, - schemas.PurchasesItem(name="Total", quantity=0, rate=0, url=[], amount=total_amount), + schemas.PurchasesItem(name="Total", quantity=Decimal(0), rate=Decimal(0), url=[], amount=total_amount), ) diff --git a/brewman/brewman/routers/reports/raw_material_cost.py b/brewman/brewman/routers/reports/raw_material_cost.py index a94cbcf5..6cb0347b 100644 --- a/brewman/brewman/routers/reports/raw_material_cost.py +++ b/brewman/brewman/routers/reports/raw_material_cost.py @@ -1,6 +1,7 @@ import uuid from datetime import date, datetime +from decimal import Decimal import brewman.schemas.raw_material_cost as schemas @@ -33,8 +34,8 @@ def report_blank( user: UserToken = Security(get_user, scopes=["raw-material-cost"]), ) -> schemas.RawMaterialCost: return schemas.RawMaterialCost( - startDate=get_start_date(request.session), - finishDate=get_finish_date(request.session), + start_date=get_start_date(request.session), + finish_date=get_finish_date(request.session), body=[], footer=None, ) @@ -53,8 +54,8 @@ def report_data( ) set_period(s, f, request.session) return schemas.RawMaterialCost( - startDate=s, - finishDate=f, + start_date=s, + finish_date=f, body=body, footer=footer, ) @@ -74,9 +75,9 @@ def report_id( ) set_period(s, f, request.session) return schemas.RawMaterialCost( - id=id_, - startDate=s, - finishDate=f, + id_=id_, + start_date=s, + finish_date=f, body=body, ) @@ -94,17 +95,17 @@ def build_report( .join(Journal.voucher) .join(Journal.account) .where( - Voucher.date >= start_date, - Voucher.date <= finish_date, + Voucher.date_ >= start_date, + Voucher.date_ <= finish_date, Journal.cost_centre_id != CostCentre.cost_centre_purchase(), AccountBase.type_id.in_([2, 3]), ) - .group_by(CostCentre) + .group_by(CostCentre) # type: ignore .order_by(sum_sale.desc()) ).all() - issues = 0 - sales = 0 + issues = Decimal(0) + sales = Decimal(0) for cost_centre, issue, sale in query: issues += issue sales += sale @@ -140,12 +141,12 @@ def build_report_id( .join(Inventory.voucher) .join(Voucher.journals) .where( - Voucher.date >= start_date, - Voucher.date <= finish_date, + Voucher.date_ >= start_date, + Voucher.date_ <= finish_date, Voucher.voucher_type.in_([VoucherType.ISSUE, VoucherType.CLOSING_STOCK]), Journal.cost_centre_id == cost_centre_id, ) - .group_by(Product, ProductGroup, Journal.debit, ProductGroup.name) + .group_by(Product, ProductGroup, Journal.debit, ProductGroup.name) # type: ignore .order_by(ProductGroup.name, sum_net.desc()) ).all() diff --git a/brewman/brewman/routers/reports/reconcile.py b/brewman/brewman/routers/reports/reconcile.py index 4e42e8f6..ecd20717 100644 --- a/brewman/brewman/routers/reports/reconcile.py +++ b/brewman/brewman/routers/reports/reconcile.py @@ -1,6 +1,7 @@ import uuid from datetime import date, datetime +from decimal import Decimal import brewman.schemas.reconcile as schemas @@ -28,8 +29,8 @@ def show_blank( user: UserToken = Security(get_user, scopes=["reconcile"]), ) -> schemas.Reconcile: return schemas.Reconcile( - startDate=get_start_date(request.session), - finishDate=get_finish_date(request.session), + start_date=get_start_date(request.session), + finish_date=get_finish_date(request.session), account=None, body=[], ) @@ -50,9 +51,9 @@ def show_data( body = build_report(account.id, start_date, finish_date, db) set_period(start_date, finish_date, request.session) return schemas.Reconcile( - startDate=start_date, - finishDate=finish_date, - account=schemas.AccountLink(id=account.id, name=account.name), + start_date=start_date, + finish_date=finish_date, + account=schemas.AccountLink(id_=account.id, name=account.name), body=body, ) @@ -81,34 +82,36 @@ def build_report( ).all() for voucher in query: - debit = 0 - credit = 0 - journal_debit = 0 + debit = Decimal(0) + credit = Decimal(0) + journal_debit = Decimal(0) name = "" for journal in voucher.journals: if journal.account_id == account_id: journal_debit = journal.debit if journal.debit == 1: debit = journal.amount - credit = 0 + credit = Decimal(0) else: credit = journal.amount - debit = 0 + debit = Decimal(0) for journal in voucher.journals: if journal.debit != journal_debit: name += "{0} / ".format(journal.account.name) name = name[:-3] body.append( schemas.ReconcileItem( - id=voucher.id, - date=voucher.date, + id_=voucher.id, + date_=voucher.date, name=name, - type=voucher.voucher_type.name.replace("_", " ").title(), + type_=voucher.voucher_type.name.replace("_", " ").title(), narration=voucher.narration, + url=[], + posted=False, debit=debit, credit=credit, - isReconciled=voucher.is_reconciled, - reconcileDate=voucher.reconcile_date, + is_reconciled=voucher.is_reconciled, + reconcile_date=voucher.reconcile_date, ) ) return body @@ -125,24 +128,26 @@ def opening_balance(account_id: uuid.UUID, start_date: date, db: Session) -> sch Journal.account_id == account_id, ) ).scalar() - opening = 0 if opening is None else opening + opening = Decimal(0) if opening is None else opening if opening < 0: credit = opening * -1 - debit = 0 + debit = Decimal(0) else: debit = opening - credit = 0 + credit = Decimal(0) return schemas.ReconcileItem( - date=start_date, - id=None, + date_=start_date, + id_=None, name="Opening Balance", - type="Opening Balance", + type_="Opening Balance", narration="", debit=debit, credit=credit, - running=opening, - isReconciled=True, - reconcileDate=start_date, + # running=opening, + url=[], + posted=False, + is_reconciled=True, + reconcile_date=start_date, ) @@ -170,8 +175,8 @@ def save( db.commit() body = build_report(account.id, start_date, finish_date, db) return schemas.Reconcile( - startDate=start_date, - finishDate=finish_date, - account=schemas.AccountLink(id=account.id, name=account.name), + start_date=start_date, + finish_date=finish_date, + account=schemas.AccountLink(id_=account.id, name=account.name), body=body, ) diff --git a/brewman/brewman/routers/reports/stock_movement.py b/brewman/brewman/routers/reports/stock_movement.py index e35de5a3..e6682236 100644 --- a/brewman/brewman/routers/reports/stock_movement.py +++ b/brewman/brewman/routers/reports/stock_movement.py @@ -32,8 +32,8 @@ def report_blank( user: UserToken = Security(get_user, scopes=["stock-movement"]), ) -> schemas.StockMovement: return schemas.StockMovement( - startDate=get_start_date(request.session), - finishDate=get_finish_date(request.session), + start_date=get_start_date(request.session), + finish_date=get_finish_date(request.session), body=[], ) @@ -48,7 +48,7 @@ def report_data( with SessionFuture() as db: body = build_stock_movement(datetime.strptime(start, "%d-%b-%Y"), datetime.strptime(finish, "%d-%b-%Y"), db) set_period(start, finish, request.session) - return schemas.StockMovement(startDate=start, finishDate=finish, body=body) + return schemas.StockMovement(start_date=start, finish_date=finish, body=body) def build_stock_movement(start_date: date, finish_date: date, db: Session) -> list[schemas.StockMovementItem]: @@ -63,18 +63,18 @@ def build_stock_movement(start_date: date, finish_date: date, db: Session) -> li .join(Inventory.voucher) .join(Voucher.journals) .options(contains_eager(StockKeepingUnit.product).contains_eager(Product.product_group)) - .where(Voucher.date < start_date, Journal.cost_centre_id == CostCentre.cost_centre_purchase()) - .group_by(StockKeepingUnit, Product, ProductGroup) + .where(Voucher.date_ < start_date, Journal.cost_centre_id == CostCentre.cost_centre_purchase()) + .group_by(StockKeepingUnit, Product, ProductGroup) # type: ignore ).all() for sku, quantity in openings: dict_[sku.id] = schemas.StockMovementItem( - id=sku.id, + id_=sku.id, name=f"{sku.product.name} ({sku.units})", group=sku.product.product_group.name, opening=Decimal(round(quantity, 2)), - purchase=0, - issue=0, - closing=0, + purchase=Decimal(0), + issue=Decimal(0), + closing=Decimal(0), url=["/", "product-ledger", str(sku.product.id)], ) purchases = db.execute( @@ -87,25 +87,25 @@ def build_stock_movement(start_date: date, finish_date: date, db: Session) -> li .join(Voucher.journals) .options(contains_eager(StockKeepingUnit.product).contains_eager(Product.product_group)) .where( - Voucher.date >= start_date, - Voucher.date <= finish_date, + Voucher.date_ >= start_date, + Voucher.date_ <= finish_date, not_(Voucher.voucher_type.in_([VoucherType.ISSUE, VoucherType.CLOSING_STOCK])), Journal.cost_centre_id == CostCentre.cost_centre_purchase(), ) - .group_by(StockKeepingUnit, Product, ProductGroup) + .group_by(StockKeepingUnit, Product, ProductGroup) # type: ignore ).all() for sku, quantity in purchases: if sku.id in dict_: dict_[sku.id].purchase = Decimal(round(quantity, 2)) else: dict_[sku.id] = schemas.StockMovementItem( - id=sku.id, + id_=sku.id, name=f"{sku.product.name} ({sku.units})", group=sku.product.product_group.name, - opening=0, + opening=Decimal(0), purchase=Decimal(round(quantity, 2)), - issue=0, - closing=0, + issue=Decimal(0), + closing=Decimal(0), url=["/", "product-ledger", str(sku.product.id)], ) issues = db.execute( @@ -118,25 +118,25 @@ def build_stock_movement(start_date: date, finish_date: date, db: Session) -> li .join(Voucher.journals) .options(contains_eager(StockKeepingUnit.product).contains_eager(Product.product_group)) .where( - Voucher.date >= start_date, - Voucher.date <= finish_date, + Voucher.date_ >= start_date, + Voucher.date_ <= finish_date, Voucher.voucher_type.in_([VoucherType.ISSUE, VoucherType.CLOSING_STOCK]), Journal.cost_centre_id == CostCentre.cost_centre_purchase(), ) - .group_by(StockKeepingUnit, Product, ProductGroup) + .group_by(StockKeepingUnit, Product, ProductGroup) # type: ignore ).all() for sku, quantity in issues: if sku.id in dict_: dict_[sku.id].issue = Decimal(round(quantity * -1, 2)) else: dict_[sku.id] = schemas.StockMovementItem( - id=sku.id, + id_=sku.id, name=f"{sku.product.name} ({sku.units})", group=sku.product.product_group.name, - opening=0, - purchase=0, + opening=Decimal(0), + purchase=Decimal(0), issue=Decimal(round(quantity * -1, 2)), - closing=0, + closing=Decimal(0), url=["/", "product-ledger", str(sku.product.id)], ) diff --git a/brewman/brewman/routers/reports/trial_balance.py b/brewman/brewman/routers/reports/trial_balance.py index 9c1a3fbc..8f3f4a67 100644 --- a/brewman/brewman/routers/reports/trial_balance.py +++ b/brewman/brewman/routers/reports/trial_balance.py @@ -26,7 +26,7 @@ def report_blank( request: Request, user: UserToken = Security(get_user, scopes=["trial-balance"]), ) -> schemas.TrialBalance: - return schemas.TrialBalance(date=get_finish_date(request.session), body=[]) + return schemas.TrialBalance(date_=get_finish_date(request.session), body=[]) @router.get("/{date_}", response_model=schemas.TrialBalance) @@ -38,7 +38,7 @@ def report_data( set_period(get_start_date(request.session), date_, request.session) with SessionFuture() as db: return schemas.TrialBalance( - date=date_, + date_=date_, body=build_report(datetime.strptime(date_, "%d-%b-%Y"), db), ) @@ -51,10 +51,10 @@ def build_report(date_: date, db: Session) -> list[schemas.TrialBalanceItem]: .join(Journal.account) .join(AccountBase.type_) .where( - Voucher.date <= date_, + Voucher.date_ <= date_, not_(Voucher.voucher_type.in_([VoucherType.ISSUE, VoucherType.CLOSING_STOCK])), ) - .group_by(AccountBase, AccountType) + .group_by(AccountBase, AccountType) # type: ignore .order_by(AccountBase.type_id, func.abs(amount_sum).desc()) .options( joinedload(AccountBase.type_, innerjoin=True), @@ -65,7 +65,7 @@ def build_report(date_: date, db: Session) -> list[schemas.TrialBalanceItem]: body = [] for account, amount in query: if amount > 0: - body.append(schemas.TrialBalanceItem(type=account.type_.name, name=account.name, debit=amount)) + body.append(schemas.TrialBalanceItem(type_=account.type_.name, name=account.name, debit=amount)) if amount < 0: - body.append(schemas.TrialBalanceItem(type=account.type_.name, name=account.name, credit=amount)) + body.append(schemas.TrialBalanceItem(type_=account.type_.name, name=account.name, credit=amount)) return body diff --git a/brewman/brewman/routers/role.py b/brewman/brewman/routers/role.py index 09af84e9..3684bf2b 100644 --- a/brewman/brewman/routers/role.py +++ b/brewman/brewman/routers/role.py @@ -1,5 +1,7 @@ import uuid +from typing import Sequence + import brewman.schemas.role as schemas from fastapi import APIRouter, HTTPException, Security, status @@ -104,10 +106,10 @@ async def show_list( user: UserToken = Security(get_user, scopes=["users"]), ) -> list[schemas.RoleList]: with SessionFuture() as db: - roles: list[Role] = db.execute(select(Role).order_by(Role.name)).scalars().all() + roles: Sequence[Role] = db.execute(select(Role).order_by(Role.name)).scalars().all() return [ schemas.RoleList( - id=item.id, + id_=item.id, name=item.name, permissions=[p.name for p in sorted(item.permissions, key=lambda p: p.name)], ) @@ -127,11 +129,11 @@ def show_id( def role_info(item: Role, db: Session) -> schemas.Role: return schemas.Role( - id=item.id, + id_=item.id, name=item.name, permissions=[ schemas.PermissionItem( - id=p.id, + id_=p.id, name=p.name, enabled=True if p in item.permissions else False, ) @@ -144,7 +146,7 @@ def role_blank(db: Session) -> schemas.RoleBlank: return schemas.RoleBlank( name="", permissions=[ - schemas.PermissionItem(id=p.id, name=p.name, enabled=False) + schemas.PermissionItem(id_=p.id, name=p.name, enabled=False) for p in db.execute(select(Permission).order_by(Permission.name)).scalars().all() ], ) diff --git a/brewman/brewman/routers/user.py b/brewman/brewman/routers/user.py index b49d9ce4..42ace809 100644 --- a/brewman/brewman/routers/user.py +++ b/brewman/brewman/routers/user.py @@ -1,5 +1,7 @@ import uuid +from typing import Sequence + import brewman.schemas.user as schemas from fastapi import APIRouter, Depends, HTTPException, Security, status @@ -138,15 +140,15 @@ async def show_list( user: UserToken = Security(get_user, scopes=["users"]), ) -> list[schemas.UserList]: with SessionFuture() as db: - users: list[User] = db.execute(select(User).order_by(User.name)).scalars().all() + users: Sequence[User] = db.execute(select(User).order_by(User.name)).scalars().all() return [ schemas.UserList( - id=item.id, + id_=item.id, name=item.name, - lockedOut=item.locked_out, + locked_out=item.locked_out, roles=[p.name for p in sorted(item.roles, key=lambda p: p.name)], - lastDevice=item.login_history[0].client.name if len(item.login_history) else "None", - lastDate=item.login_history[0].date if len(item.login_history) else None, + last_device=item.login_history[0].client.name if len(item.login_history) else "None", + last_date=item.login_history[0].date if len(item.login_history) else None, ) for item in users ] @@ -156,7 +158,7 @@ async def show_list( async def show_active(user: UserToken = Depends(get_user)) -> list[schemas.UserBlank]: with SessionFuture() as db: return [ - schemas.UserBlank(name=name) + schemas.UserBlank(name=name, password="", locked_out=False, roles=[]) for name in db.execute(select(User.name).where(User.locked_out == False).order_by(User.name)) # noqa: E712 .scalars() .all() @@ -175,13 +177,13 @@ def show_id( def user_info(item: User, db: Session, user: UserToken) -> schemas.User: return schemas.User( - id=item.id, + id_=item.id, name=item.name, password="", - lockedOut=item.locked_out, + locked_out=item.locked_out, roles=[ schemas.RoleItem( - id=r.id, + id_=r.id, name=r.name, enabled=True if r in item.roles else False, ) @@ -196,9 +198,9 @@ def user_blank(db: Session) -> schemas.UserBlank: return schemas.UserBlank( name="", password="", - lockedOut=False, + locked_out=False, roles=[ - schemas.RoleItem(id=r.id, name=r.name, enabled=False) + schemas.RoleItem(id_=r.id, name=r.name, enabled=False) for r in db.execute(select(Role).order_by(Role.name)).scalars().all() ], ) diff --git a/brewman/brewman/routers/voucher.py b/brewman/brewman/routers/voucher.py index 30be00d4..93f0cbf7 100644 --- a/brewman/brewman/routers/voucher.py +++ b/brewman/brewman/routers/voucher.py @@ -2,6 +2,7 @@ import uuid from datetime import date from decimal import Decimal +from typing import Sequence import brewman.schemas.voucher as output @@ -40,7 +41,7 @@ def post_voucher( try: with SessionFuture() as db: voucher: Voucher = db.execute(select(Voucher).where(Voucher.id == id_)).scalar_one() - account_types = ( + account_types: Sequence[int] = ( db.execute( select(distinct(AccountBase.type_id)).where( AccountBase.id.in_([vj.account_id for vj in voucher.journals]) @@ -49,7 +50,7 @@ def post_voucher( .scalars() .all() ) - allowed, message = get_lock_info([voucher.date], voucher.voucher_type, account_types, db) + allowed, message = get_lock_info([voucher.date_], voucher.voucher_type, account_types, db) if not allowed: raise HTTPException( status_code=status.HTTP_423_LOCKED, @@ -96,7 +97,7 @@ def delete_voucher( voucher: Voucher = db.execute(select(Voucher).where(Voucher.id == id_)).scalar_one() images = db.execute(select(DbImage).where(DbImage.resource_id == voucher.id)).scalars().all() check_delete_permissions(voucher, user) - account_types = ( + account_types: Sequence[int] = ( db.execute( select(distinct(AccountBase.type_id)).where( AccountBase.id.in_([vj.account_id for vj in voucher.journals]) @@ -105,7 +106,7 @@ def delete_voucher( .scalars() .all() ) - allowed, message = get_lock_info([voucher.date], voucher.voucher_type, account_types, db) + allowed, message = get_lock_info([voucher.date_], voucher.voucher_type, account_types, db) if not allowed: raise HTTPException( status_code=status.HTTP_423_LOCKED, @@ -168,8 +169,8 @@ def delete_voucher( return blank_voucher( info=BlankVoucherInfo( - date=json_voucher.date_, - type=VoucherType[json_voucher.type_], + date_=json_voucher.date_, + type_=VoucherType[json_voucher.type_], source=json_voucher.source, destination=json_voucher.destination, ), @@ -179,62 +180,62 @@ def delete_voucher( def voucher_info(voucher: Voucher, db: Session) -> output.Voucher: json_voucher = output.Voucher( - id=voucher.id, - date=voucher.date, - isStarred=voucher.is_starred, - type=voucher.voucher_type.name, + id_=voucher.id, + date_=voucher.date_, + is_starred=voucher.is_starred, + type_=voucher.voucher_type.name, posted=voucher.posted, narration=voucher.narration, journals=[], inventories=[], - employeeBenefits=[], + employee_benefits=[], incentives=[], - incentive=0, + incentive=Decimal(0), files=[], - creationDate=voucher.creation_date, - lastEditDate=voucher.last_edit_date, - user=output.UserLink(id=voucher.user.id, name=voucher.user.name), + creation_date=voucher.creation_date, + last_edit_date=voucher.last_edit_date, + user=output.UserLink(id_=voucher.user.id, name=voucher.user.name), poster=voucher.poster.name if voucher.posted else "", ) if voucher.reconcile_date is not None: json_voucher.reconcile_date = voucher.reconcile_date if voucher.voucher_type == VoucherType.PURCHASE: item = [j for j in voucher.journals if j.debit == -1][0] - json_voucher.vendor = output.AccountLink(id=item.account.id, name=item.account.name) + json_voucher.vendor = output.AccountLink(id_=item.account.id, name=item.account.name) elif voucher.voucher_type == VoucherType.ISSUE: item = [j for j in voucher.journals if j.debit == -1][0] - json_voucher.source = output.CostCentreLink(id=item.cost_centre_id, name="") + json_voucher.source = output.CostCentreLink(id_=item.cost_centre_id, name="") item = [j for j in voucher.journals if j.debit == 1][0] - json_voucher.destination = output.CostCentreLink(id=item.cost_centre_id, name="") + json_voucher.destination = output.CostCentreLink(id_=item.cost_centre_id, name="") if voucher.voucher_type == VoucherType.PURCHASE_RETURN: item = [j for j in voucher.journals if j.debit == 1][0] - json_voucher.vendor = output.AccountLink(id=item.account.id, name=item.account.name) + json_voucher.vendor = output.AccountLink(id_=item.account.id, name=item.account.name) else: for journal in voucher.journals: json_voucher.journals.append( output.Journal( - id=journal.id, + id_=journal.id, debit=journal.debit, amount=journal.amount, - account=output.AccountLink(id=journal.account.id, name=journal.account.name), - costCentre=output.CostCentreLink(id=journal.cost_centre_id), + account=output.AccountLink(id_=journal.account.id, name=journal.account.name), + cost_centre=output.CostCentreLink(id_=journal.cost_centre_id), ) ) for benefit in voucher.employee_benefits: json_voucher.employee_benefits.append( output.EmployeeBenefit( - grossSalary=benefit.gross_salary, - daysWorked=benefit.days_worked, - esiEmployee=benefit.esi_ee, - pfEmployee=benefit.pf_ee, - esiEmployer=benefit.esi_er, - pfEmployer=benefit.pf_er, + gross_salary=benefit.gross_salary, + days_worked=benefit.days_worked, + esi_employee=benefit.esi_ee, + pf_employee=benefit.pf_ee, + esi_employer=benefit.esi_er, + pf_employer=benefit.pf_er, employee=output.EmployeeLink( - id=benefit.journal.account.id, + id_=benefit.journal.account.id, name=benefit.journal.account.name, designation=benefit.journal.account.designation, - costCentre=output.CostCentreLink( - id=benefit.journal.account.cost_centre.id, + cost_centre=output.CostCentreLink( + id_=benefit.journal.account.cost_centre.id, name=benefit.journal.account.cost_centre.name, ), ), @@ -246,11 +247,11 @@ def voucher_info(voucher: Voucher, db: Session) -> output.Voucher: ).scalar_one() json_voucher.incentives.append( output.Incentive( - employeeId=incentive.journal.account_id, + employee_id=incentive.journal.account_id, name=incentive.journal.account.name, designation=employee.designation, department=incentive.journal.account.cost_centre.name, - daysWorked=incentive.days_worked, + days_worked=incentive.days_worked, points=incentive.points, ) ) @@ -264,21 +265,21 @@ def voucher_info(voucher: Voucher, db: Session) -> output.Voucher: ) json_voucher.inventories.append( output.Inventory( - id=inventory.id, + id_=inventory.id, quantity=inventory.quantity, rate=inventory.rate, tax=inventory.tax, discount=inventory.discount, amount=inventory.amount, batch=output.Batch( - id=inventory.batch.id, + id_=inventory.batch.id, name=text, - quantityRemaining=inventory.batch.quantity_remaining, + quantity_remaining=inventory.batch.quantity_remaining, tax=inventory.batch.tax, discount=inventory.batch.discount, rate=inventory.batch.rate, sku=output.ProductLink( - id=inventory.batch.sku.id, + id_=inventory.batch.sku.id, name=f"{inventory.batch.sku.product.name} ({inventory.batch.sku.units})" if inventory.batch.sku.units else inventory.batch.sku.product.name, @@ -290,7 +291,7 @@ def voucher_info(voucher: Voucher, db: Session) -> output.Voucher: for image in images: json_voucher.files.append( output.ImageUpload( - id=image.id, + id_=image.id, resized=f"/db-image/{image.id}/resized", thumbnail=f"/db-image/{image.id}/thumbnail", ) @@ -300,15 +301,15 @@ def voucher_info(voucher: Voucher, db: Session) -> output.Voucher: def blank_voucher(info: BlankVoucherInfo, db: Session) -> output.Voucher: json_voucher = output.Voucher( - type=info.type_.name, - date=info.date_, - isStarred=False, + type_=info.type_.name, + date_=info.date_, + is_starred=False, posted=False, narration="", journals=[], inventories=[], incentives=[], - employeeBenefits=[], + employee_benefits=[], files=[], ) if info.type_ == VoucherType.JOURNAL: @@ -318,32 +319,32 @@ def blank_voucher(info: BlankVoucherInfo, db: Session) -> output.Voucher: if info.account is not None: account = db.execute(select(AccountBase).where(AccountBase.id == info.account.id_)).scalars().one_or_none() if account is not None: - j_account = output.AccountLink(id=account.id, name=account.name) + j_account = output.AccountLink(id_=account.id, name=account.name) else: j_account = AccountBase.cash_in_hand() - json_voucher.journals.append(output.Journal(account=j_account, amount=0, debit=-1)) + json_voucher.journals.append(output.Journal(account=j_account, amount=Decimal(0), debit=-1)) elif info.type_ == VoucherType.RECEIPT: account = None if info.account is not None: account = db.execute(select(AccountBase).where(AccountBase.id == info.account.id_)).scalars().one_or_none() if account is not None: - j_account = output.AccountLink(id=account.id, name=account.name) + j_account = output.AccountLink(id_=account.id, name=account.name) else: j_account = AccountBase.cash_in_hand() - json_voucher.journals.append(output.Journal(account=j_account, amount=0, debit=1)) + json_voucher.journals.append(output.Journal(account=j_account, amount=Decimal(0), debit=1)) elif info.type_ == VoucherType.PURCHASE: json_voucher.vendor = AccountBase.local_purchase() elif info.type_ == VoucherType.PURCHASE_RETURN: json_voucher.vendor = AccountBase.local_purchase() elif info.type_ == VoucherType.ISSUE: if info.source is not None: - json_voucher.source = output.CostCentreLink(id=info.source.id_) + json_voucher.source = output.CostCentreLink(id_=info.source.id_) else: - json_voucher.source = output.CostCentreLink(id=CostCentre.cost_centre_purchase()) + json_voucher.source = output.CostCentreLink(id_=CostCentre.cost_centre_purchase()) if info.destination is not None: - json_voucher.destination = output.CostCentreLink(id=info.destination.id_) + json_voucher.destination = output.CostCentreLink(id_=info.destination.id_) else: - json_voucher.destination = output.CostCentreLink(id=CostCentre.cost_centre_kitchen()) + json_voucher.destination = output.CostCentreLink(id_=CostCentre.cost_centre_kitchen()) elif info.type_ == VoucherType.EMPLOYEE_BENEFIT: pass elif info.type_ == VoucherType.INCENTIVE: @@ -373,26 +374,26 @@ def incentive_employees(date_: date, db: Session) -> tuple[list[output.Incentive .all() ) for employee in employees: - att: list[Attendance] = ( + att: Sequence[Attendance] = ( db.execute( select(Attendance).where( Attendance.employee_id == employee.id, - Attendance.date >= start_date, - Attendance.date <= finish_date, + Attendance.date_ >= start_date, + Attendance.date_ <= finish_date, Attendance.is_valid == True, # noqa: E712 ) ) .scalars() .all() ) - days_worked = sum(AttendanceType.by_id(x.attendance_type).value for x in att) + days_worked = sum(AttendanceType.by_id(x.attendance_type).value for x in att) or Decimal(0) details.append( output.Incentive( - employeeId=employee.id, + employee_id=employee.id, name=employee.name, designation=employee.designation, department=employee.cost_centre.name, - daysWorked=days_worked, + days_worked=days_worked, points=employee.points, ) ) @@ -404,9 +405,9 @@ def incentive_employees(date_: date, db: Session) -> tuple[list[output.Incentive Journal.account_id == Account.incentive_id(), Voucher.voucher_type != VoucherType.ISSUE, or_( - Voucher.date <= finish_date, + Voucher.date_ <= finish_date, and_( - Voucher.date == finish_date, + Voucher.date_ == finish_date, Voucher.voucher_type != VoucherType.INCENTIVE, ), ), diff --git a/brewman/brewman/routers/voucher_types.py b/brewman/brewman/routers/voucher_types.py index 7a92cf9f..387e32bd 100644 --- a/brewman/brewman/routers/voucher_types.py +++ b/brewman/brewman/routers/voucher_types.py @@ -12,4 +12,4 @@ router = APIRouter() @router.get("", response_model=list[schemas.AccountType]) def account_type_list(user: UserToken = Depends(get_user)) -> list[schemas.AccountType]: - return [schemas.AccountType(id=item.value, name=item.name) for item in list(VoucherType)] + return [schemas.AccountType(id_=item.value, name=item.name) for item in list(VoucherType)] diff --git a/brewman/brewman/schemas/account.py b/brewman/brewman/schemas/account.py index 1253f2d6..f96ce315 100644 --- a/brewman/brewman/schemas/account.py +++ b/brewman/brewman/schemas/account.py @@ -1,6 +1,6 @@ import uuid -from pydantic import BaseModel, Field +from pydantic import BaseModel, ConfigDict, Field from . import to_camel from .cost_centre import CostCentreLink @@ -8,10 +8,8 @@ from .cost_centre import CostCentreLink class AccountLink(BaseModel): id_: uuid.UUID = Field(...) - name: str | None - - class Config: - fields = {"id_": "id"} + name: str | None = None + model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True) class AccountBase(BaseModel): @@ -19,18 +17,13 @@ class AccountBase(BaseModel): is_starred: bool is_active: bool cost_centre: CostCentreLink - - class Config: - anystr_strip_whitespace = True - alias_generator = to_camel + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) class AccountIn(AccountBase): type_: int is_reconcilable: bool - - class Config: - alias_generator = to_camel + model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True) class Account(AccountIn): @@ -42,7 +35,4 @@ class Account(AccountIn): class AccountBlank(AccountIn): name: str is_fixture: bool - - class Config: - anystr_strip_whitespace = True - alias_generator = to_camel + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) diff --git a/brewman/brewman/schemas/account_type.py b/brewman/brewman/schemas/account_type.py index d9e88079..9aca9a09 100644 --- a/brewman/brewman/schemas/account_type.py +++ b/brewman/brewman/schemas/account_type.py @@ -1,9 +1,8 @@ -from pydantic import BaseModel +from brewman.schemas import to_camel +from pydantic import BaseModel, ConfigDict class AccountType(BaseModel): id_: int name: str - - class Config: - fields = {"id_": "id"} + model_config = ConfigDict(alias_generator=to_camel, str_strip_whitespace=True, populate_by_name=True) diff --git a/brewman/brewman/schemas/attendance.py b/brewman/brewman/schemas/attendance.py index b14c43ea..a6e26622 100644 --- a/brewman/brewman/schemas/attendance.py +++ b/brewman/brewman/schemas/attendance.py @@ -4,7 +4,13 @@ from datetime import date, datetime from brewman.schemas import to_camel from brewman.schemas.attendance_type import AttendanceType -from pydantic import BaseModel, validator +from pydantic import ( + BaseModel, + ConfigDict, + FieldSerializationInfo, + field_serializer, + field_validator, +) class AttendanceItem(BaseModel): @@ -16,23 +22,22 @@ class AttendanceItem(BaseModel): attendance_type: AttendanceType prints: str hours_worked: str - full_day: bool | None - - class Config: - alias_generator = to_camel + full_day: bool | None = None + model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True) class Attendance(BaseModel): - date_: date | None + date_: date | None = None body: list[AttendanceItem] + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) - @validator("date_", pre=True) + @field_validator("date_", mode="before") + @classmethod def parse_date(cls, value: date | str) -> date: if isinstance(value, date): return 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")} + @field_serializer("date_") + def serialize_date(self, value: date, info: FieldSerializationInfo) -> str: + return value.strftime("%d-%b-%Y") diff --git a/brewman/brewman/schemas/attendance_type.py b/brewman/brewman/schemas/attendance_type.py index d4c80d24..f5eed822 100644 --- a/brewman/brewman/schemas/attendance_type.py +++ b/brewman/brewman/schemas/attendance_type.py @@ -1,13 +1,11 @@ from decimal import Decimal from brewman.schemas import to_camel -from pydantic import BaseModel +from pydantic import BaseModel, ConfigDict class AttendanceType(BaseModel): id_: int - name: str | None - value: Decimal | None - - class Config: - alias_generator = to_camel + name: str | None = None + value: Decimal | None = None + model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True) diff --git a/brewman/brewman/schemas/balance.py b/brewman/brewman/schemas/balance.py index 302ec60c..8954a23a 100644 --- a/brewman/brewman/schemas/balance.py +++ b/brewman/brewman/schemas/balance.py @@ -3,6 +3,7 @@ from decimal import Decimal from pydantic import BaseModel +# TODO: Add config class AccountBalance(BaseModel): - date: Decimal + date_: Decimal total: Decimal diff --git a/brewman/brewman/schemas/balance_sheet.py b/brewman/brewman/schemas/balance_sheet.py index abdc62d2..ad5e6230 100644 --- a/brewman/brewman/schemas/balance_sheet.py +++ b/brewman/brewman/schemas/balance_sheet.py @@ -1,36 +1,39 @@ from datetime import date, datetime from decimal import Decimal -from pydantic import validator +from pydantic import ( + ConfigDict, + FieldSerializationInfo, + field_serializer, + field_validator, +) from pydantic.main import BaseModel from . import to_camel class BalanceSheetItem(BaseModel): - name: str | None - group: str | None - amount: Decimal | None - sub_amount: Decimal | None + name: str | None = None + group: str | None = None + amount: Decimal | None = None + sub_amount: Decimal | None = None order: int - - class Config: - anystr_strip_whitespace = True - alias_generator = to_camel + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) class BalanceSheet(BaseModel): - date_: date + date_: date | str body: list[BalanceSheetItem] - footer: BalanceSheetItem | None + footer: BalanceSheetItem | None = None + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) - class Config: - anystr_strip_whitespace = True - alias_generator = to_camel - json_encoders = {date: lambda v: v.strftime("%d-%b-%Y")} - - @validator("date_", pre=True) + @field_validator("date_", mode="before") + @classmethod def parse_date(cls, value: date | str) -> date: if isinstance(value, date): return value return datetime.strptime(value, "%d-%b-%Y").date() + + @field_serializer("date_") + def serialize_date(self, value: date, info: FieldSerializationInfo) -> str: + return value.strftime("%d-%b-%Y") diff --git a/brewman/brewman/schemas/batch.py b/brewman/brewman/schemas/batch.py index 79f61f9d..435dbf4e 100644 --- a/brewman/brewman/schemas/batch.py +++ b/brewman/brewman/schemas/batch.py @@ -4,17 +4,15 @@ from decimal import Decimal from brewman.schemas import to_camel from brewman.schemas.product import ProductLink -from pydantic import BaseModel +from pydantic import BaseModel, ConfigDict class Batch(BaseModel): - id_: uuid.UUID | None + id_: uuid.UUID | None = None name: str sku: ProductLink quantity_remaining: Decimal rate: Decimal tax: Decimal discount: Decimal - - class Config: - alias_generator = to_camel + model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True) diff --git a/brewman/brewman/schemas/batch_integrity.py b/brewman/brewman/schemas/batch_integrity.py index 5d0da60a..939188bd 100644 --- a/brewman/brewman/schemas/batch_integrity.py +++ b/brewman/brewman/schemas/batch_integrity.py @@ -3,7 +3,12 @@ import uuid from datetime import date, datetime from decimal import Decimal -from pydantic import validator +from pydantic import ( + ConfigDict, + FieldSerializationInfo, + field_serializer, + field_validator, +) from pydantic.main import BaseModel from . import to_camel @@ -15,18 +20,19 @@ class BatchIntegrityItem(BaseModel): url: list[str] quantity: Decimal price: Decimal + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) - class Config: - anystr_strip_whitespace = True - alias_generator = to_camel - json_encoders = {date: lambda v: v.strftime("%d-%b-%Y")} - - @validator("date_", pre=True) + @field_validator("date_", mode="before") + @classmethod def parse_start_date(cls, value: date | str) -> date: if isinstance(value, date): return value return datetime.strptime(value, "%d-%b-%Y").date() + @field_serializer("date_") + def serialize_date(self, value: date, info: FieldSerializationInfo) -> str: + return value.strftime("%d-%b-%Y") + class BatchIntegrity(BaseModel): id_: uuid.UUID @@ -36,14 +42,15 @@ class BatchIntegrity(BaseModel): showing: Decimal actual: Decimal details: list[BatchIntegrityItem] + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) - class Config: - anystr_strip_whitespace = True - alias_generator = to_camel - json_encoders = {date: lambda v: v.strftime("%d-%b-%Y")} - - @validator("date_", pre=True) - def parse_start_date(cls, value: date | str) -> date: + @field_validator("date_", mode="before") + @classmethod + def parse_date(cls, value: date | str) -> date: if isinstance(value, date): return value return datetime.strptime(value, "%d-%b-%Y").date() + + @field_serializer("date_") + def serialize_date(self, value: date, info: FieldSerializationInfo) -> str: + return value.strftime("%d-%b-%Y") diff --git a/brewman/brewman/schemas/blank_voucher_info.py b/brewman/brewman/schemas/blank_voucher_info.py index 634d3e83..73ebf695 100644 --- a/brewman/brewman/schemas/blank_voucher_info.py +++ b/brewman/brewman/schemas/blank_voucher_info.py @@ -1,6 +1,12 @@ from datetime import date, datetime -from pydantic import BaseModel, validator +from pydantic import ( + BaseModel, + ConfigDict, + FieldSerializationInfo, + field_serializer, + field_validator, +) from ..models.voucher_type import VoucherType from . import to_camel @@ -11,16 +17,18 @@ from .cost_centre import CostCentreLink class BlankVoucherInfo(BaseModel): type_: VoucherType date_: date - account: AccountLink | None - source: CostCentreLink | None - destination: CostCentreLink | None + account: AccountLink | None = None + source: CostCentreLink | None = None + destination: CostCentreLink | None = None + model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True) - class Config: - alias_generator = to_camel - json_encoders = {date: lambda v: v.strftime("%d-%b-%Y")} - - @validator("date_", pre=True) + @field_validator("date_", mode="before") + @classmethod def parse_date(cls, value: date | str) -> date: if isinstance(value, date): return value return datetime.strptime(value, "%d-%b-%Y").date() + + @field_serializer("date_") + def serialize_date(self, value: date, info: FieldSerializationInfo) -> str: + return value.strftime("%d-%b-%Y") diff --git a/brewman/brewman/schemas/cash_flow.py b/brewman/brewman/schemas/cash_flow.py index db300e7c..f7afd091 100644 --- a/brewman/brewman/schemas/cash_flow.py +++ b/brewman/brewman/schemas/cash_flow.py @@ -1,7 +1,12 @@ from datetime import date, datetime from decimal import Decimal -from pydantic import validator +from pydantic import ( + ConfigDict, + FieldSerializationInfo, + field_serializer, + field_validator, +) from pydantic.main import BaseModel from . import to_camel @@ -9,12 +14,9 @@ from . import to_camel class CashFlowItem(BaseModel): name: str - url: list[str] | None + url: list[str] | None = None amount: Decimal - - class Config: - anystr_strip_whitespace = True - alias_generator = to_camel + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) class CashFlowBody(BaseModel): @@ -22,31 +24,34 @@ class CashFlowBody(BaseModel): investing: list[CashFlowItem] financing: list[CashFlowItem] details: list[CashFlowItem] - - class Config: - anystr_strip_whitespace = True - alias_generator = to_camel + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) class CashFlow(BaseModel): - start_date: date - finish_date: date + start_date: date | str + finish_date: date | str body: CashFlowBody footer: list[CashFlowItem] + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) - 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) + @field_validator("start_date", mode="before") + @classmethod def parse_start_date(cls, value: date | str) -> date: if isinstance(value, date): return value return datetime.strptime(value, "%d-%b-%Y").date() - @validator("finish_date", pre=True) + @field_serializer("start_date") + def serialize_start_date(self, value: date, info: FieldSerializationInfo) -> str: + return value.strftime("%d-%b-%Y") + + @field_validator("finish_date", mode="before") + @classmethod def parse_finish_date(cls, value: date | str) -> date: if isinstance(value, date): return value return datetime.strptime(value, "%d-%b-%Y").date() + + @field_serializer("finish_date") + def serialize_finish_date(self, value: date, info: FieldSerializationInfo) -> str: + return value.strftime("%d-%b-%Y") diff --git a/brewman/brewman/schemas/client.py b/brewman/brewman/schemas/client.py index d1af972c..f09b7d27 100644 --- a/brewman/brewman/schemas/client.py +++ b/brewman/brewman/schemas/client.py @@ -2,6 +2,12 @@ import uuid from datetime import datetime +from pydantic import ( + ConfigDict, + FieldSerializationInfo, + field_serializer, + field_validator, +) from pydantic.main import BaseModel from . import to_camel @@ -10,24 +16,39 @@ from . import to_camel class ClientIn(BaseModel): name: str enabled: bool - otp: int | None + otp: int | None = None class Client(ClientIn): id_: uuid.UUID code: int creation_date: datetime + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) - class Config: - anystr_strip_whitespace = True - alias_generator = to_camel + @field_validator("creation_date", mode="before") + @classmethod + def parse_creation_date(cls, value: datetime | str) -> datetime | None: + if isinstance(value, datetime): + return value + return datetime.strptime(value, "%d-%b-%Y %H:%M") + + @field_serializer("creation_date") + def serialize_creation_date(self, value: datetime, info: FieldSerializationInfo) -> str: + return value.strftime("%d-%b-%Y %H:%M") class ClientList(Client): last_user: str - last_date: datetime | None + last_date: datetime | None = None + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) - class Config: - anystr_strip_whitespace = True - alias_generator = to_camel - json_encoders = {datetime: lambda v: v.strftime("%d-%b-%Y %H:%M")} + @field_validator("last_date", mode="before") + @classmethod + def parse_last_date(cls, value: datetime | str) -> datetime | None: + if isinstance(value, datetime): + return value + return datetime.strptime(value, "%d-%b-%Y %H:%M") + + @field_serializer("last_date") + def serialize_last_date(self, value: datetime, info: FieldSerializationInfo) -> str: + return value.strftime("%d-%b-%Y %H:%M") diff --git a/brewman/brewman/schemas/closing_stock.py b/brewman/brewman/schemas/closing_stock.py index 11a2112b..bb5c30bd 100644 --- a/brewman/brewman/schemas/closing_stock.py +++ b/brewman/brewman/schemas/closing_stock.py @@ -3,7 +3,12 @@ import uuid from datetime import date, datetime from decimal import Decimal -from pydantic import validator +from pydantic import ( + ConfigDict, + FieldSerializationInfo, + field_serializer, + field_validator, +) from pydantic.main import BaseModel from . import to_camel @@ -13,41 +18,40 @@ from .user_link import UserLink class ClosingStockItem(BaseModel): - id_: uuid.UUID | None + id_: uuid.UUID | None = None product: ProductLink group: str quantity: Decimal amount: Decimal physical: Decimal - cost_centre: CostCentreLink | None - - class Config: - anystr_strip_whitespace = True - alias_generator = to_camel + cost_centre: CostCentreLink | None = None + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) class ClosingStock(BaseModel): date_: date cost_centre: CostCentreLink items: list[ClosingStockItem] - creation_date: datetime | None - last_edit_date: datetime | None - user: UserLink | None + creation_date: datetime | None = None + last_edit_date: datetime | None = None + user: UserLink | None = None posted: bool - poster: UserLink | None + poster: UserLink | None = None + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) - class Config: - anystr_strip_whitespace = True - alias_generator = to_camel - json_encoders = {date: lambda v: v.strftime("%d-%b-%Y"), datetime: lambda v: v.strftime("%d-%b-%Y %H:%M")} - - @validator("date_", pre=True) + @field_validator("date_", mode="before") + @classmethod def parse_date(cls, value: date | str) -> date: if isinstance(value, date): return value return datetime.strptime(value, "%d-%b-%Y").date() - @validator("creation_date", pre=True) + @field_serializer("date_") + def serialize_date(self, value: date, info: FieldSerializationInfo) -> str: + return value.strftime("%d-%b-%Y") + + @field_validator("creation_date", mode="before") + @classmethod def parse_creation_date(cls, value: None | datetime | str) -> datetime | None: if value is None: return None @@ -55,10 +59,19 @@ class ClosingStock(BaseModel): return value return datetime.strptime(value, "%d-%b-%Y %H:%M") - @validator("last_edit_date", pre=True) + @field_serializer("creation_date") + def serialize_creation_date(self, value: datetime | None, info: FieldSerializationInfo) -> str | None: + return None if value is None else value.strftime("%d-%b-%Y %H:%M") + + @field_validator("last_edit_date", mode="before") + @classmethod def parse_last_edit_date(cls, value: None | datetime | str) -> datetime | None: if value is None: return None if isinstance(value, datetime): return value return datetime.strptime(value, "%d-%b-%Y %H:%M") + + @field_serializer("last_edit_date") + def serialize_last_edit_date(self, value: datetime | None, info: FieldSerializationInfo) -> str | None: + return None if value is None else value.strftime("%d-%b-%Y %H:%M") diff --git a/brewman/brewman/schemas/cost_centre.py b/brewman/brewman/schemas/cost_centre.py index aaa8e3dd..97a12822 100644 --- a/brewman/brewman/schemas/cost_centre.py +++ b/brewman/brewman/schemas/cost_centre.py @@ -1,38 +1,28 @@ import uuid -from pydantic import BaseModel, Field +from pydantic import BaseModel, ConfigDict, Field from . import to_camel class CostCentreIn(BaseModel): name: str = Field(..., min_length=1) - - class Config: - anystr_strip_whitespace = True + model_config = ConfigDict(str_strip_whitespace=True, populate_by_name=True) class CostCentre(CostCentreIn): id_: uuid.UUID is_fixture: bool - - class Config: - anystr_strip_whitespace = True - alias_generator = to_camel + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) class CostCentreLink(BaseModel): id_: uuid.UUID = Field(...) - name: str | None - - class Config: - fields = {"id_": "id"} + name: str | None = None + model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True) class CostCentreBlank(CostCentreIn): name: str is_fixture: bool - - class Config: - anystr_strip_whitespace = True - alias_generator = to_camel + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) diff --git a/brewman/brewman/schemas/daybook.py b/brewman/brewman/schemas/daybook.py index 1c0d0058..2ca78027 100644 --- a/brewman/brewman/schemas/daybook.py +++ b/brewman/brewman/schemas/daybook.py @@ -3,54 +3,66 @@ import uuid from datetime import date, datetime from decimal import Decimal -from pydantic import validator +from pydantic import ( + ConfigDict, + FieldSerializationInfo, + field_serializer, + field_validator, +) from pydantic.main import BaseModel from . import to_camel class DaybookItem(BaseModel): - id_: uuid.UUID | None - date_: date + id_: uuid.UUID | None = None + date_: date | str url: list[str] type_: str narration: str - debit_text: str | None - debit_amount: Decimal | None - credit_text: str | None - credit_amount: Decimal | None + debit_text: str | None = None + debit_amount: Decimal | None = None + credit_text: str | None = None + credit_amount: Decimal | None = None posted: bool + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) - @validator("date_", pre=True) + @field_validator("date_", mode="before") + @classmethod def parse_date(cls, value: date | str) -> date: if isinstance(value, date): return 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")} + @field_serializer("date_") + def serialize_date(self, value: date, info: FieldSerializationInfo) -> str: + return value.strftime("%d-%b-%Y") class Daybook(BaseModel): - start_date: date - finish_date: date + start_date: date | str + finish_date: date | str body: list[DaybookItem] + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) - 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) + @field_validator("start_date", mode="before") + @classmethod def parse_start_date(cls, value: date | str) -> date: if isinstance(value, date): return value return datetime.strptime(value, "%d-%b-%Y").date() - @validator("finish_date", pre=True) + @field_serializer("start_date") + def serialize_start_date(self, value: date, info: FieldSerializationInfo) -> str: + return value.strftime("%d-%b-%Y") + + @field_validator("finish_date", mode="before") + @classmethod def parse_finish_date(cls, value: date | str) -> date: if isinstance(value, date): return value return datetime.strptime(value, "%d-%b-%Y").date() + + @field_serializer("finish_date") + def serialize_finish_date(self, value: date, info: FieldSerializationInfo) -> str: + return value.strftime("%d-%b-%Y") diff --git a/brewman/brewman/schemas/employee.py b/brewman/brewman/schemas/employee.py index d3b68fbb..6cd5eb90 100644 --- a/brewman/brewman/schemas/employee.py +++ b/brewman/brewman/schemas/employee.py @@ -2,9 +2,16 @@ import uuid from datetime import date, datetime from decimal import Decimal -from typing import Any -from pydantic import BaseModel, Field, validator +from pydantic import ( + BaseModel, + ConfigDict, + Field, + FieldSerializationInfo, + field_serializer, + field_validator, + model_validator, +) from . import to_camel from .account import AccountBase @@ -14,17 +21,24 @@ from .cost_centre import CostCentreLink class EmployeeIn(AccountBase): designation: str salary: int = Field(ge=0) - points: Decimal = Field(ge=0, lt=1000, multiple_of=0.01) + points: Decimal = Field(ge=0, lt=1000) joining_date: date - leaving_date: date | None + leaving_date: date | None = None + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) - @validator("joining_date", pre=True) + @field_validator("joining_date", mode="before") + @classmethod def parse_joining_date(cls, value: date | str) -> date: if isinstance(value, date): return value return datetime.strptime(value, "%d-%b-%Y").date() - @validator("leaving_date", pre=True) + @field_serializer("joining_date") + def serialize_joining_date(self, value: date, info: FieldSerializationInfo) -> str: + return value.strftime("%d-%b-%Y") + + @field_validator("leaving_date", mode="before") + @classmethod def parse_leaving_date(cls, value: None | date | str) -> date | None: if isinstance(value, date): return value @@ -32,18 +46,19 @@ class EmployeeIn(AccountBase): return value return datetime.strptime(value, "%d-%b-%Y").date() - @validator("leaving_date") - def leaving_date_more_than_joining_date(cls, v: date | None, values: dict, **kwargs: Any) -> date | None: - if values["is_active"]: - return None - if v < values["joining_date"]: - raise ValueError("Leaving Date cannot be less than Joining Date") - return v + @field_serializer("leaving_date") + def serialize_leaving_date(self, value: date | None, info: FieldSerializationInfo) -> str | None: + return None if value is None else value.strftime("%d-%b-%Y") - class Config: - anystr_strip_whitespace = True - alias_generator = to_camel - json_encoders = {datetime: lambda v: v.strftime("%d-%b-%Y %H:%M"), date: lambda v: v.strftime("%d-%b-%Y")} + @model_validator(mode="after") + def leaving_date_more_than_joining_date(self) -> "EmployeeIn": + if self.is_active: + self.leaving_date = None + if (not self.is_active) and (self.leaving_date is None): + raise ValueError("Need leaving date for employee") + if self.leaving_date < self.joining_date: + raise ValueError("Leaving Date cannot be less than Joining Date") + return self class Employee(EmployeeIn): @@ -54,18 +69,12 @@ class Employee(EmployeeIn): class EmployeeBlank(EmployeeIn): name: str - - class Config: - anystr_strip_whitespace = True - alias_generator = to_camel - json_encoders = {datetime: lambda v: v.strftime("%d-%b-%Y %H:%M"), date: lambda v: v.strftime("%d-%b-%Y")} + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) class EmployeeLink(BaseModel): id_: uuid.UUID = Field(...) - name: str | None - designation: str | None + name: str | None = None + designation: str | None = None cost_centre: CostCentreLink - - class Config: - alias_generator = to_camel + model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True) diff --git a/brewman/brewman/schemas/employee_attendance.py b/brewman/brewman/schemas/employee_attendance.py index b64cc166..c0a282cd 100644 --- a/brewman/brewman/schemas/employee_attendance.py +++ b/brewman/brewman/schemas/employee_attendance.py @@ -3,7 +3,13 @@ from datetime import date, datetime from brewman.schemas import to_camel from brewman.schemas.account import AccountLink from brewman.schemas.attendance_type import AttendanceType -from pydantic import BaseModel, validator +from pydantic import ( + BaseModel, + ConfigDict, + FieldSerializationInfo, + field_serializer, + field_validator, +) class EmployeeAttendanceItem(BaseModel): @@ -11,39 +17,50 @@ class EmployeeAttendanceItem(BaseModel): attendance_type: AttendanceType prints: str hours_worked: str - full_day: bool | None + full_day: bool | None = None + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) - @validator("date_", pre=True) + @field_validator("date_", mode="before") + @classmethod def parse_date(cls, value: date | str) -> date: if isinstance(value, date): return 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")} + @field_serializer("date_") + def serialize_date(self, value: date, info: FieldSerializationInfo) -> str: + return value.strftime("%d-%b-%Y") class EmployeeAttendance(BaseModel): - start_date: date | None - finish_date: date | None - employee: AccountLink | None + start_date: date | None = None + finish_date: date | None = None + employee: AccountLink | None = None body: list[EmployeeAttendanceItem] + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) - @validator("start_date", pre=True) - def parse_start_date(cls, value: date | str) -> date: + @field_validator("start_date", mode="before") + @classmethod + def parse_start_date(cls, value: date | str | None) -> date | None: + if value is None: + return None if isinstance(value, date): return value return datetime.strptime(value, "%d-%b-%Y").date() - @validator("finish_date", pre=True) - def parse_finish_date(cls, value: date | str) -> date: + @field_serializer("start_date") + def serialize_start_date(self, value: date, info: FieldSerializationInfo) -> str | None: + return None if value is None else value.strftime("%d-%b-%Y") + + @field_validator("finish_date", mode="before") + @classmethod + def parse_finish_date(cls, value: date | str | None) -> date | None: + if value is None: + return None if isinstance(value, date): return 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")} + @field_serializer("finish_date") + def serialize_finish_date(self, value: date, info: FieldSerializationInfo) -> str | None: + return None if value is None else value.strftime("%d-%b-%Y") diff --git a/brewman/brewman/schemas/employee_benefit.py b/brewman/brewman/schemas/employee_benefit.py index 44b51414..5c826484 100644 --- a/brewman/brewman/schemas/employee_benefit.py +++ b/brewman/brewman/schemas/employee_benefit.py @@ -2,11 +2,11 @@ import uuid from brewman.schemas import to_camel from brewman.schemas.employee import EmployeeLink -from pydantic import BaseModel, Field +from pydantic import BaseModel, ConfigDict, Field class EmployeeBenefit(BaseModel): - id_: uuid.UUID | None + id_: uuid.UUID | None = None employee: EmployeeLink gross_salary: int = Field(ge=0) days_worked: int = Field(ge=0) @@ -14,6 +14,4 @@ class EmployeeBenefit(BaseModel): pf_employee: int | None = Field(ge=0) esi_employer: int | None = Field(ge=0) pf_employer: int | None = Field(ge=0) - - class Config: - alias_generator = to_camel + model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True) diff --git a/brewman/brewman/schemas/entries.py b/brewman/brewman/schemas/entries.py index 9dc366cf..3aa76a2b 100644 --- a/brewman/brewman/schemas/entries.py +++ b/brewman/brewman/schemas/entries.py @@ -3,7 +3,13 @@ import uuid from datetime import date, datetime from decimal import Decimal -from pydantic import BaseModel, validator +from pydantic import ( + BaseModel, + ConfigDict, + FieldSerializationInfo, + field_serializer, + field_validator, +) from . import to_camel from .user_link import UserLink @@ -22,42 +28,43 @@ class Entries(BaseModel): creation_date: datetime last_edit_date: datetime user: UserLink + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) - class Config: - anystr_strip_whitespace = True - alias_generator = to_camel - json_encoders = { - date: lambda v: v.strftime("%d-%b-%Y"), - datetime: lambda v: v.strftime("%d-%b-%Y %H:%M"), - } - - @validator("date_", pre=True) + @field_validator("date_", mode="before") + @classmethod def parse_date(cls, value: date | str) -> date: if isinstance(value, date): return value return datetime.strptime(value, "%d-%b-%Y").date() - @validator("creation_date", pre=True) + @field_serializer("date_") + def serialize_date(self, value: date, info: FieldSerializationInfo) -> str: + return value.strftime("%d-%b-%Y") + + @field_validator("creation_date", mode="before") + @classmethod def parse_creation_date(cls, value: datetime | str) -> datetime: if isinstance(value, datetime): return value return datetime.strptime(value, "%d-%b-%Y %H:%M") - @validator("last_edit_date", pre=True) + @field_serializer("creation_date") + def serialize_creation_date(self, value: datetime, info: FieldSerializationInfo) -> str: + return value.strftime("%d-%b-%Y %H:%M") + + @field_validator("last_edit_date", mode="before") + @classmethod def parse_last_edit_date(cls, value: datetime | str) -> datetime: if isinstance(value, datetime): return value return datetime.strptime(value, "%d-%b-%Y %H:%M") + @field_serializer("last_edit_date") + def serialize_last_edit_date(self, value: datetime, info: FieldSerializationInfo) -> str: + return value.strftime("%d-%b-%Y %H:%M") + class Report(BaseModel): counts: int report: list[Entries] - - class Config: - anystr_strip_whitespace = True - alias_generator = to_camel - json_encoders = { - date: lambda v: v.strftime("%d-%b-%Y"), - datetime: lambda v: v.strftime("%d-%b-%Y %H:%M"), - } + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) diff --git a/brewman/brewman/schemas/fingerprint.py b/brewman/brewman/schemas/fingerprint.py index c164efaf..70f5c0f8 100644 --- a/brewman/brewman/schemas/fingerprint.py +++ b/brewman/brewman/schemas/fingerprint.py @@ -1,11 +1,30 @@ import uuid -from datetime import datetime +from datetime import date, datetime -from pydantic import BaseModel +from brewman.schemas import to_camel +from pydantic import ( + BaseModel, + ConfigDict, + FieldSerializationInfo, + field_serializer, + field_validator, +) class Fingerprint(BaseModel): - id: uuid.UUID + id_: uuid.UUID employee_id: uuid.UUID - date: datetime + date_: datetime + model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True) + + @field_validator("date_", mode="before") + @classmethod + def parse_date(cls, value: date | str) -> date: + if isinstance(value, date): + return value + return datetime.strptime(value, "%d-%b-%Y").date() + + @field_serializer("date_") + def serialize_date(self, value: date, info: FieldSerializationInfo) -> str: + return value.strftime("%d-%b-%Y") diff --git a/brewman/brewman/schemas/image_upload.py b/brewman/brewman/schemas/image_upload.py index 0cafd615..eb91ee79 100644 --- a/brewman/brewman/schemas/image_upload.py +++ b/brewman/brewman/schemas/image_upload.py @@ -1,13 +1,11 @@ import uuid from brewman.schemas import to_camel -from pydantic import BaseModel +from pydantic import BaseModel, ConfigDict class ImageUpload(BaseModel): - id_: uuid.UUID | None - resized: str | None - thumbnail: str | None - - class Config: - alias_generator = to_camel + id_: uuid.UUID | None = None + resized: str | None = None + thumbnail: str | None = None + model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True) diff --git a/brewman/brewman/schemas/incentive.py b/brewman/brewman/schemas/incentive.py index b3f93722..3b78bf22 100644 --- a/brewman/brewman/schemas/incentive.py +++ b/brewman/brewman/schemas/incentive.py @@ -3,7 +3,7 @@ import uuid from decimal import Decimal from brewman.schemas import to_camel -from pydantic import BaseModel, Field +from pydantic import BaseModel, ConfigDict, Field class Incentive(BaseModel): @@ -11,8 +11,6 @@ class Incentive(BaseModel): name: str designation: str department: str - days_worked: Decimal = Field(ge=0, multiple_of=0.5) - points: Decimal = Field(ge=0, multiple_of=0.01) - - class Config: - alias_generator = to_camel + days_worked: Decimal = Field(ge=0) + points: Decimal = Field(ge=0) + model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True) diff --git a/brewman/brewman/schemas/input.py b/brewman/brewman/schemas/input.py index 59e52f7d..d11edb54 100644 --- a/brewman/brewman/schemas/input.py +++ b/brewman/brewman/schemas/input.py @@ -5,7 +5,7 @@ from datetime import date, datetime from decimal import Decimal from fastapi import Form -from pydantic import BaseModel, Field, validator +from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator from . import to_camel from .account import AccountLink @@ -19,16 +19,10 @@ from .voucher import VoucherIn class JournalIn(VoucherIn): journals: list[Journal] + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) - class Config: - anystr_strip_whitespace = True - alias_generator = to_camel - json_encoders = { - date: lambda v: v.strftime("%d-%b-%Y"), - datetime: lambda v: v.strftime("%d-%b-%Y %H:%M"), - } - - @validator("date_", pre=True) + @field_validator("date_", mode="before") + @classmethod def parse_date(cls, value: date | str) -> date: if isinstance(value, date): return value @@ -43,16 +37,10 @@ class JournalIn(VoucherIn): class PurchaseIn(VoucherIn): vendor: AccountLink inventories: list[Inventory] + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) - class Config: - anystr_strip_whitespace = True - alias_generator = to_camel - json_encoders = { - date: lambda v: v.strftime("%d-%b-%Y"), - datetime: lambda v: v.strftime("%d-%b-%Y %H:%M"), - } - - @validator("date_", pre=True) + @field_validator("date_", mode="before") + @classmethod def parse_date(cls, value: date | str) -> date: if isinstance(value, date): return value @@ -68,26 +56,13 @@ class IssueIn(VoucherIn): source: CostCentreLink destination: CostCentreLink inventories: list[Inventory] + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) - class Config: - anystr_strip_whitespace = True - alias_generator = to_camel - json_encoders = { - date: lambda v: v.strftime("%d-%b-%Y"), - datetime: lambda v: v.strftime("%d-%b-%Y %H:%M"), - } - - @validator("date_", pre=True) - def parse_date(cls, value: date | str) -> date: - if isinstance(value, date): - return value - return datetime.strptime(value, "%d-%b-%Y").date() - - @validator("destination") # For Purchase, Issue and Return Vouchers - def source_destination_unique(cls, value: CostCentreLink, values: dict) -> CostCentreLink: - if value.id_ == values["source"].id_: + @model_validator(mode="after") + def source_destination_unique(self) -> "IssueIn": + if self.source.id_ == self.destination.id_: raise ValueError("Source and destination cannot be the same") - return value + return self @classmethod def load_form(cls, data: str = Form(...)) -> BaseModel: @@ -97,16 +72,10 @@ class IssueIn(VoucherIn): class EmployeeBenefitIn(VoucherIn): employee_benefits: list[EmployeeBenefit] + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) - class Config: - anystr_strip_whitespace = True - alias_generator = to_camel - json_encoders = { - date: lambda v: v.strftime("%d-%b-%Y"), - datetime: lambda v: v.strftime("%d-%b-%Y %H:%M"), - } - - @validator("date_", pre=True) + @field_validator("date_", mode="before") + @classmethod def parse_date(cls, value: date | str) -> date: if isinstance(value, date): return value @@ -120,16 +89,10 @@ class EmployeeBenefitIn(VoucherIn): class IncentiveIn(VoucherIn): incentives: list[Incentive] + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) - class Config: - anystr_strip_whitespace = True - alias_generator = to_camel - json_encoders = { - date: lambda v: v.strftime("%d-%b-%Y"), - datetime: lambda v: v.strftime("%d-%b-%Y %H:%M"), - } - - @validator("date_", pre=True) + @field_validator("date_", mode="before") + @classmethod def parse_date(cls, value: date | str) -> date: if isinstance(value, date): return value @@ -142,9 +105,9 @@ class IncentiveIn(VoucherIn): class IncentiveEmployee(BaseModel): - id_: uuid.UUID | None + id_: uuid.UUID | None = None employee_id: uuid.UUID cost_centre_id: uuid.UUID - journal: Journal | None - days_worked: Decimal = Field(ge=0, multiple_of=0.5) - points: Decimal = Field(ge=0, multiple_of=0.01) + journal: Journal | None = None + days_worked: Decimal = Field(ge=0) + points: Decimal = Field(ge=0) diff --git a/brewman/brewman/schemas/inventory.py b/brewman/brewman/schemas/inventory.py index 3e9f1146..1c033c4f 100644 --- a/brewman/brewman/schemas/inventory.py +++ b/brewman/brewman/schemas/inventory.py @@ -4,17 +4,15 @@ from decimal import Decimal from brewman.schemas import to_camel from brewman.schemas.batch import Batch -from pydantic import BaseModel, Field +from pydantic import BaseModel, ConfigDict, Field class Inventory(BaseModel): - id_: uuid.UUID | None + id_: uuid.UUID | None = None batch: Batch - quantity: Decimal = Field(ge=0, multiple_of=0.01) - rate: Decimal = Field(ge=0, multiple_of=0.01) - tax: Decimal = Field(ge=0, multiple_of=0.00001, le=5) - discount: Decimal = Field(ge=0, multiple_of=0.00001, le=1) - amount: Decimal | None - - class Config: - alias_generator = to_camel + 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 + model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True) diff --git a/brewman/brewman/schemas/issue_grid_item.py b/brewman/brewman/schemas/issue_grid_item.py index d52c67fd..3d3c9d87 100644 --- a/brewman/brewman/schemas/issue_grid_item.py +++ b/brewman/brewman/schemas/issue_grid_item.py @@ -2,7 +2,8 @@ import uuid from decimal import Decimal -from pydantic import BaseModel +from brewman.schemas import to_camel +from pydantic import BaseModel, ConfigDict class IssueGridItem(BaseModel): @@ -10,6 +11,4 @@ class IssueGridItem(BaseModel): amount: Decimal source: str destination: str - - class Config: - fields = {"id_": "id"} + model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True) diff --git a/brewman/brewman/schemas/journal.py b/brewman/brewman/schemas/journal.py index 87ef9560..e5e9e056 100644 --- a/brewman/brewman/schemas/journal.py +++ b/brewman/brewman/schemas/journal.py @@ -5,16 +5,13 @@ 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, Field +from pydantic import BaseModel, ConfigDict, Field class Journal(BaseModel): - id_: uuid.UUID | None - debit: int = Field(ge=-1, le=1, multiple_of=1) + id_: uuid.UUID | None = None + debit: int = Field(ge=-1, le=1) amount: Decimal = Field(ge=0) account: AccountLink - cost_centre: CostCentreLink | None - - class Config: - anystr_strip_whitespace = True - alias_generator = to_camel + cost_centre: CostCentreLink | None = None + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) diff --git a/brewman/brewman/schemas/ledger.py b/brewman/brewman/schemas/ledger.py index 3aa7fe98..a8d8d72e 100644 --- a/brewman/brewman/schemas/ledger.py +++ b/brewman/brewman/schemas/ledger.py @@ -3,7 +3,12 @@ import uuid from datetime import date, datetime from decimal import Decimal -from pydantic import validator +from pydantic import ( + ConfigDict, + FieldSerializationInfo, + field_serializer, + field_validator, +) from pydantic.main import BaseModel from . import to_camel @@ -11,8 +16,8 @@ from .account import AccountLink class LedgerItem(BaseModel): - id_: uuid.UUID | None - date_: date + id_: uuid.UUID | None = None + date_: date | str name: str url: list[str] type_: str @@ -20,38 +25,45 @@ class LedgerItem(BaseModel): debit: Decimal credit: Decimal posted: bool + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) - @validator("date_", pre=True) + @field_validator("date_", mode="before") + @classmethod def parse_date(cls, value: date | str) -> date: if isinstance(value, date): return 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")} + @field_serializer("date_") + def serialize_date(self, value: date, info: FieldSerializationInfo) -> str: + return value.strftime("%d-%b-%Y") class Ledger(BaseModel): - start_date: date - finish_date: date - account: AccountLink | None + start_date: date | str + finish_date: date | str + account: AccountLink | None = None body: list[LedgerItem] + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) - 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) + @field_validator("start_date", mode="before") + @classmethod def parse_start_date(cls, value: date | str) -> date: if isinstance(value, date): return value return datetime.strptime(value, "%d-%b-%Y").date() - @validator("finish_date", pre=True) + @field_serializer("start_date") + def serialize_start_date(self, value: date, info: FieldSerializationInfo) -> str: + return value.strftime("%d-%b-%Y") + + @field_validator("finish_date", mode="before") + @classmethod def parse_finish_date(cls, value: date | str) -> date: if isinstance(value, date): return value return datetime.strptime(value, "%d-%b-%Y").date() + + @field_serializer("finish_date") + def serialize_finish_date(self, value: date, info: FieldSerializationInfo) -> str: + return value.strftime("%d-%b-%Y") diff --git a/brewman/brewman/schemas/login_history.py b/brewman/brewman/schemas/login_history.py index f629849b..bbb1ad95 100644 --- a/brewman/brewman/schemas/login_history.py +++ b/brewman/brewman/schemas/login_history.py @@ -2,7 +2,7 @@ import uuid from datetime import datetime -from pydantic import BaseModel +from pydantic import BaseModel, ConfigDict from . import to_camel @@ -12,8 +12,4 @@ class LoginHistory(BaseModel): user_id: uuid.UUID client_id: uuid.UUID date: datetime - - class Config: - fields = {"id_": "id"} - anystr_strip_whitespace = True - alias_generator = to_camel + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) diff --git a/brewman/brewman/schemas/net_transactions.py b/brewman/brewman/schemas/net_transactions.py index 68c4a2d1..d47286b9 100644 --- a/brewman/brewman/schemas/net_transactions.py +++ b/brewman/brewman/schemas/net_transactions.py @@ -1,7 +1,12 @@ from datetime import date, datetime from decimal import Decimal -from pydantic import validator +from pydantic import ( + ConfigDict, + FieldSerializationInfo, + field_serializer, + field_validator, +) from pydantic.main import BaseModel from . import to_camel @@ -10,33 +15,35 @@ from . import to_camel class NetTransactionsItem(BaseModel): type_: str name: str - debit: Decimal | None - credit: Decimal | None - - class Config: - anystr_strip_whitespace = True - alias_generator = to_camel - json_encoders = {date: lambda v: v.strftime("%d-%b-%Y")} + debit: Decimal | None = None + credit: Decimal | None = None + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) class NetTransactions(BaseModel): - start_date: date - finish_date: date + start_date: date | str + finish_date: date | str body: list[NetTransactionsItem] + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) - 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) + @field_validator("start_date", mode="before") + @classmethod def parse_start_date(cls, value: date | str) -> date: if isinstance(value, date): return value return datetime.strptime(value, "%d-%b-%Y").date() - @validator("finish_date", pre=True) + @field_serializer("start_date") + def serialize_start_date(self, value: date, info: FieldSerializationInfo) -> str: + return value.strftime("%d-%b-%Y") + + @field_validator("finish_date", mode="before") + @classmethod def parse_finish_date(cls, value: date | str) -> date: if isinstance(value, date): return value return datetime.strptime(value, "%d-%b-%Y").date() + + @field_serializer("finish_date") + def serialize_finish_date(self, value: date, info: FieldSerializationInfo) -> str: + return value.strftime("%d-%b-%Y") diff --git a/brewman/brewman/schemas/non_contract_purchase.py b/brewman/brewman/schemas/non_contract_purchase.py index d532d2ab..a2564ba1 100644 --- a/brewman/brewman/schemas/non_contract_purchase.py +++ b/brewman/brewman/schemas/non_contract_purchase.py @@ -1,7 +1,12 @@ from datetime import date, datetime from decimal import Decimal -from pydantic import validator +from pydantic import ( + ConfigDict, + FieldSerializationInfo, + field_serializer, + field_validator, +) from pydantic.main import BaseModel from . import to_camel @@ -14,14 +19,15 @@ class NonContractPurchase(BaseModel): url: list[str] contract_price: Decimal purchase_price: Decimal + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) - class Config: - anystr_strip_whitespace = True - alias_generator = to_camel - json_encoders = {date: lambda v: v.strftime("%d-%b-%Y")} - - @validator("date_", pre=True) + @field_validator("date_", mode="before") + @classmethod def parse_start_date(cls, value: date | str) -> date: if isinstance(value, date): return value return datetime.strptime(value, "%d-%b-%Y").date() + + @field_serializer("date_") + def serialize_date(self, value: date, info: FieldSerializationInfo) -> str: + return value.strftime("%d-%b-%Y") diff --git a/brewman/brewman/schemas/period.py b/brewman/brewman/schemas/period.py index 28700a09..012267c9 100644 --- a/brewman/brewman/schemas/period.py +++ b/brewman/brewman/schemas/period.py @@ -2,7 +2,14 @@ import uuid from datetime import date, datetime -from pydantic import BaseModel, Field, validator +from pydantic import ( + BaseModel, + ConfigDict, + Field, + FieldSerializationInfo, + field_serializer, + field_validator, +) from . import to_camel @@ -10,36 +17,36 @@ from . import to_camel class PeriodIn(BaseModel): valid_from: date valid_till: date + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) - class Config: - anystr_strip_whitespace = True - alias_generator = to_camel - json_encoders = {date: lambda v: v.strftime("%d-%b-%Y") if v is not None else None} - - @validator("valid_from", pre=True) + @field_validator("valid_from", mode="before") + @classmethod def parse_valid_from(cls, value: date | str) -> date: if isinstance(value, date): return value return datetime.strptime(value, "%d-%b-%Y").date() - @validator("valid_till", pre=True) + @field_serializer("valid_from") + def serialize_valid_from(self, value: date, info: FieldSerializationInfo) -> str: + return value.strftime("%d-%b-%Y") + + @field_validator("valid_till", mode="before") + @classmethod def parse_valid_till(cls, value: date | str) -> date: if isinstance(value, date): return value return datetime.strptime(value, "%d-%b-%Y").date() + @field_serializer("valid_till") + def serialize_valid_till(self, value: date, info: FieldSerializationInfo) -> str: + return value.strftime("%d-%b-%Y") + class Period(PeriodIn): id_: uuid.UUID - - class Config: - anystr_strip_whitespace = True - alias_generator = to_camel - json_encoders = {date: lambda v: v.strftime("%d-%b-%Y")} + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) class PeriodLink(BaseModel): id_: uuid.UUID = Field(...) - - class Config: - fields = {"id_": "id"} + model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True) diff --git a/brewman/brewman/schemas/permission.py b/brewman/brewman/schemas/permission.py index a43d2fdf..c7b2e28b 100644 --- a/brewman/brewman/schemas/permission.py +++ b/brewman/brewman/schemas/permission.py @@ -1,5 +1,7 @@ import uuid +from brewman.schemas import to_camel +from pydantic import ConfigDict from pydantic.main import BaseModel @@ -7,6 +9,4 @@ class PermissionItem(BaseModel): id_: uuid.UUID name: str enabled: bool - - class Config: - fields = {"id_": "id"} + model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True) diff --git a/brewman/brewman/schemas/product.py b/brewman/brewman/schemas/product.py index a3667f35..e4c81252 100644 --- a/brewman/brewman/schemas/product.py +++ b/brewman/brewman/schemas/product.py @@ -1,6 +1,6 @@ import uuid -from pydantic import BaseModel, Field +from pydantic import BaseModel, ConfigDict, Field from . import to_camel from .product_group import ProductGroupLink @@ -9,10 +9,8 @@ from .stock_keeping_unit import StockKeepingUnit class ProductLink(BaseModel): id_: uuid.UUID = Field(...) - name: str | None - - class Config: - fields = {"id_": "id"} + name: str | None = None + model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True) class ProductIn(BaseModel): @@ -23,10 +21,7 @@ class ProductIn(BaseModel): is_active: bool is_purchased: bool is_sold: bool - - class Config: - anystr_strip_whitespace = True - alias_generator = to_camel + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) class Product(ProductIn): @@ -39,9 +34,6 @@ class ProductBlank(ProductIn): name: str fraction_units: str skus: list[StockKeepingUnit] - product_group: ProductGroupLink | None # type: ignore[assignment] + product_group: ProductGroupLink | None = None # type: ignore[assignment] is_fixture: bool - - class Config: - anystr_strip_whitespace = True - alias_generator = to_camel + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) diff --git a/brewman/brewman/schemas/product_group.py b/brewman/brewman/schemas/product_group.py index 0cdbbde2..ee59add8 100644 --- a/brewman/brewman/schemas/product_group.py +++ b/brewman/brewman/schemas/product_group.py @@ -1,6 +1,6 @@ import uuid -from pydantic import BaseModel, Field +from pydantic import BaseModel, ConfigDict, Field from . import to_camel @@ -12,24 +12,16 @@ class ProductGroupIn(BaseModel): class ProductGroup(ProductGroupIn): id_: uuid.UUID is_fixture: bool - - class Config: - anystr_strip_whitespace = True - alias_generator = to_camel + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) class ProductGroupBlank(ProductGroupIn): name: str is_fixture: bool - - class Config: - anystr_strip_whitespace = True - alias_generator = to_camel + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) class ProductGroupLink(BaseModel): id_: uuid.UUID = Field(...) - name: str | None - - class Config: - fields = {"id_": "id"} + name: str | None = None + model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True) diff --git a/brewman/brewman/schemas/product_ledger.py b/brewman/brewman/schemas/product_ledger.py index 8f2084a1..8884d3c2 100644 --- a/brewman/brewman/schemas/product_ledger.py +++ b/brewman/brewman/schemas/product_ledger.py @@ -3,7 +3,12 @@ import uuid from datetime import date, datetime from decimal import Decimal -from pydantic import validator +from pydantic import ( + ConfigDict, + FieldSerializationInfo, + field_serializer, + field_validator, +) from pydantic.main import BaseModel from . import to_camel @@ -11,53 +16,60 @@ from .product import ProductLink class ProductLedgerItem(BaseModel): - id_: uuid.UUID | None + id_: uuid.UUID | None = None date_: date name: str url: list[str] type_: str narration: str - debit_quantity: Decimal | None - debit_amount: Decimal | None - debit_unit: str | None - credit_quantity: Decimal | None - credit_amount: Decimal | None - credit_unit: str | None + debit_quantity: Decimal | None = None + debit_amount: Decimal | None = None + debit_unit: str | None = None + credit_quantity: Decimal | None = None + credit_amount: Decimal | None = None + credit_unit: str | None = None running_quantity: Decimal running_amount: Decimal posted: bool + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) - @validator("date_", pre=True) + @field_validator("date_", mode="before") + @classmethod def parse_date(cls, value: date | str) -> date: if isinstance(value, date): return 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")} + @field_serializer("date_") + def serialize_date(self, value: date, info: FieldSerializationInfo) -> str: + return value.strftime("%d-%b-%Y") class ProductLedger(BaseModel): - start_date: date - finish_date: date - product: ProductLink | None + start_date: date | str + finish_date: date | str + product: ProductLink | None = None body: list[ProductLedgerItem] + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) - 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) + @field_validator("start_date", mode="before") + @classmethod def parse_start_date(cls, value: date | str) -> date: if isinstance(value, date): return value return datetime.strptime(value, "%d-%b-%Y").date() - @validator("finish_date", pre=True) + @field_serializer("start_date") + def serialize_start_date(self, value: date, info: FieldSerializationInfo) -> str: + return value.strftime("%d-%b-%Y") + + @field_validator("finish_date", mode="before") + @classmethod def parse_finish_date(cls, value: date | str) -> date: if isinstance(value, date): return value return datetime.strptime(value, "%d-%b-%Y").date() + + @field_serializer("finish_date") + def serialize_finish_date(self, value: date, info: FieldSerializationInfo) -> str: + return value.strftime("%d-%b-%Y") diff --git a/brewman/brewman/schemas/product_sku.py b/brewman/brewman/schemas/product_sku.py index b6255470..b0c2e060 100644 --- a/brewman/brewman/schemas/product_sku.py +++ b/brewman/brewman/schemas/product_sku.py @@ -3,7 +3,7 @@ import uuid from decimal import Decimal from brewman.schemas import to_camel -from pydantic import BaseModel, Field +from pydantic import BaseModel, ConfigDict, Field class ProductSku(BaseModel): @@ -13,6 +13,4 @@ class ProductSku(BaseModel): cost_price: Decimal sale_price: Decimal is_rate_contracted: bool - - class Config: - alias_generator = to_camel + model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True) diff --git a/brewman/brewman/schemas/profit_loss.py b/brewman/brewman/schemas/profit_loss.py index c4a8c42d..21f690e4 100644 --- a/brewman/brewman/schemas/profit_loss.py +++ b/brewman/brewman/schemas/profit_loss.py @@ -1,44 +1,51 @@ from datetime import date, datetime from decimal import Decimal -from pydantic import validator +from pydantic import ( + ConfigDict, + FieldSerializationInfo, + field_serializer, + field_validator, +) from pydantic.main import BaseModel from . import to_camel class ProfitLossItem(BaseModel): - group: str | None - name: str | None - amount: Decimal | None - total: Decimal | None + group: str | None = None + name: str | None = None + amount: Decimal | None = None + total: Decimal | None = None order: int - - class Config: - anystr_strip_whitespace = True - alias_generator = to_camel - json_encoders = {date: lambda v: v.strftime("%d-%b-%Y")} + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) class ProfitLoss(BaseModel): - start_date: date - finish_date: date + start_date: date | str + finish_date: date | str body: list[ProfitLossItem] footer: ProfitLossItem + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) - 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) + @field_validator("start_date", mode="before") + @classmethod def parse_start_date(cls, value: date | str) -> date: if isinstance(value, date): return value return datetime.strptime(value, "%d-%b-%Y").date() - @validator("finish_date", pre=True) + @field_serializer("start_date") + def serialize_start_date(self, value: date, info: FieldSerializationInfo) -> str: + return value.strftime("%d-%b-%Y") + + @field_validator("finish_date", mode="before") + @classmethod def parse_finish_date(cls, value: date | str) -> date: if isinstance(value, date): return value return datetime.strptime(value, "%d-%b-%Y").date() + + @field_serializer("finish_date") + def serialize_finish_date(self, value: date, info: FieldSerializationInfo) -> str: + return value.strftime("%d-%b-%Y") diff --git a/brewman/brewman/schemas/purchase_entries.py b/brewman/brewman/schemas/purchase_entries.py index e61c39fa..3729dc2b 100644 --- a/brewman/brewman/schemas/purchase_entries.py +++ b/brewman/brewman/schemas/purchase_entries.py @@ -1,7 +1,12 @@ from datetime import date, datetime from decimal import Decimal -from pydantic import validator +from pydantic import ( + ConfigDict, + FieldSerializationInfo, + field_serializer, + field_validator, +) from pydantic.main import BaseModel from . import to_camel @@ -18,35 +23,40 @@ class PurchaseEntriesItem(BaseModel): discount: Decimal amount: Decimal - @validator("date_", pre=True) + @field_validator("date_", mode="before") + @classmethod def parse_date(cls, value: date | str) -> date: if isinstance(value, date): return value return datetime.strptime(value, "%d-%b-%Y").date() - class Config: - anystr_strip_whitespace = True - alias_generator = to_camel + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) class PurchaseEntries(BaseModel): - start_date: date - finish_date: date + start_date: date | str + finish_date: date | str body: list[PurchaseEntriesItem] + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) - 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) + @field_validator("start_date", mode="before") + @classmethod def parse_start_date(cls, value: date | str) -> date: if isinstance(value, date): return value return datetime.strptime(value, "%d-%b-%Y").date() - @validator("finish_date", pre=True) + @field_serializer("start_date") + def serialize_start_date(self, value: date, info: FieldSerializationInfo) -> str: + return value.strftime("%d-%b-%Y") + + @field_validator("finish_date", mode="before") + @classmethod def parse_finish_date(cls, value: date | str) -> date: if isinstance(value, date): return value return datetime.strptime(value, "%d-%b-%Y").date() + + @field_serializer("finish_date") + def serialize_finish_date(self, value: date, info: FieldSerializationInfo) -> str: + return value.strftime("%d-%b-%Y") diff --git a/brewman/brewman/schemas/purchases.py b/brewman/brewman/schemas/purchases.py index f1dd0a7f..d2909bf4 100644 --- a/brewman/brewman/schemas/purchases.py +++ b/brewman/brewman/schemas/purchases.py @@ -1,7 +1,12 @@ from datetime import date, datetime from decimal import Decimal -from pydantic import validator +from pydantic import ( + ConfigDict, + FieldSerializationInfo, + field_serializer, + field_validator, +) from pydantic.main import BaseModel from . import to_camel @@ -13,31 +18,34 @@ class PurchasesItem(BaseModel): rate: Decimal amount: Decimal url: list[str] - - class Config: - anystr_strip_whitespace = True - alias_generator = to_camel + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) class Purchases(BaseModel): - start_date: date - finish_date: date + start_date: date | str + finish_date: date | str body: list[PurchasesItem] footer: PurchasesItem + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) - 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) + @field_validator("start_date", mode="before") + @classmethod def parse_start_date(cls, value: date | str) -> date: if isinstance(value, date): return value return datetime.strptime(value, "%d-%b-%Y").date() - @validator("finish_date", pre=True) + @field_serializer("start_date") + def serialize_start_date(self, value: date, info: FieldSerializationInfo) -> str: + return value.strftime("%d-%b-%Y") + + @field_validator("finish_date", mode="before") + @classmethod def parse_finish_date(cls, value: date | str) -> date: if isinstance(value, date): return value return datetime.strptime(value, "%d-%b-%Y").date() + + @field_serializer("finish_date") + def serialize_finish_date(self, value: date, info: FieldSerializationInfo) -> str: + return value.strftime("%d-%b-%Y") diff --git a/brewman/brewman/schemas/rate_contract.py b/brewman/brewman/schemas/rate_contract.py index dc27cbd9..e6ad0080 100644 --- a/brewman/brewman/schemas/rate_contract.py +++ b/brewman/brewman/schemas/rate_contract.py @@ -2,7 +2,13 @@ import uuid from datetime import date, datetime -from pydantic import BaseModel, validator +from pydantic import ( + BaseModel, + ConfigDict, + FieldSerializationInfo, + field_serializer, + field_validator, +) from . import to_camel from .account import AccountLink @@ -12,50 +18,56 @@ from .user_link import UserLink class RateContractBlank(BaseModel): date_: date - valid_from: date - valid_till: date + valid_from: date | None + valid_till: date | None narration: str items: list[RateContractItem] + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) - class Config: - anystr_strip_whitespace = True - alias_generator = to_camel - json_encoders = { - date: lambda v: v.strftime("%d-%b-%Y"), - datetime: lambda v: v.strftime("%d-%b-%Y %H:%M"), - } - - @validator("date_", pre=True) + @field_validator("date_", mode="before") + @classmethod def parse_date(cls, value: date | str) -> date: if isinstance(value, date): return value return datetime.strptime(value, "%d-%b-%Y").date() - @validator("valid_from", pre=True) - def parse_valid_from(cls, value: date | str) -> date: + @field_serializer("date_") + def serialize_date(self, value: date, info: FieldSerializationInfo) -> str: + return value.strftime("%d-%b-%Y") + + @field_validator("valid_from", mode="before") + @classmethod + def parse_valid_from(cls, value: date | str | None) -> date | None: + if value is None: + return value if isinstance(value, date): return value return datetime.strptime(value, "%d-%b-%Y").date() - @validator("valid_till", pre=True) - def parse_valid_till(cls, value: date | str) -> date: + @field_serializer("valid_from") + def serialize_valid_from(self, value: date | None, info: FieldSerializationInfo) -> str | None: + return None if value is None else value.strftime("%d-%b-%Y") + + @field_validator("valid_till", mode="before") + @classmethod + def parse_valid_till(cls, value: date | str | None) -> date | None: + if value is None: + return value if isinstance(value, date): return value return datetime.strptime(value, "%d-%b-%Y").date() + @field_serializer("valid_till") + def serialize_valid_till(self, value: date | None, info: FieldSerializationInfo) -> str | None: + return None if value is None else value.strftime("%d-%b-%Y") + class RateContractIn(RateContractBlank): vendor: AccountLink + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) - class Config: - anystr_strip_whitespace = True - alias_generator = to_camel - json_encoders = { - date: lambda v: v.strftime("%d-%b-%Y"), - datetime: lambda v: v.strftime("%d-%b-%Y %H:%M"), - } - - @validator("date_", pre=True) + @field_validator("date_", mode="before") + @classmethod def parse_date(cls, value: date | str) -> date: if isinstance(value, date): return value @@ -67,23 +79,26 @@ class RateContract(RateContractIn): creation_date: datetime last_edit_date: datetime user: UserLink + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) - class Config: - anystr_strip_whitespace = True - alias_generator = to_camel - json_encoders = { - date: lambda v: v.strftime("%d-%b-%Y"), - datetime: lambda v: v.strftime("%d-%b-%Y %H:%M"), - } - - @validator("creation_date", pre=True) - def parse_creation_date(cls, value: datetime | str) -> datetime: + @field_validator("creation_date", mode="before") + @classmethod + def parse_creation_date(cls, value: datetime | str) -> datetime | None: if isinstance(value, datetime): return value return datetime.strptime(value, "%d-%b-%Y %H:%M") - @validator("last_edit_date", pre=True) - def parse_last_edit_date(cls, value: datetime | str) -> datetime: + @field_serializer("creation_date") + def serialize_creation_date(self, value: datetime, info: FieldSerializationInfo) -> str: + return value.strftime("%d-%b-%Y %H:%M") + + @field_validator("last_edit_date", mode="before") + @classmethod + def parse_last_edit_date(cls, value: datetime | str) -> datetime | None: if isinstance(value, datetime): return value return datetime.strptime(value, "%d-%b-%Y %H:%M") + + @field_serializer("last_edit_date") + def serialize_last_edit_date(self, value: datetime, info: FieldSerializationInfo) -> str: + return value.strftime("%d-%b-%Y %H:%M") diff --git a/brewman/brewman/schemas/rate_contract_item.py b/brewman/brewman/schemas/rate_contract_item.py index b1670ff7..dfa628d7 100644 --- a/brewman/brewman/schemas/rate_contract_item.py +++ b/brewman/brewman/schemas/rate_contract_item.py @@ -4,13 +4,11 @@ from decimal import Decimal from brewman.schemas import to_camel from brewman.schemas.product import ProductLink -from pydantic import BaseModel, Field +from pydantic import BaseModel, ConfigDict, Field class RateContractItem(BaseModel): - id_: uuid.UUID | None + id_: uuid.UUID | None = None sku: ProductLink - price: Decimal = Field(ge=0, multiple_of=0.01) - - class Config: - alias_generator = to_camel + price: Decimal = Field(ge=0) + model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True) diff --git a/brewman/brewman/schemas/raw_material_cost.py b/brewman/brewman/schemas/raw_material_cost.py index 4baff878..888bc7ef 100644 --- a/brewman/brewman/schemas/raw_material_cost.py +++ b/brewman/brewman/schemas/raw_material_cost.py @@ -3,52 +3,60 @@ import uuid from datetime import date, datetime from decimal import Decimal -from pydantic import validator +from pydantic import ( + ConfigDict, + FieldSerializationInfo, + field_serializer, + field_validator, +) from pydantic.main import BaseModel from . import to_camel class RawMaterialCostItem(BaseModel): - name: str | None - issue: Decimal | None - sale: Decimal | None - rmc: Decimal | None - url: list[str] | None + name: str | None = None + issue: Decimal | None = None + sale: Decimal | None = None + rmc: Decimal | None = None + url: list[str] | None = None - group: str | None - quantity: Decimal | None - net: Decimal | None - gross: Decimal | None + group: str | None = None + quantity: Decimal | None = None + net: Decimal | None = None + gross: Decimal | None = None order: int - heading: bool | None - - class Config: - anystr_strip_whitespace = True - alias_generator = to_camel + heading: bool | None = None + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) class RawMaterialCost(BaseModel): - id_: uuid.UUID | None - start_date: date - finish_date: date + id_: uuid.UUID | None = None + start_date: date | str + finish_date: date | str body: list[RawMaterialCostItem] - footer: RawMaterialCostItem | None + footer: RawMaterialCostItem | None = None + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) - 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) + @field_validator("start_date", mode="before") + @classmethod def parse_start_date(cls, value: date | str) -> date: if isinstance(value, date): return value return datetime.strptime(value, "%d-%b-%Y").date() - @validator("finish_date", pre=True) + @field_serializer("start_date") + def serialize_start_date(self, value: date, info: FieldSerializationInfo) -> str: + return value.strftime("%d-%b-%Y") + + @field_validator("finish_date", mode="before") + @classmethod def parse_finish_date(cls, value: date | str) -> date: if isinstance(value, date): return value return datetime.strptime(value, "%d-%b-%Y").date() + + @field_serializer("finish_date") + def serialize_finish_date(self, value: date, info: FieldSerializationInfo) -> str: + return value.strftime("%d-%b-%Y") diff --git a/brewman/brewman/schemas/recipe.py b/brewman/brewman/schemas/recipe.py index 8e035f50..0ffbaad0 100644 --- a/brewman/brewman/schemas/recipe.py +++ b/brewman/brewman/schemas/recipe.py @@ -3,7 +3,13 @@ import uuid from datetime import date, datetime from decimal import Decimal -from pydantic import BaseModel, validator +from pydantic import ( + BaseModel, + ConfigDict, + FieldSerializationInfo, + field_serializer, + field_validator, +) from . import to_camel from .product import ProductLink @@ -21,32 +27,27 @@ class RecipeIn(BaseModel): notes: str items: list[RecipeItem] + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) - class Config: - anystr_strip_whitespace = True - alias_generator = to_camel - json_encoders = {date: lambda v: v.strftime("%d-%b-%Y")} - - @validator("date_", pre=True) + @field_validator("date_", mode="before") + @classmethod def parse_start_date(cls, value: date | str) -> date: if isinstance(value, date): return value return datetime.strptime(value, "%d-%b-%Y").date() + @field_serializer("date_") + def serialize_date(self, value: date, info: FieldSerializationInfo) -> str: + return value.strftime("%d-%b-%Y") + class Recipe(RecipeIn): id_: uuid.UUID - product_group_id: uuid.UUID | None - units: str | None - - class Config: - anystr_strip_whitespace = True - alias_generator = to_camel + product_group_id: uuid.UUID | None = None + units: str | None = None + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) class RecipeBlank(RecipeIn): - sku: ProductLink | None # type: ignore[assignment] - - class Config: - anystr_strip_whitespace = True - alias_generator = to_camel + sku: ProductLink | None = None # type: ignore[assignment] + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) diff --git a/brewman/brewman/schemas/recipe_item.py b/brewman/brewman/schemas/recipe_item.py index dad716e3..63047e77 100644 --- a/brewman/brewman/schemas/recipe_item.py +++ b/brewman/brewman/schemas/recipe_item.py @@ -2,15 +2,14 @@ import uuid from decimal import Decimal +from brewman.schemas import to_camel from brewman.schemas.product import ProductLink -from pydantic import BaseModel +from pydantic import BaseModel, ConfigDict class RecipeItem(BaseModel): - id_: uuid.UUID | None + id_: uuid.UUID | None = None product: ProductLink quantity: Decimal description: str - - class Config: - fields = {"id_": "id"} + model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True) diff --git a/brewman/brewman/schemas/recipe_template.py b/brewman/brewman/schemas/recipe_template.py index 404a505b..e01727aa 100644 --- a/brewman/brewman/schemas/recipe_template.py +++ b/brewman/brewman/schemas/recipe_template.py @@ -2,7 +2,12 @@ import uuid from datetime import date, datetime -from pydantic import validator +from pydantic import ( + ConfigDict, + FieldSerializationInfo, + field_serializer, + field_validator, +) from pydantic.main import BaseModel from . import to_camel @@ -10,28 +15,26 @@ from . import to_camel class RecipeTemplateIn(BaseModel): name: str - date_: date | None + date_: date | None = None text: str selected: bool - @validator("date_", pre=True) - def parse_valid_from(cls, value: date | str | None) -> date: + @field_validator("date_", mode="before") + @classmethod + def parse_valid_from(cls, value: date | str | None) -> date | None: if value is None: return None if isinstance(value, date): return 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") if v is not None else None} + @field_serializer("date_") + def serialize_date(self, value: date | None, info: FieldSerializationInfo) -> str | None: + return None if value is None else value.strftime("%d-%b-%Y") + + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) class RecipeTemplate(RecipeTemplateIn): id_: uuid.UUID - - class Config: - anystr_strip_whitespace = True - alias_generator = to_camel - json_encoders = {date: lambda v: v.strftime("%d-%b-%Y") if v is not None else None} + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) diff --git a/brewman/brewman/schemas/reconcile.py b/brewman/brewman/schemas/reconcile.py index 5db7e65e..5a63dab3 100644 --- a/brewman/brewman/schemas/reconcile.py +++ b/brewman/brewman/schemas/reconcile.py @@ -3,7 +3,12 @@ import uuid from datetime import date, datetime from decimal import Decimal -from pydantic import validator +from pydantic import ( + ConfigDict, + FieldSerializationInfo, + field_serializer, + field_validator, +) from pydantic.main import BaseModel from . import to_camel @@ -11,7 +16,7 @@ from .account import AccountLink class ReconcileItem(BaseModel): - id_: uuid.UUID | None + id_: uuid.UUID | None = None date_: date name: str url: list[str] @@ -21,15 +26,22 @@ class ReconcileItem(BaseModel): credit: Decimal posted: bool is_reconciled: bool - reconcile_date: date | None + reconcile_date: date | None = None + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) - @validator("date_", pre=True) + @field_validator("date_", mode="before") + @classmethod def parse_date(cls, value: date | str) -> date: if isinstance(value, date): return value return datetime.strptime(value, "%d-%b-%Y").date() - @validator("reconcile_date", pre=True) + @field_serializer("date_") + def serialize_date(self, value: date, info: FieldSerializationInfo) -> str: + return value.strftime("%d-%b-%Y") + + @field_validator("reconcile_date", mode="before") + @classmethod def parse_reconcile_date(cls, value: None | date | str) -> date | None: if value is None: return None @@ -37,31 +49,36 @@ class ReconcileItem(BaseModel): return 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")} + @field_serializer("reconcile_date") + def serialize_reconcile_date(self, value: date | None, info: FieldSerializationInfo) -> str | None: + return None if value is None else value.strftime("%d-%b-%Y") class Reconcile(BaseModel): - start_date: date - finish_date: date - account: AccountLink | None + start_date: date | str + finish_date: date | str + account: AccountLink | None = None body: list[ReconcileItem] + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) - 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) + @field_validator("start_date", mode="before") + @classmethod def parse_start_date(cls, value: date | str) -> date: if isinstance(value, date): return value return datetime.strptime(value, "%d-%b-%Y").date() - @validator("finish_date", pre=True) + @field_serializer("start_date") + def serialize_start_date(self, value: date, info: FieldSerializationInfo) -> str: + return value.strftime("%d-%b-%Y") + + @field_validator("finish_date", mode="before") + @classmethod def parse_finish_date(cls, value: date | str) -> date: if isinstance(value, date): return value return datetime.strptime(value, "%d-%b-%Y").date() + + @field_serializer("finish_date") + def serialize_finish_date(self, value: date, info: FieldSerializationInfo) -> str: + return value.strftime("%d-%b-%Y") diff --git a/brewman/brewman/schemas/role.py b/brewman/brewman/schemas/role.py index 73ecf6de..4dfb44cc 100644 --- a/brewman/brewman/schemas/role.py +++ b/brewman/brewman/schemas/role.py @@ -1,6 +1,7 @@ import uuid -from pydantic import Field +from brewman.schemas import to_camel +from pydantic import ConfigDict, Field from pydantic.main import BaseModel from .permission import PermissionItem @@ -9,41 +10,28 @@ from .permission import PermissionItem class RoleIn(BaseModel): name: str = Field(..., min_length=1) permissions: list[PermissionItem] - - class Config: - anystr_strip_whitespace = True + model_config = ConfigDict(str_strip_whitespace=True, populate_by_name=True) class Role(RoleIn): id_: uuid.UUID - - class Config: - fields = {"id_": "id"} - anystr_strip_whitespace = True + model_config = ConfigDict(alias_generator=to_camel, str_strip_whitespace=True, populate_by_name=True) class RoleList(BaseModel): id_: uuid.UUID name: str permissions: list[str] - - class Config: - fields = {"id_": "id"} - anystr_strip_whitespace = True + model_config = ConfigDict(alias_generator=to_camel, str_strip_whitespace=True, populate_by_name=True) class RoleItem(BaseModel): id_: uuid.UUID name: str enabled: bool - - class Config: - fields = {"id_": "id"} + model_config = ConfigDict(alias_generator=to_camel, str_strip_whitespace=True, populate_by_name=True) class RoleBlank(RoleIn): name: str - - class Config: - fields = {"id_": "id"} - anystr_strip_whitespace = True + model_config = ConfigDict(alias_generator=to_camel, str_strip_whitespace=True, populate_by_name=True) diff --git a/brewman/brewman/schemas/settings.py b/brewman/brewman/schemas/settings.py index 16b5aaab..a881fe4d 100644 --- a/brewman/brewman/schemas/settings.py +++ b/brewman/brewman/schemas/settings.py @@ -2,22 +2,24 @@ import uuid from datetime import date, datetime -from pydantic import BaseModel, validator +from pydantic import ( + BaseModel, + ConfigDict, + FieldSerializationInfo, + field_serializer, + field_validator, +) from . import to_camel class LockDate(BaseModel): - days: int | None - date_: date | None + days: int | None = None + date_: date | None = None + model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True) - class Config: - fields = {"date_": "date"} - json_encoders = { - date: lambda v: v.strftime("%d-%b-%Y"), - } - - @validator("date_", pre=True) + @field_validator("date_", mode="before") + @classmethod def parse_date(cls, value: None | date | str) -> date | None: if value is None: return None @@ -25,28 +27,28 @@ class LockDate(BaseModel): return value return datetime.strptime(value, "%d-%b-%Y").date() + @field_serializer("date_") + def serialize_date(self, value: date | None, info: FieldSerializationInfo) -> str | None: + return None if value is None else value.strftime("%d-%b-%Y") + class VoucherTypesSelected(BaseModel): id_: int name: str - - class Config: - fields = {"id_": "id"} + model_config = ConfigDict(alias_generator=to_camel, str_strip_whitespace=True, populate_by_name=True) class AccountTypesSelected(BaseModel): id_: int name: str - - class Config: - alias_generator = to_camel + model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True) class LockInformation(BaseModel): - id_: uuid.UUID | None + id_: uuid.UUID | None = None - valid_from: date | None - valid_till: date | None + valid_from: date | None = None + valid_till: date | None = None voucher_types: list[VoucherTypesSelected] account_types: list[AccountTypesSelected] @@ -55,29 +57,34 @@ class LockInformation(BaseModel): finish: LockDate index: int + model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True) - class Config: - alias_generator = to_camel - json_encoders = { - date: lambda v: v.strftime("%d-%b-%Y"), - } - - @validator("valid_from", pre=True) - def parse_valid_from(cls, value: None | date | str) -> date | None: + @field_validator("valid_from", mode="before") + @classmethod + def parse_valid_from(cls, value: date | str | None) -> date | None: if value is None: return None if isinstance(value, date): return value return datetime.strptime(value, "%d-%b-%Y").date() - @validator("valid_till", pre=True) - def parse_valid_till(cls, value: None | date | str) -> date | None: + @field_serializer("valid_from") + def serialize_valid_from(self, value: date | None, info: FieldSerializationInfo) -> str | None: + return None if value is None else value.strftime("%d-%b-%Y") + + @field_validator("valid_till", mode="before") + @classmethod + def parse_valid_till(cls, value: date | str | None) -> date | None: if value is None: return None if isinstance(value, date): return value return datetime.strptime(value, "%d-%b-%Y").date() + @field_serializer("valid_till") + def serialize_valid_till(self, value: date | None, info: FieldSerializationInfo) -> str | None: + return None if value is None else value.strftime("%d-%b-%Y") + class Maintenance(BaseModel): enabled: bool @@ -86,6 +93,4 @@ class Maintenance(BaseModel): class AttendanceCount(BaseModel): attendance_count: int - - class Config: - alias_generator = to_camel + model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True) diff --git a/brewman/brewman/schemas/stock_keeping_unit.py b/brewman/brewman/schemas/stock_keeping_unit.py index cbf43353..85ff8975 100644 --- a/brewman/brewman/schemas/stock_keeping_unit.py +++ b/brewman/brewman/schemas/stock_keeping_unit.py @@ -2,19 +2,16 @@ import uuid from decimal import Decimal -from pydantic import BaseModel, Field +from pydantic import BaseModel, ConfigDict, Field from . import to_camel class StockKeepingUnit(BaseModel): - id_: uuid.UUID | None + 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, multiple_of=0.01, default=0) - sale_price: Decimal = Field(ge=0, multiple_of=0.01, default=0) - - class Config: - anystr_strip_whitespace = True - alias_generator = to_camel + cost_price: Decimal = Field(ge=0, default=0) + sale_price: Decimal = Field(ge=0, default=0) + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) diff --git a/brewman/brewman/schemas/stock_movement.py b/brewman/brewman/schemas/stock_movement.py index bfef314f..bc0c6aac 100644 --- a/brewman/brewman/schemas/stock_movement.py +++ b/brewman/brewman/schemas/stock_movement.py @@ -3,7 +3,12 @@ import uuid from datetime import date, datetime from decimal import Decimal -from pydantic import validator +from pydantic import ( + ConfigDict, + FieldSerializationInfo, + field_serializer, + field_validator, +) from pydantic.main import BaseModel from . import to_camel @@ -18,30 +23,33 @@ class StockMovementItem(BaseModel): issue: Decimal closing: Decimal url: list[str] - - class Config: - anystr_strip_whitespace = True - alias_generator = to_camel + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) class StockMovement(BaseModel): - start_date: date - finish_date: date + start_date: date | str + finish_date: date | str body: list[StockMovementItem] + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) - 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) + @field_validator("start_date", mode="before") + @classmethod def parse_start_date(cls, value: date | str) -> date: if isinstance(value, date): return value return datetime.strptime(value, "%d-%b-%Y").date() - @validator("finish_date", pre=True) + @field_serializer("start_date") + def serialize_start_date(self, value: date, info: FieldSerializationInfo) -> str: + return value.strftime("%d-%b-%Y") + + @field_validator("finish_date", mode="before") + @classmethod def parse_finish_date(cls, value: date | str) -> date: if isinstance(value, date): return value return datetime.strptime(value, "%d-%b-%Y").date() + + @field_serializer("finish_date") + def serialize_finish_date(self, value: date, info: FieldSerializationInfo) -> str: + return value.strftime("%d-%b-%Y") diff --git a/brewman/brewman/schemas/trial_balance.py b/brewman/brewman/schemas/trial_balance.py index e25da93a..d8e26981 100644 --- a/brewman/brewman/schemas/trial_balance.py +++ b/brewman/brewman/schemas/trial_balance.py @@ -1,34 +1,37 @@ from datetime import date, datetime from decimal import Decimal -from pydantic import validator +from pydantic import ( + ConfigDict, + FieldSerializationInfo, + field_serializer, + field_validator, +) from pydantic.main import BaseModel from . import to_camel class TrialBalanceItem(BaseModel): - type_: str | None - name: str | None - debit: Decimal | None - credit: Decimal | None - - class Config: - anystr_strip_whitespace = True - alias_generator = to_camel + type_: str | None = None + name: str | None = None + debit: Decimal | None = None + credit: Decimal | None = None + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) class TrialBalance(BaseModel): - date_: date + date_: date | str body: list[TrialBalanceItem] + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) - class Config: - anystr_strip_whitespace = True - alias_generator = to_camel - json_encoders = {date: lambda v: v.strftime("%d-%b-%Y")} - - @validator("date_", pre=True) + @field_validator("date_", mode="before") + @classmethod def parse_date(cls, value: date | str) -> date: if isinstance(value, date): return value return datetime.strptime(value, "%d-%b-%Y").date() + + @field_serializer("date_") + def serialize_date(self, value: date, info: FieldSerializationInfo) -> str: + return value.strftime("%d-%b-%Y") diff --git a/brewman/brewman/schemas/user.py b/brewman/brewman/schemas/user.py index 3955c89a..94888ef0 100644 --- a/brewman/brewman/schemas/user.py +++ b/brewman/brewman/schemas/user.py @@ -2,7 +2,13 @@ import uuid from datetime import datetime -from pydantic import Field +from pydantic import ( + ConfigDict, + Field, + FieldSerializationInfo, + field_serializer, + field_validator, +) from pydantic.main import BaseModel from . import to_camel @@ -14,31 +20,35 @@ class UserIn(BaseModel): password: str locked_out: bool roles: list[RoleItem] - - class Config: - anystr_strip_whitespace = True - alias_generator = to_camel + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) class User(UserIn): id_: uuid.UUID - - class Config: - anystr_strip_whitespace = True - alias_generator = to_camel + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) class UserList(BaseModel): id_: uuid.UUID name: str + locked_out: bool roles: list[str] last_device: str - last_date: datetime | None + last_date: datetime | None = None + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) - class Config: - anystr_strip_whitespace = True - alias_generator = to_camel - json_encoders = {datetime: lambda v: v.strftime("%d-%b-%Y %H:%M")} + @field_validator("last_date", mode="before") + @classmethod + def parse_last_edit_date(cls, value: datetime | str | None) -> datetime | None: + if value is None: + return value + if isinstance(value, datetime): + return value + return datetime.strptime(value, "%d-%b-%Y %H:%M") + + @field_serializer("last_date") + def serialize_last_edit_date(self, value: datetime, info: FieldSerializationInfo) -> str: + return None if value is None else value.strftime("%d-%b-%Y %H:%M") class UserToken(BaseModel): @@ -51,7 +61,4 @@ class UserToken(BaseModel): class UserBlank(UserIn): name: str - - class Config: - anystr_strip_whitespace = True - alias_generator = to_camel + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) diff --git a/brewman/brewman/schemas/user_link.py b/brewman/brewman/schemas/user_link.py index 86ab3dd1..85063ab3 100644 --- a/brewman/brewman/schemas/user_link.py +++ b/brewman/brewman/schemas/user_link.py @@ -1,12 +1,10 @@ import uuid from brewman.schemas import to_camel -from pydantic import BaseModel +from pydantic import BaseModel, ConfigDict class UserLink(BaseModel): id_: uuid.UUID name: str - - class Config: - alias_generator = to_camel + model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True) diff --git a/brewman/brewman/schemas/voucher.py b/brewman/brewman/schemas/voucher.py index 628d3ca2..14d41754 100644 --- a/brewman/brewman/schemas/voucher.py +++ b/brewman/brewman/schemas/voucher.py @@ -5,7 +5,13 @@ from datetime import date, datetime from decimal import Decimal from fastapi import Form -from pydantic import BaseModel, validator +from pydantic import ( + BaseModel, + ConfigDict, + FieldSerializationInfo, + field_serializer, + field_validator, +) from . import to_camel from .account import AccountLink @@ -28,6 +34,17 @@ class VoucherIn(BaseModel): type_: str files: list[ImageUpload] + @field_validator("date_", mode="before") + @classmethod + def parse_date(cls, value: date | str) -> date: + if isinstance(value, date): + return value + return datetime.strptime(value, "%d-%b-%Y").date() + + @field_serializer("date_") + def serialize_date(self, value: date, info: FieldSerializationInfo) -> str: + return value.strftime("%d-%b-%Y") + @classmethod def load_form(cls, data: str = Form(...)) -> BaseModel: json_data = json.loads(data) @@ -35,39 +52,40 @@ class VoucherIn(BaseModel): class Voucher(VoucherIn): - id_: uuid.UUID | None - is_reconciled: bool | None - reconcile_date: date | None - creation_date: datetime | None - last_edit_date: datetime | None - user: UserLink | None - posted: bool | None - poster: str | None + id_: uuid.UUID | None = None + is_reconciled: bool | None = None + reconcile_date: date | None = None + creation_date: datetime | None = None + last_edit_date: datetime | None = None + user: UserLink | None = None + posted: bool | None = None + poster: str | None = None journals: list[Journal] inventories: list[Inventory] - vendor: AccountLink | None - source: CostCentreLink | None - destination: CostCentreLink | None + vendor: AccountLink | None = None + source: CostCentreLink | None = None + destination: CostCentreLink | None = None incentives: list[Incentive] - incentive: Decimal | None + incentive: Decimal | None = None employee_benefits: list[EmployeeBenefit] files: list[ImageUpload] + model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True) - class Config: - anystr_strip_whitespace = True - alias_generator = to_camel - json_encoders = { - date: lambda v: v.strftime("%d-%b-%Y"), - datetime: lambda v: v.strftime("%d-%b-%Y %H:%M"), - } - - @validator("date_", pre=True) - def parse_date(cls, value: date | str) -> date: + @field_validator("reconcile_date", mode="before") + @classmethod + def parse_reconcile_date(cls, value: None | date | str) -> date | None: + if value is None or value == "": + return None if isinstance(value, date): return value return datetime.strptime(value, "%d-%b-%Y").date() - @validator("creation_date", pre=True) + @field_serializer("reconcile_date") + def serialize_reconcile_date(self, value: date | None, info: FieldSerializationInfo) -> str | None: + return None if value is None else value.strftime("%d-%b-%Y") + + @field_validator("creation_date", mode="before") + @classmethod def parse_creation_date(cls, value: None | datetime | str) -> datetime | None: if value is None or value == "": return None @@ -75,7 +93,12 @@ class Voucher(VoucherIn): return value return datetime.strptime(value, "%d-%b-%Y %H:%M") - @validator("last_edit_date", pre=True) + @field_serializer("creation_date") + def serialize_creation_date(self, value: datetime, info: FieldSerializationInfo) -> str | None: + return value.strftime("%d-%b-%Y %H:%M") + + @field_validator("last_edit_date", mode="before") + @classmethod def parse_last_edit_date(cls, value: None | datetime | str) -> datetime | None: if value is None or value == "": return None @@ -83,10 +106,6 @@ class Voucher(VoucherIn): return value return datetime.strptime(value, "%d-%b-%Y %H:%M") - @validator("reconcile_date", pre=True) - def parse_reconcile_date(cls, value: None | date | str) -> date | None: - if value is None or value == "": - return None - if isinstance(value, date): - return value - return datetime.strptime(value, "%d-%b-%Y").date() + @field_serializer("last_edit_date") + def serialize_last_edit_date(self, value: datetime, info: FieldSerializationInfo) -> str: + return value.strftime("%d-%b-%Y %H:%M") diff --git a/brewman/pyproject.toml b/brewman/pyproject.toml index 751adf13..42d33544 100644 --- a/brewman/pyproject.toml +++ b/brewman/pyproject.toml @@ -7,31 +7,41 @@ authors = ["tanshu "] [tool.poetry.dependencies] python = "^3.11" uvicorn = {extras = ["standard"], version = "^0.21.1"} -fastapi = "^0.95.0" +fastapi = {extras = ["all"], version = "^0.100.0"} python-jose = {extras = ["cryptography"], version = "^3.3.0"} passlib = {extras = ["bcrypt"], version = "^1.7.4"} psycopg2-binary = "^2.9.5" SQLAlchemy = "^2.0.7" python-multipart = "^0.0.6" -PyJWT = "^2.6.0" -alembic = "^1.10.2" +PyJWT = "^2.8.0" +alembic = "^1.11.1" itsdangerous = "^2.1.2" python-dotenv = "^1.0.0" -pydantic = {extras = ["dotenv"], version = "^1.10.7"} -starlette = "^0.26.1" +pydantic = {extras = ["dotenv"], version = "^2.0.3"} +starlette = "^0.27.0" +pandas = "^2.0.0" +arq = "^0.25.0" openpyxl = "^3.1.2" -[tool.poetry.dev-dependencies] +[tool.poetry.group.dev.dependencies] flake8 = "^6.0.0" -black = "^23.1.0" +black = "^23.7.0" isort = {extras = ["toml"], version = "^5.12.0"} -pre-commit = "^3.2.0" -mypy = "^1.1.1" +pre-commit = "^3.3.3" +mypy = "^1.4.1" +types-python-jose = "^3.3.4.8" +ruff = "^0.0.280" +bandit = "^1.7.5" +safety = "^2.3.5" [build-system] requires = ["poetry-core>=1.0.0"] build-backend = "poetry.core.masonry.api" +[tool.ruff] +line-length = 120 +# Assume Python 3.11. +target-version = "py311" [tool.mypy] # --strict diff --git a/lint.sh b/lint.sh index 1a7513dd..aae756d0 100755 --- a/lint.sh +++ b/lint.sh @@ -11,3 +11,8 @@ cd "$parent_path/brewman" || exit isort brewman black brewman flake8 brewman + +# ruff check . # Lint all files in the current directory (and any subdirectories) +# bandit --recursive brewman +# bandit --recursive . +# safety check \ No newline at end of file