Move / Merge KOT Done.

We need to check if it is the only kot and raise an error if it is.
Split Bill Done
This commit is contained in:
Amritanshu
2019-08-18 01:05:59 +05:30
parent dcaf23b390
commit e697631cd4
15 changed files with 539 additions and 295 deletions

View File

@ -350,6 +350,9 @@ def includeme(config):
config.add_route("v1_vouchers_new", "/v1/vouchers/new") config.add_route("v1_vouchers_new", "/v1/vouchers/new")
config.add_route("v1_vouchers_id", "/v1/vouchers/{id}") config.add_route("v1_vouchers_id", "/v1/vouchers/{id}")
config.add_route("v1_move_table", "/v1/move-table")
config.add_route("v1_move_kot", "/v1/move-kot")
# Done till here # Done till here
config.add_route("customer", "/Customer.json") config.add_route("customer", "/Customer.json")
@ -365,16 +368,10 @@ def includeme(config):
config.add_route("machine_location_id", "/MachineLocation/{id}.json") config.add_route("machine_location_id", "/MachineLocation/{id}.json")
config.add_route("merge_kot", "/MergeKot.json") config.add_route("merge_kot", "/MergeKot.json")
config.add_route("merge_table", "/MergeTable.json")
config.add_route("move_kot", "/MoveKot.json") config.add_route("move_kot", "/MoveKot.json")
config.add_route("permission_list", "/Permissions.json") config.add_route("permission_list", "/Permissions.json")
config.add_route("print_location", "/PrintLocation.json")
config.add_route("print_location_list", "/PrintLocations.json")
config.add_route("print_location_id", "/PrintLocation/{id}.json")
config.add_route("v1_bills_new", "/v1/bills/new") config.add_route("v1_bills_new", "/v1/bills/new")
config.add_route("v1_bills_id", "/v1/bills/{id}") config.add_route("v1_bills_id", "/v1/bills/{id}")
@ -392,8 +389,6 @@ def includeme(config):
config.add_route("sa_tax", "/SaleAnalysis/Tax.json") config.add_route("sa_tax", "/SaleAnalysis/Tax.json")
config.add_route("voucher_reprint", "/ReprintVoucher/{id}.json") config.add_route("voucher_reprint", "/ReprintVoucher/{id}.json")
config.add_route("voucher_split", "/Split/{id}.json")
config.add_route("voucher_void", "/Void/{id}.json")
config.add_route("api_lock_info", "/api/LockInfo") config.add_route("api_lock_info", "/api/LockInfo")
config.add_route("api_maintenance", "/api/Maintenance") config.add_route("api_maintenance", "/api/Maintenance")

View File

@ -1,4 +1,9 @@
from barker.models import VoucherType, Settlement, SettleOption import uuid
from sqlalchemy import func
from barker.exceptions import ValidationFailure
from barker.models import VoucherType, Settlement, SettleOption, Voucher, Overview, GuestBook
from barker.models.validation_exception import ValidationError from barker.models.validation_exception import ValidationError
@ -11,45 +16,81 @@ def get_tax(tax, voucher_type):
raise ValidationError("Unexpected Voucher Type") raise ValidationError("Unexpected Voucher Type")
def get_settlements(voucher, dbsession): def get_bill_id(voucher_type, dbsession):
amount = voucher.amount if voucher_type == VoucherType.KOT:
so_amount = [s for s in voucher.settlements if s.settled == SettleOption.AMOUNT()] return None
if len(so_amount) == 1: return (
so_amount[0].amount = amount dbsession.query(func.coalesce(func.max(Voucher.bill_id), 0) + 1)
else: .filter(Voucher.voucher_type == voucher_type.value)
s = Settlement(voucher.id, SettleOption.AMOUNT(), amount) .scalar()
voucher.settlements.append(s)
dbsession.add(s)
round_off = round(amount) - amount
so_round_off = [
s for s in voucher.settlements if s.settled == SettleOption.ROUND_OFF()
]
if len(so_round_off) == 1 and round_off != 0:
so_round_off[0].amount = round_off
elif len(so_round_off) == 1 and round_off == 0:
voucher.settlements.remove(so_round_off[0])
dbsession.delete(so_round_off[0])
elif len(so_round_off) == 0 and round_off != 0:
s = Settlement(voucher.id, SettleOption.ROUND_OFF(), round_off)
voucher.settlements.append(s)
dbsession.add(s)
unsettled = sum(
s.amount for s in voucher.settlements if s.settled != SettleOption.UNSETTLED()
) )
so_unsettled = [
s for s in voucher.settlements if s.settled == SettleOption.UNSETTLED()
]
if len(so_unsettled) == 1 and unsettled != 0:
so_unsettled[0].amount = unsettled
elif len(so_unsettled) == 1 and unsettled == 0:
voucher.settlements.remove(so_unsettled[0])
dbsession.delete(so_unsettled[0])
elif len(so_unsettled) == 0 and unsettled != 0:
s = Settlement(voucher.id, SettleOption.UNSETTLED(), unsettled)
voucher.settlements.append(s)
dbsession.add(s)
return unsettled
def do_update_table(item, guest_book, dbsession):
status = "running" if item.voucher_type == VoucherType.KOT else "printed"
if item.status is None:
item.status = Overview(
voucher_id=item.id,
food_table_id=item.food_table_id,
guest_book_id=guest_book.id if guest_book is not None else None,
status=status,
)
dbsession.add(item.status)
else:
item.status.status = status
def check_permissions(item, voucher_type, permissions):
if voucher_type == VoucherType.KOT and "Print Kot" not in permissions:
raise ValidationFailure("You are not allowed to print a kot")
if voucher_type != VoucherType.KOT and "Print Bill" not in permissions:
raise ValidationFailure("You are not allowed to print bill")
if item is None:
return
if item.voucher_type != VoucherType.KOT and "Edit Printed Bill" not in permissions:
raise ValidationFailure("You are not allowed to edit a printed bill")
if item.voucher_type != VoucherType.KOT and voucher_type == VoucherType.KOT:
raise ValidationFailure("This Bill is already printed\nCannot add a Kot to it.")
if item.is_void:
raise ValidationFailure(
"This Bill is already void.\nReason: {0}".format(item.void_reason)
)
def get_guest_book(guest_book_id, dbsession):
if guest_book_id is None:
return guest_book_id
return (
dbsession.query(GuestBook)
.filter(GuestBook.id == uuid.UUID(guest_book_id))
.first()
)
def do_update_settlements(voucher, dbsession):
settlements = []
total_amount = voucher.amount
settlements.append({"id": SettleOption.AMOUNT(), "amount": -total_amount})
round_off = round(total_amount) - total_amount
if round_off != 0:
settlements.append({"id": SettleOption.ROUND_OFF(), "amount": -round_off})
settlements.append({"id": SettleOption.UNSETTLED(), "amount": round(total_amount)})
for i in settlements:
amount = i["amount"]
settlement_type_id = i["id"]
old = [s for s in voucher.settlements if s.settled == settlement_type_id]
if len(old) == 1:
old[0].amount = amount
else:
s = Settlement(voucher.id, settlement_type_id, amount)
voucher.settlements.append(s)
dbsession.add(s)
for i in (i for i in voucher.settlements if i.settled not in [x["id"] for x in settlements]):
voucher.settlements.remove(i)
dbsession.delete(i)

View File

@ -1,74 +1,82 @@
import uuid import uuid
import transaction import transaction
from datetime import datetime
from pyramid.view import view_config from pyramid.view import view_config
from sqlalchemy import func
from barker.models import Kot, Voucher, Overview from barker.models import Kot, Voucher, Overview
from barker.views.voucher import get_bill_id, do_update_table
@view_config( @view_config(
request_method="POST", request_method="POST",
route_name="merge_kot", route_name="v1_move_kot",
renderer="json", renderer="json",
request_param="merge",
permission="Merge Kots", permission="Merge Kots",
trans=True, trans=True,
) )
def merge_kot(request): def merge_kot(request):
json = request.json_body json = request.json_body
kot_id = uuid.UUID(json["KotID"]) kot_id = uuid.UUID(json["kot"]["id"])
voucher_id = uuid.UUID(json["NewVoucherID"]) new_voucher_id = uuid.UUID(json["newVoucher"]["id"])
request.dbsession.query(Kot).filter(Kot.id == kot_id).update( request.dbsession.query(Kot).filter(Kot.id == kot_id).update(
{Kot.voucher_id: voucher_id} {Kot.voucher_id: new_voucher_id}
) )
transaction.commit() transaction.commit()
return voucher_id return True
@view_config( @view_config(
request_method="POST", request_method="POST",
route_name="move_kot", route_name="v1_move_kot",
renderer="json", renderer="json",
permission="Move Kot", request_param="move",
permission="Move Kot to New Table",
trans=True, trans=True,
) )
def move_kot(request): def move_kot(request):
json = request.json_body json = request.json_body
kot_id = uuid.UUID(json["KotID"]) now = datetime.now()
food_table_id = uuid.UUID(json["FoodTableID"]) kot_id = uuid.UUID(json["kot"]["id"])
table_id = uuid.UUID(json["table"]["id"])
kot = request.dbsession.query(Kot).filter(Kot.id == kot_id).first() kot = request.dbsession.query(Kot).filter(Kot.id == kot_id).first()
bill_id = get_bill_id(kot.voucher.voucher_type, request.dbsession)
kot_id = request.dbsession.query(
func.coalesce(func.max(Voucher.kot_id), 0) + 1
).scalar()
item = Voucher( item = Voucher(
now,
kot.voucher.pax, kot.voucher.pax,
food_table_id, bill_id,
kot_id,
table_id,
kot.voucher.customer_id, kot.voucher.customer_id,
False,
kot.voucher.voucher_type, kot.voucher.voucher_type,
kot.voucher.user_id, uuid.UUID(request.authenticated_userid)
request.dbsession,
) )
request.dbsession.add(item) request.dbsession.add(item)
item.kots.append(kot) item.kots.append(kot)
status = "printed" if item.is_printed else "running" do_update_table(item, None, request.dbsession)
item.status = Overview(
voucher_id=None, food_table_id=item.food_table_id, status=status
)
request.dbsession.add(item.status) request.dbsession.add(item.status)
transaction.commit() transaction.commit()
return item.id return True
@view_config( @view_config(
request_method="POST", request_method="POST",
route_name="v1_vouchers_id", route_name="v1_move_table",
request_param="move-table", request_param="move",
renderer="json", renderer="json",
permission="Move Table", permission="Move Table",
trans=True, trans=True,
) )
def move_table(request): def move_table(request):
id_ = uuid.UUID(request.matchdict["id"]) id_ = uuid.UUID(request.json_body["voucher"]["id"])
table_id = uuid.UUID(request.json_body["table"]["id"]) table_id = uuid.UUID(request.json_body["table"]["id"])
request.dbsession.query(Overview).filter(Overview.voucher_id == id_).update( request.dbsession.query(Overview).filter(Overview.voucher_id == id_).update(
@ -85,22 +93,25 @@ def move_table(request):
@view_config( @view_config(
request_method="POST", request_method="POST",
route_name="merge_table", route_name="v1_move_table",
request_param="merge",
renderer="json", renderer="json",
permission="Merge Tables", permission="Merge Tables",
trans=True, trans=True,
) )
def merge_table(request): def merge_table(request):
json = request.json_body json = request.json_body
voucher_id = uuid.UUID(json["VoucherID"])
new_voucher_id = uuid.UUID(json["NewVoucherID"])
request.dbsession.query(Kot).filter(Kot.voucher_id == voucher_id).update( id_ = uuid.UUID(json["oldVoucher"]["id"])
# table_id = uuid.UUID(json["table"]["id"])
new_voucher_id = uuid.UUID(json["newVoucher"]["id"])
request.dbsession.query(Kot).filter(Kot.voucher_id == id_).update(
{Kot.voucher_id: new_voucher_id} {Kot.voucher_id: new_voucher_id}
) )
request.dbsession.query(Voucher).filter(Voucher.id == voucher_id).delete() request.dbsession.query(Voucher).filter(Voucher.id == id_).delete()
transaction.commit() transaction.commit()
return voucher_id return True
# VoucherBI.UpdateTable(x => x.FoodTableID == _voucher.Table.FoodTableID && x.VoucherID == _voucher.VoucherID, null, null); # VoucherBI.UpdateTable(x => x.FoodTableID == _voucher.Table.FoodTableID && x.VoucherID == _voucher.VoucherID, null, null);
# throw new NotImplementedException(); # throw new NotImplementedException();

View File

@ -3,24 +3,27 @@ import uuid
from decimal import Decimal from decimal import Decimal
import transaction import transaction
from pyramid.httpexceptions import HTTPForbidden
from pyramid.view import view_config from pyramid.view import view_config
from sqlalchemy import func from sqlalchemy import func
from barker.models import ( from barker.models import (
Overview,
Voucher, Voucher,
Kot, Kot,
Inventory, Inventory,
InventoryModifier, InventoryModifier,
VoucherType, VoucherType,
Product, Product,
GuestBook,
FoodTable, FoodTable,
) )
from barker.models.validation_exception import ValidationError from barker.models.validation_exception import ValidationError
from barker.views.voucher import get_tax, get_settlements from barker.views.voucher import (
from barker.views.voucher.show import voucher_info get_tax,
do_update_settlements,
get_bill_id,
do_update_table,
check_permissions,
get_guest_book,
)
@view_config( @view_config(
@ -39,7 +42,7 @@ def save(request):
.first() .first()
) )
check_permissions(voucher_type, request.effective_principals) check_permissions(None, voucher_type, request.effective_principals)
bill_id = get_bill_id(voucher_type, request.dbsession) bill_id = get_bill_id(voucher_type, request.dbsession)
kot_id = request.dbsession.query( kot_id = request.dbsession.query(
@ -54,68 +57,20 @@ def save(request):
json["table"]["id"], json["table"]["id"],
json["customer"]["id"] if "id" in json["customer"] else None, json["customer"]["id"] if "id" in json["customer"] else None,
voucher_type, voucher_type,
uuid.UUID(request.authenticated_userid) uuid.UUID(request.authenticated_userid),
) )
request.dbsession.add(item) request.dbsession.add(item)
add_kots(json, item, voucher_type, request.dbsession)
if len(item.kots) == 0 or len(item.kots[0].inventories) == 0:
raise ValidationError("Please add some products!")
if update_table:
do_update_table(item, voucher_type, guest_book, request.dbsession)
transaction.commit()
item = request.dbsession.query(Voucher).filter(Voucher.id == item.id).first()
return voucher_info(item)
def check_permissions(voucher_type, permissions):
if voucher_type == VoucherType.KOT and "Print Kot" not in permissions:
raise HTTPForbidden("You are not allowed to print a kot")
if voucher_type != VoucherType.KOT and "Print Bill" not in permissions:
raise HTTPForbidden("You are not allowed to print bill")
def get_guest_book(guest_book_id, dbsession):
if guest_book_id is None:
return guest_book_id
return (
dbsession.query(GuestBook)
.filter(GuestBook.id == uuid.UUID(guest_book_id))
.first()
)
def get_bill_id(voucher_type, dbsession):
if voucher_type == VoucherType.KOT:
return None
return (
dbsession.query(func.coalesce(func.max(Voucher.bill_id), 0) + 1)
.filter(Voucher.voucher_type == voucher_type.value)
.scalar()
)
def do_update_table(item, voucher_type, guest_book, dbsession):
status = "running" if voucher_type == VoucherType.KOT else "printed"
item.status = Overview(
voucher_id=None,
food_table_id=item.food_table_id,
guest_book_id=guest_book.id if guest_book is not None else None,
status=status,
)
dbsession.add(item.status)
def add_kots(json, item, voucher_type, dbsession):
for k in json["kots"]: for k in json["kots"]:
code = dbsession.query(func.coalesce(func.max(Kot.code), 0) + 1).scalar() code = request.dbsession.query(func.coalesce(func.max(Kot.code), 0) + 1).scalar()
kot = Kot(item.id, code, item.food_table_id, item.date, item.user_id) kot = Kot(item.id, code, item.food_table_id, item.date, item.user_id)
item.kots.append(kot) item.kots.append(kot)
dbsession.add(kot) request.dbsession.add(kot)
for index, i in enumerate(k["inventories"]): for index, i in enumerate(k["inventories"]):
product = dbsession.query(Product).filter(Product.id == uuid.UUID(i["product"]["id"])).first() product = (
request.dbsession.query(Product)
.filter(Product.id == uuid.UUID(i["product"]["id"]))
.first()
)
tax_rate = get_tax(product.sale_category.tax.rate, voucher_type) tax_rate = get_tax(product.sale_category.tax.rate, voucher_type)
inv = Inventory( inv = Inventory(
kot.id, kot.id,
@ -129,9 +84,16 @@ def add_kots(json, item, voucher_type, dbsession):
index, index,
) )
kot.inventories.append(inv) kot.inventories.append(inv)
dbsession.add(inv) request.dbsession.add(inv)
for m in i["modifiers"]: for m in i["modifiers"]:
mod = InventoryModifier(None, uuid.UUID(m["id"]), 0) mod = InventoryModifier(None, uuid.UUID(m["id"]), 0)
inv.modifiers.append(mod) inv.modifiers.append(mod)
dbsession.add(mod) request.dbsession.add(mod)
get_settlements(item, dbsession) do_update_settlements(item, request.dbsession)
if len(item.kots) == 0 or len(item.kots[0].inventories) == 0:
raise ValidationError("Please add some products!")
if update_table:
do_update_table(item, guest_book, request.dbsession)
transaction.commit()
return True

View File

@ -1,40 +1,133 @@
import uuid import uuid
import transaction import transaction
from datetime import datetime
from pyramid.view import view_config from pyramid.view import view_config
from sqlalchemy import func
from barker.models import Voucher, Overview from barker.models import Voucher, Overview, Kot, Inventory, InventoryModifier
from barker.views.voucher.save import save from barker.models.validation_exception import ValidationError
from barker.views.voucher import get_bill_id, do_update_settlements, do_update_table
from barker.views.voucher.update import check_permissions
from barker.views.voucher.void import do_void_settlements
@view_config( @view_config(
request_method="POST", request_method="POST",
route_name="voucher_split", route_name="v1_vouchers_id",
renderer="json", renderer="json",
request_param="split-bill",
permission="Split Bill", permission="Split Bill",
trans=True, trans=True,
) )
def split_voucher(request): def split_voucher(request):
json = request.json_body json = request.json_body
now = datetime.now()
id_ = uuid.UUID(request.matchdict["id"]) id_ = uuid.UUID(request.matchdict["id"])
update_table = request.GET["u"] == "true"
item = request.dbsession.query(Voucher).filter(Voucher.id == id_).first() item = request.dbsession.query(Voucher).filter(Voucher.id == id_).first()
item.void = True item.void = True
item.void_reason = "Bill Split" item.void_reason = "Bill Split"
# TODO: Set the Void Settlement do_void_settlements(item, request.dbsession)
if update_table:
request.dbsession.query(Overview).filter(
Overview.voucher_id == item.id
).delete()
new_one = save(json["One"], request.dbsession) inventories = [uuid.UUID(i) for i in json["inventories"]]
new_two = save(json["Two"], request.dbsession)
status = "printed" if item.is_printed else "running" one_inventories = [i for k in item.kots for i in k.inventories if i.id in inventories]
new_one.status = Overview( two_inventories = [i for k in item.kots for i in k.inventories if i.id not in inventories]
voucher_id=None, food_table_id=new_one.food_table_id, status=status
save(
one_inventories,
now,
item.voucher_type,
0,
uuid.UUID(json["table"]["id"]),
item.customer_id,
update_table,
uuid.UUID(request.authenticated_userid),
request.effective_principals,
request.dbsession,
) )
save(
request.dbsession.add(new_one.status) two_inventories,
request.dbsession.query(Overview).filter(Overview.voucher_id == item.id).update( now,
{Overview.voucher_id: new_two.id} item.voucher_type,
item.pax,
item.food_table_id,
item.customer_id,
update_table,
uuid.UUID(request.authenticated_userid),
request.effective_principals,
request.dbsession,
) )
transaction.commit() transaction.commit()
return True
def save(
inventories,
now,
voucher_type,
pax,
table_id,
customer_id,
update_table,
user_id,
permissions,
dbsession,
):
product_quantities = {}
skip_products = set()
for i in inventories:
if i.product_id in product_quantities:
product_quantities[i.product_id] += i.quantity
else:
product_quantities[i.product_id] = i.quantity
for product, quantity in product_quantities.items():
if quantity < 0:
raise ValidationError("Quantity is negative")
elif quantity == 0:
skip_products.add(product)
check_permissions(None, voucher_type, permissions)
bill_id = get_bill_id(voucher_type, dbsession)
kot_id = dbsession.query(func.coalesce(func.max(Voucher.kot_id), 0) + 1).scalar()
item = Voucher(
now, pax, bill_id, kot_id, table_id, customer_id, voucher_type, user_id
)
dbsession.add(item)
code = dbsession.query(func.coalesce(func.max(Kot.code), 0) + 1).scalar()
kot = Kot(item.id, code, item.food_table_id, item.date, item.user_id)
item.kots.append(kot)
dbsession.add(kot)
for index, old_inventory in enumerate(
[i for i in inventories if i.product_id not in skip_products]
):
inv = Inventory(
kot.id,
old_inventory.product_id,
old_inventory.quantity,
old_inventory.price,
old_inventory.discount,
old_inventory.is_happy_hour,
old_inventory.tax_id,
old_inventory.tax_rate,
index,
)
kot.inventories.append(inv)
dbsession.add(inv)
for m in old_inventory.modifiers:
mod = InventoryModifier(None, m.modifier_id, m.price)
inv.modifiers.append(mod)
dbsession.add(mod)
do_update_settlements(item, dbsession)
if len(kot.inventories) == 0:
raise ValidationError("Please add some products!")
if update_table:
do_update_table(item, None, dbsession)

View File

@ -3,23 +3,25 @@ import uuid
from decimal import Decimal from decimal import Decimal
import transaction import transaction
from pyramid.httpexceptions import HTTPForbidden
from pyramid.view import view_config from pyramid.view import view_config
from sqlalchemy import func from sqlalchemy import func
from barker.exceptions import ValidationFailure
from barker.models import ( from barker.models import (
Voucher, Voucher,
Kot, Kot,
Inventory, Inventory,
InventoryModifier, InventoryModifier,
Overview,
VoucherType, VoucherType,
GuestBook,
Product, Product,
) )
from barker.views.voucher import get_tax, get_settlements from barker.views.voucher import (
from barker.views.voucher.show import voucher_info get_tax,
do_update_settlements,
get_bill_id,
do_update_table,
check_permissions,
get_guest_book,
)
@view_config( @view_config(
@ -60,10 +62,8 @@ def update(request):
if uuid.UUID(inv["id"]) == i.id if uuid.UUID(inv["id"]) == i.id
) )
for k in (k for k in json["kots"] if "id" not in k and len(k["inventories"]) > 0): for k in (k for k in json["kots"] if "id" not in k and len(k["inventories"]) > 0):
code = request.dbsession.query( code = request.dbsession.query(func.coalesce(func.max(Kot.code), 0) + 1).scalar()
func.coalesce(func.max(Kot.code), 0) + 1 kot = Kot(item.id, code, item.food_table_id, now, item.user_id)
).scalar()
kot = Kot(item.id, code, item.food_table_id, item.date, item.user_id)
item.kots.append(kot) item.kots.append(kot)
request.dbsession.add(kot) request.dbsession.add(kot)
for index, i in enumerate(k["inventories"]): for index, i in enumerate(k["inventories"]):
@ -90,64 +90,8 @@ def update(request):
mod = InventoryModifier(None, uuid.UUID(m["id"]), 0) mod = InventoryModifier(None, uuid.UUID(m["id"]), 0)
inv.modifiers.append(mod) inv.modifiers.append(mod)
request.dbsession.add(mod) request.dbsession.add(mod)
get_settlements(item, request.dbsession) do_update_settlements(item, request.dbsession)
if update_table: if update_table:
do_update_table(item, voucher_type, guest_book, request.dbsession) do_update_table(item, guest_book, request.dbsession)
transaction.commit() transaction.commit()
item = request.dbsession.query(Voucher).filter(Voucher.id == item.id).first() return True
return voucher_info(item)
def check_permissions(item, voucher_type, permissions):
if voucher_type == VoucherType.KOT and "Print Kot" not in permissions:
raise HTTPForbidden("You are not allowed to print a kot")
if voucher_type != VoucherType.KOT and "Print Bill" not in permissions:
raise HTTPForbidden("You are not allowed to print bill")
if item.voucher_type != VoucherType.KOT and "Edit Printed Bill" not in permissions:
raise HTTPForbidden("You are not allowed to edit a printed bill")
if item.voucher_type != VoucherType.KOT and voucher_type == VoucherType.KOT:
transaction.abort()
raise ValidationFailure("This Bill is already printed\nCannot add a Kot to it.")
if item.is_void:
transaction.abort()
raise ValidationFailure(
"This Bill is already void.\nReason: {0}".format(item.void_reason)
)
def get_guest_book(guest_book_id, dbsession):
if guest_book_id is None:
return guest_book_id
return (
dbsession.query(GuestBook)
.filter(GuestBook.id == uuid.UUID(guest_book_id))
.first()
)
def get_bill_id(voucher_type, dbsession):
if voucher_type == VoucherType.KOT:
return None
return (
dbsession.query(func.coalesce(func.max(Voucher.bill_id), 0) + 1)
.filter(Voucher.voucher_type == voucher_type.value)
.scalar()
)
def do_update_table(item, voucher_type, guest_book, dbsession):
status = "running" if voucher_type == VoucherType.KOT else "printed"
if item.status is None:
item.status = Overview(
voucher_id=item.id,
food_table_id=item.food_table_id,
guest_book_id=guest_book.id if guest_book is not None else None,
status=status,
)
dbsession.add(item.status)
else:
item.status.status = status

View File

@ -17,13 +17,24 @@ from barker.models import Voucher, SettleOption, Settlement, Overview
def void_voucher(request): def void_voucher(request):
id_ = uuid.UUID(request.matchdict["id"]) id_ = uuid.UUID(request.matchdict["id"])
reason = request.json_body["reason"] reason = request.json_body["reason"]
update_table = request.GET["u"] update_table = request.GET["u"] == "true"
item = request.dbsession.query(Voucher).filter(Voucher.id == id_).first() item = request.dbsession.query(Voucher).filter(Voucher.id == id_).first()
item.void = True item.void = True
item.void_reason = reason item.void_reason = reason
do_void_settlements(item, request.dbsession)
if update_table:
request.dbsession.query(Overview).filter(
Overview.voucher_id == item.id
).delete()
transaction.commit()
return True
def do_void_settlements(item, dbsession):
settlements = [] settlements = []
total_amount = item.amount total_amount = item.amount
settlements.append({"id": SettleOption.AMOUNT(), "amount": -total_amount}) settlements.append({"id": SettleOption.AMOUNT(), "amount": -total_amount})
@ -41,17 +52,8 @@ def void_voucher(request):
else: else:
s = Settlement(item.id, settlement_type_id, amount) s = Settlement(item.id, settlement_type_id, amount)
item.settlements.append(s) item.settlements.append(s)
request.dbsession.add(s) dbsession.add(s)
for i in (i for i in item.settlements if i.settled not in [x["id"] for x in settlements]): for i in (i for i in item.settlements if i.settled not in [x["id"] for x in settlements]):
item.settlements.remove(i) item.settlements.remove(i)
request.dbsession.delete(i) dbsession.delete(i)
if update_table:
request.dbsession.query(Overview).filter(
Overview.voucher_id == item.id
).delete()
transaction.commit()
return True

View File

@ -10,18 +10,19 @@ import { ModifierCategory } from '../core/modifier-category';
import { Bill, Inventory, Kot, PrintType } from './bills/bill'; import { Bill, Inventory, Kot, PrintType } from './bills/bill';
import { VoucherService } from './bills/voucher.service'; import { VoucherService } from './bills/voucher.service';
import { ToasterService } from '../core/toaster.service'; import { ToasterService } from '../core/toaster.service';
import { tap } from 'rxjs/operators';
import { Table } from '../core/table'; import { Table } from '../core/table';
import { SelectionModel } from "@angular/cdk/collections";
@Injectable() @Injectable()
export class BillService { export class BillService {
public dataObs; public dataObs;
public data; public data: any[];
private bill; private bill;
public netAmount: BehaviorSubject<number>; public netAmount: BehaviorSubject<number>;
public discountAmount: BehaviorSubject<number>; public discountAmount: BehaviorSubject<number>;
public taxAmount: BehaviorSubject<number>; public taxAmount: BehaviorSubject<number>;
public amount: BehaviorSubject<number>; public amount: BehaviorSubject<number>;
public selection = new SelectionModel<any>(true, []);
constructor( constructor(
private dialog: MatDialog, private dialog: MatDialog,
@ -41,12 +42,14 @@ export class BillService {
this.bill = bill; this.bill = bill;
const view = this.bill.kots.map(k => { const view = this.bill.kots.map(k => {
return [{ return [{
id: k.id,
isKot: true, isKot: true,
oldKot: true, oldKot: true,
info: `Kot: ${k.code} / ${k.date} (${k.user.name}) ` info: `Kot: ${k.code} / ${k.date} (${k.user.name}) `
}, ...k.inventories.map(i => { }, ...k.inventories.map(i => {
return { return {
id: i.id, id: i.id,
kotId: k.id,
isKot: false, isKot: false,
product: i.product, product: i.product,
productId: i.product.id, productId: i.product.id,
@ -178,7 +181,7 @@ export class BillService {
}); });
} }
printKot(guest_book_id: string): Observable<Bill> { printKot(guest_book_id: string): Observable<boolean> {
const item = JSON.parse(JSON.stringify(this.bill)); const item = JSON.parse(JSON.stringify(this.bill));
const newKot = this.getKot(); const newKot = this.getKot();
if (newKot.inventories.length == 0) { if (newKot.inventories.length == 0) {
@ -188,7 +191,7 @@ export class BillService {
return this.ser.saveOrUpdate(item, PrintType.Kot, guest_book_id, true); return this.ser.saveOrUpdate(item, PrintType.Kot, guest_book_id, true);
} }
printBill(guest_book_id: string, printType: PrintType): Observable<Bill> { printBill(guest_book_id: string, printType: PrintType): Observable<boolean> {
const item = JSON.parse(JSON.stringify(this.bill)); const item = JSON.parse(JSON.stringify(this.bill));
item.kots.forEach(k => { item.kots.forEach(k => {
k.inventories.forEach(i => { k.inventories.forEach(i => {
@ -211,8 +214,16 @@ export class BillService {
return this.ser.moveTable(this.bill.id, table); return this.ser.moveTable(this.bill.id, table);
} }
moveKot(id: string, table: Table): Observable<boolean> { mergeTable(table: Table): Observable<boolean> {
return this.ser.moveKot(this.bill.id, id, table); return this.ser.mergeTable(this.bill.id, table);
}
moveKot(kotId: string, table: Table): Observable<boolean> {
return this.ser.moveKotToNewTable(this.bill.id, kotId, table);
}
mergeKot(kotId: string, table: Table): Observable<boolean> {
return this.ser.mergeKotWithOldBill(this.bill.id, kotId, table);
} }
voidBill(reason: string): Observable<boolean> { voidBill(reason: string): Observable<boolean> {
@ -249,4 +260,9 @@ export class BillService {
, 0) , 0)
, 0)); , 0));
} }
splitBill(table: Table): Observable<boolean> {
const inventoriesToMove: string[] = this.selection.selected.map((x:any)=> x.id)
return this.ser.splitBill(this.bill.id, inventoriesToMove, table);
}
} }

View File

@ -13,6 +13,10 @@ table {
width: 100%; width: 100%;
} }
.mat-column-select{
flex: 0 0 50px;
}
.grey900 { .grey900 {
background-color: #1b5e20; background-color: #1b5e20;
color: #ffffff; color: #ffffff;

View File

@ -8,6 +8,22 @@
</mat-card-title-group> </mat-card-title-group>
<mat-card-content> <mat-card-content>
<table mat-table #table [dataSource]="dataSource" aria-label="Elements" class="mat-elevation-z8"> <table mat-table #table [dataSource]="dataSource" aria-label="Elements" class="mat-elevation-z8">
<!-- Checkbox Column -->
<ng-container matColumnDef="select">
<mat-cell *matCellDef="let row">
<mat-checkbox *ngIf="row.oldKot"
(change)="$event ? masterToggle(row) : null"
[checked]="bs.selection.hasValue() && isAllSelected(row)"
[indeterminate]="isAnySelected(row)">
</mat-checkbox>
<mat-checkbox *ngIf="!row.isKot" [disabled]="!row.id"
(click)="$event.stopPropagation()"
(change)="$event ? bs.selection.toggle(row) : null"
[checked]="bs.selection.isSelected(row)">
</mat-checkbox>
</mat-cell>
<mat-footer-cell *matFooterCellDef class="grey900">Amount</mat-footer-cell>
</ng-container>
<!-- Info Column --> <!-- Info Column -->
<ng-container matColumnDef="info"> <ng-container matColumnDef="info">
<mat-cell *matCellDef="let row" [class.blue800]="row.newKot"> <mat-cell *matCellDef="let row" [class.blue800]="row.newKot">
@ -18,7 +34,7 @@
<li *ngFor="let m of row.modifiers">{{m.name}}</li> <li *ngFor="let m of row.modifiers">{{m.name}}</li>
</ul> </ul>
</mat-cell> </mat-cell>
<mat-footer-cell *matFooterCellDef class="grey900 bold">Amount</mat-footer-cell> <mat-footer-cell *matFooterCellDef class="grey900 bold"></mat-footer-cell>
</ng-container> </ng-container>
<!-- Quantity Column --> <!-- Quantity Column -->
<ng-container matColumnDef="quantity"> <ng-container matColumnDef="quantity">
@ -39,7 +55,7 @@
<button mat-icon-button (click)="modifier(row)" [disabled]="row.isPrinted" *ngIf="!row.isKot"> <button mat-icon-button (click)="modifier(row)" [disabled]="row.isPrinted" *ngIf="!row.isKot">
<mat-icon class="del">assignment</mat-icon> <mat-icon class="del">assignment</mat-icon>
</button> </button>
<button mat-icon-button (click)="modifier(row)" [disabled]="row.newKot" *ngIf="row.isKot"> <button mat-icon-button (click)="moveKot(row)" [disabled]="row.newKot" *ngIf="row.isKot">
<mat-icon class="del">open_in_new</mat-icon> <mat-icon class="del">open_in_new</mat-icon>
</button> </button>
</mat-cell> </mat-cell>

View File

@ -12,6 +12,8 @@ import { map, switchMap } from 'rxjs/operators';
import { TablesDialogComponent } from '../tables-dialog/tables-dialog.component'; import { TablesDialogComponent } from '../tables-dialog/tables-dialog.component';
import { TableService } from '../../tables/table.service'; import { TableService } from '../../tables/table.service';
import { ToasterService } from '../../core/toaster.service'; import { ToasterService } from '../../core/toaster.service';
import { AuthService } from "../../auth/auth.service";
import { SelectionModel } from "@angular/cdk/collections";
@Component({ @Component({
selector: 'app-bills', selector: 'app-bills',
@ -22,13 +24,14 @@ export class BillsComponent implements OnInit {
dataSource: BillsDataSource; dataSource: BillsDataSource;
item: Bill; item: Bill;
/** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */ /** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */
displayedColumns: string[] = ['info', 'quantity']; displayedColumns: string[] = ['select', 'info', 'quantity'];
constructor( constructor(
private route: ActivatedRoute, private route: ActivatedRoute,
private router: Router, private router: Router,
private dialog: MatDialog, private dialog: MatDialog,
private toaster: ToasterService, private toaster: ToasterService,
private auth: AuthService,
private bs: BillService, private bs: BillService,
private tSer: TableService private tSer: TableService
) { ) {
@ -43,6 +46,38 @@ export class BillsComponent implements OnInit {
this.dataSource = new BillsDataSource(this.bs.dataObs); this.dataSource = new BillsDataSource(this.bs.dataObs);
} }
isAllSelected(kot: Kot) {
return this.bs.data.filter(
x => x.kotId === kot.id
).reduce(
(p: boolean, c: any) => p && this.bs.selection.isSelected(c)
, true
);
}
isAnySelected(kot: Kot) {
let total: number = 0,
found: number = 0;
this.bs.data.filter(
x => x.kotId === kot.id
).forEach((c: any) => {
total += 1;
if (this.bs.selection.isSelected(c)) {
found += 1;
}
});
return found > 0 && found < total;
}
masterToggle(kot: Kot) {
const isAllSelected = this.isAllSelected(kot);
this.bs.data.filter(
x => x.kotId === kot.id
).forEach(
row => isAllSelected ? this.bs.selection.deselect(row) : this.bs.selection.select(row)
);
}
addOne(item: any): void { addOne(item: any): void {
this.bs.addOne(item); this.bs.addOne(item);
} }
@ -72,4 +107,48 @@ export class BillsComponent implements OnInit {
modifier(item: any): void { modifier(item: any): void {
this.bs.modifier(item); this.bs.modifier(item);
} }
confirmMoveKotDialog(table: Table): Observable<{table: Table, confirmed: boolean}> {
return this.dialog.open(ConfirmDialogComponent, {
width: '250px',
data: {title: 'Move KOT?', content: 'Are you sure?'}
}).afterClosed().pipe(
map ((x: boolean) => ({table: table, confirmed: x}))
);
}
moveKot(kot: Kot) {
const canMergeTables = this.auth.hasPermission("Merge Tables");
this.dialog.open(TablesDialogComponent, {
// width: '750px',
data: {
list: this.tSer.running(),
canChooseRunning: canMergeTables
}
}).afterClosed().pipe(
switchMap((x: boolean | Table) => {
if (!!x) {
return this.confirmMoveKotDialog(x as Table);
} else {
return throwError('Please choose a table');
}
}),
switchMap((value: { table: Table, confirmed: boolean }, index: number) => {
if (!value.confirmed) {
return throwError('Please confirm move');
} else if (value.table.status) {
return this.bs.mergeKot(kot.id, value.table);
} else {
return this.bs.moveKot(kot.id, value.table);
}
}
)
).subscribe((x) => {
this.toaster.show('Success', '');
this.router.navigate(['/sales']);
},
x => {
this.toaster.show('Error', x);
});
}
} }

View File

@ -11,6 +11,8 @@ const httpOptions = {
}; };
const url = '/v1/vouchers'; const url = '/v1/vouchers';
const urlMoveTable = '/v1/move-table';
const urlMoveKot = '/v1/move-kot';
const serviceName = 'VoucherService'; const serviceName = 'VoucherService';
@Injectable({providedIn: 'root'}) @Injectable({providedIn: 'root'})
@ -47,29 +49,29 @@ export class VoucherService {
); );
} }
save(voucher: Bill, printType: PrintType, guest_book_id: string, updateTable: boolean): Observable<Bill> { save(voucher: Bill, printType: PrintType, guest_book_id: string, updateTable: boolean): Observable<boolean> {
const options = {params: new HttpParams().set('p', printType).set('u', updateTable.toString())}; const options = {params: new HttpParams().set('p', printType).set('u', updateTable.toString())};
if (guest_book_id !== null) { if (guest_book_id !== null) {
options.params = options.params.set('g', guest_book_id); options.params = options.params.set('g', guest_book_id);
} }
return <Observable<Bill>>this.http.post<Bill>(`${url}/new`, voucher, options) return <Observable<boolean>>this.http.post<boolean>(`${url}/new`, voucher, options)
.pipe( .pipe(
catchError(this.log.handleError(serviceName, 'save')) catchError(this.log.handleError(serviceName, 'save'))
); );
} }
update(voucher: Bill, printType: PrintType, guest_book_id: string, updateTable: boolean): Observable<Bill> { update(voucher: Bill, printType: PrintType, guest_book_id: string, updateTable: boolean): Observable<boolean> {
const options = {params: new HttpParams().set('p', printType).set('u', updateTable.toString())}; const options = {params: new HttpParams().set('p', printType).set('u', updateTable.toString())};
if (guest_book_id !== null) { if (guest_book_id !== null) {
options.params = options.params.set('g', guest_book_id); options.params = options.params.set('g', guest_book_id);
} }
return <Observable<Bill>>this.http.put<Bill>(`${url}/${voucher.id}`, voucher, options) return <Observable<boolean>>this.http.put<boolean>(`${url}/${voucher.id}`, voucher, options)
.pipe( .pipe(
catchError(this.log.handleError(serviceName, 'update')) catchError(this.log.handleError(serviceName, 'update'))
); );
} }
saveOrUpdate(voucher: Bill, printType: PrintType, guest_book_id: string, updateTable: boolean): Observable<Bill> { saveOrUpdate(voucher: Bill, printType: PrintType, guest_book_id: string, updateTable: boolean): Observable<boolean> {
if (!voucher.id) { if (!voucher.id) {
return this.save(voucher, printType, guest_book_id, updateTable); return this.save(voucher, printType, guest_book_id, updateTable);
} else { } else {
@ -78,26 +80,75 @@ export class VoucherService {
} }
receivePayment(id: string, amounts: { id: string; name: string; amount: number }[], updateTable: boolean): Observable<boolean> { receivePayment(id: string, amounts: { id: string; name: string; amount: number }[], updateTable: boolean): Observable<boolean> {
const options = {params: new HttpParams().set('receive-payment', '').set('u', updateTable.toString())}; const options = {params: new HttpParams().set('receive-payment', '').set('u', updateTable.toString())};
return <Observable<boolean>>this.http.post<boolean>(`${url}/${id}`, amounts, options) return <Observable<boolean>>this.http.post<boolean>(
.pipe( `${url}/${id}`, amounts, options
catchError(this.log.handleError(serviceName, 'receivePayment')) ).pipe(
); catchError(this.log.handleError(serviceName, 'receivePayment'))
} );
moveTable(id: string, table: Table): Observable<boolean> {
const options = {params: new HttpParams().set('move-table', '')};
return <Observable<boolean>>this.http.post<boolean>(`${url}/${id}`, {table: {id: table.id}}, options)
.pipe(
catchError(this.log.handleError(serviceName, 'moveTable'))
);
} }
voidBill(id: string, reason: string, updateTable: boolean): Observable<boolean> { voidBill(id: string, reason: string, updateTable: boolean): Observable<boolean> {
const options = {params: new HttpParams().set('void-bill', '').set('u', updateTable.toString())}; const options = {params: new HttpParams().set('void-bill', '').set('u', updateTable.toString())};
return <Observable<boolean>>this.http.post<boolean>(`${url}/${id}`, {reason: reason}, options) return <Observable<boolean>>this.http.post<boolean>(
.pipe( `${url}/${id}`, {reason: reason}, options
catchError(this.log.handleError(serviceName, 'voidBill')) ).pipe(
); catchError(this.log.handleError(serviceName, 'voidBill'))
);
}
moveTable(id: string, table: Table): Observable<boolean> {
const options = {params: new HttpParams().set('move', '')};
return <Observable<boolean>>this.http.post<boolean>(urlMoveTable, {
voucher: {id: id},
table: {id: table.id}
}, options).pipe(
catchError(this.log.handleError(serviceName, 'moveTable'))
);
}
mergeTable(id: string, table: Table): Observable<boolean> {
const options = {params: new HttpParams().set('merge', '')};
return <Observable<boolean>>this.http.post<boolean>(urlMoveTable, {
voucher: {id: id},
table: {id: table.id},
newVoucher: {id: table.voucherId}
}, options).pipe(
catchError(this.log.handleError(serviceName, 'mergeTable'))
);
}
moveKotToNewTable(id: string, kotId: string, table: Table): Observable<boolean> {
const options = {params: new HttpParams().set('move', '')};
return <Observable<boolean>>this.http.post<boolean>(urlMoveKot, {
voucher: {id: id},
kot: {id: kotId},
table: {id: table.id}
}, options).pipe(
catchError(this.log.handleError(serviceName, 'moveKotToNewTable'))
);
}
mergeKotWithOldBill(id: string, kotId: string, table: Table): Observable<boolean> {
const options = {params: new HttpParams().set('merge', '')};
return <Observable<boolean>>this.http.post<boolean>(urlMoveKot, {
voucher: {id: id},
kot: {id: kotId},
table: {id: table.id},
newVoucher: {id: table.voucherId}
}, options).pipe(
catchError(this.log.handleError(serviceName, 'mergeKotWithOldBill'))
);
}
splitBill(id: string, inventoriesToMove: string[], table: Table) {
const options = {params: new HttpParams().set('split-bill', '').set('u', 'true')};
return <Observable<boolean>>this.http.post<boolean>(`${url}/${id}`, {
voucher: {id: id},
inventories: inventoriesToMove,
table: {id: table.id}
}, options).pipe(
catchError(this.log.handleError(serviceName, 'splitBill'))
);
} }
} }

View File

@ -24,10 +24,7 @@
<mat-card fxLayout="column" class="square-button" matRipple (click)="voidBill()"> <mat-card fxLayout="column" class="square-button" matRipple (click)="voidBill()">
<h3 class="item-name">Void Bill</h3> <h3 class="item-name">Void Bill</h3>
</mat-card> </mat-card>
<mat-card fxLayout="column" class="square-button" matRipple [routerLink]="['../../tables']"> <mat-card fxLayout="column" class="square-button" matRipple (click)="splitBill()">
<h3 class="item-name">Move KOT</h3>
</mat-card>
<mat-card fxLayout="column" class="square-button" matRipple [routerLink]="['../../tables']">
<h3 class="item-name">Split Bill</h3> <h3 class="item-name">Split Bill</h3>
</mat-card> </mat-card>
</div> </div>

View File

@ -1,8 +1,8 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router'; import { ActivatedRoute, Router } from '@angular/router';
import { MatDialog } from '@angular/material'; import { MatDialog } from '@angular/material';
import { concatMap, map, switchMap, tap } from 'rxjs/operators'; import { map, switchMap, tap } from 'rxjs/operators';
import { iif, Observable, of as observableOf, throwError } from 'rxjs'; import { Observable, of as observableOf, throwError } from 'rxjs';
import { BillService } from '../bill.service'; import { BillService } from '../bill.service';
import { ToasterService } from '../../core/toaster.service'; import { ToasterService } from '../../core/toaster.service';
import { DiscountComponent } from '../discount/discount.component'; import { DiscountComponent } from '../discount/discount.component';
@ -70,13 +70,11 @@ export class SalesHomeComponent implements OnInit {
} }
discountDialog (canGiveDiscount: boolean): Observable<any> { discountDialog (canGiveDiscount: boolean): Observable<any> {
let discObs = null;
if (canGiveDiscount) { if (canGiveDiscount) {
return discObs = this.showDiscount(); return this.showDiscount();
} else { } else {
return discObs = observableOf(''); return observableOf('');
} }
} }
billTypeDialog() { billTypeDialog() {
@ -89,10 +87,10 @@ export class SalesHomeComponent implements OnInit {
); );
} }
confirmMoveTableDialog(table: Table): Observable<{table: Table, confirmed: boolean}> { confirmTableDialog(table: Table): Observable<{table: Table, confirmed: boolean}> {
return this.dialog.open(ConfirmDialogComponent, { return this.dialog.open(ConfirmDialogComponent, {
width: '250px', width: '250px',
data: {title: 'Move Table?', content: 'Are you sure?'} data: {title: 'Select Table?', content: 'Are you sure?'}
}).afterClosed().pipe( }).afterClosed().pipe(
map ((x: boolean) => ({table: table, confirmed: x})) map ((x: boolean) => ({table: table, confirmed: x}))
); );
@ -114,20 +112,19 @@ export class SalesHomeComponent implements OnInit {
guestBookId = this.route.snapshot.queryParamMap.get('guest'); guestBookId = this.route.snapshot.queryParamMap.get('guest');
} }
this.discountDialog(canGiveDiscount).pipe( this.discountDialog(canGiveDiscount).pipe(
concatMap(() => this.billTypeDialog()) switchMap(() => this.billTypeDialog()),
).pipe( switchMap((x: boolean | PrintType) => {
concatMap( if (!!x) {
(x: boolean | PrintType) => iif( return this.bs.printBill(guestBookId, x as PrintType);
() => !!x, } else {
this.bs.printBill(guestBookId, x as PrintType), return throwError(x);
throwError(x) }
) }),
),
).subscribe(() => { ).subscribe(() => {
this.toaster.show('Success', ''); this.toaster.show('Success', '');
this.router.navigate(['/sales']); this.router.navigate(['/sales']);
}, },
x => { () => {
this.toaster.show('Error', 'No Bill Type Chosen'); this.toaster.show('Error', 'No Bill Type Chosen');
}); });
} }
@ -153,29 +150,32 @@ export class SalesHomeComponent implements OnInit {
} }
moveTable() { moveTable() {
const canMergeTables = this.auth.hasPermission("Merge Tables");
this.dialog.open(TablesDialogComponent, { this.dialog.open(TablesDialogComponent, {
// width: '750px', // width: '750px',
data: { data: {
list: this.tSer.running(), list: this.tSer.running(),
canChooseRunning: false canChooseRunning: canMergeTables
} }
}).afterClosed().pipe( }).afterClosed().pipe(
switchMap((x: boolean | Table) => { switchMap((x: boolean | Table) => {
if (!!x) { if (!x) {
return this.confirmMoveTableDialog(x as Table); return this.confirmTableDialog(x as Table);
} else { } else {
return throwError('Please choose a table'); return throwError('Please choose a table');
} }
}), }),
switchMap((value: { table: Table, confirmed: boolean }, index: number) => { switchMap((value: { table: Table, confirmed: boolean }, index: number) => {
if (!!value.confirmed) { if (!value.confirmed) {
return this.bs.moveTable(value.table);
} else {
return throwError('Please confirm move'); return throwError('Please confirm move');
} else if (value.table.status) {
return this.bs.mergeTable(value.table);
} else {
return this.bs.moveTable(value.table);
} }
} }
) )
).subscribe((x) => { ).subscribe(() => {
this.toaster.show('Success', ''); this.toaster.show('Success', '');
this.router.navigate(['/sales']); this.router.navigate(['/sales']);
}, },
@ -210,4 +210,35 @@ export class SalesHomeComponent implements OnInit {
this.toaster.show('Error', x); this.toaster.show('Error', x);
}); });
} }
splitBill() {
this.dialog.open(TablesDialogComponent, {
// width: '750px',
data: {
list: this.tSer.running(),
canChooseRunning: false
}
}).afterClosed().pipe(
switchMap((x: boolean | Table) => {
if (!!x) {
return this.confirmTableDialog(x as Table);
} else {
return throwError('Please choose a table');
}
}),
switchMap((value: { table: Table, confirmed: boolean }, index: number) => {
if (!value.confirmed) {
return throwError('Please confirm split');
} else {
return this.bs.splitBill(value.table);
}
})
).subscribe((x) => {
this.toaster.show('Success', '');
this.router.navigate(['/sales']);
},
x => {
this.toaster.show('Error', x);
});
}
} }

View File

@ -5,6 +5,7 @@ import { MatBadgeModule } from '@angular/material/badge';
import { MatButtonModule } from '@angular/material/button'; import { MatButtonModule } from '@angular/material/button';
import { MatButtonToggleModule } from '@angular/material/button-toggle'; import { MatButtonToggleModule } from '@angular/material/button-toggle';
import { MatCardModule } from '@angular/material/card'; import { MatCardModule } from '@angular/material/card';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { MatChipsModule } from '@angular/material/chips'; import { MatChipsModule } from '@angular/material/chips';
import { MatDialogModule } from '@angular/material/dialog'; import { MatDialogModule } from '@angular/material/dialog';
import { MatDividerModule } from '@angular/material/divider'; import { MatDividerModule } from '@angular/material/divider';
@ -57,6 +58,7 @@ import { VoidReasonComponent } from './void-reason/void-reason.component';
MatButtonModule, MatButtonModule,
MatButtonToggleModule, MatButtonToggleModule,
MatCardModule, MatCardModule,
MatCheckboxModule,
MatChipsModule, MatChipsModule,
MatDialogModule, MatDialogModule,
MatDividerModule, MatDividerModule,