Product list / detail / router fully working.
Need to test the sale / reports
This commit is contained in:
parent
4aaa3fc72b
commit
a92726f5e6
|
@ -21,10 +21,10 @@ branch_labels = None
|
|||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
def update_sale_categories():
|
||||
product = table(
|
||||
"products",
|
||||
column("product_id", postgresql.UUID(as_uuid=True)),
|
||||
column("sale_category_id", postgresql.UUID(as_uuid=True)),
|
||||
column("sale_category_name", sa.Unicode(length=255)),
|
||||
)
|
||||
|
@ -40,7 +40,12 @@ def upgrade():
|
|||
}
|
||||
)
|
||||
)
|
||||
with op.batch_alter_table("products") as batch_op:
|
||||
batch_op.alter_column("sale_category_id", nullable=False)
|
||||
batch_op.drop_column("sale_category_name")
|
||||
|
||||
|
||||
def update_section_printers():
|
||||
section_printer = table(
|
||||
"section_printers",
|
||||
column("section_id", postgresql.UUID(as_uuid=True)),
|
||||
|
@ -66,75 +71,8 @@ def upgrade():
|
|||
batch_op.alter_column("printer_id", nullable=False)
|
||||
batch_op.drop_column("printer_name")
|
||||
|
||||
with op.batch_alter_table("products") as batch_op:
|
||||
batch_op.alter_column("sale_category_id", nullable=False)
|
||||
batch_op.drop_column("sale_category_name")
|
||||
|
||||
# Migration to temporal products
|
||||
op.rename_table("products", "product_histories")
|
||||
with op.batch_alter_table("product_histories") as batch_op:
|
||||
batch_op.add_column(sa.Column("valid_from", sa.Date(), nullable=True))
|
||||
batch_op.add_column(sa.Column("valid_till", sa.Date(), nullable=True))
|
||||
batch_op.drop_column("is_active")
|
||||
|
||||
op.create_table(
|
||||
"product_versions",
|
||||
sa.Column("id", postgresql.UUID(as_uuid=True), server_default=sa.text("gen_random_uuid()"), nullable=False),
|
||||
sa.Column("version_id", postgresql.UUID(as_uuid=True), nullable=False),
|
||||
sa.ForeignKeyConstraint(
|
||||
["version_id"], ["product_histories.id"], name=op.f("fk_product_versions_version_id_product_histories")
|
||||
),
|
||||
sa.PrimaryKeyConstraint("id", name=op.f("pk_product_versions")),
|
||||
sa.UniqueConstraint("id", "version_id", name=op.f("uq_product_versions_id")),
|
||||
)
|
||||
op.drop_constraint("fk_inventories_product_id_products", "inventories", type_="foreignkey")
|
||||
op.create_foreign_key(
|
||||
op.f("fk_inventories_product_id_product_versions"), "inventories", "product_versions", ["product_id"], ["id"]
|
||||
)
|
||||
|
||||
pv = table(
|
||||
"product_versions",
|
||||
column("id", postgresql.UUID(as_uuid=True)),
|
||||
column("version_id", postgresql.UUID(as_uuid=True)),
|
||||
)
|
||||
|
||||
prod = table(
|
||||
"product_histories",
|
||||
column("id", postgresql.UUID(as_uuid=True)),
|
||||
column("name", sa.Unicode(length=255)),
|
||||
column("units", sa.Unicode(length=255)),
|
||||
column("valid_from", sa.Date()),
|
||||
column("valid_till", sa.Date()),
|
||||
)
|
||||
op.execute(pv.insert().from_select([pv.c.id, pv.c.version_id], select([prod.c.id, prod.c.id.label("vid")])))
|
||||
|
||||
op.alter_column("modifier_categories_products", "modifier_categories_id", new_column_name="modifier_category_id")
|
||||
op.drop_constraint("uq_modifier_categories_products_product_id", "modifier_categories_products", type_="unique")
|
||||
op.create_unique_constraint(
|
||||
op.f("uq_modifier_categories_products_product_id"),
|
||||
"modifier_categories_products",
|
||||
["product_id", "modifier_category_id"],
|
||||
)
|
||||
|
||||
op.drop_constraint(
|
||||
"fk_modifier_categories_products_product_id_products", "modifier_categories_products", type_="foreignkey"
|
||||
)
|
||||
op.create_foreign_key(
|
||||
op.f("fk_modifier_categories_products_product_id_product_versions"),
|
||||
"modifier_categories_products",
|
||||
"product_versions",
|
||||
["product_id"],
|
||||
["id"],
|
||||
)
|
||||
op.create_exclude_constraint(
|
||||
"uq_product_histories_name",
|
||||
"product_histories",
|
||||
(prod.c.name, "="),
|
||||
(prod.c.units, "="),
|
||||
(func.daterange(prod.c.valid_from, prod.c.valid_till, text("'[]'")), "&&"),
|
||||
)
|
||||
op.drop_constraint("uq_products_name", "product_histories", type_="unique")
|
||||
|
||||
def add_all_roles_to_owner():
|
||||
r = table(
|
||||
"roles",
|
||||
column("id", postgresql.UUID(as_uuid=True)),
|
||||
|
@ -159,6 +97,92 @@ def upgrade():
|
|||
)
|
||||
.on_conflict_do_nothing(),
|
||||
)
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
update_sale_categories()
|
||||
update_section_printers()
|
||||
|
||||
# Migration to temporal products
|
||||
op.drop_constraint("fk_inventories_product_id_products", "inventories", type_="foreignkey")
|
||||
op.drop_constraint(
|
||||
"fk_modifier_categories_products_product_id_products", "modifier_categories_products", type_="foreignkey"
|
||||
)
|
||||
op.drop_constraint("uq_products_name", "products", type_="unique")
|
||||
op.drop_constraint("pk_products", "products", type_="primary")
|
||||
op.rename_table("products", "product_versions")
|
||||
with op.batch_alter_table("product_versions") as batch_op:
|
||||
batch_op.add_column(sa.Column("product_id", postgresql.UUID(as_uuid=True), nullable=True)),
|
||||
batch_op.add_column(sa.Column("valid_from", sa.Date(), nullable=True))
|
||||
batch_op.add_column(sa.Column("valid_till", sa.Date(), nullable=True))
|
||||
batch_op.drop_column("is_active")
|
||||
batch_op.create_primary_key("pk_product_versions", ["id"])
|
||||
|
||||
prod_v = table(
|
||||
"product_versions",
|
||||
column("id", postgresql.UUID(as_uuid=True)),
|
||||
column("product_id", postgresql.UUID(as_uuid=True)),
|
||||
)
|
||||
|
||||
op.execute(prod_v.update(values={"product_id": prod_v.c.id}))
|
||||
op.create_table(
|
||||
"products",
|
||||
sa.Column("id", postgresql.UUID(as_uuid=True), server_default=sa.text("gen_random_uuid()"), nullable=False),
|
||||
# sa.Column("version_id", postgresql.UUID(as_uuid=True), nullable=False),
|
||||
# sa.ForeignKeyConstraint(
|
||||
# ["version_id"], ["product_versions.id"], name=op.f("fk_products_version_id_product_versions")
|
||||
# ),
|
||||
sa.PrimaryKeyConstraint("id", name=op.f("pk_products")),
|
||||
# sa.UniqueConstraint("id", "version_id", name=op.f("uq_products_id")),
|
||||
)
|
||||
op.alter_column("product_versions", "product_id", nullable=False)
|
||||
|
||||
prod = table(
|
||||
"product_versions",
|
||||
column("id", postgresql.UUID(as_uuid=True)),
|
||||
column("name", sa.Unicode(length=255)),
|
||||
column("units", sa.Unicode(length=255)),
|
||||
column("valid_from", sa.Date()),
|
||||
column("valid_till", sa.Date()),
|
||||
)
|
||||
|
||||
pv = table(
|
||||
"products",
|
||||
column("id", postgresql.UUID(as_uuid=True)),
|
||||
)
|
||||
|
||||
op.execute(pv.insert().from_select([pv.c.id], select([prod.c.id])))
|
||||
|
||||
op.create_foreign_key(
|
||||
op.f("fk_product_versions_product_id_products"), "product_versions", "products", ["product_id"], ["id"]
|
||||
)
|
||||
|
||||
op.create_foreign_key(op.f("fk_inventories_product_id_products"), "inventories", "products", ["product_id"], ["id"])
|
||||
op.create_foreign_key(
|
||||
op.f("fk_modifier_categories_products_product_id_products"),
|
||||
"modifier_categories_products",
|
||||
"products",
|
||||
["product_id"],
|
||||
["id"],
|
||||
)
|
||||
|
||||
op.alter_column("modifier_categories_products", "modifier_categories_id", new_column_name="modifier_category_id")
|
||||
op.drop_constraint("uq_modifier_categories_products_product_id", "modifier_categories_products", type_="unique")
|
||||
op.create_unique_constraint(
|
||||
op.f("uq_modifier_categories_products_product_id"),
|
||||
"modifier_categories_products",
|
||||
["product_id", "modifier_category_id"],
|
||||
)
|
||||
|
||||
op.create_exclude_constraint(
|
||||
"uq_product_versions_name",
|
||||
"product_versions",
|
||||
(prod.c.name, "="),
|
||||
(prod.c.units, "="),
|
||||
(func.daterange(prod.c.valid_from, prod.c.valid_till, text("'[]'")), "&&"),
|
||||
)
|
||||
add_all_roles_to_owner()
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
|
|
|
@ -10,8 +10,8 @@ from .master import (
|
|||
Modifier,
|
||||
ModifierCategory,
|
||||
Printer,
|
||||
ProductHistory,
|
||||
ProductVersions,
|
||||
ProductNew,
|
||||
ProductVersion,
|
||||
SaleCategory,
|
||||
Section,
|
||||
SectionPrinter,
|
||||
|
|
|
@ -138,21 +138,23 @@ class SaleCategory(Base):
|
|||
self.id = id_
|
||||
|
||||
|
||||
class ProductVersions(Base):
|
||||
__tablename__ = "product_versions"
|
||||
__table_args__ = (UniqueConstraint("id", "version_id"),)
|
||||
class ProductNew(Base):
|
||||
__tablename__ = "products"
|
||||
id = Column(
|
||||
"id", UUID(as_uuid=True), primary_key=True, server_default=text("gen_random_uuid()"), default=uuid.uuid4
|
||||
)
|
||||
version_id = Column("version_id", UUID(as_uuid=True), ForeignKey("product_histories.id"), nullable=False)
|
||||
histories = relationship("ProductHistory")
|
||||
versions = relationship("ProductVersion")
|
||||
|
||||
def __init__(self, id_=None, version_id=None):
|
||||
self.id = id_
|
||||
self.version_id = version_id
|
||||
|
||||
|
||||
modifier_categories_products = Table(
|
||||
"modifier_categories_products",
|
||||
Base.metadata,
|
||||
Column("id", UUID(as_uuid=True), primary_key=True, server_default=text("gen_random_uuid()"), default=uuid.uuid4),
|
||||
Column("product_id", UUID(as_uuid=True), ForeignKey("product_versions.id"), nullable=False),
|
||||
Column("product_id", UUID(as_uuid=True), ForeignKey("products.id"), nullable=False),
|
||||
Column(
|
||||
"modifier_category_id",
|
||||
UUID(as_uuid=True),
|
||||
|
@ -163,11 +165,12 @@ modifier_categories_products = Table(
|
|||
)
|
||||
|
||||
|
||||
class ProductHistory(Base):
|
||||
__tablename__ = "product_histories"
|
||||
class ProductVersion(Base):
|
||||
__tablename__ = "product_versions"
|
||||
id = Column(
|
||||
"id", UUID(as_uuid=True), primary_key=True, server_default=text("gen_random_uuid()"), default=uuid.uuid4
|
||||
)
|
||||
product_id = Column("product_id", UUID(as_uuid=True), ForeignKey("products.id"), nullable=False)
|
||||
name = Column("name", Unicode(255), nullable=False)
|
||||
units = Column("units", Unicode(255), nullable=False)
|
||||
menu_category_id = Column(
|
||||
|
@ -193,15 +196,16 @@ class ProductHistory(Base):
|
|||
|
||||
menu_category = relationship("MenuCategory", backref="products")
|
||||
sale_category = relationship("SaleCategory", backref="products")
|
||||
modifier_categories = relationship(
|
||||
"ModifierCategory",
|
||||
secondary="join(product_versions, modifier_categories_products, "
|
||||
"ProductVersions.id==modifier_categories_products.c.product_id)",
|
||||
primaryjoin="ProductHistory.id==ProductVersions.version_id",
|
||||
secondaryjoin="modifier_categories_products.c.modifier_category_id==ModifierCategory.id",
|
||||
order_by="ModifierCategory.sort_order",
|
||||
backref="products",
|
||||
)
|
||||
# modifier_categories = relationship(
|
||||
# "ModifierCategory",
|
||||
# secondary="join(products, modifier_categories_products, "
|
||||
# "ProductNew.id==modifier_categories_products.c.product_id)",
|
||||
# primaryjoin="ProductVersion.id==ProductNew.version_id",
|
||||
# secondaryjoin="modifier_categories_products.c.modifier_category_id==ModifierCategory.id",
|
||||
# order_by="ModifierCategory.sort_order",
|
||||
# backref="products",
|
||||
# )
|
||||
product = relationship("ProductNew")
|
||||
|
||||
__table_args__ = (
|
||||
postgresql.ExcludeConstraint(
|
||||
|
@ -213,6 +217,7 @@ class ProductHistory(Base):
|
|||
|
||||
def __init__(
|
||||
self,
|
||||
product_id=None,
|
||||
name=None,
|
||||
units=None,
|
||||
menu_category_id=None,
|
||||
|
@ -221,10 +226,12 @@ class ProductHistory(Base):
|
|||
has_happy_hour=None,
|
||||
is_not_available=None,
|
||||
quantity=None,
|
||||
is_active=None,
|
||||
valid_from=None,
|
||||
valid_till=None,
|
||||
sort_order=0,
|
||||
id_=None,
|
||||
):
|
||||
self.product_id = product_id
|
||||
self.name = name
|
||||
self.units = units
|
||||
self.menu_category_id = menu_category_id
|
||||
|
@ -233,7 +240,8 @@ class ProductHistory(Base):
|
|||
self.has_happy_hour = has_happy_hour
|
||||
self.is_not_available = is_not_available
|
||||
self.quantity = quantity
|
||||
self.is_active = is_active
|
||||
self.valid_from = valid_from
|
||||
self.valid_till = valid_till
|
||||
self.sort_order = sort_order
|
||||
self.id = id_
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ from sqlalchemy.dialects.postgresql import UUID
|
|||
from sqlalchemy.ext.hybrid import hybrid_property
|
||||
from sqlalchemy.orm import backref, relationship, synonym
|
||||
|
||||
from .master import ProductVersions
|
||||
from .master import ProductNew
|
||||
from .meta import Base
|
||||
|
||||
|
||||
|
@ -311,7 +311,7 @@ class Inventory(Base):
|
|||
"id", UUID(as_uuid=True), primary_key=True, server_default=text("gen_random_uuid()"), default=uuid.uuid4
|
||||
)
|
||||
kot_id = Column("kot_id", UUID(as_uuid=True), ForeignKey("kots.id"), nullable=False, index=True)
|
||||
product_id = Column("product_id", UUID(as_uuid=True), ForeignKey("product_versions.id"), nullable=False)
|
||||
product_id = Column("product_id", UUID(as_uuid=True), ForeignKey("products.id"), nullable=False)
|
||||
quantity = Column("quantity", Numeric(precision=15, scale=2))
|
||||
price = Column("price", Numeric(precision=15, scale=2))
|
||||
is_happy_hour = Column("is_happy_hour", Boolean, nullable=False)
|
||||
|
@ -322,7 +322,7 @@ class Inventory(Base):
|
|||
|
||||
kot = relationship("Kot", backref="inventories")
|
||||
tax = relationship("Tax", foreign_keys=tax_id)
|
||||
product = relationship("ProductHistory", secondary=ProductVersions.__table__, backref="inventories")
|
||||
product = relationship("ProductVersion", secondary=ProductNew.__table__, backref="inventories")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
|
|
|
@ -10,7 +10,7 @@ from sqlalchemy.orm import Session
|
|||
|
||||
from ..core.security import get_current_active_user as get_user
|
||||
from ..db.session import SessionLocal
|
||||
from ..models.master import MenuCategory, ProductVersions
|
||||
from ..models.master import MenuCategory, ProductNew
|
||||
from ..schemas.auth import UserToken
|
||||
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ from sqlalchemy.orm import Session
|
|||
|
||||
from ..core.security import get_current_active_user as get_user
|
||||
from ..db.session import SessionLocal
|
||||
from ..models.master import MenuCategory, ModifierCategory, ProductVersions
|
||||
from ..models.master import MenuCategory, ModifierCategory, ProductNew
|
||||
from ..schemas.auth import UserToken
|
||||
|
||||
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import uuid
|
||||
|
||||
from datetime import date, datetime, timedelta
|
||||
from typing import List, Optional
|
||||
from typing import List
|
||||
|
||||
import barker.schemas.master as schemas
|
||||
import barker.schemas.product as product_schemas
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException, Security, status
|
||||
from sqlalchemy import and_, or_
|
||||
|
@ -13,7 +14,7 @@ from sqlalchemy.orm import Session, contains_eager, joinedload
|
|||
from ..core.config import settings
|
||||
from ..core.security import get_current_active_user as get_user
|
||||
from ..db.session import SessionLocal
|
||||
from ..models.master import MenuCategory, ProductHistory, ProductVersions, SaleCategory
|
||||
from ..models.master import MenuCategory, ProductNew, ProductVersion, SaleCategory
|
||||
from ..schemas.auth import UserToken
|
||||
|
||||
|
||||
|
@ -29,9 +30,18 @@ def get_db():
|
|||
db.close()
|
||||
|
||||
|
||||
def effective_date(d: str = None) -> date:
|
||||
return (
|
||||
(datetime.now() - timedelta(minutes=settings.NEW_DAY_OFFSET_MINUTES)).date()
|
||||
if d is None
|
||||
else datetime.strptime(d, "%d-%b-%Y").date()
|
||||
)
|
||||
|
||||
|
||||
@router.post("/list", response_model=List[schemas.Product])
|
||||
def sort_order(
|
||||
data: List[schemas.Product],
|
||||
date_: date = Depends(effective_date),
|
||||
db: Session = Depends(get_db),
|
||||
user: UserToken = Security(get_user, scopes=["products"]),
|
||||
):
|
||||
|
@ -42,19 +52,15 @@ def sort_order(
|
|||
indexes[item.menu_category.id_] += 1
|
||||
else:
|
||||
indexes[item.menu_category.id_] = 0
|
||||
db.query(Product).filter(Product.id == item.id_).update(
|
||||
{Product.sort_order: indexes[item.menu_category.id_]}
|
||||
)
|
||||
db.query(ProductVersion).filter(
|
||||
and_(
|
||||
ProductVersion.product_id == item.id_,
|
||||
or_(ProductVersion.valid_from == None, ProductVersion.valid_from <= date_),
|
||||
or_(ProductVersion.valid_till == None, ProductVersion.valid_till >= date_),
|
||||
)
|
||||
).update({ProductVersion.sort_order: indexes[item.menu_category.id_]})
|
||||
db.commit()
|
||||
return [
|
||||
product_info(item)
|
||||
for item in db.query(Product)
|
||||
.order_by(Product.menu_category_id)
|
||||
.order_by(Product.sort_order)
|
||||
.order_by(Product.name)
|
||||
.options(joinedload(Product.menu_category), joinedload(Product.sale_category))
|
||||
.all()
|
||||
]
|
||||
return product_list(date_, db)
|
||||
except SQLAlchemyError as e:
|
||||
db.rollback()
|
||||
raise HTTPException(
|
||||
|
@ -69,11 +75,16 @@ def sort_order(
|
|||
@router.post("", response_model=schemas.Product)
|
||||
def save(
|
||||
data: schemas.ProductIn,
|
||||
date_: date = Depends(effective_date),
|
||||
db: Session = Depends(get_db),
|
||||
user: UserToken = Security(get_user, scopes=["products"]),
|
||||
):
|
||||
try:
|
||||
item = ProductHistory(
|
||||
item = ProductNew()
|
||||
db.add(item)
|
||||
db.flush()
|
||||
product_version = ProductVersion(
|
||||
product_id=item.id,
|
||||
name=data.name,
|
||||
units=data.units,
|
||||
menu_category_id=data.menu_category.id_,
|
||||
|
@ -82,11 +93,12 @@ def save(
|
|||
has_happy_hour=data.has_happy_hour,
|
||||
is_not_available=data.is_not_available,
|
||||
quantity=data.quantity,
|
||||
is_active=data.is_active,
|
||||
valid_from=date_,
|
||||
valid_till=None,
|
||||
)
|
||||
db.add(item)
|
||||
db.add(product_version)
|
||||
db.commit()
|
||||
return product_info(item)
|
||||
return product_info(product_version)
|
||||
except SQLAlchemyError as e:
|
||||
db.rollback()
|
||||
raise HTTPException(
|
||||
|
@ -102,22 +114,59 @@ def save(
|
|||
def update(
|
||||
id_: uuid.UUID,
|
||||
data: schemas.ProductIn,
|
||||
date_: date = Depends(effective_date),
|
||||
db: Session = Depends(get_db),
|
||||
user: UserToken = Security(get_user, scopes=["products"]),
|
||||
):
|
||||
) -> schemas.Product:
|
||||
try:
|
||||
item: Product = db.query(Product).filter(Product.id == id_).first()
|
||||
item.name = data.name
|
||||
item.units = data.units
|
||||
item.menu_category_id = data.menu_category.id_
|
||||
item.sale_category_id = data.sale_category.id_
|
||||
item.price = data.price
|
||||
item.has_happy_hour = data.has_happy_hour
|
||||
item.is_not_available = data.is_not_available
|
||||
item.quantity = data.quantity
|
||||
item.is_active = data.is_active
|
||||
db.commit()
|
||||
return product_info(item)
|
||||
item: ProductVersion = (
|
||||
db.query(ProductVersion)
|
||||
.join(ProductVersion.menu_category)
|
||||
.filter(
|
||||
and_(
|
||||
ProductVersion.product_id == id_,
|
||||
or_(ProductVersion.valid_from == None, ProductVersion.valid_from <= date_),
|
||||
or_(ProductVersion.valid_till == None, ProductVersion.valid_till >= date_),
|
||||
)
|
||||
)
|
||||
.first()
|
||||
)
|
||||
if item.valid_till != None:
|
||||
# Allow adding a product here splitting the valid from and to, but not implemented right now
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail="Product has been invalidated",
|
||||
)
|
||||
if item.valid_from == date_: # Update the product as valid from the the same
|
||||
item.name = data.name
|
||||
item.units = data.units
|
||||
item.menu_category_id = data.menu_category.id_
|
||||
item.sale_category_id = data.sale_category.id_
|
||||
item.price = data.price
|
||||
item.has_happy_hour = data.has_happy_hour
|
||||
item.is_not_available = data.is_not_available
|
||||
item.quantity = data.quantity
|
||||
db.commit()
|
||||
return product_info(item)
|
||||
else: # Create a new version of the product from the new details
|
||||
item.valid_till = date_ - timedelta(days=1)
|
||||
product_version = ProductVersion(
|
||||
product_id=item.product_id,
|
||||
name=data.name,
|
||||
units=data.units,
|
||||
menu_category_id=data.menu_category.id_,
|
||||
sale_category_id=data.sale_category.id_,
|
||||
price=data.price,
|
||||
has_happy_hour=data.has_happy_hour,
|
||||
is_not_available=data.is_not_available,
|
||||
quantity=data.quantity,
|
||||
valid_from=date_,
|
||||
valid_till=None,
|
||||
)
|
||||
db.add(product_version)
|
||||
db.commit()
|
||||
return product_info(product_version)
|
||||
|
||||
except SQLAlchemyError as e:
|
||||
db.rollback()
|
||||
raise HTTPException(
|
||||
|
@ -132,21 +181,32 @@ def update(
|
|||
@router.delete("/{id_}")
|
||||
def delete(
|
||||
id_: uuid.UUID,
|
||||
date_: date = Depends(effective_date),
|
||||
db: Session = Depends(get_db),
|
||||
user: UserToken = Security(get_user, scopes=["products"]),
|
||||
):
|
||||
try:
|
||||
item: Product = db.query(Product).filter(Product.id == id_).first()
|
||||
item: ProductVersion = (
|
||||
db.query(ProductVersion)
|
||||
.filter(
|
||||
and_(
|
||||
ProductVersion.product_id == id_,
|
||||
or_(ProductVersion.valid_from == None, ProductVersion.valid_from <= date_),
|
||||
or_(ProductVersion.valid_till == None, ProductVersion.valid_till >= date_),
|
||||
)
|
||||
)
|
||||
.first()
|
||||
)
|
||||
if item is None:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="Product not found",
|
||||
)
|
||||
elif item.valid_from == date_:
|
||||
db.delete(item)
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_501_NOT_IMPLEMENTED,
|
||||
detail="Product deletion not implemented",
|
||||
)
|
||||
item.valid_till = date_ - timedelta(days=1)
|
||||
db.commit()
|
||||
except Exception:
|
||||
db.rollback()
|
||||
raise
|
||||
|
@ -157,38 +217,47 @@ def show_blank(
|
|||
db: Session = Depends(get_db),
|
||||
user: UserToken = Security(get_user, scopes=["products"]),
|
||||
):
|
||||
return product_info(None)
|
||||
|
||||
|
||||
@router.get("/list")
|
||||
def show_list(d: str = None, db: Session = Depends(get_db), user: UserToken = Depends(get_user)):
|
||||
date_ = (
|
||||
(datetime.now() - timedelta(minutes=settings.NEW_DAY_OFFSET_MINUTES)).date()
|
||||
if d is None
|
||||
else datetime.strptime(d, "%d-%b-%Y").date()
|
||||
return schemas.Product(
|
||||
name="",
|
||||
units="",
|
||||
menuCategory={},
|
||||
saleCategory={},
|
||||
price=0,
|
||||
hasHappyHour=False,
|
||||
isNotAvailable=False,
|
||||
isActive=True,
|
||||
sortOrder=0,
|
||||
)
|
||||
|
||||
|
||||
@router.get("/list", response_model=List[schemas.Product])
|
||||
def show_list(
|
||||
date_: date = Depends(effective_date), db: Session = Depends(get_db), user: UserToken = Depends(get_user)
|
||||
) -> List[schemas.Product]:
|
||||
return product_list(date_, db)
|
||||
|
||||
|
||||
def product_list(date_: date, db: Session) -> List[schemas.Product]:
|
||||
return [
|
||||
product_info(item.histories)
|
||||
for item in db.query(ProductVersions)
|
||||
.join(ProductVersions.histories)
|
||||
.join(ProductHistory.menu_category)
|
||||
product_info(item)
|
||||
for item in db.query(ProductVersion)
|
||||
.join(ProductVersion.menu_category)
|
||||
.join(ProductVersion.sale_category)
|
||||
.filter(
|
||||
and_(
|
||||
or_(ProductHistory.valid_from == None, ProductHistory.valid_from <= date_),
|
||||
or_(ProductHistory.valid_till == None, ProductHistory.valid_till >= date_),
|
||||
or_(ProductVersion.valid_from == None, ProductVersion.valid_from <= date_),
|
||||
or_(ProductVersion.valid_till == None, ProductVersion.valid_till >= date_),
|
||||
)
|
||||
)
|
||||
.order_by(MenuCategory.sort_order)
|
||||
.order_by(MenuCategory.name)
|
||||
.order_by(ProductHistory.sort_order)
|
||||
.order_by(ProductHistory.name)
|
||||
.order_by(ProductVersion.sort_order)
|
||||
.order_by(ProductVersion.name)
|
||||
.options(
|
||||
joinedload(ProductVersions.histories, innerjoin=True),
|
||||
joinedload(ProductVersions.histories, ProductHistory.menu_category, innerjoin=True),
|
||||
joinedload(ProductVersions.histories, ProductHistory.sale_category, innerjoin=True),
|
||||
contains_eager(ProductVersions.histories),
|
||||
contains_eager(ProductVersions.histories, ProductHistory.menu_category),
|
||||
contains_eager(ProductVersions.histories, ProductHistory.sale_category),
|
||||
joinedload(ProductVersion.menu_category, innerjoin=True),
|
||||
joinedload(ProductVersion.sale_category, innerjoin=True),
|
||||
contains_eager(ProductVersion.menu_category),
|
||||
contains_eager(ProductVersion.sale_category),
|
||||
)
|
||||
.all()
|
||||
]
|
||||
|
@ -197,56 +266,68 @@ def show_list(d: str = None, db: Session = Depends(get_db), user: UserToken = De
|
|||
@router.get("/query")
|
||||
async def show_term(
|
||||
mc: uuid.UUID = None,
|
||||
d: str = None,
|
||||
date_: date = Depends(effective_date),
|
||||
db: Session = Depends(get_db),
|
||||
current_user: UserToken = Depends(get_user),
|
||||
):
|
||||
date_ = (
|
||||
(datetime.now() - timedelta(minutes=settings.NEW_DAY_OFFSET_MINUTES)).date()
|
||||
if d is None
|
||||
else datetime.strptime(d, "%d-%b-%Y").date()
|
||||
)
|
||||
list_ = []
|
||||
for item in (
|
||||
db.query(ProductVersions)
|
||||
.join(ProductVersions.histories)
|
||||
.join(ProductVersions.histories, ProductHistory.sale_category)
|
||||
.join(ProductVersions.histories, ProductHistory.sale_category, SaleCategory.tax)
|
||||
db.query(ProductVersion)
|
||||
.join(ProductVersion.sale_category)
|
||||
.join(ProductVersion.sale_category, SaleCategory.tax)
|
||||
.filter(
|
||||
and_(
|
||||
ProductHistory.menu_category_id == mc,
|
||||
or_(ProductHistory.valid_from == None, ProductHistory.valid_from <= date_),
|
||||
or_(ProductHistory.valid_till == None, ProductHistory.valid_till >= date_),
|
||||
ProductVersion.menu_category_id == mc,
|
||||
or_(ProductVersion.valid_from == None, ProductVersion.valid_from <= date_),
|
||||
or_(ProductVersion.valid_till == None, ProductVersion.valid_till >= date_),
|
||||
)
|
||||
)
|
||||
.order_by(ProductHistory.sort_order, ProductHistory.name)
|
||||
.order_by(ProductVersion.sort_order, ProductVersion.name)
|
||||
.options(
|
||||
joinedload(ProductVersions.histories, innerjoin=True),
|
||||
joinedload(ProductVersions.histories, ProductHistory.sale_category, innerjoin=True),
|
||||
joinedload(ProductVersions.histories, ProductHistory.sale_category, SaleCategory.tax, innerjoin=True),
|
||||
contains_eager(ProductVersions.histories),
|
||||
contains_eager(ProductVersions.histories, ProductHistory.sale_category),
|
||||
contains_eager(ProductVersions.histories, ProductHistory.sale_category, SaleCategory.tax),
|
||||
joinedload(ProductVersion.sale_category, innerjoin=True),
|
||||
joinedload(ProductVersion.sale_category, SaleCategory.tax, innerjoin=True),
|
||||
contains_eager(ProductVersion.sale_category),
|
||||
contains_eager(ProductVersion.sale_category, SaleCategory.tax),
|
||||
)
|
||||
.all()
|
||||
):
|
||||
list_.append(query_product_info(item.histories, False))
|
||||
if item.histories.has_happy_hour:
|
||||
list_.append(query_product_info(item.histories, True))
|
||||
list_.append(query_product_info(item, False))
|
||||
if item.has_happy_hour:
|
||||
list_.append(query_product_info(item, True))
|
||||
return list_
|
||||
|
||||
|
||||
@router.get("/{id_}")
|
||||
@router.get("/{id_}", response_model=schemas.Product)
|
||||
def show_id(
|
||||
id_: uuid.UUID,
|
||||
date_: date = Depends(effective_date),
|
||||
db: Session = Depends(get_db),
|
||||
user: UserToken = Security(get_user, scopes=["products"]),
|
||||
):
|
||||
item: Product = db.query(Product).filter(Product.id == id_).first()
|
||||
) -> schemas.Product:
|
||||
item: ProductVersion = (
|
||||
db.query(ProductVersion)
|
||||
.join(ProductVersion.sale_category)
|
||||
.join(ProductVersion.sale_category, SaleCategory.tax)
|
||||
.filter(
|
||||
and_(
|
||||
ProductVersion.product_id == id_,
|
||||
or_(ProductVersion.valid_from == None, ProductVersion.valid_from <= date_),
|
||||
or_(ProductVersion.valid_till == None, ProductVersion.valid_till >= date_),
|
||||
)
|
||||
)
|
||||
.order_by(ProductVersion.sort_order, ProductVersion.name)
|
||||
.options(
|
||||
joinedload(ProductVersion.sale_category, innerjoin=True),
|
||||
joinedload(ProductVersion.sale_category, SaleCategory.tax, innerjoin=True),
|
||||
contains_eager(ProductVersion.sale_category),
|
||||
contains_eager(ProductVersion.sale_category, SaleCategory.tax),
|
||||
)
|
||||
.first()
|
||||
)
|
||||
return product_info(item)
|
||||
|
||||
|
||||
def query_product_info(item: ProductHistory, happy_hour: bool):
|
||||
def query_product_info(item: ProductVersion, happy_hour: bool):
|
||||
return {
|
||||
"id": item.id,
|
||||
"name": ("H H " if happy_hour else "") + item.full_name,
|
||||
|
@ -266,31 +347,19 @@ def query_product_info(item: ProductHistory, happy_hour: bool):
|
|||
}
|
||||
|
||||
|
||||
def product_info(item: Optional[ProductHistory]):
|
||||
if item is None:
|
||||
return {
|
||||
"name": "",
|
||||
"units": "",
|
||||
"menuCategory": {},
|
||||
"saleCategory": {},
|
||||
"price": 0,
|
||||
"hasHappyHour": False,
|
||||
"isNotAvailable": False,
|
||||
"isActive": True,
|
||||
"sortOrder": 0,
|
||||
}
|
||||
return {
|
||||
"id": item.id,
|
||||
"name": item.name,
|
||||
"units": item.units,
|
||||
"menuCategory": {"id": item.menu_category_id, "name": item.menu_category.name},
|
||||
"saleCategory": {
|
||||
"id": item.sale_category_id,
|
||||
"name": item.sale_category.name,
|
||||
},
|
||||
"price": item.price,
|
||||
"hasHappyHour": item.has_happy_hour,
|
||||
"isNotAvailable": item.is_not_available,
|
||||
"isActive": True,
|
||||
"sortOrder": item.sort_order,
|
||||
}
|
||||
def product_info(item: ProductVersion) -> schemas.Product:
|
||||
return schemas.Product(
|
||||
id=item.product_id,
|
||||
name=item.name,
|
||||
units=item.units,
|
||||
menuCategory=product_schemas.MenuCategoryLink(id=item.menu_category_id, name=item.menu_category.name),
|
||||
saleCategory=product_schemas.SaleCategoryLink(
|
||||
id=item.sale_category_id,
|
||||
name=item.sale_category.name,
|
||||
),
|
||||
price=item.price,
|
||||
hasHappyHour=item.has_happy_hour,
|
||||
isNotAvailable=item.is_not_available,
|
||||
isActive=True,
|
||||
sortOrder=item.sort_order,
|
||||
)
|
||||
|
|
|
@ -7,7 +7,7 @@ from sqlalchemy.sql.expression import func
|
|||
from ...core.config import settings
|
||||
from ...core.security import get_current_active_user as get_user
|
||||
from ...db.session import SessionLocal
|
||||
from ...models import Inventory, Kot, ProductVersions, Voucher, VoucherType
|
||||
from ...models import Inventory, Kot, ProductNew, Voucher, VoucherType
|
||||
from ...schemas.auth import UserToken
|
||||
|
||||
|
||||
|
|
|
@ -10,14 +10,7 @@ from sqlalchemy.orm import Session
|
|||
from ...core.config import settings
|
||||
from ...core.security import get_current_active_user as get_user
|
||||
from ...db.session import SessionLocal
|
||||
from ...models import (
|
||||
Inventory,
|
||||
Kot,
|
||||
ProductVersions,
|
||||
SaleCategory,
|
||||
Voucher,
|
||||
VoucherType,
|
||||
)
|
||||
from ...models import Inventory, Kot, ProductNew, SaleCategory, Voucher, VoucherType
|
||||
from ...printing.discount_report import print_discount_report
|
||||
from ...schemas.auth import UserToken
|
||||
from ...schemas.discount_report import DiscountReport, DiscountReportItem
|
||||
|
|
|
@ -11,7 +11,7 @@ from ...models import (
|
|||
Inventory,
|
||||
Kot,
|
||||
MenuCategory,
|
||||
ProductVersions,
|
||||
ProductNew,
|
||||
SaleCategory,
|
||||
Voucher,
|
||||
VoucherType,
|
||||
|
|
|
@ -13,7 +13,7 @@ from ...db.session import SessionLocal
|
|||
from ...models import (
|
||||
Inventory,
|
||||
Kot,
|
||||
ProductVersions,
|
||||
ProductNew,
|
||||
SaleCategory,
|
||||
Settlement,
|
||||
SettleOption,
|
||||
|
|
|
@ -17,7 +17,7 @@ from ...models import (
|
|||
Inventory,
|
||||
InventoryModifier,
|
||||
Kot,
|
||||
ProductVersions,
|
||||
ProductNew,
|
||||
Voucher,
|
||||
VoucherType,
|
||||
)
|
||||
|
|
|
@ -16,7 +16,7 @@ from ...models import (
|
|||
Inventory,
|
||||
InventoryModifier,
|
||||
Kot,
|
||||
ProductVersions,
|
||||
ProductNew,
|
||||
Voucher,
|
||||
VoucherType,
|
||||
)
|
||||
|
|
|
@ -20,6 +20,7 @@ class ProductLink(BaseModel):
|
|||
|
||||
class MenuCategoryLink(BaseModel): # Hack to prevent circular error
|
||||
id_: uuid.UUID = Field(...)
|
||||
name: Optional[str]
|
||||
products: Optional[List[ProductLink]]
|
||||
|
||||
class Config:
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import uuid
|
||||
|
||||
from typing import Optional
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from . import to_camel
|
||||
|
@ -27,6 +29,7 @@ class SaleCategory(SaleCategoryIn):
|
|||
|
||||
class SaleCategoryLink(BaseModel):
|
||||
id_: uuid.UUID = Field(...)
|
||||
name: Optional[str]
|
||||
|
||||
class Config:
|
||||
fields = {"id_": "id"}
|
||||
|
|
|
@ -58,7 +58,6 @@
|
|||
>
|
||||
<mat-checkbox formControlName="hasHappyHour">Has Happy Hour?</mat-checkbox>
|
||||
<mat-checkbox formControlName="isNotAvailable">Is Not Available?</mat-checkbox>
|
||||
<mat-checkbox formControlName="isActive">Is Active?</mat-checkbox>
|
||||
</div>
|
||||
<div
|
||||
fxLayout="row"
|
||||
|
|
|
@ -44,7 +44,6 @@ export class ProductDetailComponent implements OnInit, AfterViewInit {
|
|||
hasHappyHour: '',
|
||||
isNotAvailable: '',
|
||||
quantity: '',
|
||||
isActive: '',
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -70,7 +69,6 @@ export class ProductDetailComponent implements OnInit, AfterViewInit {
|
|||
hasHappyHour: this.item.hasHappyHour,
|
||||
isNotAvailable: this.item.isNotAvailable,
|
||||
quantity: this.item.quantity || '',
|
||||
isActive: this.item.isActive,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -127,7 +125,6 @@ export class ProductDetailComponent implements OnInit, AfterViewInit {
|
|||
this.item.hasHappyHour = formModel.hasHappyHour;
|
||||
this.item.isNotAvailable = formModel.isNotAvailable;
|
||||
this.item.quantity = +formModel.quantity;
|
||||
this.item.isActive = formModel.isActive;
|
||||
return this.item;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,8 +6,8 @@ import { Product } from '../../core/product';
|
|||
|
||||
export class ProductListDataSource extends DataSource<Product> {
|
||||
public data: Product[];
|
||||
public viewData: Product[];
|
||||
private filterValue: string;
|
||||
public filteredData: Product[];
|
||||
public filterValue: string;
|
||||
|
||||
constructor(
|
||||
private readonly filter: Observable<string>,
|
||||
|
@ -15,39 +15,38 @@ export class ProductListDataSource extends DataSource<Product> {
|
|||
) {
|
||||
super();
|
||||
this.data = [];
|
||||
this.viewData = [];
|
||||
this.filter = filter.pipe(
|
||||
tap((x) => {
|
||||
this.filterValue = x;
|
||||
}),
|
||||
);
|
||||
this.dataObs = dataObs.pipe(
|
||||
tap((x) => {
|
||||
this.data = x;
|
||||
}),
|
||||
);
|
||||
this.filteredData = [];
|
||||
this.filterValue = '';
|
||||
}
|
||||
|
||||
connect(): Observable<Product[]> {
|
||||
const dataMutations = [this.dataObs, this.filter];
|
||||
|
||||
const dataMutations = [
|
||||
this.dataObs.pipe(
|
||||
tap((x) => {
|
||||
this.data = x;
|
||||
}),
|
||||
),
|
||||
this.filter.pipe(
|
||||
tap((x) => {
|
||||
this.filterValue = x;
|
||||
}),
|
||||
),
|
||||
];
|
||||
return merge(...dataMutations).pipe(
|
||||
map(() => {
|
||||
this.viewData = this.getFilteredData([...this.data]);
|
||||
return this.viewData;
|
||||
map(() => this.getFilteredData(this.data, this.filterValue)),
|
||||
tap((x) => {
|
||||
this.filteredData = x;
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
disconnect() {}
|
||||
|
||||
private getFilteredData(data: Product[]): Product[] {
|
||||
const filter = this.filterValue === undefined ? '' : this.filterValue;
|
||||
if (filter === '') {
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
private getFilteredData(data: Product[], filter: string): Product[] {
|
||||
if (filter === undefined) {
|
||||
return data;
|
||||
}
|
||||
return data.filter((x) => {
|
||||
return x.menuCategory.id === filter;
|
||||
});
|
||||
return data.filter((x) => x.menuCategory.id === filter);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
.right {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
|
@ -4,7 +4,8 @@
|
|||
<button mat-button (click)="updateSortOrder()" [disabled]="!(filter | async)">
|
||||
Update Order
|
||||
</button>
|
||||
<button mat-button mat-icon-button *ngIf="dataSource.viewData.length" (click)="exportCsv()">
|
||||
<!-- This should check filtered data and not data-->
|
||||
<button mat-button mat-icon-button (click)="exportCsv()" [disabled]="!((data | async).length)">
|
||||
<mat-icon>save_alt</mat-icon>
|
||||
</button>
|
||||
<a mat-button [routerLink]="['/products', 'new']">
|
||||
|
@ -26,7 +27,7 @@
|
|||
<mat-select
|
||||
placeholder="Menu Category"
|
||||
formControlName="menuCategory"
|
||||
(selectionChange)="filterOn($event)"
|
||||
(selectionChange)="filterOn($event.value)"
|
||||
>
|
||||
<mat-option>-- All Products --</mat-option>
|
||||
<mat-option *ngFor="let mc of menuCategories" [value]="mc.id">
|
||||
|
@ -54,8 +55,8 @@
|
|||
|
||||
<!-- Price Column -->
|
||||
<ng-container matColumnDef="price">
|
||||
<mat-header-cell *matHeaderCellDef>Price</mat-header-cell>
|
||||
<mat-cell *matCellDef="let row">{{ row.price | currency: 'INR' }}</mat-cell>
|
||||
<mat-header-cell *matHeaderCellDef class="right">Price</mat-header-cell>
|
||||
<mat-cell *matCellDef="let row" class="right">{{ row.price | currency: 'INR' }}</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<!-- Menu Category Column -->
|
||||
|
@ -87,20 +88,14 @@
|
|||
</mat-icon>
|
||||
<b> {{ row.isNotAvailable ? 'Not Available' : 'Available' }}</b>
|
||||
</div>
|
||||
<div flex>
|
||||
<mat-icon>
|
||||
{{ row.isActive ? 'visibility' : 'visibility_off' }}
|
||||
</mat-icon>
|
||||
<b> {{ row.isActive ? 'Active' : 'Deactivated' }}</b>
|
||||
</div>
|
||||
</div>
|
||||
</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<!-- Yield Column -->
|
||||
<ng-container matColumnDef="quantity">
|
||||
<mat-header-cell *matHeaderCellDef>Quantity</mat-header-cell>
|
||||
<mat-cell *matCellDef="let row">{{ row.quantity | currency: 'INR' }}</mat-cell>
|
||||
<mat-header-cell *matHeaderCellDef class="right">Quantity</mat-header-cell>
|
||||
<mat-cell *matCellDef="let row" class="right">{{ row.quantity | number: '1.2-2' }}</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
|
||||
|
|
|
@ -44,15 +44,15 @@ export class ProductListComponent implements OnInit {
|
|||
this.form = this.fb.group({
|
||||
menuCategory: '',
|
||||
});
|
||||
this.filter = new BehaviorSubject('');
|
||||
this.filter = new BehaviorSubject(undefined);
|
||||
this.data = new BehaviorSubject([]);
|
||||
this.data.subscribe((data: Product[]) => {
|
||||
this.list = data;
|
||||
});
|
||||
}
|
||||
|
||||
filterOn(val: any) {
|
||||
this.filter.next(val.value);
|
||||
filterOn(val: string) {
|
||||
this.filter.next(val);
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
|
@ -68,7 +68,7 @@ export class ProductListComponent implements OnInit {
|
|||
}
|
||||
|
||||
updateSortOrder() {
|
||||
this.ser.updateSortOrder(this.dataSource.viewData).subscribe(
|
||||
this.ser.updateSortOrder(this.dataSource.filteredData).subscribe(
|
||||
(result: Product[]) => {
|
||||
this.toaster.show('Success', '');
|
||||
this.loadData(result, this.menuCategories);
|
||||
|
@ -80,8 +80,15 @@ export class ProductListComponent implements OnInit {
|
|||
}
|
||||
|
||||
dropTable(event: CdkDragDrop<ProductListDataSource>) {
|
||||
const prevIndex = this.list.indexOf(event.item.data);
|
||||
moveItemInArray(this.list, prevIndex, event.currentIndex);
|
||||
const prevIndex = this.dataSource.filteredData.indexOf(event.item.data);
|
||||
moveItemInArray(this.dataSource.filteredData, prevIndex, event.currentIndex);
|
||||
if (this.dataSource.filterValue === undefined) {
|
||||
this.list = this.dataSource.filteredData;
|
||||
} else {
|
||||
this.list = this.list
|
||||
.filter((x) => x.menuCategory.id !== this.dataSource.filterValue)
|
||||
.concat(this.dataSource.filteredData);
|
||||
}
|
||||
this.data.next(this.list);
|
||||
}
|
||||
|
||||
|
@ -95,7 +102,7 @@ export class ProductListComponent implements OnInit {
|
|||
SaleCategory: 'saleCategory',
|
||||
};
|
||||
|
||||
const csvData = new Blob([this.toCsv.toCsv(headers, this.dataSource.viewData)], {
|
||||
const csvData = new Blob([this.toCsv.toCsv(headers, this.dataSource.filteredData)], {
|
||||
type: 'text/csv;charset=utf-8;',
|
||||
});
|
||||
const link = document.createElement('a');
|
||||
|
|
|
@ -35,7 +35,7 @@ export class ProductService {
|
|||
}
|
||||
|
||||
listIsActiveOfCategory(id: string): Observable<Product[]> {
|
||||
const options = { params: new HttpParams().set('mc', id).set('a', 'true') };
|
||||
const options = { params: new HttpParams().set('mc', id) };
|
||||
return <Observable<Product[]>>(
|
||||
this.http
|
||||
.get<Product[]>(`${url}/query`, options)
|
||||
|
|
Loading…
Reference in New Issue