make Selling.payment_method a SmallIntegerField

This commit is contained in:
imperosol
2025-11-19 19:56:21 +01:00
parent 2a5893aa79
commit 78fe4e52ca
8 changed files with 53 additions and 25 deletions

View File

@@ -4,9 +4,35 @@ from django.db import migrations, models
from django.db.migrations.state import StateApps from django.db.migrations.state import StateApps
def migrate_payment_method(apps: StateApps, schema_editor):
Selling = apps.get_model("counter", "Selling")
Selling.objects.filter(payment_method_str="CARD").update(payment_method=1)
def migrate_payment_method_reverse(apps: StateApps, schema_editor):
Selling = apps.get_model("counter", "Selling")
Selling.objects.filter(payment_method=1).update(payment_method_str="CARD")
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [("counter", "0034_alter_selling_date_selling_date_month_idx")] dependencies = [("counter", "0034_alter_selling_date_selling_date_month_idx")]
operations = [ operations = [
migrations.RemoveField(model_name="selling", name="is_validated"), migrations.RemoveField(model_name="selling", name="is_validated"),
migrations.RenameField(
model_name="selling",
old_name="payment_method",
new_name="payment_method_str",
),
migrations.AddField(
model_name="selling",
name="payment_method",
field=models.PositiveSmallIntegerField(
choices=[(0, "Sith account"), (1, "Credit card")],
default=0,
verbose_name="payment method",
),
),
migrations.RunPython(migrate_payment_method, migrate_payment_method_reverse),
migrations.RemoveField(model_name="selling", name="payment_method_str"),
] ]

View File

@@ -80,7 +80,8 @@ class CustomerQuerySet(models.QuerySet):
) )
money_out = Subquery( money_out = Subquery(
Selling.objects.filter( Selling.objects.filter(
customer=OuterRef("pk"), payment_method="SITH_ACCOUNT" customer=OuterRef("pk"),
payment_method=Selling.PaymentMethod.SITH_ACCOUNT,
) )
.values("customer_id") .values("customer_id")
.annotate(res=Sum(F("unit_price") * F("quantity"), default=0)) .annotate(res=Sum(F("unit_price") * F("quantity"), default=0))
@@ -814,6 +815,10 @@ class SellingQuerySet(models.QuerySet):
class Selling(models.Model): class Selling(models.Model):
"""Handle the sellings.""" """Handle the sellings."""
class PaymentMethod(models.IntegerChoices):
SITH_ACCOUNT = 0, _("Sith account")
CARD = 1, _("Credit card")
# We make sure that sellings have a way begger label than any product name is allowed to # We make sure that sellings have a way begger label than any product name is allowed to
label = models.CharField(_("label"), max_length=128) label = models.CharField(_("label"), max_length=128)
product = models.ForeignKey( product = models.ForeignKey(
@@ -850,11 +855,8 @@ class Selling(models.Model):
on_delete=models.SET_NULL, on_delete=models.SET_NULL,
) )
date = models.DateTimeField(_("date"), db_index=True) date = models.DateTimeField(_("date"), db_index=True)
payment_method = models.CharField( payment_method = models.PositiveSmallIntegerField(
_("payment method"), _("payment method"), choices=PaymentMethod, default=PaymentMethod.SITH_ACCOUNT
max_length=255,
choices=[("SITH_ACCOUNT", _("Sith account")), ("CARD", _("Credit card"))],
default="SITH_ACCOUNT",
) )
objects = SellingQuerySet.as_manager() objects = SellingQuerySet.as_manager()
@@ -874,7 +876,10 @@ class Selling(models.Model):
if not self.date: if not self.date:
self.date = timezone.now() self.date = timezone.now()
self.full_clean() self.full_clean()
if self._state.adding and self.payment_method == "SITH_ACCOUNT": if (
self._state.adding
and self.payment_method == self.PaymentMethod.SITH_ACCOUNT
):
self.customer.amount -= self.quantity * self.unit_price self.customer.amount -= self.quantity * self.unit_price
self.customer.save(allow_negative=allow_negative) self.customer.save(allow_negative=allow_negative)
user = self.customer.user user = self.customer.user
@@ -946,7 +951,9 @@ class Selling(models.Model):
def is_owned_by(self, user: User) -> bool: def is_owned_by(self, user: User) -> bool:
if user.is_anonymous: if user.is_anonymous:
return False return False
return self.payment_method != "CARD" and user.is_owner(self.counter) return self.payment_method != self.PaymentMethod.CARD and user.is_owner(
self.counter
)
def can_be_viewed_by(self, user: User) -> bool: def can_be_viewed_by(self, user: User) -> bool:
if ( if (
@@ -956,7 +963,7 @@ class Selling(models.Model):
return user == self.customer.user return user == self.customer.user
def delete(self, *args, **kwargs): def delete(self, *args, **kwargs):
if self.payment_method == "SITH_ACCOUNT": if self.payment_method == Selling.PaymentMethod.SITH_ACCOUNT:
self.customer.amount += self.quantity * self.unit_price self.customer.amount += self.quantity * self.unit_price
self.customer.save() self.customer.save()
super().delete(*args, **kwargs) super().delete(*args, **kwargs)

View File

@@ -298,7 +298,6 @@ def test_update_balance():
_quantity=len(customers), _quantity=len(customers),
unit_price=10, unit_price=10,
quantity=1, quantity=1,
payment_method="SITH_ACCOUNT",
_save_related=True, _save_related=True,
), ),
*sale_recipe.prepare( *sale_recipe.prepare(
@@ -306,14 +305,12 @@ def test_update_balance():
_quantity=3, _quantity=3,
unit_price=5, unit_price=5,
quantity=2, quantity=2,
payment_method="SITH_ACCOUNT",
_save_related=True, _save_related=True,
), ),
sale_recipe.prepare( sale_recipe.prepare(
customer=customers[4], customer=customers[4],
quantity=1, quantity=1,
unit_price=50, unit_price=50,
payment_method="SITH_ACCOUNT",
_save_related=True, _save_related=True,
), ),
*sale_recipe.prepare( *sale_recipe.prepare(
@@ -324,7 +321,7 @@ def test_update_balance():
_quantity=len(customers), _quantity=len(customers),
unit_price=50, unit_price=50,
quantity=1, quantity=1,
payment_method="CARD", payment_method=Selling.PaymentMethod.CARD,
_save_related=True, _save_related=True,
), ),
] ]

View File

@@ -74,7 +74,7 @@ class InvoiceCallView(
).aggregate(res=Sum("amount", default=0))["res"] ).aggregate(res=Sum("amount", default=0))["res"]
kwargs["sum_cb"] += ( kwargs["sum_cb"] += (
Selling.objects.filter( Selling.objects.filter(
payment_method="CARD", payment_method=Selling.PaymentMethod.CARD,
date__gte=start_date, date__gte=start_date,
date__lte=end_date, date__lte=end_date,
) )

View File

@@ -110,7 +110,9 @@ class Basket(models.Model):
)["total"] )["total"]
) )
def generate_sales(self, counter, seller: User, payment_method: str): def generate_sales(
self, counter, seller: User, payment_method: Selling.PaymentMethod
):
"""Generate a list of sold items corresponding to the items """Generate a list of sold items corresponding to the items
of this basket WITHOUT saving them NOR deleting the basket. of this basket WITHOUT saving them NOR deleting the basket.
@@ -267,7 +269,7 @@ class Invoice(models.Model):
customer=customer, customer=customer,
unit_price=i.product_unit_price, unit_price=i.product_unit_price,
quantity=i.quantity, quantity=i.quantity,
payment_method="CARD", payment_method=Selling.PaymentMethod.CARD,
date=self.date, date=self.date,
) )
new.save() new.save()

View File

@@ -114,13 +114,13 @@ class TestPaymentSith(TestPaymentBase):
"quantity" "quantity"
) )
assert len(sellings) == 2 assert len(sellings) == 2
assert sellings[0].payment_method == "SITH_ACCOUNT" assert sellings[0].payment_method == Selling.PaymentMethod.SITH_ACCOUNT
assert sellings[0].quantity == 1 assert sellings[0].quantity == 1
assert sellings[0].unit_price == self.snack.selling_price assert sellings[0].unit_price == self.snack.selling_price
assert sellings[0].counter.type == "EBOUTIC" assert sellings[0].counter.type == "EBOUTIC"
assert sellings[0].product == self.snack assert sellings[0].product == self.snack
assert sellings[1].payment_method == "SITH_ACCOUNT" assert sellings[1].payment_method == Selling.PaymentMethod.SITH_ACCOUNT
assert sellings[1].quantity == 2 assert sellings[1].quantity == 2
assert sellings[1].unit_price == self.beer.selling_price assert sellings[1].unit_price == self.beer.selling_price
assert sellings[1].counter.type == "EBOUTIC" assert sellings[1].counter.type == "EBOUTIC"
@@ -198,13 +198,13 @@ class TestPaymentCard(TestPaymentBase):
"quantity" "quantity"
) )
assert len(sellings) == 2 assert len(sellings) == 2
assert sellings[0].payment_method == "CARD" assert sellings[0].payment_method == Selling.PaymentMethod.CARD
assert sellings[0].quantity == 1 assert sellings[0].quantity == 1
assert sellings[0].unit_price == self.snack.selling_price assert sellings[0].unit_price == self.snack.selling_price
assert sellings[0].counter.type == "EBOUTIC" assert sellings[0].counter.type == "EBOUTIC"
assert sellings[0].product == self.snack assert sellings[0].product == self.snack
assert sellings[1].payment_method == "CARD" assert sellings[1].payment_method == Selling.PaymentMethod.CARD
assert sellings[1].quantity == 2 assert sellings[1].quantity == 2
assert sellings[1].unit_price == self.beer.selling_price assert sellings[1].unit_price == self.beer.selling_price
assert sellings[1].counter.type == "EBOUTIC" assert sellings[1].counter.type == "EBOUTIC"

View File

@@ -275,7 +275,7 @@ class EbouticPayWithSith(CanViewMixin, SingleObjectMixin, View):
return redirect("eboutic:payment_result", "failure") return redirect("eboutic:payment_result", "failure")
eboutic = get_eboutic() eboutic = get_eboutic()
sales = basket.generate_sales(eboutic, basket.user, "SITH_ACCOUNT") sales = basket.generate_sales(eboutic, basket.user, Selling.PaymentMethod.SITH_ACCOUNT)
try: try:
with transaction.atomic(): with transaction.atomic():
# Selling.save has some important business logic in it. # Selling.save has some important business logic in it.

View File

@@ -114,7 +114,6 @@ class TestMergeUser(TestCase):
seller=self.root, seller=self.root,
unit_price=2, unit_price=2,
quantity=2, quantity=2,
payment_method="SITH_ACCOUNT",
).save() ).save()
Selling( Selling(
label="barbar", label="barbar",
@@ -125,7 +124,6 @@ class TestMergeUser(TestCase):
seller=self.root, seller=self.root,
unit_price=2, unit_price=2,
quantity=4, quantity=4,
payment_method="SITH_ACCOUNT",
).save() ).save()
today = localtime(now()).date() today = localtime(now()).date()
# both subscriptions began last month and shall end in 5 months # both subscriptions began last month and shall end in 5 months
@@ -197,7 +195,6 @@ class TestMergeUser(TestCase):
seller=self.root, seller=self.root,
unit_price=2, unit_price=2,
quantity=4, quantity=4,
payment_method="SITH_ACCOUNT",
).save() ).save()
data = {"user1": self.to_keep.id, "user2": self.to_delete.id} data = {"user1": self.to_keep.id, "user2": self.to_delete.id}
res = self.client.post(reverse("rootplace:merge"), data) res = self.client.post(reverse("rootplace:merge"), data)
@@ -225,7 +222,6 @@ class TestMergeUser(TestCase):
seller=self.root, seller=self.root,
unit_price=2, unit_price=2,
quantity=4, quantity=4,
payment_method="SITH_ACCOUNT",
).save() ).save()
data = {"user1": self.to_keep.id, "user2": self.to_delete.id} data = {"user1": self.to_keep.id, "user2": self.to_delete.id}
res = self.client.post(reverse("rootplace:merge"), data) res = self.client.post(reverse("rootplace:merge"), data)