From 7d06a2f961657f06006c65f615f90c116225eb39 Mon Sep 17 00:00:00 2001 From: Amritanshu Date: Sat, 13 Jul 2019 21:32:18 +0530 Subject: [PATCH] Save Bill Works --- barker/models/voucher.py | 291 +++++++++++------- barker/routes.py | 3 +- barker/views/food_table.py | 56 ++-- barker/views/product.py | 14 +- barker/views/reports/sale_analysis.py | 45 +-- barker/views/voucher/__init__.py | 8 +- barker/views/voucher/save.py | 77 +++-- barker/views/voucher/show.py | 9 +- barker/views/voucher/update.py | 28 +- bookie/src/app/app.module.ts | 16 +- bookie/src/app/core/http-auth-interceptor.ts | 4 +- .../guest-book-detail.component.ts | 2 +- .../menu-category/menu-categories.module.ts | 2 +- .../sale-category/sale-categories.module.ts | 2 +- bookie/src/app/sales/bill.service.ts | 76 ++++- .../app/sales/bills/bill-resolver.service.ts | 8 +- bookie/src/app/sales/bills/bill.ts | 24 +- .../src/app/sales/bills/bills.component.css | 6 +- .../src/app/sales/bills/bills.component.html | 7 +- bookie/src/app/sales/bills/bills.component.ts | 50 ++- bookie/src/app/sales/bills/voucher.service.ts | 24 +- .../app/sales/home/sales-home.component.css | 15 + .../app/sales/home/sales-home.component.html | 23 +- .../app/sales/home/sales-home.component.ts | 22 +- .../menu-categories.component.css | 15 + .../menu-categories.component.html | 11 +- .../menu-categories.component.ts | 10 +- .../sales/modifiers/modifiers.component.css | 2 + .../sales/modifiers/modifiers.component.ts | 2 +- .../app/sales/products/products.component.css | 15 + .../sales/products/products.component.html | 10 +- .../app/sales/products/products.component.ts | 11 +- .../app/sales/quantity/quantity.component.css | 0 .../sales/quantity/quantity.component.html | 17 + .../sales/quantity/quantity.component.spec.ts | 25 ++ .../app/sales/quantity/quantity.component.ts | 37 +++ .../running-tables.component.css | 1 + .../running-tables.component.html | 12 +- .../running-tables.component.ts | 6 +- bookie/src/app/sales/sales.module.ts | 17 +- bookie/src/app/shared/accounting.pipe.ts | 2 +- bookie/src/app/tables/table.service.ts | 2 +- bookie/src/app/tables/tables.module.ts | 2 +- 43 files changed, 660 insertions(+), 349 deletions(-) create mode 100644 bookie/src/app/sales/quantity/quantity.component.css create mode 100644 bookie/src/app/sales/quantity/quantity.component.html create mode 100644 bookie/src/app/sales/quantity/quantity.component.spec.ts create mode 100644 bookie/src/app/sales/quantity/quantity.component.ts diff --git a/barker/models/voucher.py b/barker/models/voucher.py index 85c98d3..61b65da 100644 --- a/barker/models/voucher.py +++ b/barker/models/voucher.py @@ -4,27 +4,40 @@ import uuid from decimal import Decimal from sqlalchemy.ext.hybrid import hybrid_property -from sqlalchemy import Column, Integer, Boolean, Unicode, DateTime, Numeric, ForeignKey, UniqueConstraint, func, case -from sqlalchemy.orm import relationship, synonym, backref +from sqlalchemy import ( + Column, + Integer, + Boolean, + Unicode, + DateTime, + Numeric, + ForeignKey, + UniqueConstraint, + func, + case, +) +from sqlalchemy.orm import relationship, backref from barker.models.guidtype import GUID from .meta import Base class VoucherType(IntEnum): + KOT = 0 REGULAR_BILL = 1 NO_CHARGE = 2 - TAKE_AWAY = 3 STAFF = 4 class GuestBook(Base): - __tablename__ = 'guest_book' - id = Column('id', GUID(), primary_key=True, default=uuid.uuid4) - customer_id = Column('customer_id', GUID(), ForeignKey('customers.id'), nullable=False) - pax = Column('pax', Numeric, nullable=False) - date = Column('creation_date', DateTime(timezone=True), nullable=False) + __tablename__ = "guest_book" + id = Column("id", GUID(), primary_key=True, default=uuid.uuid4) + customer_id = Column( + "customer_id", GUID(), ForeignKey("customers.id"), nullable=False + ) + pax = Column("pax", Numeric, nullable=False) + date = Column("creation_date", DateTime(timezone=True), nullable=False) - customer = relationship('Customer') + customer = relationship("Customer") def __init__(self, customer_id=None, pax=None, id_=None): self.customer_id = customer_id @@ -34,16 +47,20 @@ class GuestBook(Base): class Overview(Base): - __tablename__ = 'overview' - id = Column('id', GUID(), primary_key=True, default=uuid.uuid4) - voucher_id = Column('voucher_id', GUID(), ForeignKey('vouchers.id'), unique=True) - food_table_id = Column('food_table_id', GUID(), ForeignKey('food_tables.id'), unique=True) - guest_book_id = Column('guest_book_id', GUID(), ForeignKey('guest_book.id'), unique=True) - status = Column('status', Unicode(255), nullable=False) + __tablename__ = "overview" + id = Column("id", GUID(), primary_key=True, default=uuid.uuid4) + voucher_id = Column("voucher_id", GUID(), ForeignKey("vouchers.id"), unique=True) + food_table_id = Column( + "food_table_id", GUID(), ForeignKey("food_tables.id"), unique=True + ) + guest_book_id = Column( + "guest_book_id", GUID(), ForeignKey("guest_book.id"), unique=True + ) + status = Column("status", Unicode(255), nullable=False) - voucher = relationship('Voucher', backref=backref('status', uselist=False)) - food_table = relationship('FoodTable', backref=backref('status', uselist=False)) - guest = relationship('GuestBook', backref=backref('status', uselist=False)) + voucher = relationship("Voucher", backref=backref("status", uselist=False)) + food_table = relationship("FoodTable", backref=backref("status", uselist=False)) + guest = relationship("GuestBook", backref=backref("status", uselist=False)) def __init__(self, voucher_id, food_table_id, guest_book_id, status): self.voucher_id = voucher_id @@ -53,16 +70,20 @@ class Overview(Base): class InventoryModifier(Base): - __tablename__ = 'inventory_modifiers' - __table_args__ = (UniqueConstraint('inventory_id', 'modifier_id'),) + __tablename__ = "inventory_modifiers" + __table_args__ = (UniqueConstraint("inventory_id", "modifier_id"),) - id = Column('id', GUID(), primary_key=True, default=uuid.uuid4) - inventory_id = Column('inventory_id', GUID(), ForeignKey('inventories.id'), nullable=False) - modifier_id = Column('modifier_id', GUID(), ForeignKey('modifiers.id'), nullable=False) - price = Column('price', Numeric, nullable=False) + id = Column("id", GUID(), primary_key=True, default=uuid.uuid4) + inventory_id = Column( + "inventory_id", GUID(), ForeignKey("inventories.id"), nullable=False + ) + modifier_id = Column( + "modifier_id", GUID(), ForeignKey("modifiers.id"), nullable=False + ) + price = Column("price", Numeric, nullable=False) - inventory = relationship('Inventory', backref='modifiers') - modifier = relationship('Modifier') + inventory = relationship("Inventory", backref="modifiers") + modifier = relationship("Modifier") def __init__(self, inventory_id, modifier_id, price): self.inventory_id = inventory_id @@ -71,48 +92,74 @@ class InventoryModifier(Base): class Voucher(Base): - __tablename__ = 'vouchers' - __table_args__ = (UniqueConstraint('bill_id', 'voucher_type'),) + __tablename__ = "vouchers" + __table_args__ = (UniqueConstraint("bill_id", "voucher_type"),) - id = Column('id', GUID(), primary_key=True, default=uuid.uuid4) - date = Column('date', DateTime, nullable=False, index=True) - pax = Column('pax', Numeric, nullable=False) - bill_id = Column('bill_id', Numeric) - kot_id = Column('kot_id', Numeric, nullable=False, unique=True) - creation_date = Column('creation_date', DateTime(timezone=True), nullable=False) - last_edit_date = Column('last_edit_date', DateTime(timezone=True), nullable=False) - food_table_id = Column('food_table_id', GUID(), ForeignKey('food_tables.id'), nullable=False) - customer_id = Column('customer_id', GUID(), ForeignKey('customers.id'), nullable=False) - narration = Column('narration', Unicode(1000), nullable=False) - is_void = Column('is_void', Boolean, nullable=False) - void_reason = Column('void_reason', Unicode(255)) - is_printed = Column('is_printed', Boolean, nullable=False) - voucher_type = Column('voucher_type', Integer, nullable=False) - user_id = Column('user_id', GUID(), ForeignKey('users.id'), nullable=False) + id = Column("id", GUID(), primary_key=True, default=uuid.uuid4) + date = Column("date", DateTime, nullable=False, index=True) + pax = Column("pax", Numeric, nullable=False) + bill_id = Column("bill_id", Numeric) + kot_id = Column("kot_id", Numeric, nullable=False, unique=True) + creation_date = Column("creation_date", DateTime(timezone=True), nullable=False) + last_edit_date = Column("last_edit_date", DateTime(timezone=True), nullable=False) + food_table_id = Column( + "food_table_id", GUID(), ForeignKey("food_tables.id"), nullable=False + ) + customer_id = Column("customer_id", GUID(), ForeignKey("customers.id")) + narration = Column("narration", Unicode(1000), nullable=False) + is_void = Column("is_void", Boolean, nullable=False) + void_reason = Column("void_reason", Unicode(255)) + is_printed = Column("is_printed", Boolean, nullable=False) + voucher_type = Column("voucher_type", Integer, nullable=False) + user_id = Column("user_id", GUID(), ForeignKey("users.id"), nullable=False) - user = relationship('User', backref='vouchers') - food_table = relationship('FoodTable', backref='vouchers') - customer = relationship('Customer', backref='vouchers') + user = relationship("User", backref="vouchers") + food_table = relationship("FoodTable", backref="vouchers") + customer = relationship("Customer", backref="vouchers") - kots = relationship('Kot', backref='voucher', cascade="delete, delete-orphan", cascade_backrefs=False) - settlements = relationship('Settlement', backref='voucher', cascade="delete, delete-orphan", cascade_backrefs=False) - reprints = relationship('Reprint', backref='voucher', cascade="delete, delete-orphan", cascade_backrefs=False) + kots = relationship( + "Kot", + backref="voucher", + cascade="delete, delete-orphan", + cascade_backrefs=False, + ) + settlements = relationship( + "Settlement", + backref="voucher", + cascade="delete, delete-orphan", + cascade_backrefs=False, + ) + reprints = relationship( + "Reprint", + backref="voucher", + cascade="delete, delete-orphan", + cascade_backrefs=False, + ) @property def __name__(self): return self.name - def __init__(self, pax, food_table_id, customer_id, is_printed, voucher_type, user_id, dbsession): + def __init__( + self, + pax, + food_table_id, + customer_id, + is_printed, + voucher_type, + user_id, + dbsession, + ): now = datetime.now() self.date = now self.pax = pax if is_printed: type = [1, 3] if voucher_type in [1, 3] else [voucher_type] - self.bill_id = dbsession.query( - func.coalesce(func.max(Voucher.bill_id), 0) + 1 - ).filter( - Voucher.voucher_type.in_(type) - ).scalar() + self.bill_id = ( + dbsession.query(func.coalesce(func.max(Voucher.bill_id), 0) + 1) + .filter(Voucher.voucher_type.in_(type)) + .scalar() + ) self.kot_id = dbsession.query( func.coalesce(func.max(Voucher.kot_id), 0) + 1 ).scalar() @@ -121,7 +168,7 @@ class Voucher(Base): self.last_edit_date = now self.food_table_id = food_table_id self.customer_id = customer_id - self.narration = '' + self.narration = "" self.is_void = False self.void_reason = None self.is_printed = is_printed @@ -131,31 +178,46 @@ class Voucher(Base): @property def full_bill_id(self): if self.bill_id is None: - return 'K-' + str(self.kot_id) + return "K-" + str(self.kot_id) if self.voucher_type == VoucherType.NO_CHARGE.value: return "NC-" + str(self.bill_id) if self.voucher_type == VoucherType.STAFF.value: return "ST-" + str(self.bill_id) - if self.voucher_type in [VoucherType.TAKE_AWAY.value, VoucherType.REGULAR_BILL.value]: + if self.voucher_type in [ + VoucherType.TAKE_AWAY.value, + VoucherType.REGULAR_BILL.value, + ]: return str(self.bill_id // 10000) + "-" + str(self.bill_id % 10000) else: raise Exception class Kot(Base): - __tablename__ = 'kots' + __tablename__ = "kots" - id = Column('id', GUID(), primary_key=True, default=uuid.uuid4) - voucher_id = Column('voucher_id', GUID(), ForeignKey('vouchers.id'), nullable=False, index=True) - code = Column('code', Numeric, nullable=False, unique=True) - food_table_id = Column('food_table_id', GUID(), ForeignKey('food_tables.id'), nullable=False) - date = Column('date', DateTime, nullable=False, index=True) - user_id = Column('user_id', GUID(), ForeignKey('users.id'), nullable=False) + id = Column("id", GUID(), primary_key=True, default=uuid.uuid4) + voucher_id = Column( + "voucher_id", GUID(), ForeignKey("vouchers.id"), nullable=False, index=True + ) + code = Column("code", Numeric, nullable=False, unique=True) + food_table_id = Column( + "food_table_id", GUID(), ForeignKey("food_tables.id"), nullable=False + ) + date = Column("date", DateTime, nullable=False, index=True) + user_id = Column("user_id", GUID(), ForeignKey("users.id"), nullable=False) - user = relationship('User', backref='kots') - food_table = relationship('FoodTable', backref='kots') + user = relationship("User", backref="kots") + food_table = relationship("FoodTable", backref="kots") - def __init__(self, voucher_id=None, food_table_id=None, date=None, user_id=None, id=None, dbsession=None): + def __init__( + self, + voucher_id=None, + food_table_id=None, + date=None, + user_id=None, + id=None, + dbsession=None, + ): self.id = id self.voucher_id = voucher_id self.code = dbsession.query(func.coalesce(func.max(Kot.code), 0) + 1).scalar() @@ -165,15 +227,17 @@ class Kot(Base): class Settlement(Base): - __tablename__ = 'settlements' - __table_args__ = (UniqueConstraint('voucher_id', 'settled'),) + __tablename__ = "settlements" + __table_args__ = (UniqueConstraint("voucher_id", "settled"),) - id = Column('id', GUID(), primary_key=True, default=uuid.uuid4) - voucher_id = Column('voucher_id', GUID(), ForeignKey('vouchers.id'), nullable=False, index=True) - settled = Column('settled', ForeignKey('settle_options.id'), nullable=False) - amount = Column('amount', Numeric, nullable=False) + id = Column("id", GUID(), primary_key=True, default=uuid.uuid4) + voucher_id = Column( + "voucher_id", GUID(), ForeignKey("vouchers.id"), nullable=False, index=True + ) + settled = Column("settled", ForeignKey("settle_options.id"), nullable=False) + amount = Column("amount", Numeric, nullable=False) - settle_option = relationship('SettleOption') + settle_option = relationship("SettleOption") def __init__(self, voucher_id=None, settled=None, amount=None, id=None): self.id = id @@ -183,14 +247,16 @@ class Settlement(Base): class Reprint(Base): - __tablename__ = 'reprints' + __tablename__ = "reprints" - id = Column('id', GUID(), primary_key=True, default=uuid.uuid4) - date = Column('date', DateTime, nullable=False, index=True) - voucher_id = Column('voucher_id', GUID(), ForeignKey('vouchers.id'), nullable=False, index=True) - user_id = Column('user_id', GUID(), ForeignKey('users.id'), nullable=False) + id = Column("id", GUID(), primary_key=True, default=uuid.uuid4) + date = Column("date", DateTime, nullable=False, index=True) + voucher_id = Column( + "voucher_id", GUID(), ForeignKey("vouchers.id"), nullable=False, index=True + ) + user_id = Column("user_id", GUID(), ForeignKey("users.id"), nullable=False) - user = relationship('User', backref='reprints') + user = relationship("User", backref="reprints") def __init__(self, voucher_id=None, user_id=None, id=None): self.id = id @@ -200,26 +266,38 @@ class Reprint(Base): class Inventory(Base): - __tablename__ = 'inventories' - __table_args__ = (UniqueConstraint('kot_id', 'product_id', 'is_happy_hour', 'price'),) + __tablename__ = "inventories" + __table_args__ = ( + UniqueConstraint("kot_id", "product_id", "is_happy_hour", "price"), + ) - id = Column('id', GUID(), primary_key=True, default=uuid.uuid4) - kot_id = Column('kot_id', GUID(), ForeignKey('kots.id'), nullable=False, index=True) - product_id = Column('product_id', GUID(), ForeignKey('products.id'), nullable=False) - quantity = Column('quantity', Numeric) - price = Column('price', Numeric) - is_happy_hour = Column('is_happy_hour', Boolean, nullable=False) - tax_rate = Column('tax_rate', Numeric) - tax_id = Column('tax_id', GUID(), ForeignKey('taxes.id'), nullable=False) - discount = Column('discount', Numeric) - sort_order = Column('sort_order', Numeric, nullable=False) + id = Column("id", GUID(), primary_key=True, default=uuid.uuid4) + kot_id = Column("kot_id", GUID(), ForeignKey("kots.id"), nullable=False, index=True) + product_id = Column("product_id", GUID(), ForeignKey("products.id"), nullable=False) + quantity = Column("quantity", Numeric) + price = Column("price", Numeric) + is_happy_hour = Column("is_happy_hour", Boolean, nullable=False) + tax_rate = Column("tax_rate", Numeric) + tax_id = Column("tax_id", GUID(), ForeignKey("taxes.id"), nullable=False) + discount = Column("discount", Numeric) + sort_order = Column("sort_order", Numeric, nullable=False) - kot = relationship('Kot', backref='inventories') - tax = relationship('Tax', foreign_keys=tax_id) - product = relationship('Product', backref='inventories') + kot = relationship("Kot", backref="inventories") + tax = relationship("Tax", foreign_keys=tax_id) + product = relationship("Product", backref="inventories") - def __init__(self, kot_id, product_id, quantity, price, discount, is_hh, tax_id, tax_rate, - sort_order): + def __init__( + self, + kot_id, + product_id, + quantity, + price, + discount, + is_hh, + tax_id, + tax_rate, + sort_order, + ): self.kot_id = kot_id self.product_id = product_id self.quantity = quantity @@ -236,27 +314,20 @@ class Inventory(Base): @effective_price.expression def effective_price(cls): - return case( - [(cls.is_happy_hour == True, 0)], - else_=cls.price - ) + return case([(cls.is_happy_hour == True, 0)], else_=cls.price) @hybrid_property def net(self): return self.effective_price * self.quantity * (1 - self.discount) @hybrid_property - def st_amount(self): - return self.net_taxable * self.service_tax_rate - - @hybrid_property - def vat_amount(self): - return self.net_taxable * self.vat_rate + def tax_amount(self): + return self.net_taxable * self.tax_rate @hybrid_property def amount(self): - return Decimal(self.net * (1 + self.service_tax_rate + self.vat_rate)) + return Decimal(self.net * (1 + self.tax_rate)) @amount.expression def amount(cls): - return cls.net * (1 + cls.service_tax_rate + cls.vat_rate) + return cls.net * (1 + cls.tax_rate) diff --git a/barker/routes.py b/barker/routes.py index b723180..ca16ee3 100644 --- a/barker/routes.py +++ b/barker/routes.py @@ -390,8 +390,7 @@ def includeme(config): config.add_route("sa_sale", "/SaleAnalysis/Sale.json") config.add_route("sa_settlements", "/SaleAnalysis/Settlements.json") - config.add_route("sa_st", "/SaleAnalysis/ServiceTax.json") - config.add_route("sa_vat", "/SaleAnalysis/Vat.json") + config.add_route("sa_tax", "/SaleAnalysis/Tax.json") config.add_route("voucher_reprint", "/ReprintVoucher/{id}.json") config.add_route("voucher_settle", "/Settle/{id}.json") diff --git a/barker/views/food_table.py b/barker/views/food_table.py index 3ee9a51..2f14091 100644 --- a/barker/views/food_table.py +++ b/barker/views/food_table.py @@ -122,41 +122,51 @@ def show_blank(request): request_method="GET", route_name="v1_tables_list", renderer="json", + request_param="r", permission="Authenticated", ) -def show_list(request): - active = request.GET.get("a", None) - list_ = request.dbsession.query(FoodTable) - if active is not None: - active = active == "true" - list_ = list_.filter(FoodTable.is_active == active) - list_ = list_.order_by(FoodTable.sort_order).all() +def show_running(request): + list_ = request.dbsession.query(FoodTable).filter(FoodTable.is_active == True).order_by(FoodTable.sort_order).all() food_tables = [] for item in list_: ft = { - "id": item.id, - "name": item.name, - "seats": item.seats, - "section": {"id": item.section_id, "name": item.section.name}, - "isActive": item.is_active, - "sortOrder": item.sort_order - } - if item.status is None: - ft["status"] = "" - else: + "id": item.id, + "name": item.name, + "seats": item.seats, + "section": {"id": item.section_id, "name": item.section.name}, + "isActive": item.is_active, + "sortOrder": item.sort_order + } + if item.status is not None: ft["status"] = item.status.status - if item.status.voucher is not None: - ft["voucherId"] = item.status.voucher_id - ft["pax"] = item.status.voucher.pax - ft["date"] = item.status.voucher.date.strftime("%d-%b-%Y %H:%M") - ft["amount"] = 12345 + ft["voucherId"] = item.status.voucher_id + ft["pax"] = item.status.voucher.pax + ft["date"] = item.status.voucher.date.strftime("%d-%b-%Y %H:%M") + ft["amount"] = 12345 if item.status.guest is not None: - ft["name"] = item.status.guest.customer.name + ft["guest"] = item.status.guest.customer.name food_tables.append(ft) return food_tables +@view_config( + request_method="GET", + route_name="v1_tables_list", + renderer="json", + permission="Authenticated", +) +def show_list(request): + return [{ + "id": item.id, + "name": item.name, + "seats": item.seats, + "section": {"id": item.section_id, "name": item.section.name}, + "isActive": item.is_active, + "sortOrder": item.sort_order + } for item in request.dbsession.query(FoodTable).order_by(FoodTable.sort_order).all()] + + @view_config( request_method="POST", route_name="v1_tables_list", diff --git a/barker/views/product.py b/barker/views/product.py index 8438498..938f272 100644 --- a/barker/views/product.py +++ b/barker/views/product.py @@ -194,12 +194,14 @@ def show_list_sale(request): products = [] for item in list_: if item.has_happy_hour: + p = product_info(item, request.dbsession) + p["hasHappyHour"] = False + products.append(p) i = product_info(item, request.dbsession) - i["hasHappyHour"] = False i["name"] = "H + H " + i["name"] - i["price"] = 0 products.append(i) - products.append(product_info(item, request.dbsession)) + else: + products.append(product_info(item, request.dbsession)) return products @@ -246,7 +248,11 @@ def product_info(item, dbsession): "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}, + "saleCategory": { + "id": item.sale_category_id, + "name": item.sale_category.name, + "tax": {"id": item.sale_category.tax_id, "name": item.sale_category.name}, + }, "price": item.price, "hasHappyHour": item.has_happy_hour, "isNotAvailable": item.is_not_available, diff --git a/barker/views/reports/sale_analysis.py b/barker/views/reports/sale_analysis.py index e8cab32..e709e11 100644 --- a/barker/views/reports/sale_analysis.py +++ b/barker/views/reports/sale_analysis.py @@ -72,40 +72,9 @@ def get_settlements(request): return info + [{'GroupType': 'Total', 'Amount': total}] -@view_config(request_method='GET', route_name='sa_st', renderer='json', permission=('Tax Analysis', 'Sales Analysis'), +@view_config(request_method='GET', route_name='sa_tax', renderer='json', permission=('Tax Analysis', 'Sales Analysis'), request_param=('s', 'f')) -def get_st(request): - start_date = datetime.datetime.strptime(request.GET['s'], '%d-%b-%Y %H:%M') - finish_date = datetime.datetime.strptime(request.GET['f'], '%d-%b-%Y %H:%M') - - if (datetime.date.today() - start_date.date()).days > 5 and 'Accounts Audit' not in request.effective_principals: - raise HTTPForbidden("Accounts Audit") - - amounts = request.dbsession.query( - Inventory.service_tax_rate, - func.coalesce(func.sum(Inventory.net_taxable), 0), - func.coalesce(func.sum(Inventory.st_amount), 0) - ).join(Voucher.kots).join(Kot.inventories).filter( - Voucher.date >= start_date, - Voucher.date <= finish_date, - Voucher.is_void == False, - Voucher.settlements.any(~Settlement.settled.in_([1, 4, 7, 8, 9, 10])) - ).group_by( - Inventory.service_tax_rate - ).order_by( - Inventory.service_tax_rate - ).all() - return [{ - 'Name': "Service Tax - {0:.2%}".format(i[0]), - 'TaxRate': i[0], - 'NetSale': i[1], - 'TaxAmount': i[2] - } for i in amounts] - - -@view_config(request_method='GET', route_name='sa_vat', renderer='json', permission=('Tax Analysis', 'Sales Analysis'), - request_param=('s', 'f')) -def get_vat(request): +def get_tax(request): start_date = datetime.datetime.strptime(request.GET['s'], '%d-%b-%Y %H:%M') finish_date = datetime.datetime.strptime(request.GET['f'], '%d-%b-%Y %H:%M') @@ -114,20 +83,20 @@ def get_vat(request): amounts = request.dbsession.query( Tax.name, - Inventory.vat_rate, + Inventory.tax_rate, func.coalesce(func.sum(Inventory.net_taxable), 0), - func.coalesce(func.sum(Inventory.vat_amount), 0) - ).join(Voucher.kots).join(Kot.inventories).join(Inventory.vat).filter( + func.coalesce(func.sum(Inventory.tax_amount), 0) + ).join(Voucher.kots).join(Kot.inventories).join(Inventory.tax).filter( Voucher.date >= start_date, Voucher.date <= finish_date, Voucher.is_void == False, Voucher.settlements.any(~Settlement.settled.in_([1, 4, 7, 8, 9, 10])) ).group_by( Tax.name, - Inventory.vat_rate + Inventory.tax_rate ).order_by( Tax.name, - Inventory.vat_rate + Inventory.tax_rate ).all() return [{ 'Name': "{0} - {1:.2%}".format(i[0], i[1]), diff --git a/barker/views/voucher/__init__.py b/barker/views/voucher/__init__.py index 8d09930..91da2e0 100644 --- a/barker/views/voucher/__init__.py +++ b/barker/views/voucher/__init__.py @@ -22,13 +22,13 @@ from barker.models import VoucherType, Settlement, SettleOption -def get_st_vat(st, vat, voucher_type): +def get_tax(tax, voucher_type): if voucher_type == VoucherType.STAFF.value: - return 0, 0 + return 0 elif voucher_type == VoucherType.NO_CHARGE.value: - return 0, 0 + return 0 else: # voucher_type in [REGULAR_BILL, TAKE_AWAY]: - return st, vat + return tax def get_settlements(voucher, dbsession): diff --git a/barker/views/voucher/save.py b/barker/views/voucher/save.py index 9fc9f05..16a6819 100644 --- a/barker/views/voucher/save.py +++ b/barker/views/voucher/save.py @@ -4,27 +4,46 @@ import transaction from pyramid.httpexceptions import HTTPForbidden from pyramid.view import view_config -from barker.models import Overview, Voucher, Kot, Inventory, InventoryModifier -from barker.views.voucher import get_st_vat, get_settlements +from barker.models import ( + Overview, + Voucher, + Kot, + Inventory, + InventoryModifier, + VoucherType, + Product, +) +from barker.views.voucher import get_tax, get_settlements from barker.views.voucher.show import voucher_info -@view_config(request_method="PUT", route_name="v1_vouchers_new", renderer="json", trans=True) +@view_config( + request_method="POST", route_name="v1_vouchers_new", renderer="json", trans=True +) def save(request): - update_table = request.GET["u"] + update_table = request.GET["u"] == "true" + voucher_type = VoucherType[request.GET["p"]] + guest_book_id = request.GET.get("g", None) + if guest_book_id is not None: + guest_book_id = uuid.UUID(guest_book_id) json = request.json_body - if not json["Printed"] and "Print Kot" not in request.effective_principals: + if not json["isPrinted"] and "Print Kot" not in request.effective_principals: raise HTTPForbidden("You are not allowed to print a kot") - if json["Printed"] and "Print Bill" not in request.effective_principals: + if json["isPrinted"] and "Print Bill" not in request.effective_principals: raise HTTPForbidden("You are not allowed to print bill") - item = save_voucher(json, request.dbsession) + item = save_voucher( + json, voucher_type, uuid.UUID(request.authenticated_userid), request.dbsession + ) if update_table: status = "printed" if item.is_printed else "running" item.status = Overview( - voucher_id=None, food_table_id=item.food_table_id, status=status + voucher_id=None, + food_table_id=item.food_table_id, + guest_book_id=guest_book_id, + status=status, ) request.dbsession.add(item.status) transaction.commit() @@ -32,42 +51,42 @@ def save(request): return voucher_info(item) -def save_voucher(json, dbsession): +def save_voucher(json, voucher_type, user_id, dbsession): item = Voucher( - json["Pax"], - json["Table"]["FoodTableID"], - json["Customer"]["CustomerID"], - json["Printed"], - json["VoucherType"], - json["User"]["UserID"], + json["pax"], + json["table"]["id"], + json["customer"]["id"] if "id" in json["customer"] else None, + json["isPrinted"], + voucher_type, + user_id, dbsession, ) dbsession.add(item) - for k in json["Kots"]: + for k in json["kots"]: kot = Kot( item.id, item.food_table_id, item.date, item.user_id, dbsession=dbsession ) item.kots.append(kot) dbsession.add(kot) - for index, i in enumerate(k["Inventories"]): - st, vat = get_st_vat(i["ServiceTaxRate"], i["VatRate"], json["VoucherType"]) + for index, i in enumerate(k["inventories"]): + product_id = uuid.UUID(i["product"]["id"]) + product = dbsession.query(Product).filter(Product.id == product_id).first() + tax_rate = get_tax(product.sale_category.tax.rate, voucher_type) inv = Inventory( kot.id, - uuid.UUID(i["ProductID"]), - i["Quantity"], - i["Price"], - i["Discount"], - i["IsHappyHour"], - i["ServiceTaxID"], - st, - i["VatID"], - vat, + product_id, + i["quantity"], + product.price, + i["discount"], + i["isHappyHour"], + product.sale_category.tax_id, + tax_rate, index, ) kot.inventories.append(inv) dbsession.add(inv) - for m in i["Modifiers"]: - mod = InventoryModifier(None, uuid.UUID(m["ModifierID"]), 0) + for m in i["modifiers"]: + mod = InventoryModifier(None, uuid.UUID(m["id"]), 0) inv.modifiers.append(mod) dbsession.add(mod) get_settlements(item, dbsession) diff --git a/barker/views/voucher/show.py b/barker/views/voucher/show.py index ffd9c0b..935b2dc 100644 --- a/barker/views/voucher/show.py +++ b/barker/views/voucher/show.py @@ -77,6 +77,8 @@ def show_for_table(request): table = request.dbsession.query(FoodTable).filter(FoodTable.id == table_id).first() if guest_id is not None: guest = request.dbsession.query(GuestBook).filter(GuestBook.id == guest_id).first() + else: + guest = None return voucher_blank(table, guest) @@ -90,12 +92,12 @@ def voucher_info(item): "lastEditDate": item.last_edit_date.strftime("%d-%b-%Y %H:%M:%S"), "billId": item.bill_id, "table": {"id": item.food_table_id, "name": item.food_table.name}, - "customer": {"id": item.customer_id, "name": item.customer.name}, + "customer": {"id": item.customer_id, "name": item.customer.name} if item.customer is not None else {}, "settlements": [], "narration": item.narration, "void": item.is_void, "voidReason": item.void_reason, - "printed": item.is_printed, + "isPrinted": item.is_printed, "voucherType": item.voucher_type, "kotId": item.kot_id, "kots": [ @@ -153,7 +155,8 @@ def voucher_blank(table, guest): return { "pax": table.seats if guest is None else guest.pax, "table": {"id": table.id, "name": table.name}, - "customer": {"id": guest.customer_id, "name": guest.customer.name}, + "customer": {"id": guest.customer_id, "name": guest.customer.name} if guest is not None else {}, + "isPrinted": False, "kots": [] } diff --git a/barker/views/voucher/update.py b/barker/views/voucher/update.py index 44609fa..7cea6a1 100644 --- a/barker/views/voucher/update.py +++ b/barker/views/voucher/update.py @@ -9,16 +9,16 @@ from sqlalchemy import func from barker.exceptions import ValidationFailure from barker.models import Voucher, Kot, Inventory, InventoryModifier, Overview -from barker.views.voucher import get_st_vat, get_settlements +from barker.views.voucher import get_tax, get_settlements from barker.views.voucher.show import voucher_info @view_config( - request_method="POST", route_name="v1_vouchers_id", renderer="json", trans=True + request_method="PUT", route_name="v1_vouchers_id", renderer="json", trans=True ) def update(request): now = datetime.now() - update_table = request.GET["u"] + update_table = request.GET["u"] == "true" json = request.json_body id = uuid.UUID(request.matchdict["id"]) item = request.dbsession.query(Voucher).filter(Voucher.id == id).first() @@ -64,9 +64,7 @@ def update(request): item.last_edit_date = now for k in item.kots: for i in k.inventories: - i.service_tax_rate, i.vat_rate = get_st_vat( - i.service_tax_rate, i.vat_rate, item.voucher_type - ) + i.tax_rate = get_tax(i.tax_rate, item.voucher_type) i.discount = next( Decimal(inv["Discount"]) for ko in json["Kots"] @@ -86,18 +84,16 @@ def update(request): item.kots.append(kot) request.dbsession.add(kot) for index, i in enumerate(k["Inventories"]): - st, vat = get_st_vat(i["ServiceTaxRate"], i["VatRate"], json["VoucherType"]) + tax_rate = get_tax(i["taxRate"], json["VoucherType"]) inv = Inventory( kot.id, - uuid.UUID(i["ProductID"]), - i["Quantity"], - i["Price"], - i["Discount"], - i["IsHappyHour"], - i["ServiceTaxID"], - st, - i["VatID"], - vat, + uuid.UUID(i["product"]["id"]), + i["quantity"], + i["price"], + i["discount"], + i["isHappyHour"], + i["tax"]["id"], + tax_rate, index, ) kot.inventories.append(inv) diff --git a/bookie/src/app/app.module.ts b/bookie/src/app/app.module.ts index 20c6822..4fe5c6d 100644 --- a/bookie/src/app/app.module.ts +++ b/bookie/src/app/app.module.ts @@ -1,5 +1,7 @@ import { BrowserModule } from '@angular/platform-browser'; -import { NgModule } from '@angular/core'; +import { LOCALE_ID, NgModule } from '@angular/core'; +import { registerLocaleData } from '@angular/common'; +import enIN from '@angular/common/locales/en-IN'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; @@ -18,9 +20,11 @@ import { LayoutModule } from '@angular/cdk/layout'; import { LogoutComponent } from './auth/logout/logout.component'; import { LoginComponent } from './auth/login/login.component'; import { HomeComponent } from './home/home.component'; -import {CoreModule} from './core/core.module'; -import {ReactiveFormsModule} from '@angular/forms'; -import {SharedModule} from './shared/shared.module'; +import { CoreModule } from './core/core.module'; +import { ReactiveFormsModule } from '@angular/forms'; +import { SharedModule } from './shared/shared.module'; + +registerLocaleData(enIN); @NgModule({ declarations: [ @@ -48,7 +52,9 @@ import {SharedModule} from './shared/shared.module'; CoreModule, SharedModule ], - providers: [], + providers: [ + {provide: LOCALE_ID, useValue: 'en-IN'}, + ], bootstrap: [AppComponent] }) export class AppModule { } diff --git a/bookie/src/app/core/http-auth-interceptor.ts b/bookie/src/app/core/http-auth-interceptor.ts index 2d8b99f..0f0c108 100644 --- a/bookie/src/app/core/http-auth-interceptor.ts +++ b/bookie/src/app/core/http-auth-interceptor.ts @@ -25,7 +25,9 @@ export class HttpAuthInterceptor implements HttpInterceptor { width: '250px', data: { title: 'Logged out!', - content: 'You have been logged out.\nYou can press Cancel to stay on page and login in another tab to resume here, or you can press Ok to navigate to the login page.' + content: 'You have been logged out.\n' + + 'You can press Cancel to stay on page and login in another tab to resume here,' + + ' or you can press Ok to navigate to the login page.' } }); dialogRef.afterClosed().subscribe((result: boolean) => { diff --git a/bookie/src/app/guest-book/guest-book-detail/guest-book-detail.component.ts b/bookie/src/app/guest-book/guest-book-detail/guest-book-detail.component.ts index c32f4c6..6a51fa1 100644 --- a/bookie/src/app/guest-book/guest-book-detail/guest-book-detail.component.ts +++ b/bookie/src/app/guest-book/guest-book-detail/guest-book-detail.component.ts @@ -77,7 +77,7 @@ export class GuestBookDetailComponent implements OnInit, AfterViewInit { this.item.company = formModel.company; this.item.name = formModel.name; this.item.phone = formModel.phone; - this.item.pax = parseInt(formModel.pax); + this.item.pax = parseInt(formModel.pax, 10); this.item.address = formModel.address; return this.item; } diff --git a/bookie/src/app/menu-category/menu-categories.module.ts b/bookie/src/app/menu-category/menu-categories.module.ts index 3ac7e47..c623020 100644 --- a/bookie/src/app/menu-category/menu-categories.module.ts +++ b/bookie/src/app/menu-category/menu-categories.module.ts @@ -1,7 +1,7 @@ import { NgModule} from '@angular/core'; import { CommonModule } from '@angular/common'; -import { MenuCategoryListComponent} from './menu-category-list/menu-category-list.component'; +import { MenuCategoryListComponent } from './menu-category-list/menu-category-list.component'; import { MenuCategoryDetailComponent } from './menu-category-detail/menu-category-detail.component'; import { MenuCategoriesRoutingModule } from './menu-categories-routing.module'; import { MatButtonModule } from '@angular/material/button'; diff --git a/bookie/src/app/sale-category/sale-categories.module.ts b/bookie/src/app/sale-category/sale-categories.module.ts index 6464ce6..d3fbcce 100644 --- a/bookie/src/app/sale-category/sale-categories.module.ts +++ b/bookie/src/app/sale-category/sale-categories.module.ts @@ -1,7 +1,7 @@ import { NgModule} from '@angular/core'; import { CommonModule } from '@angular/common'; -import { SaleCategoryListComponent} from './sale-category-list/sale-category-list.component'; +import { SaleCategoryListComponent } from './sale-category-list/sale-category-list.component'; import { SaleCategoryDetailComponent } from './sale-category-detail/sale-category-detail.component'; import { SaleCategoriesRoutingModule } from './sale-categories-routing.module'; import { MatButtonModule } from '@angular/material/button'; diff --git a/bookie/src/app/sales/bill.service.ts b/bookie/src/app/sales/bill.service.ts index f0984d5..aed0c13 100644 --- a/bookie/src/app/sales/bill.service.ts +++ b/bookie/src/app/sales/bill.service.ts @@ -1,49 +1,78 @@ import { Injectable } from '@angular/core'; import { MatDialog } from '@angular/material'; -import { BehaviorSubject } from "rxjs"; +import { BehaviorSubject } from 'rxjs'; import { Product } from '../core/product'; import { ModifiersComponent } from './modifiers/modifiers.component'; import { ModifierCategoryService } from '../modifier-categories/modifier-category.service'; -import { ModifierCategory } from "../core/modifier-category"; +import { ModifierCategory } from '../core/modifier-category'; +import { Bill, Inventory, Kot, PrintType } from './bills/bill'; +import {VoucherService} from './bills/voucher.service'; @Injectable() export class BillService { public dataObs; public data; + private bill; constructor( private dialog: MatDialog, + private ser: VoucherService, private modifierCategoryService: ModifierCategoryService ) { this.data = []; this.dataObs = new BehaviorSubject(this.data); } - loadData(d: any): void { - console.log("data loaded"); - this.data = d; - this.data.push({isKot: true, newKot: true, info: "== New Kot =="}) + loadData(bill: Bill): void { + this.bill = bill; + const view = this.bill.kots.map(k => { + return [{ + isKot: true, + info: `Kot: ${k.code} / ${k.date} (${k.user.name}) ` + }, ...k.inventories.map(i => { + return { + id: i.id, + isKot: false, + product: i.product, + productId: i.product.id, + isHappyHour: i.isHappyHour, + isPrinted: true, + info: `${i.product.name} (${i.product.units}) @ ${i.price}`, + quantity: i.quantity, + discount: i.discount, + taxRate: i.taxRate, + tax: i.tax, + modifiers: i.modifiers + }; + })]; + }); + this.data = view.reduce((a, c) => a.concat(c) , []); + this.data.push({isKot: true, newKot: true, info: '== New Kot =='}); this.dataObs.next(this.data); } addProduct(product: Product): void { - let old = this.data.find(x=> !x.isKot && x.productId == product.id && x.isHappyHour == product.hasHappyHour); + const old = this.data.find(x => !x.isKot && x.productId === product.id && x.isHappyHour === product.hasHappyHour); if (old !== undefined) { old.quantity += 1; } else { - let item = { + const item = { isKot: false, product: product, productId: product.id, isHappyHour: product.hasHappyHour, info: `${product.name} (${product.units}) @ ${product.price}`, + price: product.price, quantity: 1, + discount: 0, + taxRate: product.saleCategory.tax.rate, + tax: product.saleCategory.tax, modifiers: [] }; this.data.push(item); this.modifierCategoryService.listIsActiveOfProduct(product.id).subscribe(result => { if (result.reduce((a: any, c: ModifierCategory) => { - return a + c.minimum + return a + c.minimum; }, 0)) { this.showModifier(item); } @@ -76,8 +105,9 @@ export class BillService { this.dataObs.next(this.data); } - quantity(item: any): void { - + quantity(item: any, quantity: number): void { + item.quantity = quantity; + this.dataObs.next(this.data); } subtractOne(item: any): void { @@ -98,4 +128,28 @@ export class BillService { this.showModifier(item); } + printKot(guest_book_id: string): void { + const nk = new Kot({ + inventories: this.data.filter(x => !x.isKot && !x.isPrinted).map(y => new Inventory({ + product: y.product, + quantity: y.quantity, + price: y.price, + isHappyHour: y.isHappyHour, + discount: y.discount, + modifiers: y.modifiers, + taxRate: y.taxRate, + tax: y.tax + })) + }); + let item = JSON.parse(JSON.stringify(this.bill)) + item.kots.push(nk); + this.ser.saveOrUpdate(item, PrintType.Kot, guest_book_id, true).subscribe(x => + console.log(x) + ); + } + + printBill(): boolean { + return false; + } + } diff --git a/bookie/src/app/sales/bills/bill-resolver.service.ts b/bookie/src/app/sales/bills/bill-resolver.service.ts index a6f93c2..6546160 100644 --- a/bookie/src/app/sales/bills/bill-resolver.service.ts +++ b/bookie/src/app/sales/bills/bill-resolver.service.ts @@ -1,15 +1,15 @@ import { Injectable } from '@angular/core'; -import { ActivatedRouteSnapshot, Resolve, Router, RouterStateSnapshot } from '@angular/router'; +import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router'; import { Observable } from 'rxjs/internal/Observable'; -import { VoucherService } from "./voucher.service"; -import { Bill } from "./bill"; +import { VoucherService } from './voucher.service'; +import { Bill } from './bill'; @Injectable({ providedIn: 'root' }) export class BillResolver implements Resolve { - constructor(private ser: VoucherService, private router: Router) { + constructor(private ser: VoucherService) { } resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable { diff --git a/bookie/src/app/sales/bills/bill.ts b/bookie/src/app/sales/bills/bill.ts index f649bb6..6ff25d7 100644 --- a/bookie/src/app/sales/bills/bill.ts +++ b/bookie/src/app/sales/bills/bill.ts @@ -7,7 +7,6 @@ import {Modifier} from '../../core/modifier'; export class Inventory { id: string; - sortOrder: number; product: Product; quantity: number; price: number; @@ -16,14 +15,23 @@ export class Inventory { tax: Tax; discount: number; modifiers: Modifier[]; + sortOrder: number; + + public constructor(init?: Partial) { + Object.assign(this, init); + } } export class Kot { id: string; - serial: number; + code: number; date: string; user: User; inventories: Inventory[]; + + public constructor(init?: Partial) { + Object.assign(this, init); + } } export class Bill { @@ -43,4 +51,16 @@ export class Bill { serial: number; kots: Kot[]; reprints: any[]; + + public constructor(init?: Partial) { + Object.assign(this, init); + } } + +export enum PrintType { + Kot = 'KOT', + Bill = 'BILL', + NoCharge = 'NO_CHARGE', + Staff = 'STAFF' +} + diff --git a/bookie/src/app/sales/bills/bills.component.css b/bookie/src/app/sales/bills/bills.component.css index 9c2baa8..154032d 100644 --- a/bookie/src/app/sales/bills/bills.component.css +++ b/bookie/src/app/sales/bills/bills.component.css @@ -1,12 +1,10 @@ .kot { - background-color: hotpink; + background-color: lightblue; } + .printed { background-color: lightpink; } -.new-kot { - background-color: lightblue; -} .square-button { min-width: 150px; diff --git a/bookie/src/app/sales/bills/bills.component.html b/bookie/src/app/sales/bills/bills.component.html index 0026020..a9ab087 100644 --- a/bookie/src/app/sales/bills/bills.component.html +++ b/bookie/src/app/sales/bills/bills.component.html @@ -6,7 +6,7 @@ - + {{row.info}} @@ -18,7 +18,7 @@ Quantity - + @@ -38,8 +38,7 @@ - + diff --git a/bookie/src/app/sales/bills/bills.component.ts b/bookie/src/app/sales/bills/bills.component.ts index 10c87c8..80b2957 100644 --- a/bookie/src/app/sales/bills/bills.component.ts +++ b/bookie/src/app/sales/bills/bills.component.ts @@ -1,8 +1,10 @@ import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; -import {Bill, Inventory, Kot} from './bill'; -import {BillsDataSource} from './bills-datasource'; -import {BillService} from "../bill.service"; +import { Bill } from './bill'; +import { BillsDataSource } from './bills-datasource'; +import { BillService } from '../bill.service'; +import { QuantityComponent } from '../quantity/quantity.component'; +import { MatDialog } from '@angular/material'; @Component({ selector: 'app-bills', @@ -17,40 +19,18 @@ export class BillsComponent implements OnInit { constructor( private route: ActivatedRoute, + private dialog: MatDialog, private bs: BillService ) { } ngOnInit() { - console.log("ds set") - this.dataSource = new BillsDataSource(this.bs.dataObs); this.route.data .subscribe((data: { item: Bill }) => { - this.updateView(data.item); + this.item = data.item; + this.bs.loadData(data.item); }); - } - - updateView(item) { - this.item = item; - let view = item.kots.map(k => { - return [{ - isKot: true, - }, ...k.inventories.map(i => { - return { - id: i.id, - isKot: false, - product: i.product, - productId: i.product.id, - isHappyHour: i.isHappyHour, - isPrinted: true, - info: `${i.product.name} (${i.product.units}) @ ${i.price}`, - quantity: 1, - modifiers: i.modifiers - } - })] - }); - view = view.reduce((a, c) => {return a.concat(c)} , []); - this.bs.loadData(view); + this.dataSource = new BillsDataSource(this.bs.dataObs); } addOne(item: any): void { @@ -58,7 +38,17 @@ export class BillsComponent implements OnInit { } quantity(item: any): void { - this.bs.quantity(item); + const dialogRef = this.dialog.open(QuantityComponent, { + // width: '750px', + data: item.quantity + }); + + dialogRef.afterClosed().subscribe((result: boolean | number) => { + if (!result) { + return; + } + this.bs.quantity(item, result as number); + }); } subtractOne(item: any): void { diff --git a/bookie/src/app/sales/bills/voucher.service.ts b/bookie/src/app/sales/bills/voucher.service.ts index ee9b11d..385b59f 100644 --- a/bookie/src/app/sales/bills/voucher.service.ts +++ b/bookie/src/app/sales/bills/voucher.service.ts @@ -3,7 +3,7 @@ import { Observable } from 'rxjs/internal/Observable'; import { catchError } from 'rxjs/operators'; import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http'; import { ErrorLoggerService } from '../../core/error-logger.service'; -import {Bill} from "./bill"; +import { Bill, PrintType } from './bill'; const httpOptions = { headers: new HttpHeaders({'Content-Type': 'application/json'}) @@ -46,25 +46,33 @@ export class VoucherService { ); } - save(voucher: Bill): Observable { - return >this.http.post(`${url}/new`, voucher, httpOptions) + save(voucher: Bill, printType: PrintType, guest_book_id: string, updateTable: boolean): Observable { + const options = {params: new HttpParams().set('p', printType).set('u', updateTable.toString())}; + if (guest_book_id !== null) { + options.params = options.params.set('g', guest_book_id) + } + return >this.http.post(`${url}/new`, voucher, options) .pipe( catchError(this.log.handleError(serviceName, 'save')) ); } - update(voucher: Bill): Observable { - return >this.http.put(`${url}/${voucher.id}`, voucher, httpOptions) + update(voucher: Bill, printType: PrintType, guest_book_id: string, updateTable: boolean): Observable { + const options = {params: new HttpParams().set('p', printType).set('u', updateTable.toString())}; + if (guest_book_id !== null) { + options.params = options.params.set('g', guest_book_id) + } + return >this.http.put(`${url}/${voucher.id}`, voucher, options) .pipe( catchError(this.log.handleError(serviceName, 'update')) ); } - saveOrUpdate(voucher: Bill): Observable { + saveOrUpdate(voucher: Bill, printType: PrintType, guest_book_id: string, updateTable: boolean): Observable { if (!voucher.id) { - return this.save(voucher); + return this.save(voucher, printType, guest_book_id, updateTable); } else { - return this.update(voucher); + return this.update(voucher, printType, guest_book_id, updateTable); } } } diff --git a/bookie/src/app/sales/home/sales-home.component.css b/bookie/src/app/sales/home/sales-home.component.css index 853dc56..fb099a5 100644 --- a/bookie/src/app/sales/home/sales-home.component.css +++ b/bookie/src/app/sales/home/sales-home.component.css @@ -2,4 +2,19 @@ min-width: 150px; max-width: 150px; min-height: 150px; + max-height: 150px; + cursor: pointer; + margin: 20px; +} +.item-name { + text-align: center; + padding: 0.5rem; +} + +.center { + text-align: center; +} + +.warn { + background-color: red; } diff --git a/bookie/src/app/sales/home/sales-home.component.html b/bookie/src/app/sales/home/sales-home.component.html index 36f7048..26b22d7 100644 --- a/bookie/src/app/sales/home/sales-home.component.html +++ b/bookie/src/app/sales/home/sales-home.component.html @@ -1,5 +1,18 @@ - - - - - +
+ +

Add Product

+
+ +

Print KOT

+
+ +

Print Bill

+
+ +

Back to Tables

+
+ +

Receive Payment

+
+
diff --git a/bookie/src/app/sales/home/sales-home.component.ts b/bookie/src/app/sales/home/sales-home.component.ts index f1cea5e..85d92ab 100644 --- a/bookie/src/app/sales/home/sales-home.component.ts +++ b/bookie/src/app/sales/home/sales-home.component.ts @@ -1,6 +1,8 @@ -import {Component, OnInit} from '@angular/core'; -import {Subject} from 'rxjs'; -import {AuthService} from '../../auth/auth.service'; +import { Component, OnInit } from '@angular/core'; +import { Subject } from 'rxjs'; +import { AuthService } from '../../auth/auth.service'; +import { BillService } from '../bill.service'; +import { ActivatedRoute } from "@angular/router"; @Component({ selector: 'app-sales-home', @@ -10,7 +12,7 @@ import {AuthService} from '../../auth/auth.service'; export class SalesHomeComponent implements OnInit { public nameObject = new Subject(); - constructor(private auth: AuthService) { + constructor(private route: ActivatedRoute, private auth: AuthService, private bs: BillService) { } ngOnInit() { @@ -22,4 +24,16 @@ export class SalesHomeComponent implements OnInit { } }); } + + printKot() { + let guestBookId = null; + if (this.route.snapshot.queryParamMap.has("guest")) { + guestBookId = this.route.snapshot.queryParamMap.get("guest"); + } + this.bs.printKot(guestBookId); + } + + printBill() { + this.bs.printBill(); + } } diff --git a/bookie/src/app/sales/menu-categories/menu-categories.component.css b/bookie/src/app/sales/menu-categories/menu-categories.component.css index 853dc56..fb099a5 100644 --- a/bookie/src/app/sales/menu-categories/menu-categories.component.css +++ b/bookie/src/app/sales/menu-categories/menu-categories.component.css @@ -2,4 +2,19 @@ min-width: 150px; max-width: 150px; min-height: 150px; + max-height: 150px; + cursor: pointer; + margin: 20px; +} +.item-name { + text-align: center; + padding: 0.5rem; +} + +.center { + text-align: center; +} + +.warn { + background-color: red; } diff --git a/bookie/src/app/sales/menu-categories/menu-categories.component.html b/bookie/src/app/sales/menu-categories/menu-categories.component.html index 538f6da..cb36bcb 100644 --- a/bookie/src/app/sales/menu-categories/menu-categories.component.html +++ b/bookie/src/app/sales/menu-categories/menu-categories.component.html @@ -1,7 +1,12 @@ - - + +

{{item.name}}

+
+ +

Back

+
diff --git a/bookie/src/app/sales/menu-categories/menu-categories.component.ts b/bookie/src/app/sales/menu-categories/menu-categories.component.ts index 6096e9b..c4ee31b 100644 --- a/bookie/src/app/sales/menu-categories/menu-categories.component.ts +++ b/bookie/src/app/sales/menu-categories/menu-categories.component.ts @@ -1,5 +1,4 @@ import { Component, OnInit } from '@angular/core'; -import { Location } from '@angular/common'; import { ActivatedRoute } from '@angular/router'; import { MenuCategory } from '../../core/menu-category'; @@ -11,10 +10,7 @@ import { MenuCategory } from '../../core/menu-category'; export class MenuCategoriesComponent implements OnInit { list: MenuCategory[]; - constructor( - private route: ActivatedRoute, - private location: Location, - ) { + constructor(private route: ActivatedRoute) { } ngOnInit() { @@ -24,8 +20,4 @@ export class MenuCategoriesComponent implements OnInit { }); } - goBack(): void { - this.location.back(); - } - } diff --git a/bookie/src/app/sales/modifiers/modifiers.component.css b/bookie/src/app/sales/modifiers/modifiers.component.css index 853dc56..add4d3a 100644 --- a/bookie/src/app/sales/modifiers/modifiers.component.css +++ b/bookie/src/app/sales/modifiers/modifiers.component.css @@ -2,4 +2,6 @@ min-width: 150px; max-width: 150px; min-height: 150px; + cursor: pointer; + margin: 20px; } diff --git a/bookie/src/app/sales/modifiers/modifiers.component.ts b/bookie/src/app/sales/modifiers/modifiers.component.ts index 4512b29..5677d63 100644 --- a/bookie/src/app/sales/modifiers/modifiers.component.ts +++ b/bookie/src/app/sales/modifiers/modifiers.component.ts @@ -23,7 +23,7 @@ export class ModifiersComponent { } select(m: Modifier) { - let index = this.selectedIds.indexOf(m.id); + const index = this.selectedIds.indexOf(m.id); if (index === -1) { this.selected.push(m); } else { diff --git a/bookie/src/app/sales/products/products.component.css b/bookie/src/app/sales/products/products.component.css index 853dc56..fb099a5 100644 --- a/bookie/src/app/sales/products/products.component.css +++ b/bookie/src/app/sales/products/products.component.css @@ -2,4 +2,19 @@ min-width: 150px; max-width: 150px; min-height: 150px; + max-height: 150px; + cursor: pointer; + margin: 20px; +} +.item-name { + text-align: center; + padding: 0.5rem; +} + +.center { + text-align: center; +} + +.warn { + background-color: red; } diff --git a/bookie/src/app/sales/products/products.component.html b/bookie/src/app/sales/products/products.component.html index ad8e149..ec08885 100644 --- a/bookie/src/app/sales/products/products.component.html +++ b/bookie/src/app/sales/products/products.component.html @@ -1,7 +1,11 @@ - - + +

{{item.name}}

+
+ +

Back

+
diff --git a/bookie/src/app/sales/products/products.component.ts b/bookie/src/app/sales/products/products.component.ts index e2f6aab..62826f7 100644 --- a/bookie/src/app/sales/products/products.component.ts +++ b/bookie/src/app/sales/products/products.component.ts @@ -1,5 +1,4 @@ import { Component, OnInit } from '@angular/core'; -import { Location } from '@angular/common'; import { ActivatedRoute } from '@angular/router'; import { Product } from '../../core/product'; import { BillService } from '../bill.service'; @@ -12,11 +11,7 @@ import { BillService } from '../bill.service'; export class ProductsComponent implements OnInit { list: Product[]; - constructor( - private route: ActivatedRoute, - private location: Location, - private bs: BillService - ) { + constructor(private route: ActivatedRoute, private bs: BillService) { } ngOnInit() { @@ -30,8 +25,4 @@ export class ProductsComponent implements OnInit { this.bs.addProduct(product); } - goBack(): void { - this.location.back(); - } - } diff --git a/bookie/src/app/sales/quantity/quantity.component.css b/bookie/src/app/sales/quantity/quantity.component.css new file mode 100644 index 0000000..e69de29 diff --git a/bookie/src/app/sales/quantity/quantity.component.html b/bookie/src/app/sales/quantity/quantity.component.html new file mode 100644 index 0000000..a3526f8 --- /dev/null +++ b/bookie/src/app/sales/quantity/quantity.component.html @@ -0,0 +1,17 @@ +
+
+
+ + Quantity + + +
+
+
+
+ + +
+ diff --git a/bookie/src/app/sales/quantity/quantity.component.spec.ts b/bookie/src/app/sales/quantity/quantity.component.spec.ts new file mode 100644 index 0000000..77932ff --- /dev/null +++ b/bookie/src/app/sales/quantity/quantity.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { QuantityComponent } from './quantity.component'; + +describe('QuantityComponent', () => { + let component: QuantityComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ QuantityComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(QuantityComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/bookie/src/app/sales/quantity/quantity.component.ts b/bookie/src/app/sales/quantity/quantity.component.ts new file mode 100644 index 0000000..dabae71 --- /dev/null +++ b/bookie/src/app/sales/quantity/quantity.component.ts @@ -0,0 +1,37 @@ +import { Component, Inject, OnInit } from '@angular/core'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material'; +import { FormBuilder, FormGroup } from '@angular/forms'; + +@Component({ + selector: 'app-quantity', + templateUrl: './quantity.component.html', + styleUrls: ['./quantity.component.css'] +}) +export class QuantityComponent implements OnInit { + form: FormGroup; + + constructor( + public dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) public data: number, + private fb: FormBuilder, + ) { + this.createForm(); + } + + ngOnInit() { + this.form.setValue({ + quantity: this.data + }); + } + + createForm() { + this.form = this.fb.group({ + quantity: '' + }); + } + + accept(): void { + const quantity = this.form.value.quantity; + this.dialogRef.close(quantity); + } +} diff --git a/bookie/src/app/sales/running-tables/running-tables.component.css b/bookie/src/app/sales/running-tables/running-tables.component.css index fbdded4..f08b6b5 100644 --- a/bookie/src/app/sales/running-tables/running-tables.component.css +++ b/bookie/src/app/sales/running-tables/running-tables.component.css @@ -11,6 +11,7 @@ max-width: 150px; min-height: 150px; max-height: 150px; + cursor: pointer; margin: 20px; } .item-name { diff --git a/bookie/src/app/sales/running-tables/running-tables.component.html b/bookie/src/app/sales/running-tables/running-tables.component.html index 3152202..8ffdc51 100644 --- a/bookie/src/app/sales/running-tables/running-tables.component.html +++ b/bookie/src/app/sales/running-tables/running-tables.component.html @@ -3,13 +3,15 @@ Running Tables - -

{{table.name}}

+ + +

{{table.name}}

+ {{table.guest}} {{table.pax || 0}} / {{table.seats}} Seats {{table.date}} - {{table.amount}} + {{table.amount | currency:'INR'}}
diff --git a/bookie/src/app/sales/running-tables/running-tables.component.ts b/bookie/src/app/sales/running-tables/running-tables.component.ts index 5185fcd..d1abcaa 100644 --- a/bookie/src/app/sales/running-tables/running-tables.component.ts +++ b/bookie/src/app/sales/running-tables/running-tables.component.ts @@ -21,11 +21,11 @@ export class RunningTablesComponent implements OnInit { } navigateToBill(table: Table): void { - let qp = {table: table.id}; + const qp = {table: table.id}; if (table.voucherId) { - qp["voucher"] = table.voucherId; + qp['voucher'] = table.voucherId; } - let navigationExtras: NavigationExtras = { + const navigationExtras: NavigationExtras = { queryParams: qp, queryParamsHandling: 'merge', preserveFragment: true diff --git a/bookie/src/app/sales/sales.module.ts b/bookie/src/app/sales/sales.module.ts index 56aeed2..6a349d3 100644 --- a/bookie/src/app/sales/sales.module.ts +++ b/bookie/src/app/sales/sales.module.ts @@ -1,16 +1,21 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; +import { ReactiveFormsModule } from '@angular/forms'; import { MatBadgeModule } from '@angular/material/badge'; import { MatButtonModule } from '@angular/material/button'; import { MatButtonToggleModule } from '@angular/material/button-toggle'; import { MatCardModule } from '@angular/material/card'; import { MatChipsModule } from '@angular/material/chips'; import { MatDialogModule } from '@angular/material/dialog'; +import { MatDividerModule } from '@angular/material/divider'; import { MatIconModule } from '@angular/material/icon'; +import { MatInputModule } from '@angular/material/input'; +import { MatRippleModule } from '@angular/material'; import { MatTableModule } from '@angular/material/table'; import { MatTabsModule } from '@angular/material/tabs'; import { FlexLayoutModule } from '@angular/flex-layout'; +import { SharedModule } from "../shared/shared.module"; import { SalesRoutingModule } from './sales-routing.module'; import { RunningTablesComponent } from './running-tables/running-tables.component'; import { MenuCategoriesComponent } from './menu-categories/menu-categories.component'; @@ -19,6 +24,7 @@ import { ModifiersComponent } from './modifiers/modifiers.component'; import { BillsComponent } from './bills/bills.component'; import { SalesHomeComponent } from './home/sales-home.component'; import { BillService } from './bill.service'; +import { QuantityComponent } from './quantity/quantity.component'; @NgModule({ providers: [ @@ -30,24 +36,31 @@ import { BillService } from './bill.service'; ProductsComponent, ModifiersComponent, BillsComponent, - SalesHomeComponent + SalesHomeComponent, + QuantityComponent ], imports: [ CommonModule, FlexLayoutModule, + ReactiveFormsModule, MatBadgeModule, MatButtonModule, MatButtonToggleModule, MatCardModule, MatChipsModule, MatDialogModule, + MatDividerModule, MatIconModule, + MatInputModule, + MatRippleModule, MatTableModule, MatTabsModule, + SharedModule, SalesRoutingModule ], entryComponents: [ - ModifiersComponent + ModifiersComponent, + QuantityComponent ] }) export class SalesModule { } diff --git a/bookie/src/app/shared/accounting.pipe.ts b/bookie/src/app/shared/accounting.pipe.ts index 33136c4..19b8212 100644 --- a/bookie/src/app/shared/accounting.pipe.ts +++ b/bookie/src/app/shared/accounting.pipe.ts @@ -1,4 +1,4 @@ -import {Pipe, PipeTransform} from '@angular/core'; +import { Pipe, PipeTransform } from '@angular/core'; @Pipe({ name: 'accounting' diff --git a/bookie/src/app/tables/table.service.ts b/bookie/src/app/tables/table.service.ts index 5a6696f..7f4c61f 100644 --- a/bookie/src/app/tables/table.service.ts +++ b/bookie/src/app/tables/table.service.ts @@ -35,7 +35,7 @@ export class TableService { } running(): Observable { - const options = {params: new HttpParams().set('a', 'true')}; + const options = {params: new HttpParams().set('r', '')}; return >this.http.get(url, options) .pipe( catchError(this.log.handleError(serviceName, 'running')) diff --git a/bookie/src/app/tables/tables.module.ts b/bookie/src/app/tables/tables.module.ts index dcd8c4c..143b036 100644 --- a/bookie/src/app/tables/tables.module.ts +++ b/bookie/src/app/tables/tables.module.ts @@ -13,7 +13,7 @@ import { MatTableModule } from '@angular/material/table'; import { CdkTableModule } from '@angular/cdk/table'; import { DragDropModule } from '@angular/cdk/drag-drop'; import { FlexLayoutModule } from '@angular/flex-layout'; -import { TableListComponent } from './table-list/table-list.component'; +import { TableListComponent } from './table-list/table-list.component'; import { TableDetailComponent } from './table-detail/table-detail.component'; import { TableRoutingModule } from './tables-routing.module';