Fix: Recipe was crashing the whole thing

This commit is contained in:
Amritanshu Agrawal 2021-11-02 16:39:15 +05:30
parent 5e66db381b
commit 4df8c916ab
5 changed files with 92 additions and 47 deletions

View File

@ -0,0 +1,55 @@
"""recipe
Revision ID: 0e6c5953a63f
Revises: c39eb451a683
Create Date: 2021-11-01 12:11:16.813756
"""
import sqlalchemy as sa
from alembic import op
from sqlalchemy import column, func, table, text
from sqlalchemy.dialects import postgresql
# revision identifiers, used by Alembic.
revision = "0e6c5953a63f"
down_revision = "c39eb451a683"
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.alter_column("recipes", "product_id", new_column_name="sku_id")
op.alter_column("recipes", "valid_to", new_column_name="valid_till", existing_type=sa.DATE(), nullable=True)
op.alter_column("recipes", "valid_from", existing_type=sa.DATE(), nullable=True)
op.drop_constraint("recipes_product_id_fkey", "recipes", type_="foreignkey")
op.create_foreign_key(
op.f("fk_recipes_sku_id_stock_keeping_units"), "recipes", "stock_keeping_units", ["sku_id"], ["id"]
)
op.drop_column("recipes", "effective_to")
op.drop_column("recipes", "effective_from")
recipe = table(
"recipes",
column("sku_id", postgresql.UUID(as_uuid=True)),
column("valid_from", sa.Date()),
column("valid_till", sa.Date()),
)
op.create_exclude_constraint(
"uq_recipes_sku_id",
"recipes",
(recipe.c.sku_id, "="),
(func.daterange(recipe.c.valid_from, recipe.c.valid_till, text("'[]'")), "&&"),
)
# ### end Alembic commands ###
# delete from recipe_items where recipe_id in (select id from recipes where product_id in (select product_id from recipes group by product_id having count(*) > 1) and effective_to is not null);
# delete from recipes where id in (select id from recipes where product_id in (select product_id from recipes group by product_id having count(*) > 1) and effective_to is not null);
def downgrade():
pass

View File

@ -1,7 +1,5 @@
import uuid
from datetime import date
from sqlalchemy import Column, Date, ForeignKey, Numeric, Unicode
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import relationship
@ -13,7 +11,7 @@ class Recipe(Base):
__tablename__ = "recipes"
id = Column("id", UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
product_id = Column("product_id", UUID(as_uuid=True), ForeignKey("products.id"), nullable=False)
sku_id = Column("sku_id", UUID(as_uuid=True), ForeignKey("stock_keeping_units.id"), nullable=False)
quantity = Column("quantity", Numeric(precision=15, scale=2), nullable=False)
cost_price = Column("cost_price", Numeric(precision=15, scale=2), nullable=False)
@ -23,31 +21,25 @@ class Recipe(Base):
valid_from = Column("valid_from", Date, nullable=True)
valid_till = Column("valid_till", Date, nullable=True)
effective_from = Column("effective_from", Date, nullable=False)
effective_to = Column("effective_to", Date)
recipe_items = relationship("RecipeItem", backref="recipe")
product = relationship("Product", back_populates="recipes")
items = relationship("RecipeItem", back_populates="recipe")
sku = relationship("StockKeepingUnit", back_populates="recipes")
def __init__(
self,
product_id=None,
sku_id=None,
quantity=None,
cost_price=None,
sale_price=None,
valid_from=None,
valid_till=None,
notes=None,
effective_from=None,
id_=None,
):
self.product_id = product_id
self.sku_id = sku_id
self.quantity = quantity
self.cost_price = cost_price
self.sale_price = sale_price
self.valid_from = valid_from
self.valid_till = valid_till
self.notes = "" if notes is None else notes
self.effective_from = date.today() if effective_from is None else effective_from
self.effective_to = None
self.id = id_

View File

@ -17,11 +17,17 @@ class RecipeItem(Base):
quantity = Column("quantity", Integer, nullable=False)
price = Column("price", Integer, nullable=False)
recipe = relationship("Recipe", back_populates="items")
product = relationship("Product")
def __init__(self, recipe_id=None, product_id=None, quantity=None, price=None, id_=None):
def __init__(self, recipe_id=None, product_id=None, quantity=None, price=None, recipe=None, id_=None):
self.recipe_id = recipe_id
self.product_id = product_id
self.quantity = quantity
self.price = price
if recipe is None:
self.recipe_id = recipe_id
else:
self.recipe_id = recipe.id
self.recipe = recipe
self.id = id_

View File

@ -1,36 +1,14 @@
import uuid
from datetime import date
from datetime import date, datetime
from decimal import Decimal
from typing import List, Optional
from pydantic import BaseModel, Field
from pydantic import BaseModel, validator
from . import to_camel
class ProductLink(BaseModel):
id_: uuid.UUID = Field(...)
name: Optional[str]
units: Optional[str]
sale_price: Optional[Decimal]
is_sold: Optional[bool]
fraction_units: Optional[str]
fraction: Optional[Decimal]
product_yield: Optional[Decimal]
class Config:
alias_generator = to_camel
class RecipeItem(BaseModel):
id_: Optional[uuid.UUID]
product: ProductLink
quantity: int
price: int
class Config:
fields = {"id_": "id"}
from .product import ProductLink
from .recipe_item import RecipeItem
class RecipeIn(BaseModel):
@ -44,9 +22,6 @@ class RecipeIn(BaseModel):
valid_from: Optional[date]
valid_till: Optional[date]
effective_from: Optional[date]
effective_till: Optional[date]
items: List[RecipeItem]
class Config:
@ -54,6 +29,22 @@ class RecipeIn(BaseModel):
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)
def parse_valid_from(cls, value):
if isinstance(value, date):
return value
if value is None:
return value
return datetime.strptime(value, "%d-%b-%Y").date()
@validator("valid_till", pre=True)
def parse_valid_till(cls, value):
if isinstance(value, date):
return value
if value is None:
return value
return datetime.strptime(value, "%d-%b-%Y").date()
class Recipe(RecipeIn):
id_: uuid.UUID
@ -65,8 +56,9 @@ class Recipe(RecipeIn):
class RecipeBlank(RecipeIn):
product: Optional[ProductLink]
product: Optional[ProductLink] # type: ignore[assignment]
class Config:
anystr_strip_whitespace = True
alias_generator = to_camel
json_encoders = {date: lambda v: v.strftime("%d-%b-%Y")}

View File

@ -1,9 +1,9 @@
import uuid
from typing import Optional
from pydantic import BaseModel
from brewman.schemas.product import ProductLink
from pydantic import BaseModel
class RecipeItem(BaseModel):
@ -13,4 +13,4 @@ class RecipeItem(BaseModel):
price: int
class Config:
fields = {"id_": "id"}
fields = {"id_": "id"}