8
0
Fork 0
mirror of https://gitlab2.federez.net/re2o/re2o synced 2024-12-25 08:23:46 +00:00

Creation d'articles contenant ou non les adhésion, nouveau system fin adh fin co

This commit is contained in:
Gabriel Detraz 2017-10-28 04:59:40 +02:00 committed by root
parent 08f108a99c
commit 898ae901e0
7 changed files with 168 additions and 16 deletions

View file

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2017-10-27 03:02
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('cotisations', '0024_auto_20171015_2033'),
]
operations = [
migrations.AddField(
model_name='article',
name='type_user',
field=models.CharField(choices=[('Adherent', 'Adherent'), ('Club', 'Club'), ('All', 'All')], default='All', max_length=255),
),
]

View file

@ -0,0 +1,78 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2017-10-27 23:26
from __future__ import unicode_literals
from django.db import migrations, models
def create_type(apps, schema_editor):
Cotisation = apps.get_model('cotisations', 'Cotisation')
Vente = apps.get_model('cotisations', 'Vente')
Article = apps.get_model('cotisations', 'Article')
db_alias = schema_editor.connection.alias
articles = Articles.objects.using(db_alias).all()
ventes = Vente.objects.using(db_alias).all()
cotisations = Cotisation.objects.using(db_alias).all()
for article in articles:
if article.iscotisation:
article.type_cotisation='All'
article.save(using=db_alias)
for vente in ventes:
if vente.iscotisation:
vente.type_cotisation='All'
vente.save(using=db_alias)
for cotisation in cotisations:
cotisation.type_cotisation='All'
cotisation.save(using=db_alias)
def delete_type(apps, schema_editor):
Vente = apps.get_model('cotisations', 'Vente')
Article = apps.get_model('cotisations', 'Article')
db_alias = schema_editor.connection.alias
articles = Articles.objects.using(db_alias).all()
ventes = Vente.objects.using(db_alias).all()
for article in articles:
if article.type_cotisation:
article.iscotisation=True
else:
article.iscotisation=False
article.save(using=db_alias)
for vente in ventes:
if vente.iscotisation:
vente.iscotisation=True
else:
vente.iscotisation=False
vente.save(using=db_alias)
class Migration(migrations.Migration):
dependencies = [
('cotisations', '0025_article_type_user'),
]
operations = [
migrations.AddField(
model_name='article',
name='type_cotisation',
field=models.CharField(choices=[('Connexion', 'Connexion'), ('Adhesion', 'Adhesion'), ('All', 'All')], default=None, max_length=255, null=True),
),
migrations.AddField(
model_name='cotisation',
name='type_cotisation',
field=models.CharField(choices=[('Connexion', 'Connexion'), ('Adhesion', 'Adhesion'), ('All', 'All')], max_length=255),
),
migrations.AddField(
model_name='vente',
name='type_cotisation',
field=models.CharField(blank=True, choices=[('Connexion', 'Connexion'), ('Adhesion', 'Adhesion'), ('All', 'All')], max_length=255, null=True),
),
migrations.RunPython(create_type, delete_type),
migrations.RemoveField(
model_name='article',
name='iscotisation',
),
migrations.RemoveField(
model_name='vente',
name='iscotisation',
),
]

View file

@ -127,15 +127,26 @@ class Vente(models.Model):
iscotisation""" iscotisation"""
PRETTY_NAME = "Ventes effectuées" PRETTY_NAME = "Ventes effectuées"
COTISATION_TYPE = (
('Connexion', 'Connexion'),
('Adhesion', 'Adhesion'),
('All', 'All'),
)
facture = models.ForeignKey('Facture', on_delete=models.CASCADE) facture = models.ForeignKey('Facture', on_delete=models.CASCADE)
number = models.IntegerField(validators=[MinValueValidator(1)]) number = models.IntegerField(validators=[MinValueValidator(1)])
name = models.CharField(max_length=255) name = models.CharField(max_length=255)
prix = models.DecimalField(max_digits=5, decimal_places=2) prix = models.DecimalField(max_digits=5, decimal_places=2)
iscotisation = models.BooleanField()
duration = models.PositiveIntegerField( duration = models.PositiveIntegerField(
help_text="Durée exprimée en mois entiers", help_text="Durée exprimée en mois entiers",
blank=True, blank=True,
null=True) null=True)
type_cotisation = models.CharField(
choices=COTISATION_TYPE,
blank=True,
null=True,
max_length=255
)
def prix_total(self): def prix_total(self):
"""Renvoie le prix_total de self (nombre*prix)""" """Renvoie le prix_total de self (nombre*prix)"""
@ -155,22 +166,26 @@ class Vente(models.Model):
"""Update et crée l'objet cotisation associé à une facture, prend """Update et crée l'objet cotisation associé à une facture, prend
en argument l'user, la facture pour la quantitéi, et l'article pour en argument l'user, la facture pour la quantitéi, et l'article pour
la durée""" la durée"""
if not hasattr(self, 'cotisation'): if not hasattr(self, 'cotisation') and self.type_cotisation:
cotisation = Cotisation(vente=self) cotisation = Cotisation(vente=self)
cotisation.type_cotisation = self.type_cotisation
if date_start: if date_start:
end_adhesion = Cotisation.objects.filter( end_adhesion = Cotisation.objects.filter(
vente__in=Vente.objects.filter( vente__in=Vente.objects.filter(
facture__in=Facture.objects.filter( facture__in=Facture.objects.filter(
user=self.facture.user user=self.facture.user
).exclude(valid=False)) ).exclude(valid=False))
).filter(Q(type_cotisation='All') | Q(type_cotisation=self.type_cotisation)
).filter( ).filter(
date_start__lt=date_start date_start__lt=date_start
).aggregate(Max('date_end'))['date_end__max'] ).aggregate(Max('date_end'))['date_end__max']
elif self.type_cotisation=="Adhesion":
end_cotisation = self.facture.user.end_adhesion()
else: else:
end_adhesion = self.facture.user.end_adhesion() end_cotisation = self.facture.user.end_connexion()
date_start = date_start or timezone.now() date_start = date_start or timezone.now()
end_adhesion = end_adhesion or date_start end_cotisation = end_cotisation or date_start
date_max = max(end_adhesion, date_start) date_max = max(end_cotisation, date_start)
cotisation.date_start = date_max cotisation.date_start = date_max
cotisation.date_end = cotisation.date_start + relativedelta( cotisation.date_end = cotisation.date_start + relativedelta(
months=self.duration*self.number months=self.duration*self.number
@ -179,7 +194,7 @@ class Vente(models.Model):
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
# On verifie que si iscotisation, duration est présent # On verifie que si iscotisation, duration est présent
if self.iscotisation and not self.duration: if self.type_cotisation and not self.duration:
raise ValidationError("Cotisation et durée doivent être présents\ raise ValidationError("Cotisation et durée doivent être présents\
ensembles") ensembles")
self.update_cotisation() self.update_cotisation()
@ -197,7 +212,7 @@ def vente_post_save(sender, **kwargs):
if hasattr(vente, 'cotisation'): if hasattr(vente, 'cotisation'):
vente.cotisation.vente = vente vente.cotisation.vente = vente
vente.cotisation.save() vente.cotisation.save()
if vente.iscotisation: if vente.type_cotisation:
vente.create_cotis() vente.create_cotis()
vente.cotisation.save() vente.cotisation.save()
user = vente.facture.user user = vente.facture.user
@ -209,7 +224,7 @@ def vente_post_delete(sender, **kwargs):
"""Après suppression d'une vente, on synchronise l'user ldap (ex """Après suppression d'une vente, on synchronise l'user ldap (ex
suppression d'une cotisation""" suppression d'une cotisation"""
vente = kwargs['instance'] vente = kwargs['instance']
if vente.iscotisation: if vente.type_cotisation:
user = vente.facture.user user = vente.facture.user
user.ldap_sync(base=False, access_refresh=True, mac_refresh=False) user.ldap_sync(base=False, access_refresh=True, mac_refresh=False)
@ -219,18 +234,45 @@ class Article(models.Model):
et duree si c'est une cotisation""" et duree si c'est une cotisation"""
PRETTY_NAME = "Articles en vente" PRETTY_NAME = "Articles en vente"
USER_TYPES = (
('Adherent', 'Adherent'),
('Club', 'Club'),
('All', 'All'),
)
COTISATION_TYPE = (
('Connexion', 'Connexion'),
('Adhesion', 'Adhesion'),
('All', 'All'),
)
name = models.CharField(max_length=255, unique=True) name = models.CharField(max_length=255, unique=True)
prix = models.DecimalField(max_digits=5, decimal_places=2) prix = models.DecimalField(max_digits=5, decimal_places=2)
iscotisation = models.BooleanField()
duration = models.PositiveIntegerField( duration = models.PositiveIntegerField(
help_text="Durée exprimée en mois entiers", help_text="Durée exprimée en mois entiers",
blank=True, blank=True,
null=True, null=True,
validators=[MinValueValidator(0)]) validators=[MinValueValidator(0)])
type_user = models.CharField(
choices=USER_TYPES,
default='All',
max_length=255
)
type_cotisation = models.CharField(
choices=COTISATION_TYPE,
default=None,
blank=True,
null=True,
max_length=255
)
def clean(self): def clean(self):
if self.name.lower() == "solde": if self.name.lower() == "solde":
raise ValidationError("Solde est un nom d'article invalide") raise ValidationError("Solde est un nom d'article invalide")
if self.type_cotisation and not self.duration:
raise ValidationError(
"La durée est obligatoire si il s'agit d'une cotisation"
)
def __str__(self): def __str__(self):
return self.name return self.name
@ -275,7 +317,17 @@ class Cotisation(models.Model):
"""Objet cotisation, debut et fin, relié en onetoone à une vente""" """Objet cotisation, debut et fin, relié en onetoone à une vente"""
PRETTY_NAME = "Cotisations" PRETTY_NAME = "Cotisations"
COTISATION_TYPE = (
('Connexion', 'Connexion'),
('Adhesion', 'Adhesion'),
('All', 'All'),
)
vente = models.OneToOneField('Vente', on_delete=models.CASCADE, null=True) vente = models.OneToOneField('Vente', on_delete=models.CASCADE, null=True)
type_cotisation = models.CharField(
choices=COTISATION_TYPE,
max_length=255,
)
date_start = models.DateTimeField() date_start = models.DateTimeField()
date_end = models.DateTimeField() date_end = models.DateTimeField()

View file

@ -27,8 +27,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<tr> <tr>
<th>Article</th> <th>Article</th>
<th>Prix</th> <th>Prix</th>
<th>Cotisation</th> <th>Type Cotisation</th>
<th>Durée (mois)</th> <th>Durée (mois)</th>
<th>Article pour</th>
<th></th> <th></th>
</tr> </tr>
</thead> </thead>
@ -36,8 +37,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<tr> <tr>
<td>{{ article.name }}</td> <td>{{ article.name }}</td>
<td>{{ article.prix }}</td> <td>{{ article.prix }}</td>
<td>{{ article.iscotisation }}</td> <td>{{ article.type_cotisation }}</td>
<td>{{ article.duration }}</td> <td>{{ article.duration }}</td>
<td>{{ article.type_user }}</td>
<td class="text-right"> <td class="text-right">
{% if is_trez %} {% if is_trez %}
<a class="btn btn-primary btn-sm" role="button" title="Éditer" href="{% url 'cotisations:edit-article' article.id %}"> <a class="btn btn-primary btn-sm" role="button" title="Éditer" href="{% url 'cotisations:edit-article' article.id %}">

View file

@ -106,7 +106,7 @@ def new_facture(request, userid):
facture=new_facture_instance, facture=new_facture_instance,
name=article.name, name=article.name,
prix=article.prix, prix=article.prix,
iscotisation=article.iscotisation, type_cotisation=article.type_cotisation,
duration=article.duration, duration=article.duration,
number=quantity number=quantity
) )
@ -114,7 +114,7 @@ def new_facture(request, userid):
new_vente.save() new_vente.save()
reversion.set_user(request.user) reversion.set_user(request.user)
reversion.set_comment("Création") reversion.set_comment("Création")
if any(art_item.cleaned_data['article'].iscotisation if any(art_item.cleaned_data['article'].type_cotisation
for art_item in articles if art_item.cleaned_data): for art_item in articles if art_item.cleaned_data):
messages.success( messages.success(
request, request,
@ -312,8 +312,6 @@ def credit_solde(request, userid):
facture=facture_instance, facture=facture_instance,
name="solde", name="solde",
prix=facture.cleaned_data['montant'], prix=facture.cleaned_data['montant'],
iscotisation=False,
duration=0,
number=1 number=1
) )
with transaction.atomic(), reversion.create_revision(): with transaction.atomic(), reversion.create_revision():

View file

@ -56,6 +56,7 @@ def all_adherent(search_time=DT_NOW):
return User.objects.filter( return User.objects.filter(
facture__in=Facture.objects.filter( facture__in=Facture.objects.filter(
vente__in=Vente.objects.filter( vente__in=Vente.objects.filter(
Q(type_cotisation='All') | Q(type_cotisation='Adhesion'),
cotisation__in=Cotisation.objects.filter( cotisation__in=Cotisation.objects.filter(
vente__in=Vente.objects.filter( vente__in=Vente.objects.filter(
facture__in=Facture.objects.all().exclude(valid=False) facture__in=Facture.objects.all().exclude(valid=False)
@ -94,6 +95,7 @@ def all_has_access(search_time=DT_NOW):
Q(facture__in=Facture.objects.filter( Q(facture__in=Facture.objects.filter(
vente__in=Vente.objects.filter( vente__in=Vente.objects.filter(
cotisation__in=Cotisation.objects.filter( cotisation__in=Cotisation.objects.filter(
Q(type_cotisation='All') | Q(type_cotisation='Connexion'),
vente__in=Vente.objects.filter( vente__in=Vente.objects.filter(
facture__in=Facture.objects.all() facture__in=Facture.objects.all()
.exclude(valid=False) .exclude(valid=False)

View file

@ -146,7 +146,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<th scope="row">Connexion</th> <th scope="row">Connexion</th>
<td class="text-right"> <td class="text-right">
{% if request_user.has_access %} {% if request_user.has_access %}
<font color="green">Active</font> <font color="green">Active (jusqu'au {{ request.user.end_access }})</font>
{% else %} {% else %}
<font color="red">Désactivée</font> <font color="red">Désactivée</font>
{% endif %} {% endif %}