Fix: Account delete did not work due to not using unique

Chore: Sqlalchemy using the right way to write expressions.
This commit is contained in:
Amritanshu Agrawal 2023-08-04 16:02:30 +05:30
parent 3109b4bec0
commit 91cf1fa04f
7 changed files with 34 additions and 10 deletions

View File

@ -61,10 +61,10 @@ def upgrade():
op.add_column("recipes", sa.Column("instructions", sa.Text(), nullable=False, server_default=""))
op.add_column("recipes", sa.Column("garnishing", sa.Text(), nullable=False, server_default=""))
op.add_column("recipes", sa.Column("plating", sa.Text(), nullable=False, server_default=""))
op.drop_constraint(op.f("uq_recipes_sku_id"), "recipes", type_="unique")
op.alter_column("recipes", "notes", existing_type=sa.VARCHAR(length=255),type=sa.Text(), nullable=False)
op.create_unique_constraint(op.f('uq_recipes_sku_id'), 'recipes', ['sku_id', 'date'])
op.create_index(op.f("ix_recipes_date"), "recipes", ["date"], unique=False)
op.drop_constraint(op.f("uq_recipes_sku_id"), "recipes", type_="unique")
op.drop_constraint("fk_recipes_period_id_periods", "recipes", type_="foreignkey")
op.drop_column("recipes", "period_id")
op.drop_column('recipes', 'sale_price')

View File

@ -70,4 +70,6 @@ class Inventory:
@amount.inplace.expression
@classmethod
def _amount_expression(cls) -> ColumnElement[Decimal]:
return type_coerce(cls.quantity * cls.rate * (1 + cls.tax) * (1 - cls.discount), Decimal)
return type_coerce(
cls.quantity * cls.rate * (1 + cls.tax) * (1 - cls.discount), Numeric(precision=15, scale=2)
).label("amount")

View File

@ -51,7 +51,7 @@ class Journal:
@signed_amount.inplace.expression
@classmethod
def _signed_amount_expression(cls) -> ColumnElement[Decimal]:
return type_coerce(cls.debit * cls.amount, Decimal)
return type_coerce(cls.debit * cls.amount, Numeric(precision=15, scale=2)).label("signed_amount")
def __init__(
self,

View File

@ -226,6 +226,7 @@ def delete_with_data(account: Account, db: Session) -> None:
.options(joinedload(Voucher.journals, innerjoin=True).joinedload(Journal.account, innerjoin=True))
.where(Voucher.journals.any(Journal.account_id == account.id))
)
.unique()
.scalars()
.all()
)

View File

@ -72,7 +72,7 @@ def build_report(
running_total_q, running_total_a, opening = opening_balance(product_id, start_date, db)
body = opening
query = db.execute(
query: list[tuple[Voucher, Inventory, Journal, StockKeepingUnit]] = db.execute(
select(Voucher, Inventory, Journal, StockKeepingUnit)
.join(Voucher.journals)
.join(Voucher.inventories)
@ -112,14 +112,14 @@ def build_report(
body.append(
schemas.ProductLedgerItem(
id_=voucher.id,
date_=voucher.date,
date_=voucher.date_,
name=name,
url=[
"/",
voucher.voucher_type.name.replace("_", "-").lower(),
str(voucher.id)
if voucher.voucher_type != VoucherType.CLOSING_STOCK
else voucher.date.strftime("%d-%b-%Y"),
else voucher.date_.strftime("%d-%b-%Y"),
],
type_=voucher.voucher_type.name.replace("_", " ").title(),
narration=voucher.narration,

View File

@ -27,6 +27,27 @@ class ClosingStockItem(BaseModel):
cost_centre: CostCentreLink | None = None
model_config = ConfigDict(str_strip_whitespace=True, alias_generator=to_camel, populate_by_name=True)
@field_validator("quantity", mode="before")
@classmethod
def parse_quantity(cls, value: Decimal | float) -> Decimal:
if isinstance(value, float):
return Decimal(round(value, 2))
return round(value, 2)
@field_validator("amount", mode="before")
@classmethod
def parse_amount(cls, value: Decimal | float) -> Decimal:
if isinstance(value, float):
return Decimal(round(value, 2))
return round(value, 2)
@field_validator("physical", mode="before")
@classmethod
def parse_physical(cls, value: Decimal | float) -> Decimal:
if isinstance(value, float):
return Decimal(round(value, 2))
return round(value, 2)
class ClosingStock(BaseModel):
date_: date

View File

@ -94,8 +94,8 @@ class Voucher(VoucherIn):
return datetime.strptime(value, "%d-%b-%Y %H:%M")
@field_serializer("creation_date")
def serialize_creation_date(self, value: datetime, info: FieldSerializationInfo) -> str | None:
return value.strftime("%d-%b-%Y %H:%M")
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
@ -107,5 +107,5 @@ class Voucher(VoucherIn):
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")
def serialize_last_edit_date(self, value: datetime, info: FieldSerializationInfo) -> str | None:
return None if value is None else value.strftime("%d-%b-%Y %H:%M")