From c13047e8128e77fdc67f2dbafe73ef43e46263d7 Mon Sep 17 00:00:00 2001 From: Amritanshu Date: Fri, 24 Mar 2023 10:17:06 +0530 Subject: [PATCH] Fix: Check if moved/merged kots could lead to negative products of a situation where happy hour products were more than regular products. Case: Kot 1: Beer Mug => 2 regular, 2 happy hour Kot 2: Beer Mug => 2 Regular Kot 3: Beer Mug => -2 Regular Then move Kot 2 to new table would leave the voucher with 2 hh and 0 regular Also, just move did not check if products were going negative. --- barker/barker/routers/voucher/__init__.py | 5 +- barker/barker/routers/voucher/merge_move.py | 61 ++++++++++++++++++--- 2 files changed, 54 insertions(+), 12 deletions(-) diff --git a/barker/barker/routers/voucher/__init__.py b/barker/barker/routers/voucher/__init__.py index f6c11d5..4ecb050 100644 --- a/barker/barker/routers/voucher/__init__.py +++ b/barker/barker/routers/voucher/__init__.py @@ -1,17 +1,16 @@ import uuid -from datetime import datetime from decimal import Decimal -from typing import List, Set +from typing import Set import barker.schemas.voucher as schemas -from barker.models.bill import Bill from fastapi import HTTPException, status from sqlalchemy import func from sqlalchemy.orm import Session from sqlalchemy.sql import expression +from ...models.bill import Bill from ...models.guest_book import GuestBook from ...models.overview import Overview from ...models.regime import Regime diff --git a/barker/barker/routers/voucher/merge_move.py b/barker/barker/routers/voucher/merge_move.py index 97616cf..180e6f0 100644 --- a/barker/barker/routers/voucher/merge_move.py +++ b/barker/barker/routers/voucher/merge_move.py @@ -50,7 +50,20 @@ def merge_kot( .where(Kot.id == data.kot_id, Kot.voucher_id == data.voucher_id) .values(voucher_id=data.new_voucher_id) ) - update_settlements([data.voucher_id, data.new_voucher_id], db) + donor: Voucher = db.execute(select(Voucher).where(Voucher.id == data.voucher_id)).scalar_one() + recipent: Voucher = db.execute(select(Voucher).where(Voucher.id == data.new_voucher_id)).scalar_one() + if has_negatives(donor.kots) or happy_hour_exceeds_regular(donor.kots): + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="Donor voucher will have negative products or too many happy hours", + ) + if has_negatives(recipent.kots) or happy_hour_exceeds_regular(recipent.kots): + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="Recipient voucher will have negative products or too many happy hours", + ) + do_update_settlements(donor, [], db) + do_update_settlements(recipent, [], db) db.commit() except SQLAlchemyError as e: raise HTTPException( @@ -91,7 +104,19 @@ def move_kot( db.flush() do_update_bill_numbers(item, db) do_update_table(item, None, db) - update_settlements([data.voucher_id, item.id], db) + donor: Voucher = db.execute(select(Voucher).where(Voucher.id == data.voucher_id)).scalar_one() + if has_negatives(donor.kots) or happy_hour_exceeds_regular(donor.kots): + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="Donor voucher will have negative products or too many happy hours", + ) + if has_negatives(item.kots) or happy_hour_exceeds_regular(item.kots): + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="Recipient voucher will have negative products or too many happy hours", + ) + do_update_settlements(donor, [], db) + do_update_settlements(item, [], db) db.commit() except SQLAlchemyError as e: raise HTTPException( @@ -133,7 +158,8 @@ def merge_table( db.execute(delete(Overview).where(Overview.voucher_id == data.voucher_id)) db.execute(delete(Settlement).where(Settlement.voucher_id == data.voucher_id)) db.execute(delete(Voucher).where(Voucher.id == data.voucher_id)) - update_settlements([data.new_voucher_id], db) + recipent: Voucher = db.execute(select(Voucher).where(Voucher.id == data.new_voucher_id)).scalar_one() + do_update_settlements(recipent, [], db) db.commit() except SQLAlchemyError as e: traceback.print_exc() @@ -143,12 +169,6 @@ def merge_table( ) -def update_settlements(vouchers: list[uuid.UUID], db: Session): - for v in vouchers: - voucher: Voucher = db.execute(select(Voucher).where(Voucher.id == v)).scalar_one() - do_update_settlements(voucher, [], db) - - def check_if_voucher_is_unprinted(voucher_id: uuid.UUID, db: Session) -> None: voucher_type: VoucherType = db.execute(select(Voucher.voucher_type).where(Voucher.id == voucher_id)).scalar_one() if voucher_type is None: @@ -161,3 +181,26 @@ def check_if_voucher_is_unprinted(voucher_id: uuid.UUID, db: Session) -> None: status_code=status.HTTP_403_FORBIDDEN, detail="Bill is printed or void.", ) + + +def has_negatives(kots: list[Kot]) -> bool: + inv = [i for k in kots for i in k.inventories] + products = set((i.product_id, i.is_happy_hour) for i in inv) + for id_, hh in products: + quantity = sum(i.quantity for i in inv if i.product_id == id_ and i.is_happy_hour == hh) + if quantity < 0: + return True + return False + + +# This is for the whole bill. eg. Kot 1 => Reg 2 + HH 2; Kot 2 => Reg 4; Kot 3 => Reg - 4 +# This is pass okay in happy hours items balanced, but overall this is wrong. Hence this check +def happy_hour_exceeds_regular(kots: list[Kot]) -> bool: + inv = [i for k in kots for i in k.inventories] + products = set(i.product_id for i in inv if i.is_happy_hour) + for p in products: + r = sum(i.quantity for i in inv if i.product_id == p and not i.is_happy_hour) + h = sum(i.quantity for i in inv if i.product_id == p and i.is_happy_hour) + if r < h: + return True + return False