Fix selling ordering bug that created "not enough money" errors

* Add tests
* Add tests for cons/dcons
This commit is contained in:
Antoine Bartuccio 2025-01-10 16:35:42 +01:00
parent 6ee2e8c5da
commit a4c6439981
3 changed files with 95 additions and 2 deletions

View File

@ -460,6 +460,7 @@ Welcome to the wiki page!
limit_age=18, limit_age=18,
) )
cons = Product.objects.create( cons = Product.objects.create(
id=settings.SITH_ECOCUP_CONS,
name="Consigne Eco-cup", name="Consigne Eco-cup",
code="CONS", code="CONS",
product_type=verre, product_type=verre,
@ -469,6 +470,7 @@ Welcome to the wiki page!
club=main_club, club=main_club,
) )
dcons = Product.objects.create( dcons = Product.objects.create(
id=settings.SITH_ECOCUP_DECO,
name="Déconsigne Eco-cup", name="Déconsigne Eco-cup",
code="DECO", code="DECO",
product_type=verre, product_type=verre,

View File

@ -236,6 +236,10 @@ class TestCounterClick(TestFullClickBase):
BanGroup.objects.get(pk=settings.SITH_GROUP_BANNED_COUNTER_ID) BanGroup.objects.get(pk=settings.SITH_GROUP_BANNED_COUNTER_ID)
) )
cls.gift = product_recipe.make(
selling_price="-1.5",
special_selling_price="-1.5",
)
cls.beer = product_recipe.make( cls.beer = product_recipe.make(
limit_age=18, selling_price="1.5", special_selling_price="1" limit_age=18, selling_price="1.5", special_selling_price="1"
) )
@ -253,7 +257,12 @@ class TestCounterClick(TestFullClickBase):
limit_age=0, selling_price="1.5", special_selling_price="1" limit_age=0, selling_price="1.5", special_selling_price="1"
) )
cls.counter.products.add(cls.beer, cls.beer_tap, cls.snack) cls.cons = Product.objects.get(id=settings.SITH_ECOCUP_CONS)
cls.dcons = Product.objects.get(id=settings.SITH_ECOCUP_DECO)
cls.counter.products.add(
cls.gift, cls.beer, cls.beer_tap, cls.snack, cls.cons, cls.dcons
)
cls.other_counter.products.add(cls.snack) cls.other_counter.products.add(cls.snack)
@ -594,6 +603,84 @@ class TestCounterClick(TestFullClickBase):
else: else:
assert not counter.has_annotated_barman assert not counter.has_annotated_barman
def test_selling_ordering(self):
# Cheaper items should be processed with a higher priority
self.login_in_bar(self.barmen)
assert (
self.submit_basket(
self.customer,
[
BasketItem(self.beer.id, 1),
BasketItem(self.gift.id, 1),
],
).status_code
== 302
)
assert self.updated_amount(self.customer) == 0
def test_recordings(self):
self.refill_user(self.customer, self.cons.selling_price * 3)
self.login_in_bar(self.barmen)
assert (
self.submit_basket(
self.customer,
[BasketItem(self.cons.id, 3)],
).status_code
== 302
)
assert self.updated_amount(self.customer) == 0
assert (
self.submit_basket(
self.customer,
[BasketItem(self.dcons.id, 3)],
).status_code
== 302
)
assert self.updated_amount(self.customer) == self.dcons.selling_price * -3
assert (
self.submit_basket(
self.customer,
[BasketItem(self.dcons.id, settings.SITH_ECOCUP_LIMIT)],
).status_code
== 302
)
assert self.updated_amount(self.customer) == self.dcons.selling_price * (
-3 - settings.SITH_ECOCUP_LIMIT
)
assert (
self.submit_basket(
self.customer,
[BasketItem(self.dcons.id, 1)],
).status_code
== 200
)
assert self.updated_amount(self.customer) == self.dcons.selling_price * (
-3 - settings.SITH_ECOCUP_LIMIT
)
assert (
self.submit_basket(
self.customer,
[
BasketItem(self.cons.id, 1),
BasketItem(self.dcons.id, 1),
],
).status_code
== 302
)
assert self.updated_amount(self.customer) == self.dcons.selling_price * (
-3 - settings.SITH_ECOCUP_LIMIT
)
class TestCounterStats(TestCase): class TestCounterStats(TestCase):
@classmethod @classmethod

View File

@ -194,7 +194,11 @@ class CounterClick(CounterTabsMixin, CanViewMixin, SingleObjectMixin, FormView):
with transaction.atomic(): with transaction.atomic():
self.request.session["last_basket"] = [] self.request.session["last_basket"] = []
for form in formset: # We sort items from cheap to expensive
# This is important because some items have a negative price
# Negative priced items gives money to the customer and should
# be processed first so that we don't throw a not enough money error
for form in sorted(formset, key=lambda form: form.product.price):
self.request.session["last_basket"].append( self.request.session["last_basket"].append(
f"{form.cleaned_data['quantity']} x {form.product.name}" f"{form.cleaned_data['quantity']} x {form.product.name}"
) )