Split bill done - TODO: If the products have different price due to paid modifiers
This commit is contained in:
2020-09-28 08:09:38 +05:30
parent cf34c2b855
commit f8778fee74
9 changed files with 159 additions and 123 deletions

View File

@ -18,6 +18,7 @@ ALGORITHM=HS256
JWT_TOKEN_EXPIRE_MINUTES=30 JWT_TOKEN_EXPIRE_MINUTES=30
NEW_DAY_OFFSET_MINUTES =420 NEW_DAY_OFFSET_MINUTES =420
TIMEZONE_OFFSET_MINUTES=330
ALEMBIC_LOG_LEVEL=INFO ALEMBIC_LOG_LEVEL=INFO
ALEMBIC_SQLALCHEMY_LOG_LEVEL=WARN ALEMBIC_SQLALCHEMY_LOG_LEVEL=WARN

View File

@ -26,7 +26,7 @@ from .routers.reports import (
sale_report, sale_report,
tax_report tax_report
) )
from .routers.voucher import show, save, update, receive_payment, void, merge_move from .routers.voucher import show, save, update, receive_payment, void, merge_move, split
from .db.base_class import Base from .db.base_class import Base
from .core.config import settings from .core.config import settings
@ -75,6 +75,7 @@ app.include_router(update.router, prefix="/api/voucher", tags=["voucher"])
app.include_router(receive_payment.router, prefix="/api/voucher", tags=["voucher"]) app.include_router(receive_payment.router, prefix="/api/voucher", tags=["voucher"])
app.include_router(void.router, prefix="/api/voucher", tags=["voucher"]) app.include_router(void.router, prefix="/api/voucher", tags=["voucher"])
app.include_router(merge_move.router, prefix="/api", tags=["voucher"]) app.include_router(merge_move.router, prefix="/api", tags=["voucher"])
app.include_router(split.router, prefix="/api", tags=["voucher"])
# app.include_router(issue_grid.router, prefix="/api/issue-grid", tags=["vouchers"]) # app.include_router(issue_grid.router, prefix="/api/issue-grid", tags=["vouchers"])
# app.include_router(batch.router, prefix="/api/batch", tags=["vouchers"]) # app.include_router(batch.router, prefix="/api/batch", tags=["vouchers"])

View File

@ -68,7 +68,7 @@ def check_permissions(item: Optional[Voucher], voucher_type: VoucherType, permis
if item is None: if item is None:
return return
if item.voucher_type != VoucherType.KOT and "Edit Printed Bill" not in permissions: if item.voucher_type != VoucherType.KOT and "edit-printed-bill" not in permissions:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN, detail="You are not allowed to edit a printed bill", status_code=status.HTTP_403_FORBIDDEN, detail="You are not allowed to edit a printed bill",
) )

View File

@ -1,101 +1,114 @@
import uuid import uuid
import transaction
from datetime import datetime from datetime import datetime
from pyramid.view import view_config from typing import Optional, List
from fastapi import APIRouter, HTTPException, status, Depends, Security
from sqlalchemy import func from sqlalchemy import func
from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.orm import Session
from barker.models import Voucher, Overview, Kot, Inventory, InventoryModifier from ...schemas.auth import UserToken
from barker.models.validation_exception import ValidationError import barker.schemas.split as schemas
from barker.views.voucher import get_bill_id, do_update_settlements, do_update_table from ...core.security import get_current_active_user as get_user
from barker.views.voucher.update import check_permissions from ...db.session import SessionLocal
from barker.views.voucher.void import do_void_settlements from ...models import Voucher, VoucherType, Kot, Inventory, InventoryModifier, SettleOption, Overview
from ...routers.voucher import (
do_update_settlements,
@view_config( get_bill_id,
request_method="POST", do_update_table,
route_name="v1_vouchers_id", check_permissions,
renderer="json",
request_param="split-bill",
permission="Split Bill",
trans=True,
) )
def split_voucher(request): from barker.schemas.receive_payment import ReceivePaymentItem as SettleSchema
json = request.json_body
now = datetime.now()
id_ = uuid.UUID(request.matchdict["id"])
update_table = request.GET["u"] == "true"
item = request.dbsession.query(Voucher).filter(Voucher.id == id_).first()
item.void = True
item.reason = "Bill Split"
do_void_settlements(item, request.dbsession)
if update_table:
request.dbsession.query(Overview).filter(Overview.voucher_id == item.id).delete()
inventories = [uuid.UUID(i) for i in json["inventories"]] router = APIRouter()
one_inventories = [i for k in item.kots for i in k.inventories if i.id in inventories]
two_inventories = [i for k in item.kots for i in k.inventories if i.id not in inventories]
save( # Dependency
one_inventories, def get_db():
now, try:
item.voucher_type, db = SessionLocal()
0, yield db
uuid.UUID(json["table"]["id"]), finally:
item.customer_id, db.close()
update_table,
uuid.UUID(request.authenticated_userid),
request.effective_principals,
request.dbsession,
)
save(
two_inventories,
now,
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()
return True @router.post("/split-bill/{id_}")
def split(
id_: uuid.UUID,
data: schemas.Split,
u: bool, # Update table?
db: Session = Depends(get_db),
user: UserToken = Security(get_user, scopes=["split-bill"]),
):
try:
now = datetime.now()
update_table = u
item: Voucher = db.query(Voucher).filter(Voucher.id == id_).first()
item.void = True
item.reason = "Bill Split"
do_update_settlements(item, [SettleSchema(id=SettleOption.VOID(), amount=round(item.amount))], db)
if update_table:
db.query(Overview).filter(Overview.voucher_id == item.id).delete()
check_permissions(None, item.voucher_type, user.permissions)
one_inventories = [i for k in item.kots for i in k.inventories if i.id in data.inventories]
two_inventories = [i for k in item.kots for i in k.inventories if i.id not in data.inventories]
one = save(one_inventories, now, item.voucher_type, 0, data.table_id, item.customer_id, user.id_, db,)
if update_table:
do_update_table(one, None, db)
two = save(
two_inventories, now, item.voucher_type, item.pax, item.food_table_id, item.customer_id, user.id_, db,
)
if update_table:
do_update_table(two, None, db)
db.commit()
except SQLAlchemyError as e:
db.rollback()
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e),
)
except Exception:
db.rollback()
raise
def save( def save(
inventories, now, voucher_type, pax, table_id, customer_id, update_table, user_id, permissions, dbsession, inventories: List[Inventory],
now: datetime,
voucher_type: VoucherType,
pax: int,
table_id: uuid.UUID,
customer_id: Optional[uuid.UUID],
user_id: uuid.UUID,
db: Session,
): ):
product_quantities = {} product_quantities = {}
skip_products = set()
for i in inventories: for i in inventories:
if i.product_id in product_quantities: if (i.product_id, i.is_happy_hour) in product_quantities:
product_quantities[i.product_id] += i.quantity product_quantities[(i.product_id, i.is_happy_hour)][1] += i.quantity
else: else:
product_quantities[i.product_id] = i.quantity product_quantities[(i.product_id, i.is_happy_hour)] = (i, i.quantity)
for product, quantity in product_quantities.items(): for (product, happy_hour), (inventory, quantity) in product_quantities.items():
if quantity < 0: if quantity < 0:
raise ValidationError("Quantity is negative") raise HTTPException(
elif quantity == 0: status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail="Quantity of a product is negative",
skip_products.add(product) )
check_permissions(None, voucher_type, permissions) bill_id = get_bill_id(voucher_type, db)
bill_id = get_bill_id(voucher_type, dbsession) kot_id = db.query(func.coalesce(func.max(Voucher.kot_id), 0) + 1).scalar()
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) item: Voucher = Voucher(now, pax, bill_id, kot_id, table_id, customer_id, voucher_type, user_id)
dbsession.add(item) db.add(item)
code = dbsession.query(func.coalesce(func.max(Kot.code), 0) + 1).scalar() code = db.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) db.add(kot) # Multiple inventories of the same product give a key error, but combining messes with modifiers, this
for index, old_inventory in enumerate([i for i in inventories if i.product_id not in skip_products]): # will get important when modifiers have a price.
for index, (old_inventory, q) in enumerate([i for i in product_quantities.values() if i[1] != 0]):
inv = Inventory( inv = Inventory(
kot.id, kot.id,
old_inventory.product_id, old_inventory.product_id,
old_inventory.quantity, q,
old_inventory.price, old_inventory.price,
old_inventory.discount, old_inventory.discount,
old_inventory.is_happy_hour, old_inventory.is_happy_hour,
@ -104,15 +117,16 @@ def save(
index, index,
) )
kot.inventories.append(inv) kot.inventories.append(inv)
dbsession.add(inv) db.add(inv)
for m in old_inventory.modifiers: for m in old_inventory.modifiers:
mod = InventoryModifier(None, m.modifier_id, m.price) mod = InventoryModifier(None, m.modifier_id, m.price)
inv.modifiers.append(mod) inv.modifiers.append(mod)
dbsession.add(mod) db.add(mod)
do_update_settlements(item, dbsession) do_update_settlements(item, [], db)
if len(kot.inventories) == 0: if len(kot.inventories) == 0:
raise ValidationError("Please add some products!") raise HTTPException(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail="No inventories selected",
if update_table: )
do_update_table(item, None, dbsession) db.flush()
return item

View File

@ -58,6 +58,11 @@ def update(
item.food_table_id = data.table.id_ item.food_table_id = data.table.id_
if data.customer is not None: if data.customer is not None:
item.customer_id = data.customer.id_ item.customer_id = data.customer.id_
if item.voucher_type != VoucherType.KOT:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="Internal error, reprints should not reach here",
)
if item.voucher_type == VoucherType.KOT and voucher_type != VoucherType.KOT: if item.voucher_type == VoucherType.KOT and voucher_type != VoucherType.KOT:
item.date = now item.date = now
item.bill_id = get_bill_id(voucher_type, db) item.bill_id = get_bill_id(voucher_type, db)

15
barker/schemas/split.py Normal file
View File

@ -0,0 +1,15 @@
import uuid
from typing import List
from pydantic import BaseModel
from barker.schemas import to_camel
class Split(BaseModel):
inventories: List[uuid.UUID]
table_id: uuid.UUID
class Config:
alias_generator = to_camel
fields = {"id_": "id"}

View File

@ -1,68 +1,68 @@
<div fxLayout="row wrap" fxLayoutGap="grid 20px"> <div fxLayout="row wrap" fxLayoutGap="grid 20px">
<mat-card fxLayout="column" class="square-button" matRipple *ngIf="auth.user.perms.indexOf('guest-book') !== -1" [routerLink]="['/', 'guest-book']"> <mat-card fxLayout="column" class="square-button" matRipple *ngIf="auth.user && auth.user.perms.indexOf('guest-book') !== -1" [routerLink]="['/', 'guest-book']">
<h3 class="item-name">Guest Book</h3> <h3 class="item-name">Guest Book</h3>
</mat-card> </mat-card>
<mat-card fxLayout="column" class="square-button" matRipple *ngIf="auth.user.perms.indexOf('sales') !== -1" [routerLink]="['/', 'sales']"> <mat-card fxLayout="column" class="square-button" matRipple *ngIf="auth.user && auth.user.perms.indexOf('sales') !== -1" [routerLink]="['/', 'sales']">
<h3 class="item-name">Sales</h3> <h3 class="item-name">Sales</h3>
</mat-card> </mat-card>
<mat-card fxLayout="column" class="square-button" matRipple *ngIf="auth.user.perms.indexOf('cashier-report') !== -1" [routerLink]="['/', 'cashier-report']"> <mat-card fxLayout="column" class="square-button" matRipple *ngIf="auth.user && auth.user.perms.indexOf('cashier-report') !== -1" [routerLink]="['/', 'cashier-report']">
<h3 class="item-name">Cashier Report</h3> <h3 class="item-name">Cashier Report</h3>
</mat-card> </mat-card>
<mat-card fxLayout="column" class="square-button" matRipple *ngIf="auth.user.perms.indexOf('sale-report') !== -1" [routerLink]="['/', 'sale-report']"> <mat-card fxLayout="column" class="square-button" matRipple *ngIf="auth.user && auth.user.perms.indexOf('sale-report') !== -1" [routerLink]="['/', 'sale-report']">
<h3 class="item-name">Sale Report</h3> <h3 class="item-name">Sale Report</h3>
</mat-card> </mat-card>
<mat-card fxLayout="column" class="square-button" matRipple *ngIf="auth.user.perms.indexOf('tax-report') !== -1" [routerLink]="['/', 'tax-report']"> <mat-card fxLayout="column" class="square-button" matRipple *ngIf="auth.user && auth.user.perms.indexOf('tax-report') !== -1" [routerLink]="['/', 'tax-report']">
<h3 class="item-name">Tax Report</h3> <h3 class="item-name">Tax Report</h3>
</mat-card> </mat-card>
<mat-card fxLayout="column" class="square-button" matRipple *ngIf="auth.user.perms.indexOf('product-sale-report') !== -1" [routerLink]="['/', 'product-sale-report']"> <mat-card fxLayout="column" class="square-button" matRipple *ngIf="auth.user && auth.user.perms.indexOf('product-sale-report') !== -1" [routerLink]="['/', 'product-sale-report']">
<h3 class="item-name">Product Sale Report</h3> <h3 class="item-name">Product Sale Report</h3>
</mat-card> </mat-card>
<mat-card fxLayout="column" class="square-button" matRipple *ngIf="auth.user.perms.indexOf('bill-settlement-report') !== -1" [routerLink]="['/', 'bill-settlement-report']"> <mat-card fxLayout="column" class="square-button" matRipple *ngIf="auth.user && auth.user.perms.indexOf('bill-settlement-report') !== -1" [routerLink]="['/', 'bill-settlement-report']">
<h3 class="item-name">Bill Settlement Report</h3> <h3 class="item-name">Bill Settlement Report</h3>
</mat-card> </mat-card>
<mat-card fxLayout="column" class="square-button" matRipple *ngIf="auth.user.perms.indexOf('beer-consumption-report') !== -1" [routerLink]="['/', 'beer-consumption-report']"> <mat-card fxLayout="column" class="square-button" matRipple *ngIf="auth.user && auth.user.perms.indexOf('beer-consumption-report') !== -1" [routerLink]="['/', 'beer-consumption-report']">
<h3 class="item-name">Beer Consumption Report</h3> <h3 class="item-name">Beer Consumption Report</h3>
</mat-card> </mat-card>
<mat-card fxLayout="column" class="square-button" matRipple *ngIf="auth.user.perms.indexOf('discount-report') !== -1" [routerLink]="['/', 'discount-report']"> <mat-card fxLayout="column" class="square-button" matRipple *ngIf="auth.user && auth.user.perms.indexOf('discount-report') !== -1" [routerLink]="['/', 'discount-report']">
<h3 class="item-name">Discount Report</h3> <h3 class="item-name">Discount Report</h3>
</mat-card> </mat-card>
<mat-card fxLayout="column" class="square-button" matRipple *ngIf="auth.user.perms.indexOf('tables') !== -1" [routerLink]="['/', 'tables']"> <mat-card fxLayout="column" class="square-button" matRipple *ngIf="auth.user && auth.user.perms.indexOf('tables') !== -1" [routerLink]="['/', 'tables']">
<h3 class="item-name">Tables</h3> <h3 class="item-name">Tables</h3>
</mat-card> </mat-card>
<mat-card fxLayout="column" class="square-button" matRipple *ngIf="auth.user.perms.indexOf('sections') !== -1" [routerLink]="['/', 'sections']"> <mat-card fxLayout="column" class="square-button" matRipple *ngIf="auth.user && auth.user.perms.indexOf('sections') !== -1" [routerLink]="['/', 'sections']">
<h3 class="item-name">Sections</h3> <h3 class="item-name">Sections</h3>
</mat-card> </mat-card>
<mat-card fxLayout="column" class="square-button" matRipple *ngIf="auth.user.perms.indexOf('products') !== -1" [routerLink]="['/', 'menu-categories']"> <mat-card fxLayout="column" class="square-button" matRipple *ngIf="auth.user && auth.user.perms.indexOf('products') !== -1" [routerLink]="['/', 'menu-categories']">
<h3 class="item-name">Menu Categories</h3> <h3 class="item-name">Menu Categories</h3>
</mat-card> </mat-card>
<mat-card fxLayout="column" class="square-button" matRipple *ngIf="auth.user.perms.indexOf('products') !== -1" [routerLink]="['/', 'sale-categories']"> <mat-card fxLayout="column" class="square-button" matRipple *ngIf="auth.user && auth.user.perms.indexOf('products') !== -1" [routerLink]="['/', 'sale-categories']">
<h3 class="item-name">Sale Categories</h3> <h3 class="item-name">Sale Categories</h3>
</mat-card> </mat-card>
<mat-card fxLayout="column" class="square-button" matRipple *ngIf="auth.user.perms.indexOf('products') !== -1" [routerLink]="['/', 'products']"> <mat-card fxLayout="column" class="square-button" matRipple *ngIf="auth.user && auth.user.perms.indexOf('products') !== -1" [routerLink]="['/', 'products']">
<h3 class="item-name">Products</h3> <h3 class="item-name">Products</h3>
</mat-card> </mat-card>
<mat-card fxLayout="column" class="square-button" matRipple *ngIf="auth.user.perms.indexOf('modifiers') !== -1" [routerLink]="['/', 'modifier-categories']"> <mat-card fxLayout="column" class="square-button" matRipple *ngIf="auth.user && auth.user.perms.indexOf('modifiers') !== -1" [routerLink]="['/', 'modifier-categories']">
<h3 class="item-name">Modifier Categories</h3> <h3 class="item-name">Modifier Categories</h3>
</mat-card> </mat-card>
<mat-card fxLayout="column" class="square-button" matRipple *ngIf="auth.user.perms.indexOf('modifiers') !== -1" [routerLink]="['/', 'modifiers']"> <mat-card fxLayout="column" class="square-button" matRipple *ngIf="auth.user && auth.user.perms.indexOf('modifiers') !== -1" [routerLink]="['/', 'modifiers']">
<h3 class="item-name">Modifiers</h3> <h3 class="item-name">Modifiers</h3>
</mat-card> </mat-card>
<mat-card fxLayout="column" class="square-button" matRipple *ngIf="auth.user.perms.indexOf('taxes') !== -1" [routerLink]="['/', 'taxes']"> <mat-card fxLayout="column" class="square-button" matRipple *ngIf="auth.user && auth.user.perms.indexOf('taxes') !== -1" [routerLink]="['/', 'taxes']">
<h3 class="item-name">Taxes</h3> <h3 class="item-name">Taxes</h3>
</mat-card> </mat-card>
<mat-card fxLayout="column" class="square-button" matRipple *ngIf="auth.user.perms.indexOf('devices') !== -1" [routerLink]="['/', 'devices']"> <mat-card fxLayout="column" class="square-button" matRipple *ngIf="auth.user && auth.user.perms.indexOf('devices') !== -1" [routerLink]="['/', 'devices']">
<h3 class="item-name">Devices</h3> <h3 class="item-name">Devices</h3>
</mat-card> </mat-card>
<mat-card fxLayout="column" class="square-button" matRipple *ngIf="auth.user.perms.indexOf('section-printers') !== -1" [routerLink]="['/', 'section-printers']"> <mat-card fxLayout="column" class="square-button" matRipple *ngIf="auth.user && auth.user.perms.indexOf('section-printers') !== -1" [routerLink]="['/', 'section-printers']">
<h3 class="item-name">Section Printers</h3> <h3 class="item-name">Section Printers</h3>
</mat-card> </mat-card>
<mat-card fxLayout="column" class="square-button" matRipple *ngIf="auth.user.perms.indexOf('printers') !== -1" [routerLink]="['/', 'printers']"> <mat-card fxLayout="column" class="square-button" matRipple *ngIf="auth.user && auth.user.perms.indexOf('printers') !== -1" [routerLink]="['/', 'printers']">
<h3 class="item-name">Printers</h3> <h3 class="item-name">Printers</h3>
</mat-card> </mat-card>
<mat-card fxLayout="column" class="square-button" matRipple *ngIf="auth.user.perms.indexOf('users') !== -1" [routerLink]="['/', 'roles']"> <mat-card fxLayout="column" class="square-button" matRipple *ngIf="auth.user && auth.user.perms.indexOf('users') !== -1" [routerLink]="['/', 'roles']">
<h3 class="item-name">Roles</h3> <h3 class="item-name">Roles</h3>
</mat-card> </mat-card>
<mat-card fxLayout="column" class="square-button" matRipple *ngIf="auth.user.perms.indexOf('users') !== -1" [routerLink]="['/', 'users']"> <mat-card fxLayout="column" class="square-button" matRipple *ngIf="auth.user && auth.user.perms.indexOf('users') !== -1" [routerLink]="['/', 'users']">
<h3 class="item-name">Users</h3> <h3 class="item-name">Users</h3>
</mat-card> </mat-card>
</div> </div>

View File

@ -13,6 +13,7 @@ const httpOptions = {
const url = '/api/voucher'; const url = '/api/voucher';
const urlMoveTable = '/api/move-table'; const urlMoveTable = '/api/move-table';
const urlMoveKot = '/api/move-kot'; const urlMoveKot = '/api/move-kot';
const urlSplitBill = '/api/split-bill';
const serviceName = 'VoucherService'; const serviceName = 'VoucherService';
@Injectable({providedIn: 'root'}) @Injectable({providedIn: 'root'})
@ -140,11 +141,10 @@ export class VoucherService {
} }
splitBill(id: string, inventoriesToMove: string[], table: Table) { splitBill(id: string, inventoriesToMove: string[], table: Table) {
const options = {params: new HttpParams().set('split-bill', '').set('u', 'true')}; const options = {params: new HttpParams().set('u', 'true')};
return <Observable<boolean>>this.http.post<boolean>(`${url}/${id}`, { return <Observable<boolean>>this.http.post<boolean>(`${urlSplitBill}/${id}`, {
voucher: {id: id},
inventories: inventoriesToMove, inventories: inventoriesToMove,
table: {id: table.id} tableId: table.id
}, options).pipe( }, options).pipe(
catchError(this.log.handleError(serviceName, 'splitBill')) catchError(this.log.handleError(serviceName, 'splitBill'))
); );

View File

@ -39,7 +39,7 @@ export class SalesHomeComponent implements OnInit {
} }
printKotAllowed(): boolean { printKotAllowed(): boolean {
if (this.auth.user.perms.indexOf('print-kot') === -1) { if (this.auth.user && this.auth.user.perms.indexOf('print-kot') === -1) {
return false; return false;
} }
if (!this.bs.bill.id) { if (!this.bs.bill.id) {
@ -69,7 +69,7 @@ export class SalesHomeComponent implements OnInit {
} }
discountAllowed(): boolean { discountAllowed(): boolean {
return this.auth.user.perms.indexOf('discount') !== -1; return this.auth.user && this.auth.user.perms.indexOf('discount') !== -1;
} }
showDiscount(): Observable<boolean | { id: string, name: string, discount: number }[]> { showDiscount(): Observable<boolean | { id: string, name: string, discount: number }[]> {
@ -120,7 +120,7 @@ export class SalesHomeComponent implements OnInit {
} }
printBillAllowed(): boolean { printBillAllowed(): boolean {
if (this.auth.user.perms.indexOf('print-bill') === -1) { if (this.auth.user && this.auth.user.perms.indexOf('print-bill') === -1) {
return false; return false;
} }
if (!this.bs.bill.id) { if (!this.bs.bill.id) {
@ -143,7 +143,7 @@ export class SalesHomeComponent implements OnInit {
if (this.route.snapshot.queryParamMap.has('guest')) { if (this.route.snapshot.queryParamMap.has('guest')) {
guestBookId = this.route.snapshot.queryParamMap.get('guest'); guestBookId = this.route.snapshot.queryParamMap.get('guest');
} }
let discountObservable: Observable<any> = (this.discountAllowed()) ? this.showDiscount() : observableOf(''); const discountObservable: Observable<any> = (this.discountAllowed()) ? this.showDiscount() : observableOf('');
discountObservable.pipe( discountObservable.pipe(
tap((result: boolean | { id: string, name: string, discount: number }[]) => { tap((result: boolean | { id: string, name: string, discount: number }[]) => {
@ -169,7 +169,7 @@ export class SalesHomeComponent implements OnInit {
} }
receivePaymentAllowed(): boolean { receivePaymentAllowed(): boolean {
if (this.auth.user.perms.indexOf('settle-bill') === -1) { if (this.auth.user && this.auth.user.perms.indexOf('settle-bill') === -1) {
return false; return false;
} }
if (!this.bs.bill.id) { if (!this.bs.bill.id) {
@ -184,7 +184,7 @@ export class SalesHomeComponent implements OnInit {
return true; return true;
} }
receivePaymentWithReason(type:string, amount: number): Observable<boolean> { receivePaymentWithReason(type: string, amount: number): Observable<boolean> {
const types = { const types = {
NO_CHARGE: [ NO_CHARGE: [
{ {
@ -203,13 +203,13 @@ export class SalesHomeComponent implements OnInit {
}; };
return this.dialog.open(ReasonComponent, { return this.dialog.open(ReasonComponent, {
// width: '750px' // width: '750px'
data: {title: (type === "NO_CHARGE") ? "NC for whom" : "Staff name"} data: {title: (type === 'NO_CHARGE') ? 'NC for whom' : 'Staff name'}
}).afterClosed().pipe( }).afterClosed().pipe(
switchMap((value: boolean | string) => { switchMap((value: boolean | string) => {
if (!!value) { if (!!value) {
return this.bs.receivePayment(types[type], value as string) return this.bs.receivePayment(types[type], value as string);
} else { } else {
return throwError("Cancelled"); return throwError('Cancelled');
} }
}) })
); );
@ -227,7 +227,7 @@ export class SalesHomeComponent implements OnInit {
if (!!value) { if (!!value) {
return this.bs.receivePayment(value as { id: number, name: string, amount: number }[], '') return this.bs.receivePayment(value as { id: number, name: string, amount: number }[], '')
} else { } else {
return throwError("Cancelled"); return throwError('Cancelled');
} }
}) })
); );
@ -252,7 +252,7 @@ export class SalesHomeComponent implements OnInit {
moveTableAllowed(): boolean { moveTableAllowed(): boolean {
// TODO: Check if this condition should be "and" or "or" // TODO: Check if this condition should be "and" or "or"
if (this.auth.user.perms.indexOf('move-table') === -1 && this.auth.user.perms.indexOf('merge-tables') === -1) { if (this.auth.user && this.auth.user.perms.indexOf('move-table') === -1 && this.auth.user.perms.indexOf('merge-tables') === -1) {
return false; return false;
} }
if (!this.bs.bill.id) { if (!this.bs.bill.id) {
@ -300,7 +300,7 @@ export class SalesHomeComponent implements OnInit {
} }
voidBillAllowed(): boolean { voidBillAllowed(): boolean {
if (this.auth.user.perms.indexOf('void-bill') === -1) { if (this.auth.user && this.auth.user.perms.indexOf('void-bill') === -1) {
return false; return false;
} }
if (!this.bs.bill.id) { if (!this.bs.bill.id) {
@ -352,7 +352,7 @@ export class SalesHomeComponent implements OnInit {
} }
splitBillAllowed(): boolean { splitBillAllowed(): boolean {
if (this.auth.user.perms.indexOf('split-bill') === -1) { if (this.auth.user && this.auth.user.perms.indexOf('split-bill') === -1) {
return false; return false;
} }
if (!this.bs.bill.id) { if (!this.bs.bill.id) {