Merge branch 'master' into aureplop/kpsul_js_refactor

This commit is contained in:
Aurélien Delobelle 2017-04-10 13:08:23 +02:00
commit c75b2946e3
10 changed files with 231 additions and 131 deletions

View file

@ -18,7 +18,10 @@ class Tirage(models.Model):
fermeture = models.DateTimeField("Date et heure de fermerture du tirage")
tokens = models.TextField("Graine(s) du tirage", blank=True)
active = models.BooleanField("Tirage actif", default=False)
appear_catalogue = models.BooleanField("Tirage à afficher dans le catalogue", default=False)
appear_catalogue = models.BooleanField(
"Tirage à afficher dans le catalogue",
default=False
)
enable_do_tirage = models.BooleanField("Le tirage peut être lancé",
default=False)

View file

@ -1,22 +1,79 @@
# -*- coding: utf-8 -*-
"""
This file demonstrates writing tests using the unittest module. These will pass
when you run "manage.py test".
import json
Replace this with more appropriate tests for your application.
"""
from django.test import TestCase, Client
from django.utils import timezone
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
from .models import Tirage, Spectacle, Salle, CategorieSpectacle
from django.test import TestCase
class TestBdAViews(TestCase):
def setUp(self):
self.tirage = Tirage.objects.create(
title="Test tirage",
appear_catalogue=True,
ouverture=timezone.now(),
fermeture=timezone.now(),
)
self.category = CategorieSpectacle.objects.create(name="Category")
self.location = Salle.objects.create(name="here")
Spectacle.objects.bulk_create([
Spectacle(
title="foo", date=timezone.now(), location=self.location,
price=0, slots=42, tirage=self.tirage, listing=False,
category=self.category
),
Spectacle(
title="bar", date=timezone.now(), location=self.location,
price=1, slots=142, tirage=self.tirage, listing=False,
category=self.category
),
Spectacle(
title="baz", date=timezone.now(), location=self.location,
price=2, slots=242, tirage=self.tirage, listing=False,
category=self.category
),
])
def test_catalogue(self):
"""Test the catalogue JSON API"""
client = Client()
class SimpleTest(TestCase):
def test_basic_addition(self):
"""
Tests that 1 + 1 always equals 2.
"""
self.assertEqual(1 + 1, 2)
# The `list` hooh
resp = client.get("/bda/catalogue/list")
self.assertJSONEqual(
resp.content.decode("utf-8"),
[{"id": self.tirage.id, "title": self.tirage.title}]
)
# The `details` hook
resp = client.get(
"/bda/catalogue/details?id={}".format(self.tirage.id)
)
self.assertJSONEqual(
resp.content.decode("utf-8"),
{
"categories": [{
"id": self.category.id,
"name": self.category.name
}],
"locations": [{
"id": self.location.id,
"name": self.location.name
}],
}
)
# The `descriptions` hook
resp = client.get(
"/bda/catalogue/descriptions?id={}".format(self.tirage.id)
)
raw = resp.content.decode("utf-8")
try:
results = json.loads(raw)
except ValueError:
self.fail("Not valid JSON: {}".format(raw))
self.assertEqual(len(results), 3)
self.assertEqual(
{(s["title"], s["price"], s["slots"]) for s in results},
{("foo", 0, 42), ("bar", 1, 142), ("baz", 2, 242)}
)

View file

@ -22,7 +22,6 @@ from django.core.urlresolvers import reverse
from django.conf import settings
from django.utils import timezone, formats
from django.views.generic.list import ListView
from django.core.exceptions import ObjectDoesNotExist
from gestioncof.decorators import cof_required, buro_required
from bda.models import (
Spectacle, Participant, ChoixSpectacle, Attribution, Tirage,
@ -657,29 +656,35 @@ def catalogue(request, request_type):
if request_type == "list":
# Dans ce cas on retourne la liste des tirages et de leur id en JSON
data_return = list(
Tirage.objects.filter(appear_catalogue=True).values('id', 'title'))
Tirage.objects.filter(appear_catalogue=True).values('id', 'title')
)
return JsonResponse(data_return, safe=False)
if request_type == "details":
# Dans ce cas on retourne une liste des catégories et des salles
tirage_id = request.GET.get('id', '')
try:
tirage = Tirage.objects.get(id=tirage_id)
except ObjectDoesNotExist:
tirage_id = request.GET.get('id', None)
if tirage_id is None:
return HttpResponseBadRequest(
"Aucun tirage correspondant à l'id "
+ tirage_id)
"Missing GET parameter: id <int>"
)
try:
tirage = get_object_or_404(Tirage, id=int(tirage_id))
except ValueError:
return HttpResponseBadRequest(
"Mauvais format d'identifiant : "
+ tirage_id)
"Bad format: int expected for `id`"
)
shows = tirage.spectacle_set.values_list("id", flat=True)
categories = list(
CategorieSpectacle.objects.filter(
spectacle__in=tirage.spectacle_set.all())
.distinct().values('id', 'name'))
CategorieSpectacle.objects
.filter(spectacle__in=shows)
.distinct()
.values('id', 'name')
)
locations = list(
Salle.objects.filter(
spectacle__in=tirage.spectacle_set.all())
.distinct().values('id', 'name'))
Salle.objects
.filter(spectacle__in=shows)
.distinct()
.values('id', 'name')
)
data_return = {'categories': categories, 'locations': locations}
return JsonResponse(data_return, safe=False)
if request_type == "descriptions":
@ -687,33 +692,35 @@ def catalogue(request, request_type):
# à la salle spécifiées
tirage_id = request.GET.get('id', '')
categories = request.GET.get('category', '[0]')
locations = request.GET.get('location', '[0]')
categories = request.GET.get('category', '[]')
locations = request.GET.get('location', '[]')
try:
category_id = json.loads(categories)
location_id = json.loads(locations)
tirage = Tirage.objects.get(id=tirage_id)
shows_qs = tirage.spectacle_set
if not(0 in category_id):
shows_qs = shows_qs.filter(
category__id__in=category_id)
if not(0 in location_id):
shows_qs = shows_qs.filter(
location__id__in=location_id)
except ObjectDoesNotExist:
return HttpResponseBadRequest(
"Impossible de trouver des résultats correspondant "
"à ces caractéristiques : "
+ "id = " + tirage_id
+ ", catégories = " + categories
+ ", salles = " + locations)
tirage_id = int(tirage_id)
categories_id = json.loads(categories)
locations_id = json.loads(locations)
# Integers expected
if not all(isinstance(id, int) for id in categories_id):
raise ValueError
if not all(isinstance(id, int) for id in locations_id):
raise ValueError
except ValueError: # Contient JSONDecodeError
return HttpResponseBadRequest(
"Impossible de parser les paramètres donnés : "
+ "id = " + request.GET.get('id', '')
+ ", catégories = " + request.GET.get('category', '[0]')
+ ", salles = " + request.GET.get('location', '[0]'))
"Parse error, please ensure the GET parameters have the "
"following types:\n"
"id: int, category: [int], location: [int]\n"
"Data received:\n"
"id = {}, category = {}, locations = {}"
.format(request.GET.get('id', ''),
request.GET.get('category', '[]'),
request.GET.get('location', '[]'))
)
tirage = get_object_or_404(Tirage, id=tirage_id)
shows_qs = tirage.spectacle_set
if categories_id:
shows_qs = shows_qs.filter(category__id__in=categories_id)
if locations_id:
shows_qs = shows_qs.filter(location__id__in=locations_id)
# On convertit les descriptions à envoyer en une liste facilement
# JSONifiable (il devrait y avoir un moyen plus efficace en

View file

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
('kfet', '0052_category_addcost'),
]
operations = [
migrations.AlterField(
model_name='account',
name='created_at',
field=models.DateTimeField(default=django.utils.timezone.now),
),
]

View file

@ -41,7 +41,7 @@ class Account(models.Model):
max_digits = 6, decimal_places = 2,
default = 0)
is_frozen = models.BooleanField("est gelé", default = False)
created_at = models.DateTimeField(auto_now_add = True, null = True)
created_at = models.DateTimeField(default=timezone.now)
# Optional
PROMO_CHOICES = [(r,r) for r in range(1980, date.today().year+1)]
promo = models.IntegerField(

View file

@ -86,6 +86,16 @@ textarea {
color:#FFF;
}
.buttons .nav-pills > li > a {
border-radius:0;
border:1px solid rgba(200,16,46,0.9);
}
.buttons .nav-pills > li.active > a {
background-color:rgba(200,16,46,0.9);
background-clip:padding-box;
}
.row-page-header {
background-color:rgba(200,16,46,1);
color:#FFF;

View file

@ -56,45 +56,40 @@ $(document).ready(function() {
<div class="col-sm-8 col-md-9 col-content-right">
{% include "kfet/base_messages.html" %}
<div class="content-right">
{% if addcosts %}
<div class="content-right-block">
<h2>Gagné des majorations</h2>
<div>
<ul>
{% for addcost in addcosts %}
<li>{{ addcost.date|date:'l j F' }}: +{{ addcost.sum_addcosts }}€</li>
{% endfor %}
</ul>
</div>
</div>
{% endif %}
{% if account.user == request.user %}
<div class="content-right-block content-right-block-transparent">
<h2>Statistiques</h2>
<div class="row">
<div class="col-sm-12 nopadding">
<div class="panel-md-margin">
<h3>Ma balance</h3>
<div id="stat_balance"></div>
</div>
</div>
</div><!-- /row -->
<div class="row">
<div class="col-sm-12 nopadding">
<div class="panel-md-margin">
<h3>Ma consommation</h3>
<div id="stat_last"></div>
</div>
</div>
</div><!-- /row -->
</div>
{% endif %}
<div class="content-right-block">
<h2>Historique</h2>
<div id="history">
</div>
</div>
</div>
<div class="col-sm-12 nopadding">
{% if account.user == request.user %}
<div class='tab-content'>
<div class="tab-pane fade in active" id="tab_stats">
<h2>Statistiques</h2>
<div class="panel-md-margin">
<h3>Ma balance</h3>
<div id="stat_balance"></div>
<h3>Ma consommation</h3>
<div id="stat_last"></div>
</div>
</div>
<div class="tab-pane fade" id="tab_history">
{% endif %}
{% if addcosts %}
<h2>Gagné des majorations</h2>
<div>
<ul>
{% for addcost in addcosts %}
<li>{{ addcost.date|date:'l j F' }}: +{{ addcost.sum_addcosts }}€</li>
{% endfor %}
</ul>
</div>
{% endif %}
<h2>Historique</h2>
<div id="history"></div>
{% if account.user == request.user %}
</div>
</div><!-- tab-content -->
{% endif %}
</div><!-- col-sm-12 -->
</div><!-- content-right-block -->
</div><!-- content-right-->
</div>
</div>

View file

@ -20,40 +20,42 @@
<div class="content-right">
<div class="content-right-block">
<h2>Carte</h2>
<div class="column-row">
<div class="column-sm-1 column-md-2 column-lg-3">
<div class="unbreakable carte-inverted">
<h3>Pressions du moment</h3>
<ul class="carte">
{% for article in pressions %}
<li class="carte-line">
<div class="filler"></div>
<span class="carte-label">{{ article.name }}</span>
<span class="carte-ukf">{{ article.price | ukf:False}} UKF</span>
</li>
{% endfor %}
</ul>
</div><!-- endblock unbreakable -->
{% for article in articles %}
{% ifchanged article.category %}
{% if not forloop.first %}
</ul>
</div><!-- endblock unbreakable -->
{% endif %}
<div class="unbreakable">
<h3>{{ article.category.name }}</h3>
<ul class="carte">
{% endifchanged %}
<li class="carte-line">
<div class="filler"></div>
<span class="carte-label">{{ article.name }}</span>
<span class="carte-ukf">{{ article.price | ukf:False}} UKF</span>
</li>
{% if foorloop.last %}
</ul>
</div><!-- endblock unbreakable -->
{% endif %}
<div class="column-row">
<div class="column-sm-1 column-md-2 column-lg-3">
<div class="unbreakable carte-inverted">
{% if pressions %}
<h3>Pressions du moment</h3>
<ul class="carte">
{% for article in pressions %}
<li class="carte-line">
<div class="filler"></div>
<span class="carte-label">{{ article.name }}</span>
<span class="carte-ukf">{{ article.price | ukf:False}} UKF</span>
</li>
{% endfor %}
</ul>
{% endif %}
</div><!-- endblock unbreakable -->
{% for article in articles %}
{% ifchanged article.category %}
{% if not forloop.first %}
</ul>
</div><!-- endblock unbreakable -->
{% endif %}
<div class="unbreakable">
<h3>{{ article.category.name }}</h3>
<ul class="carte">
{% endifchanged %}
<li class="carte-line">
<div class="filler"></div>
<span class="carte-label">{{ article.name }}</span>
<span class="carte-ukf">{{ article.price | ukf:False}} UKF</span>
</li>
{% if forloop.last %}
</ul>
</div><!-- endblock unbreakable -->
{% endif %}
{% endfor %}
</div>
</div>
</div>

View file

@ -291,7 +291,7 @@ $(document).ready(function() {
var reduc_divisor = 1;
if (kpsul.account_manager.account.is_cof)
reduc_divisor = 1 + Config.get('subvention_cof') / 100;
return amount_euro / reduc_divisor;
return (amount_euro / reduc_divisor).toFixed(2);
}
function addPurchase(article, nb) {
@ -306,7 +306,7 @@ $(document).ready(function() {
}
});
if (!existing) {
var amount_euro = amountEuroPurchase(article, nb).toFixed(2);
var amount_euro = amountEuroPurchase(article, nb);
var index = addPurchaseToFormset(article.id, nb, amount_euro);
var article_basket_html = $(item_basket_default_html);
article_basket_html

View file

@ -36,6 +36,12 @@
</div>
</div>
<div class="buttons">
{% if account.user == request.user %}
<ul class='nav nav-pills nav-justified'>
<li class="active"><a data-toggle="pill" href="#tab_stats">Statistiques</a></li>
<li><a data-toggle="pill" href="#tab_history">Historique</a></li>
</ul>
{% endif %}
<a class="btn btn-primary btn-lg" href="{% url 'kfet.account.update' account.trigramme %}">
Modifier
</a>