From 0f0e4f854a2a9346d6cd60c00f1a20b7fed935dd Mon Sep 17 00:00:00 2001 From: Gabriel Augendre Date: Mon, 27 Mar 2023 18:26:40 +0200 Subject: [PATCH] Remove no payment method as option --- .../commands/generate_dummy_baskets.py | 4 +- .../0014_alter_basket_payment_method.py | 35 ++++++++++++++++ src/purchase/models.py | 7 +--- .../templates/purchase/basket_list.html | 2 +- src/purchase/templates/purchase/reports.html | 3 -- .../snippets/report_no_payment_method.html | 21 ---------- src/purchase/tests/test_cashier_flow.py | 42 ++++++++----------- src/purchase/views/reports.py | 1 - 8 files changed, 57 insertions(+), 58 deletions(-) create mode 100644 src/purchase/migrations/0014_alter_basket_payment_method.py delete mode 100644 src/purchase/templates/purchase/snippets/report_no_payment_method.html diff --git a/src/purchase/management/commands/generate_dummy_baskets.py b/src/purchase/management/commands/generate_dummy_baskets.py index 68ae2e5..0cb7d4a 100644 --- a/src/purchase/management/commands/generate_dummy_baskets.py +++ b/src/purchase/management/commands/generate_dummy_baskets.py @@ -36,9 +36,7 @@ class Command(BaseCommand): methods_weights = [random.randint(1, 6) for _ in range(len(payment_methods))] products_weights = [1 / product.display_order for product in products] for _ in range(count): - method = None - if random.random() < 0.99: # noqa: PLR2004 - method = random.choices(payment_methods, weights=methods_weights)[0] + method = random.choices(payment_methods, weights=methods_weights)[0] basket = Basket.objects.create(payment_method=method) items_in_basket = int(random.normalvariate(3, 2)) if items_in_basket > len(products): diff --git a/src/purchase/migrations/0014_alter_basket_payment_method.py b/src/purchase/migrations/0014_alter_basket_payment_method.py new file mode 100644 index 0000000..6be2bb4 --- /dev/null +++ b/src/purchase/migrations/0014_alter_basket_payment_method.py @@ -0,0 +1,35 @@ +# Generated by Django 4.1.7 on 2023-03-27 16:22 + +import django.db.models.deletion +from django.db import migrations, models + + +def delete_baskets_without_payment_method(apps, schema_editor): + Basket = apps.get_model("purchase", "Basket") # noqa: N806 + Basket.objects.using(schema_editor.connection.alias).filter( + payment_method=None, + ).delete() + + +class Migration(migrations.Migration): + dependencies = [ + ("purchase", "0013_remove_basketitem_unique_product_per_basket_and_more"), + ] + + operations = [ + # Remove baskets with no payment method + migrations.RunPython( + delete_baskets_without_payment_method, + migrations.RunPython.noop, + ), + migrations.AlterField( + model_name="basket", + name="payment_method", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + related_name="baskets", + to="purchase.paymentmethod", + verbose_name="payment method", + ), + ), + ] diff --git a/src/purchase/models.py b/src/purchase/models.py index 22e7b26..4470d77 100644 --- a/src/purchase/models.py +++ b/src/purchase/models.py @@ -179,17 +179,14 @@ class BasketQuerySet(models.QuerySet): def turnover(self) -> int: return self.priced().aggregate(total=Sum("price"))["total"] - def no_payment_method(self) -> BasketQuerySet: - return self.filter(payment_method=None) - class Basket(Model): payment_method = models.ForeignKey( to=PaymentMethod, on_delete=models.PROTECT, related_name="baskets", - null=True, - blank=True, + null=False, + blank=False, verbose_name=_("payment method"), ) diff --git a/src/purchase/templates/purchase/basket_list.html b/src/purchase/templates/purchase/basket_list.html index f80048d..ffe053e 100644 --- a/src/purchase/templates/purchase/basket_list.html +++ b/src/purchase/templates/purchase/basket_list.html @@ -6,7 +6,7 @@
{% for basket in baskets %}
-
+
{% blocktranslate with basket_id=basket.id %}Basket #{{ basket_id }}{% endblocktranslate %}

diff --git a/src/purchase/templates/purchase/reports.html b/src/purchase/templates/purchase/reports.html index 17a232d..c114d7e 100644 --- a/src/purchase/templates/purchase/reports.html +++ b/src/purchase/templates/purchase/reports.html @@ -35,9 +35,6 @@

{% translate "Turnover by payment method" %}

{% include "purchase/snippets/report_payment_methods.html" %} - -

{% translate "Baskets without payment method" %}

- {% include "purchase/snippets/report_no_payment_method.html" %} {% endblock %} {% block extrascript %} diff --git a/src/purchase/templates/purchase/snippets/report_no_payment_method.html b/src/purchase/templates/purchase/snippets/report_no_payment_method.html deleted file mode 100644 index 18fc5b3..0000000 --- a/src/purchase/templates/purchase/snippets/report_no_payment_method.html +++ /dev/null @@ -1,21 +0,0 @@ -{% load i18n %} -{% load purchase %} - - - - - - - - {% for basket in no_payment_method %} - - - - - {% endfor %} - -
{% translate "Basket" %}{% translate "Price" %}
- - {{ basket }} - - {{ basket.price|currency }}
diff --git a/src/purchase/tests/test_cashier_flow.py b/src/purchase/tests/test_cashier_flow.py index 4b44597..b1658d5 100644 --- a/src/purchase/tests/test_cashier_flow.py +++ b/src/purchase/tests/test_cashier_flow.py @@ -114,14 +114,21 @@ def test_cashier_create_and_update_basket( # noqa: PLR0915 chain.double_click(price_input).perform() price_input.send_keys("401") - # Don't add payment method + # Add payment method + selenium.find_element(By.TAG_NAME, "html").send_keys(Keys.END) + time.sleep(1) + selenium.find_element( + By.CSS_SELECTOR, + f'input[type="radio"][value="{payment_methods[1].pk}"]', + ).click() + # Save selenium.find_element(By.ID, "submit-id-submit").click() # Assert entries saved in DB (new basket with proper products) assert Basket.objects.count() == 1 basket = Basket.objects.priced().first() - assert basket.payment_method is None + assert basket.payment_method == payment_methods[1] assert basket.items.count() == 4 assert basket.items.get(product=products[0]).quantity == 2 assert ( @@ -150,10 +157,6 @@ def test_cashier_create_and_update_basket( # noqa: PLR0915 created_message = selenium.find_element(By.CSS_SELECTOR, ".messages .alert-success") assert created_message.text == "Panier correctement créé." - # Assert message in red for missing payment method - missing_payment = selenium.find_element(By.CSS_SELECTOR, ".alert.alert-danger") - assert missing_payment.text == "Moyen de paiement manquant." - # Assert ID, price, date & product quantities # Selected products have a green background title = selenium.find_element(By.TAG_NAME, "h1") @@ -193,11 +196,6 @@ def test_cashier_create_and_update_basket( # noqa: PLR0915 quantity = int(quantity_input.get_attribute("value")) assert quantity == 3 - # Add payment method - selenium.find_element(By.TAG_NAME, "html").send_keys(Keys.END) - time.sleep(1) - selenium.find_element(By.ID, f"id_payment_method_{payment_methods[1].pk}").click() - # Save selenium.find_element(By.ID, "submit-id-submit").click() @@ -275,34 +273,30 @@ def test_baskets_list(live_server: LiveServer, selenium: WebDriver): pk=basket_with_payment_method.pk, ) with freezegun.freeze_time("2022-09-24 19:02:00+0200"): - basket_no_payment_method = BasketWithItemsFactory(payment_method=None) - basket_no_payment_method = Basket.objects.priced().get( - pk=basket_no_payment_method.pk, + another_basket = BasketWithItemsFactory() + another_basket = Basket.objects.priced().get( + pk=another_basket.pk, ) # Login url = reverse("purchase:list") login(live_server, selenium, cashier, url) - # Assert first basket (last created) has yellow background # Assert basket info displayed displayed_baskets = selenium.find_elements(By.CSS_SELECTOR, ".card.h-100") first_basket = displayed_baskets[0] - assert "bg-warning" in first_basket.get_attribute("class") text = first_basket.text.replace("\n", " ") - assert f"n°{basket_no_payment_method.pk} " in text - expected_articles_count = basket_no_payment_method.items.count() + assert f"n°{another_basket.pk} " in text + expected_articles_count = another_basket.items.count() assert f" {expected_articles_count} article" in text - expected_price = basket_no_payment_method.price / 100 + expected_price = another_basket.price / 100 assert f" {expected_price:.2f}€" in text - expected_payment_method = "-" + expected_payment_method = another_basket.payment_method.name assert f" {expected_payment_method} " in text assert "19:02" in text - # Assert second basket (first created) doesn't have yellow background # Assert basket info displayed including payment method second_basket = displayed_baskets[1] - assert "bg-warning" not in second_basket.get_attribute("class") text = second_basket.text.replace("\n", " ") assert f"n°{basket_with_payment_method.pk} " in text expected_articles_count = basket_with_payment_method.items.count() @@ -321,7 +315,7 @@ def test_baskets_list(live_server: LiveServer, selenium: WebDriver): # Assert object deleted in DB assert Basket.objects.count() == 1 - assert Basket.objects.first() == basket_no_payment_method + assert Basket.objects.first() == another_basket # Assert redirected to list view wait.until( @@ -336,7 +330,7 @@ def test_baskets_list(live_server: LiveServer, selenium: WebDriver): redirect_url = live_reverse( live_server, "purchase:update", - pk=basket_no_payment_method.pk, + pk=another_basket.pk, ) wait.until(lambda driver: driver.current_url == redirect_url) diff --git a/src/purchase/views/reports.py b/src/purchase/views/reports.py index eb217bb..602b9e7 100644 --- a/src/purchase/views/reports.py +++ b/src/purchase/views/reports.py @@ -79,7 +79,6 @@ def reports(request): "average_basket_by_day": average_basket_by_day, "products": products, "payment_methods": PaymentMethod.objects.with_turnover().with_sold(), - "no_payment_method": Basket.objects.no_payment_method().priced(), } return TemplateResponse(request, template_name, context)