Fix: Recipe was crashing the whole thing
This commit is contained in:
parent
5e66db381b
commit
4df8c916ab
55
brewman/alembic/versions/0e6c5953a63f_recipe.py
Normal file
55
brewman/alembic/versions/0e6c5953a63f_recipe.py
Normal 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
|
@ -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_
|
||||
|
@ -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_
|
||||
|
@ -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")}
|
||||
|
@ -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"}
|
||||
|
Loading…
Reference in New Issue
Block a user