Skip to content

Commit

Permalink
💰 Add cashprizes to the Tournament fields
Browse files Browse the repository at this point in the history
Use an ArrayField, which is Postgresql specific, to store a list of
Decimal fields that have a minimal value of 0.

Also adds tests, and is needed for #49.
  • Loading branch information
Lymkwi committed Oct 23, 2023
1 parent c41efb9 commit 7c17e34
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 33 deletions.
2 changes: 1 addition & 1 deletion insalan/tournament/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class GameAdmin(admin.ModelAdmin):
class TournamentAdmin(admin.ModelAdmin):
"""Admin handler for Tournaments"""

list_display = ("id", "name", "event", "game", "is_announced")
list_display = ("id", "name", "event", "game", "is_announced", "cashprizes")
search_fields = ["name", "event", "game"]


Expand Down
89 changes: 57 additions & 32 deletions insalan/tournament/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@
MinLengthValidator,
)
from django.utils.translation import gettext_lazy as _
from django.contrib.postgres.fields import ArrayField

from insalan.tickets.models import Ticket
from insalan.user.models import User


class Event(models.Model):
"""
An Event is any single event that is characterized by the following:
Expand Down Expand Up @@ -137,8 +139,7 @@ class Tournament(models.Model):
validators=[MinLengthValidator(3)],
max_length=40,
)
is_announced = models.BooleanField(verbose_name=_("Annoncé"),
default=False)
is_announced = models.BooleanField(verbose_name=_("Annoncé"), default=False)
rules = models.TextField(
verbose_name=_("Règlement du tournoi"),
max_length=50000,
Expand All @@ -155,62 +156,86 @@ class Tournament(models.Model):
FileExtensionValidator(allowed_extensions=["png", "jpg", "jpeg", "svg"])
],
)
# Tournament player slot prices
# Tournament player slot prices
# These prices are used at the tournament creation to create associated
# products
player_price_online = models.DecimalField(
null=False, default=0.0, max_digits=5, decimal_places=2,
verbose_name=_("prix joueur en ligne")
) # when paying on the website
null=False,
default=0.0,
max_digits=5,
decimal_places=2,
verbose_name=_("prix joueur en ligne"),
) # when paying on the website

player_price_onsite = models.DecimalField(
null=False, default=0.0, max_digits=5, decimal_places=2,
verbose_name=_("prix joueur sur place")
) # when paying on site
null=False,
default=0.0,
max_digits=5,
decimal_places=2,
verbose_name=_("prix joueur sur place"),
) # when paying on site

# Tournament manager slot prices
# Tournament manager slot prices
manager_price_online = models.DecimalField(
null=False, default=0.0, max_digits=5, decimal_places=2,
verbose_name=_("prix manager en ligne")
) # when paying on the website
null=False,
default=0.0,
max_digits=5,
decimal_places=2,
verbose_name=_("prix manager en ligne"),
) # when paying on the website

manager_price_onsite = models.DecimalField(
null=False, default=0.0, max_digits=5, decimal_places=2,
verbose_name=_("prix manager sur place")
) # when paying on site
null=False,
default=0.0,
max_digits=5,
decimal_places=2,
verbose_name=_("prix manager sur place"),
) # when paying on site
cashprizes = ArrayField(
models.DecimalField(
null=False,
default=0.0,
decimal_places=2,
max_digits=6,
validators=[MinValueValidator(0)],
),
default=list,
blank=True,
verbose_name=_("Cashprizes"),
)

class Meta:
"""Meta options"""

verbose_name = _("Tournoi")
verbose_name_plural = _("Tournois")

def save(self, *args, **kwargs):
"""
Override default save of Tournament.
When a Tournament object is created, it creates 2 products, its associated
products to allow players and managers to pay the entry fee
"""

from insalan.payment.models import Product, ProductCategory
super().save() # Get the self accessible to the products

super().save() # Get the self accessible to the products
Product.objects.create(
price=self.player_price_online,
name=_(f"Place {self.name} Joueur en ligne"),
desc=_(f"Inscription au tournoi {self.name} joueur"),
category = ProductCategory.REGISTRATION_PLAYER,
associated_tournament = self
)
price=self.player_price_online,
name=_(f"Place {self.name} Joueur en ligne"),
desc=_(f"Inscription au tournoi {self.name} joueur"),
category=ProductCategory.REGISTRATION_PLAYER,
associated_tournament=self,
)

Product.objects.create(
price=self.manager_price_online,
name=_(f"Place {self.name} manager en ligne"),
desc=_(f"Inscription au tournoi {self.name} manager"),
category = ProductCategory.REGISTRATION_MANAGER,
associated_tournament = self
)
price=self.manager_price_online,
name=_(f"Place {self.name} manager en ligne"),
desc=_(f"Inscription au tournoi {self.name} manager"),
category=ProductCategory.REGISTRATION_MANAGER,
associated_tournament=self,
)


def __str__(self) -> str:
"""Format this Tournament to a str"""
return f"{self.name} (@ {self.event})"
Expand Down
39 changes: 39 additions & 0 deletions insalan/tournament/tests.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Tournament Module Tests"""

from decimal import Decimal
from io import BytesIO
from types import NoneType

Expand Down Expand Up @@ -347,6 +348,44 @@ def test_get_teams(self):
self.assertTrue(team_two in teams)
self.assertFalse(team_three in teams)

def test_default_cashprizes(self):
"""Test that the default for cashprizes is an empty list"""
tourney = Tournament.objects.all()[0]
self.assertEqual([], tourney.cashprizes)

def test_get_set_cashprizes(self):
"""Verify that getting and setting cashprizes is possible"""
tourney = Tournament.objects.all()[0]

# One price
tourney.cashprizes = [Decimal(28)]
tourney.save()
self.assertEqual(1, len(tourney.cashprizes))
self.assertEqual(Decimal(28), tourney.cashprizes[0])

# Many prices
tourney.cashprizes = [Decimal(18), Decimal(22), Decimal(89)]
tourney.save()
self.assertEqual(3, len(tourney.cashprizes))
self.assertEqual(Decimal(18), tourney.cashprizes[0])
self.assertEqual(Decimal(22), tourney.cashprizes[1])
self.assertEqual(Decimal(89), tourney.cashprizes[2])

# Back to zero
tourney.cashprizes = []
tourney.save()
self.assertEqual(0, len(tourney.cashprizes))

def test_cashprizes_cannot_be_strictly_negative(self):
"""Test that a cashprize cannot be strictly negative"""
tourney = Tournament.objects.all()[0]

tourney.cashprizes = [Decimal(278), Decimal(-1), Decimal(0)]
self.assertRaises(ValidationError, tourney.full_clean)

tourney.cashprizes = [Decimal(278), Decimal(0), Decimal(0)]
tourney.full_clean()

def test_name_too_short(self):
"""Verify that a tournament name cannot be too short"""
tourneyobj = Tournament.objects.all()[0]
Expand Down

0 comments on commit 7c17e34

Please sign in to comment.