8
0
Fork 0
mirror of https://gitlab2.federez.net/re2o/re2o synced 2024-12-25 00:13:45 +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"""
PRETTY_NAME = "Ventes effectuées"
COTISATION_TYPE = (
('Connexion', 'Connexion'),
('Adhesion', 'Adhesion'),
('All', 'All'),
)
facture = models.ForeignKey('Facture', on_delete=models.CASCADE)
number = models.IntegerField(validators=[MinValueValidator(1)])
name = models.CharField(max_length=255)
prix = models.DecimalField(max_digits=5, decimal_places=2)
iscotisation = models.BooleanField()
duration = models.PositiveIntegerField(
help_text="Durée exprimée en mois entiers",
blank=True,
null=True)
type_cotisation = models.CharField(
choices=COTISATION_TYPE,
blank=True,
null=True,
max_length=255
)
def prix_total(self):
"""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
en argument l'user, la facture pour la quantitéi, et l'article pour
la durée"""
if not hasattr(self, 'cotisation'):
if not hasattr(self, 'cotisation') and self.type_cotisation:
cotisation = Cotisation(vente=self)
cotisation.type_cotisation = self.type_cotisation
if date_start:
end_adhesion = Cotisation.objects.filter(
vente__in=Vente.objects.filter(
facture__in=Facture.objects.filter(
user=self.facture.user
).exclude(valid=False))
).filter(Q(type_cotisation='All') | Q(type_cotisation=self.type_cotisation)
).filter(
date_start__lt=date_start
).aggregate(Max('date_end'))['date_end__max']
elif self.type_cotisation=="Adhesion":
end_cotisation = self.facture.user.end_adhesion()
else:
end_adhesion = self.facture.user.end_adhesion()
end_cotisation = self.facture.user.end_connexion()
date_start = date_start or timezone.now()
end_adhesion = end_adhesion or date_start
date_max = max(end_adhesion, date_start)
end_cotisation = end_cotisation or date_start
date_max = max(end_cotisation, date_start)
cotisation.date_start = date_max
cotisation.date_end = cotisation.date_start + relativedelta(
months=self.duration*self.number
@ -179,7 +194,7 @@ class Vente(models.Model):
def save(self, *args, **kwargs):
# 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\
ensembles")
self.update_cotisation()
@ -197,7 +212,7 @@ def vente_post_save(sender, **kwargs):
if hasattr(vente, 'cotisation'):
vente.cotisation.vente = vente
vente.cotisation.save()
if vente.iscotisation:
if vente.type_cotisation:
vente.create_cotis()
vente.cotisation.save()
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
suppression d'une cotisation"""
vente = kwargs['instance']
if vente.iscotisation:
if vente.type_cotisation:
user = vente.facture.user
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"""
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)
prix = models.DecimalField(max_digits=5, decimal_places=2)
iscotisation = models.BooleanField()
duration = models.PositiveIntegerField(
help_text="Durée exprimée en mois entiers",
blank=True,
null=True,
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):
if self.name.lower() == "solde":
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):
return self.name
@ -275,7 +317,17 @@ class Cotisation(models.Model):
"""Objet cotisation, debut et fin, relié en onetoone à une vente"""
PRETTY_NAME = "Cotisations"
COTISATION_TYPE = (
('Connexion', 'Connexion'),
('Adhesion', 'Adhesion'),
('All', 'All'),
)
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_end = models.DateTimeField()

View file

@ -27,8 +27,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<tr>
<th>Article</th>
<th>Prix</th>
<th>Cotisation</th>
<th>Type Cotisation</th>
<th>Durée (mois)</th>
<th>Article pour</th>
<th></th>
</tr>
</thead>
@ -36,8 +37,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
<tr>
<td>{{ article.name }}</td>
<td>{{ article.prix }}</td>
<td>{{ article.iscotisation }}</td>
<td>{{ article.type_cotisation }}</td>
<td>{{ article.duration }}</td>
<td>{{ article.type_user }}</td>
<td class="text-right">
{% if is_trez %}
<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,
name=article.name,
prix=article.prix,
iscotisation=article.iscotisation,
type_cotisation=article.type_cotisation,
duration=article.duration,
number=quantity
)
@ -114,7 +114,7 @@ def new_facture(request, userid):
new_vente.save()
reversion.set_user(request.user)
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):
messages.success(
request,
@ -312,8 +312,6 @@ def credit_solde(request, userid):
facture=facture_instance,
name="solde",
prix=facture.cleaned_data['montant'],
iscotisation=False,
duration=0,
number=1
)
with transaction.atomic(), reversion.create_revision():

View file

@ -56,6 +56,7 @@ def all_adherent(search_time=DT_NOW):
return User.objects.filter(
facture__in=Facture.objects.filter(
vente__in=Vente.objects.filter(
Q(type_cotisation='All') | Q(type_cotisation='Adhesion'),
cotisation__in=Cotisation.objects.filter(
vente__in=Vente.objects.filter(
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(
vente__in=Vente.objects.filter(
cotisation__in=Cotisation.objects.filter(
Q(type_cotisation='All') | Q(type_cotisation='Connexion'),
vente__in=Vente.objects.filter(
facture__in=Facture.objects.all()
.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>
<td class="text-right">
{% if request_user.has_access %}
<font color="green">Active</font>
<font color="green">Active (jusqu'au {{ request.user.end_access }})</font>
{% else %}
<font color="red">Désactivée</font>
{% endif %}