Merge branch 'Kerl/postgres' into 'master'
Préparation au passage à postgres - Suppression du champ num du modèle CofProfile. - Suppression des LOCK (spécifique MySQL). - Le code devient compatible avec tous les backends supportés par Django. - Suppressions de code servant à la compatibilité python2. - Corrige le message de succès à la fin de l'inscription. Celui-ci ne prenait pas en compte le statut is_cof à jour du profil. See merge request !234
This commit is contained in:
commit
0815c96c1c
8 changed files with 133 additions and 149 deletions
|
@ -1,9 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django import forms
|
||||
from django.contrib import admin
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
@ -18,13 +12,12 @@ from django.contrib.auth.admin import UserAdmin
|
|||
from django.core.urlresolvers import reverse
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.db.models import Q
|
||||
import django.utils.six as six
|
||||
|
||||
import autocomplete_light
|
||||
|
||||
|
||||
def add_link_field(target_model='', field='', link_text=six.text_type,
|
||||
desc_text=six.text_type):
|
||||
def add_link_field(target_model='', field='', link_text=str,
|
||||
desc_text=str):
|
||||
def add_link(cls):
|
||||
reverse_name = target_model or cls.model.__name__.lower()
|
||||
|
||||
|
@ -139,7 +132,6 @@ def ProfileInfo(field, short_description, boolean=False):
|
|||
|
||||
User.profile_login_clipper = FkeyLookup("profile__login_clipper",
|
||||
"Login clipper")
|
||||
User.profile_num = FkeyLookup("profile__num", "Numéro")
|
||||
User.profile_phone = ProfileInfo("phone", "Téléphone")
|
||||
User.profile_occupation = ProfileInfo("occupation", "Occupation")
|
||||
User.profile_departement = ProfileInfo("departement", "Departement")
|
||||
|
@ -166,10 +158,12 @@ class UserProfileAdmin(UserAdmin):
|
|||
is_cof.short_description = 'Membre du COF'
|
||||
is_cof.boolean = True
|
||||
|
||||
list_display = ('profile_num',) + UserAdmin.list_display \
|
||||
list_display = (
|
||||
UserAdmin.list_display
|
||||
+ ('profile_login_clipper', 'profile_phone', 'profile_occupation',
|
||||
'profile_mailing_cof', 'profile_mailing_bda',
|
||||
'profile_mailing_bda_revente', 'is_cof', 'is_buro', )
|
||||
)
|
||||
list_display_links = ('username', 'email', 'first_name', 'last_name')
|
||||
list_filter = UserAdmin.list_filter \
|
||||
+ ('profile__is_cof', 'profile__is_buro', 'profile__mailing_cof',
|
||||
|
@ -215,21 +209,17 @@ class UserProfileAdmin(UserAdmin):
|
|||
|
||||
|
||||
# FIXME: This is absolutely horrible.
|
||||
def user_unicode(self):
|
||||
def user_str(self):
|
||||
if self.first_name and self.last_name:
|
||||
return "%s %s (%s)" % (self.first_name, self.last_name, self.username)
|
||||
return "{} ({})".format(self.get_full_name(), self.username)
|
||||
else:
|
||||
return self.username
|
||||
if six.PY2:
|
||||
User.__unicode__ = user_unicode
|
||||
else:
|
||||
User.__str__ = user_unicode
|
||||
User.__str__ = user_str
|
||||
|
||||
|
||||
class EventRegistrationAdmin(admin.ModelAdmin):
|
||||
form = autocomplete_light.modelform_factory(EventRegistration, exclude=[])
|
||||
list_display = ('__unicode__' if six.PY2 else '__str__', 'event', 'user',
|
||||
'paid')
|
||||
list_display = ('__str__', 'event', 'user', 'paid')
|
||||
list_filter = ('paid',)
|
||||
search_fields = ('user__username', 'user__first_name', 'user__last_name',
|
||||
'user__email', 'event__title')
|
||||
|
|
|
@ -1,21 +1,13 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django import forms
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.contrib.auth.models import User
|
||||
from django.forms.widgets import RadioSelect, CheckboxSelectMultiple
|
||||
from django.forms.formsets import BaseFormSet, formset_factory
|
||||
from django.db.models import Max
|
||||
from django.core.validators import MinLengthValidator
|
||||
|
||||
from gestioncof.models import CofProfile, EventCommentValue, \
|
||||
CalendarSubscription, Club
|
||||
from gestioncof.widgets import TriStateCheckbox
|
||||
from gestioncof.shared import lock_table, unlock_table
|
||||
|
||||
from bda.models import Spectacle
|
||||
|
||||
|
@ -243,7 +235,6 @@ class RegistrationProfileForm(forms.ModelForm):
|
|||
self.fields['mailing_cof'].initial = True
|
||||
self.fields['mailing_bda'].initial = True
|
||||
self.fields['mailing_bda_revente'].initial = True
|
||||
self.fields['num'].widget.attrs['readonly'] = True
|
||||
|
||||
self.fields.keyOrder = [
|
||||
'login_clipper',
|
||||
|
@ -251,7 +242,6 @@ class RegistrationProfileForm(forms.ModelForm):
|
|||
'occupation',
|
||||
'departement',
|
||||
'is_cof',
|
||||
'num',
|
||||
'type_cotiz',
|
||||
'mailing_cof',
|
||||
'mailing_bda',
|
||||
|
@ -259,24 +249,9 @@ class RegistrationProfileForm(forms.ModelForm):
|
|||
'comments'
|
||||
]
|
||||
|
||||
def save(self, *args, **kw):
|
||||
instance = super(RegistrationProfileForm, self).save(*args, **kw)
|
||||
if instance.is_cof and not instance.num:
|
||||
# Generate new number
|
||||
try:
|
||||
lock_table(CofProfile)
|
||||
aggregate = CofProfile.objects.aggregate(Max('num'))
|
||||
instance.num = aggregate['num__max'] + 1
|
||||
instance.save()
|
||||
self.cleaned_data['num'] = instance.num
|
||||
self.data['num'] = instance.num
|
||||
finally:
|
||||
unlock_table(CofProfile)
|
||||
return instance
|
||||
|
||||
class Meta:
|
||||
model = CofProfile
|
||||
fields = ("login_clipper", "num", "phone", "occupation",
|
||||
fields = ("login_clipper", "phone", "occupation",
|
||||
"departement", "is_cof", "type_cotiz", "mailing_cof",
|
||||
"mailing_bda", "mailing_bda_revente", "comments")
|
||||
|
||||
|
|
18
gestioncof/migrations/0011_remove_cofprofile_num.py
Normal file
18
gestioncof/migrations/0011_remove_cofprofile_num.py
Normal file
|
@ -0,0 +1,18 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('gestioncof', '0010_delete_custommail'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='cofprofile',
|
||||
name='num',
|
||||
),
|
||||
]
|
|
@ -1,11 +1,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from django.db import models
|
||||
from django.dispatch import receiver
|
||||
from django.contrib.auth.models import User
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.encoding import python_2_unicode_compatible
|
||||
import django.utils.six as six
|
||||
from django.db.models.signals import post_save, post_delete
|
||||
|
||||
from gestioncof.petits_cours_models import choices_length
|
||||
|
@ -35,12 +31,10 @@ TYPE_COMMENT_FIELD = (
|
|||
)
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class CofProfile(models.Model):
|
||||
user = models.OneToOneField(User, related_name="profile")
|
||||
login_clipper = models.CharField("Login clipper", max_length=8, blank=True)
|
||||
is_cof = models.BooleanField("Membre du COF", default=False)
|
||||
num = models.IntegerField("Numéro d'adhérent", blank=True, default=0)
|
||||
phone = models.CharField("Téléphone", max_length=20, blank=True)
|
||||
occupation = models.CharField(_("Occupation"),
|
||||
default="1A",
|
||||
|
@ -72,7 +66,7 @@ class CofProfile(models.Model):
|
|||
verbose_name_plural = "Profils COF"
|
||||
|
||||
def __str__(self):
|
||||
return six.text_type(self.user.username)
|
||||
return self.user.username
|
||||
|
||||
|
||||
@receiver(post_save, sender=User)
|
||||
|
@ -86,7 +80,6 @@ def post_delete_user(sender, instance, *args, **kwargs):
|
|||
instance.user.delete()
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class Club(models.Model):
|
||||
name = models.CharField("Nom", max_length=200, unique=True)
|
||||
description = models.TextField("Description", blank=True)
|
||||
|
@ -98,7 +91,6 @@ class Club(models.Model):
|
|||
return self.name
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class Event(models.Model):
|
||||
title = models.CharField("Titre", max_length=200)
|
||||
location = models.CharField("Lieu", max_length=200)
|
||||
|
@ -115,10 +107,9 @@ class Event(models.Model):
|
|||
verbose_name = "Événement"
|
||||
|
||||
def __str__(self):
|
||||
return six.text_type(self.title)
|
||||
return self.title
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class EventCommentField(models.Model):
|
||||
event = models.ForeignKey(Event, related_name="commentfields")
|
||||
name = models.CharField("Champ", max_length=200)
|
||||
|
@ -130,10 +121,9 @@ class EventCommentField(models.Model):
|
|||
verbose_name = "Champ"
|
||||
|
||||
def __str__(self):
|
||||
return six.text_type(self.name)
|
||||
return self.name
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class EventCommentValue(models.Model):
|
||||
commentfield = models.ForeignKey(EventCommentField, related_name="values")
|
||||
registration = models.ForeignKey("EventRegistration",
|
||||
|
@ -144,7 +134,6 @@ class EventCommentValue(models.Model):
|
|||
return "Commentaire de %s" % self.commentfield
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class EventOption(models.Model):
|
||||
event = models.ForeignKey(Event, related_name="options")
|
||||
name = models.CharField("Option", max_length=200)
|
||||
|
@ -154,10 +143,9 @@ class EventOption(models.Model):
|
|||
verbose_name = "Option"
|
||||
|
||||
def __str__(self):
|
||||
return six.text_type(self.name)
|
||||
return self.name
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class EventOptionChoice(models.Model):
|
||||
event_option = models.ForeignKey(EventOption, related_name="choices")
|
||||
value = models.CharField("Valeur", max_length=200)
|
||||
|
@ -167,10 +155,9 @@ class EventOptionChoice(models.Model):
|
|||
verbose_name_plural = "Choix"
|
||||
|
||||
def __str__(self):
|
||||
return six.text_type(self.value)
|
||||
return self.value
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class EventRegistration(models.Model):
|
||||
user = models.ForeignKey(User)
|
||||
event = models.ForeignKey(Event)
|
||||
|
@ -184,11 +171,9 @@ class EventRegistration(models.Model):
|
|||
unique_together = ("user", "event")
|
||||
|
||||
def __str__(self):
|
||||
return "Inscription de %s à %s" % (six.text_type(self.user),
|
||||
six.text_type(self.event.title))
|
||||
return "Inscription de {} à {}".format(self.user, self.event.title)
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class Survey(models.Model):
|
||||
title = models.CharField("Titre", max_length=200)
|
||||
details = models.TextField("Détails", blank=True)
|
||||
|
@ -199,10 +184,9 @@ class Survey(models.Model):
|
|||
verbose_name = "Sondage"
|
||||
|
||||
def __str__(self):
|
||||
return six.text_type(self.title)
|
||||
return self.title
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class SurveyQuestion(models.Model):
|
||||
survey = models.ForeignKey(Survey, related_name="questions")
|
||||
question = models.CharField("Question", max_length=200)
|
||||
|
@ -212,10 +196,9 @@ class SurveyQuestion(models.Model):
|
|||
verbose_name = "Question"
|
||||
|
||||
def __str__(self):
|
||||
return six.text_type(self.question)
|
||||
return self.question
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class SurveyQuestionAnswer(models.Model):
|
||||
survey_question = models.ForeignKey(SurveyQuestion, related_name="answers")
|
||||
answer = models.CharField("Réponse", max_length=200)
|
||||
|
@ -224,10 +207,9 @@ class SurveyQuestionAnswer(models.Model):
|
|||
verbose_name = "Réponse"
|
||||
|
||||
def __str__(self):
|
||||
return six.text_type(self.answer)
|
||||
return self.answer
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class SurveyAnswer(models.Model):
|
||||
user = models.ForeignKey(User)
|
||||
survey = models.ForeignKey(Survey)
|
||||
|
@ -244,7 +226,6 @@ class SurveyAnswer(models.Model):
|
|||
self.survey.title)
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class CalendarSubscription(models.Model):
|
||||
token = models.UUIDField()
|
||||
user = models.OneToOneField(User)
|
||||
|
|
|
@ -12,15 +12,15 @@ from django.views.decorators.csrf import csrf_exempt
|
|||
from django.conf import settings
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.contrib import messages
|
||||
from django.db import transaction
|
||||
|
||||
from gestioncof.models import CofProfile
|
||||
from gestioncof.petits_cours_models import (
|
||||
PetitCoursDemande, PetitCoursAttribution, PetitCoursAttributionCounter,
|
||||
PetitCoursAbility, PetitCoursSubject
|
||||
PetitCoursAbility
|
||||
)
|
||||
from gestioncof.petits_cours_forms import DemandeForm, MatieresFormSet
|
||||
from gestioncof.decorators import buro_required
|
||||
from gestioncof.shared import lock_table, unlock_tables
|
||||
|
||||
|
||||
class DemandeListView(ListView):
|
||||
|
@ -274,17 +274,17 @@ def _traitement_post(request, demande):
|
|||
headers={'Reply-To': replyto}))
|
||||
connection = mail.get_connection(fail_silently=False)
|
||||
connection.send_messages(mails_to_send)
|
||||
lock_table(PetitCoursAttributionCounter, PetitCoursAttribution, User)
|
||||
for matiere in proposals:
|
||||
for rank, user in enumerate(proposals[matiere]):
|
||||
counter = PetitCoursAttributionCounter.objects.get(user=user,
|
||||
matiere=matiere)
|
||||
counter.count += 1
|
||||
counter.save()
|
||||
attrib = PetitCoursAttribution(user=user, matiere=matiere,
|
||||
demande=demande, rank=rank + 1)
|
||||
attrib.save()
|
||||
unlock_tables()
|
||||
with transaction.atomic():
|
||||
for matiere in proposals:
|
||||
for rank, user in enumerate(proposals[matiere]):
|
||||
counter = PetitCoursAttributionCounter.objects.get(
|
||||
user=user, matiere=matiere
|
||||
)
|
||||
counter.count += 1
|
||||
counter.save()
|
||||
attrib = PetitCoursAttribution(user=user, matiere=matiere,
|
||||
demande=demande, rank=rank + 1)
|
||||
attrib.save()
|
||||
demande.traitee = True
|
||||
demande.traitee_par = request.user
|
||||
demande.processed = datetime.now()
|
||||
|
@ -309,17 +309,15 @@ def inscription(request):
|
|||
profile.petits_cours_accept = "receive_proposals" in request.POST
|
||||
profile.petits_cours_remarques = request.POST["remarques"]
|
||||
profile.save()
|
||||
lock_table(PetitCoursAttributionCounter, PetitCoursAbility, User,
|
||||
PetitCoursSubject)
|
||||
abilities = (
|
||||
PetitCoursAbility.objects.filter(user=request.user).all()
|
||||
)
|
||||
for ability in abilities:
|
||||
PetitCoursAttributionCounter.get_uptodate(
|
||||
ability.user,
|
||||
ability.matiere
|
||||
with transaction.atomic():
|
||||
abilities = (
|
||||
PetitCoursAbility.objects.filter(user=request.user).all()
|
||||
)
|
||||
unlock_tables()
|
||||
for ability in abilities:
|
||||
PetitCoursAttributionCounter.get_uptodate(
|
||||
ability.user,
|
||||
ability.matiere
|
||||
)
|
||||
success = True
|
||||
formset = MatieresFormSet(instance=request.user)
|
||||
else:
|
||||
|
|
|
@ -1,15 +1,8 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.contrib.sites.models import Site
|
||||
from django.conf import settings
|
||||
from django_cas_ng.backends import CASBackend
|
||||
from django_cas_ng.utils import get_cas_client
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.db import connection
|
||||
|
||||
from gestioncof.models import CofProfile
|
||||
|
||||
|
@ -74,25 +67,3 @@ def context_processor(request):
|
|||
"site": Site.objects.get_current(),
|
||||
}
|
||||
return data
|
||||
|
||||
|
||||
def lock_table(*models):
|
||||
query = "LOCK TABLES "
|
||||
for i, model in enumerate(models):
|
||||
table = model._meta.db_table
|
||||
if i > 0:
|
||||
query += ", "
|
||||
query += "%s WRITE" % table
|
||||
cursor = connection.cursor()
|
||||
cursor.execute(query)
|
||||
row = cursor.fetchone()
|
||||
return row
|
||||
|
||||
|
||||
def unlock_tables(*models):
|
||||
cursor = connection.cursor()
|
||||
cursor.execute("UNLOCK TABLES")
|
||||
row = cursor.fetchone()
|
||||
return row
|
||||
|
||||
unlock_table = unlock_tables
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
import unicodecsv
|
||||
import uuid
|
||||
from datetime import timedelta
|
||||
|
@ -14,7 +12,6 @@ from django.contrib.auth.models import User
|
|||
from django.contrib.sites.models import Site
|
||||
from django.utils import timezone
|
||||
from django.contrib import messages
|
||||
import django.utils.six as six
|
||||
|
||||
from gestioncof.models import Survey, SurveyAnswer, SurveyQuestion, \
|
||||
SurveyQuestionAnswer
|
||||
|
@ -403,12 +400,8 @@ def registration_form2(request, login_clipper=None, username=None,
|
|||
def registration(request):
|
||||
if request.POST:
|
||||
request_dict = request.POST.copy()
|
||||
# num ne peut pas être défini manuellement
|
||||
if "num" in request_dict:
|
||||
del request_dict["num"]
|
||||
member = None
|
||||
login_clipper = None
|
||||
success = False
|
||||
|
||||
# -----
|
||||
# Remplissage des formulaires
|
||||
|
@ -445,7 +438,6 @@ def registration(request):
|
|||
member = user_form.save()
|
||||
profile, _ = CofProfile.objects.get_or_create(user=member)
|
||||
was_cof = profile.is_cof
|
||||
request_dict["num"] = profile.num
|
||||
# Maintenant on remplit le formulaire de profil
|
||||
profile_form = RegistrationProfileForm(request_dict,
|
||||
instance=profile)
|
||||
|
@ -499,16 +491,18 @@ def registration(request):
|
|||
for club in clubs_form.cleaned_data['clubs']:
|
||||
club.membres.add(member)
|
||||
club.save()
|
||||
success = True
|
||||
# Messages
|
||||
if success:
|
||||
msg = ("L'inscription de {:s} (<tt>{:s}</tt>) a été "
|
||||
"enregistrée avec succès"
|
||||
.format(member.get_full_name(), member.email))
|
||||
if member.profile.is_cof:
|
||||
msg += "Il est désormais membre du COF n°{:d} !".format(
|
||||
member.profile.num)
|
||||
messages.success(request, msg, extra_tags='safe')
|
||||
|
||||
# ---
|
||||
# Success
|
||||
# ---
|
||||
|
||||
msg = ("L'inscription de {:s} (<tt>{:s}</tt>) a été "
|
||||
"enregistrée avec succès."
|
||||
.format(member.get_full_name(), member.email))
|
||||
if profile.is_cof:
|
||||
msg += "\nIl est désormais membre du COF n°{:d} !".format(
|
||||
member.profile.id)
|
||||
messages.success(request, msg, extra_tags='safe')
|
||||
return render(request, "gestioncof/registration_post.html",
|
||||
{"user_form": user_form,
|
||||
"profile_form": profile_form,
|
||||
|
@ -572,10 +566,10 @@ def export_members(request):
|
|||
writer = unicodecsv.writer(response)
|
||||
for profile in CofProfile.objects.filter(is_cof=True).all():
|
||||
user = profile.user
|
||||
bits = [profile.num, user.username, user.first_name, user.last_name,
|
||||
bits = [profile.id, user.username, user.first_name, user.last_name,
|
||||
user.email, profile.phone, profile.occupation,
|
||||
profile.departement, profile.type_cotiz]
|
||||
writer.writerow([six.text_type(bit) for bit in bits])
|
||||
writer.writerow([str(bit) for bit in bits])
|
||||
|
||||
return response
|
||||
|
||||
|
@ -591,10 +585,10 @@ def csv_export_mega(filename, qs):
|
|||
comments = "---".join(
|
||||
[comment.content for comment in reg.comments.all()])
|
||||
bits = [user.username, user.first_name, user.last_name, user.email,
|
||||
profile.phone, profile.num,
|
||||
profile.phone, profile.id,
|
||||
profile.comments if profile.comments else "", comments]
|
||||
|
||||
writer.writerow([six.text_type(bit) for bit in bits])
|
||||
writer.writerow([str(bit) for bit in bits])
|
||||
|
||||
return response
|
||||
|
||||
|
@ -613,8 +607,8 @@ def export_mega_remarksonly(request):
|
|||
user = reg.user
|
||||
profile = user.profile
|
||||
bits = [user.username, user.first_name, user.last_name, user.email,
|
||||
profile.phone, profile.num, profile.comments, val.content]
|
||||
writer.writerow([six.text_type(bit) for bit in bits])
|
||||
profile.phone, profile.id, profile.comments, val.content]
|
||||
writer.writerow([str(bit) for bit in bits])
|
||||
|
||||
return response
|
||||
|
||||
|
|
57
kfet/tests/test_views.py
Normal file
57
kfet/tests/test_views.py
Normal file
|
@ -0,0 +1,57 @@
|
|||
from decimal import Decimal
|
||||
|
||||
from django.test import TestCase, Client
|
||||
from django.contrib.auth.models import User
|
||||
from django.utils import timezone
|
||||
|
||||
from ..models import Account, OperationGroup, Checkout, Operation
|
||||
|
||||
|
||||
class AccountTests(TestCase):
|
||||
"""Account related views"""
|
||||
|
||||
def setUp(self):
|
||||
# A user and its account
|
||||
self.user = User.objects.create_user(username="foobar", password="foo")
|
||||
acc = Account.objects.create(
|
||||
trigramme="FOO", cofprofile=self.user.profile
|
||||
)
|
||||
|
||||
# Dummy operations and operation groups
|
||||
checkout = Checkout.objects.create(
|
||||
created_by=acc, name="checkout",
|
||||
valid_from=timezone.now(),
|
||||
valid_to=timezone.now() + timezone.timedelta(days=365)
|
||||
)
|
||||
opeg_data = [
|
||||
(timezone.now(), Decimal('10')),
|
||||
(timezone.now() - timezone.timedelta(days=3), Decimal('3')),
|
||||
]
|
||||
OperationGroup.objects.bulk_create([
|
||||
OperationGroup(
|
||||
on_acc=acc, checkout=checkout, at=at, is_cof=False,
|
||||
amount=amount
|
||||
)
|
||||
for (at, amount) in opeg_data
|
||||
])
|
||||
self.operation_groups = OperationGroup.objects.order_by("-amount")
|
||||
Operation.objects.create(
|
||||
group=self.operation_groups[0],
|
||||
type=Operation.PURCHASE,
|
||||
amount=Decimal('10')
|
||||
)
|
||||
Operation.objects.create(
|
||||
group=self.operation_groups[1],
|
||||
type=Operation.PURCHASE,
|
||||
amount=Decimal('3')
|
||||
)
|
||||
|
||||
def test_account_read(self):
|
||||
"""We can query the "Accout - Read" page."""
|
||||
client = Client()
|
||||
self.assertTrue(client.login(
|
||||
username="foobar",
|
||||
password="foo"
|
||||
))
|
||||
resp = client.get("/k-fet/accounts/FOO")
|
||||
self.assertEqual(200, resp.status_code)
|
Loading…
Reference in a new issue