from django.db import models from simple_history.models import HistoricalRecords from django.core.validators import MinValueValidator from django.contrib.auth.models import User class PaymentMethod(models.Model): """ Stores payment methods. """ class Meta: verbose_name="Moyen de paiement" verbose_name_plural = "Moyens de paiement" name = models.CharField(max_length=255, verbose_name="Nom") """ The name of the PaymentMethod. """ is_active = models.BooleanField(default=True, verbose_name="Actif") """ If False, the PaymentMethod can't be use anywhere. """ is_usable_in_cotisation = models.BooleanField(default=True, verbose_name="Cotisations ?") """ If true, the PaymentMethod can be used to pay cotisation. """ is_usable_in_reload = models.BooleanField(default=True, verbose_name="Rechargements ?") """ If true, the PaymentMethod can be used to reload an user account. """ affect_balance = models.BooleanField(default=False, verbose_name="Affecte le solde") """ If true, the PaymentMethod will decrease the user's balance when used. """ icon = models.CharField(max_length=255, verbose_name="Icône", blank=True) """ A font awesome icon (without the fa) """ history = HistoricalRecords() def __str__(self): return self.name class GeneralPreferences(models.Model): """ Stores a unique line of general preferences """ class Meta: verbose_name="Préférences générales" verbose_name_plural = "Préférences générales" is_active = models.BooleanField(default=True, verbose_name="Site actif") """ If True, the site will be accessible. If False, all the requests are redirect to :func:`~preferences.views.inactive`. """ active_message = models.TextField(blank=True, verbose_name="Message non actif") """ Message displayed on the :func:`~preferences.views.inactive` """ global_message = models.TextField(blank=True, verbose_name="Message global") """ List of messages, separated by a carriage return. One will be chosen randomly at each request on displayed in the header """ president = models.CharField(max_length=255, blank=True, verbose_name="Président") """ The name of the president """ treasurer = models.CharField(max_length=255, blank=True, verbose_name="Trésorier") """ The name of the treasurer """ secretary = models.CharField(max_length=255, blank=True, verbose_name="Secrétaire") """ The name of the secretary """ phoenixTM_responsible = models.CharField(max_length=255, blank=True, verbose_name="Responsable Phœnix Technopôle Metz") """ The name of the people in charge of the club """ use_pinte_monitoring = models.BooleanField(default=False, verbose_name="Suivi de pintes") """ If True, alert will be displayed to allocate pints during order """ lost_pintes_allowed = models.PositiveIntegerField(default=0, verbose_name="Nombre de pintes perdus admises") """ If > 0, a user will be blocked if he has losted more pints than the value """ floating_buttons = models.BooleanField(default=False, verbose_name="Boutons flottants") """ If True, displays floating paymentButtons on the :func:`~gestion.views.manage` view. """ home_text = models.TextField(blank=True, verbose_name="Message d'accueil") """ Text display on the home page """ automatic_logout_time = models.PositiveIntegerField(null=True, verbose_name="Temps de déconnexion automatique") """ Duration after which the user is automatically disconnected if inactive """ statutes = models.FileField(blank=True, null=True, verbose_name="Statuts") """ The file of the statutes """ rules = models.FileField(blank=True, null=True, verbose_name="Règlement intérieur") """ The file of the internal rules """ menu = models.FileField(blank=True, null=True, verbose_name="Menu") """ The file of the menu """ alcohol_charter = models.FileField(blank=True, null=True, verbose_name="Charte alcool") """ The file of the alcohol charter """ history = HistoricalRecords() class Cotisation(models.Model): """ Stores cotisations. """ class Meta: permissions = (("can_divide", "Can divide money for cotisation"),) amount = models.DecimalField(max_digits=5, decimal_places=2, null=True, verbose_name="Montant", validators=[MinValueValidator(0)]) """ Price of the cotisation. """ duration = models.PositiveIntegerField(verbose_name="Durée de la cotisation (jours)") """ Duration (in days) of the cotisation """ amount_ptm = models.DecimalField(max_digits=5, decimal_places=2, null=True, verbose_name="Montant pour le club Phœnix Technopôle Metz", default=0) """ Amount of money given to the PTM club """ history = HistoricalRecords() def __str__(self): if self.duration == 1: jour = "jour" else: jour = "jours" return "Cotisation de " + str(self.duration) + " " + jour + " pour le prix de " + str(self.amount) + "€" class DivideHistory(models.Model): """ Stores divide history """ class Meta: verbose_name = "Historique répartition" date = models.DateTimeField(auto_now_add=True) """ Date of the divide """ total_cotisations = models.IntegerField(verbose_name="Nombre de cotisations") """ Number of non-divided cotisations (before the divide) """ total_cotisations_amount = models.DecimalField(max_digits=5, decimal_places=2, verbose_name="Montant total des cotisations") """ Amount of non-divided cotisations (before the divide) """ total_ptm_amount = models.DecimalField(max_digits=5, decimal_places=2, verbose_name="Montant donné au Phœnix Technopôle Metz") """ Amount given to the PTM """ coopeman = models.ForeignKey(User, on_delete=models.PROTECT, related_name="divide_realized") """ Coopeman (:class:`django.contrib.auth.models.User`) who collected the reload. """ def __str__(self): return "Répartition du " + str(self.date) class PriceProfile(models.Model): """ Stores parameters to compute price """ class Meta: verbose_name = "Profil de prix" verbose_name_plural = "Profils de prix" name = models.CharField(max_length=255, verbose_name="Nom") a = models.DecimalField(verbose_name="Marge constante", max_digits=3, decimal_places=2) b = models.DecimalField(verbose_name="Marge variable", max_digits=3, decimal_places=2) c = models.DecimalField(verbose_name="Paramètre de forme", max_digits=4, decimal_places=2) alpha = models.DecimalField(verbose_name="Étendue", max_digits=4, decimal_places=2) use_for_draft = models.BooleanField(default=False, verbose_name="Utiliser pour les pressions ?") def save(self, *args, **kwargs): if self.use_for_draft: try: temp = PriceProfile.objects.get(use_for_draft=True) if self != temp: temp.use_for_draft = False temp.save() except PriceProfile.DoesNotExist: pass super(PriceProfile, self).save(*args, **kwargs) def __str__(self): return self.name class Improvement(models.Model): """ Stores bugs and amelioration proposals. """ BUG = 0 AMELIORATION = 1 NEWFEATURE = 2 MODES = ( (BUG, "Bug"), (AMELIORATION, "Amélioration"), (NEWFEATURE, "Nouvelle fonctionnalité") ) class Meta: verbose_name = "Amélioration" title = models.CharField(max_length=255, verbose_name="Titre") mode = models.IntegerField(choices=MODES, verbose_name="Type") description = models.TextField() seen = models.BooleanField(default=False, verbose_name="Vu ?") done = models.BooleanField(default=False, verbose_name="Fait ?") coopeman = models.ForeignKey(User, on_delete=models.PROTECT, related_name="improvement_submitted") date = models.DateTimeField(auto_now_add=True)