Vues gestion caisses et amélioration Account

- General :
    - Ajout de la gestion des messages dans le template base
    - jQuery et bootstrap ajoutés au template base
    - Ajout de DateTimeWidget utilisant bootstrap-datetimepicker pour
      les champs DateTime
- Account :
    - Ajout de propriétés aux modèles pour accéder directement à
      certains éléments sans avoir à passer par les relations
    - Suppression d'une méthode inutile dans le modèle
    - Correction de permission dans la vue update
    - Utilisation des messages pour la création et l'édition d'un compte
- Checkout :
    - gestion initiale CRU
This commit is contained in:
Aurélien Delobelle 2016-08-04 05:21:04 +02:00
parent 9677fd9ef6
commit 2786f834a5
16 changed files with 4647 additions and 59 deletions

View file

@ -1,8 +1,29 @@
from django import forms from django import forms
from django.contrib.auth.models import User from django.contrib.auth.models import User
from kfet.models import Account from kfet.models import Account, Checkout
from gestioncof.models import CofProfile from gestioncof.models import CofProfile
# -----
# Widgets
# -----
class DateTimeWidget(forms.DateTimeInput):
def __init__(self, attrs = None):
super(DateTimeWidget, self).__init__(attrs)
self.attrs['format'] = '%Y-%m-%d %H:%M'
class Media:
css = {
'all': ('bootstrap-datetimepicker.min.css',)
}
js = (
'moment.js',
'moment-fr.js',
'bootstrap-datetimepicker.min.js',
)
# -----
# Account forms
# -----
class AccountForm(forms.ModelForm): class AccountForm(forms.ModelForm):
# Surcharge pour passer data à Account.save() # Surcharge pour passer data à Account.save()
@ -56,3 +77,20 @@ class UserForm(forms.ModelForm):
class UserRestrictForm(UserForm): class UserRestrictForm(UserForm):
class Meta(UserForm.Meta): class Meta(UserForm.Meta):
fields = ['first_name', 'last_name', 'email'] fields = ['first_name', 'last_name', 'email']
# -----
# Checkout forms
# -----
class CheckoutForm(forms.ModelForm):
class Meta:
model = Checkout
fields = ['name', 'valid_from', 'valid_to', 'balance', 'is_protected']
widgets = {
'valid_from': DateTimeWidget(),
'valid_to' : DateTimeWidget(),
}
class CheckoutRestrictForm(CheckoutForm):
class Meta(CheckoutForm.Meta):
fields = ['name', 'valid_from', 'valid_to']

View file

@ -1,4 +1,5 @@
from django.db import models from django.db import models
from django.core.urlresolvers import reverse
from django.core.exceptions import PermissionDenied from django.core.exceptions import PermissionDenied
from django.contrib.auth.models import User, AnonymousUser from django.contrib.auth.models import User, AnonymousUser
from django.core.validators import RegexValidator from django.core.validators import RegexValidator
@ -40,7 +41,46 @@ class Account(models.Model):
blank = True, null = True, default = None) blank = True, null = True, default = None)
def __str__(self): def __str__(self):
return self.trigramme return '%s (%s)' % (self.trigramme, self.name)
# Propriétés pour accéder aux attributs de user et cofprofile et user
@property
def user(self):
return self.cofprofile.user
@property
def username(self):
return self.cofprofile.user.username
@property
def first_name(self):
return self.cofprofile.user.first_name
@property
def last_name(self):
return self.cofprofile.user.last_name
@property
def email(self):
return self.cofprofile.user.email
@property
def departement(self):
return self.cofprofile.departement
@property
def is_cof(self):
return self.cofprofile.is_cof
# Propriétés supplémentaires
@property
def real_balance(self):
if (hasattr(self, 'negative')):
return self.balance + self.negative.balance_offset
return self.balance
@property
def name(self):
if self.first_name and self.last_name:
return '%s %s' % (self.first_name, self.last_name)
elif self.first_name:
return '%s %s' % self.first_name
else:
return self.last_name
@staticmethod @staticmethod
def is_validandfree(trigramme): def is_validandfree(trigramme):
@ -53,14 +93,6 @@ class Account(models.Model):
data['is_free'] = True data['is_free'] = True
return data return data
def real_balance(self):
if (hasattr(self, 'negative')):
return self.balance + self.negative.balance_offset
return self.balance
def read(self, auth_user = AnonymousUser()):
user = self.cofprofile.user
# Surcharge Méthode save() avec gestions de User et CofProfile # Surcharge Méthode save() avec gestions de User et CofProfile
# Args: # Args:
# - data : datas pour User et CofProfile # - data : datas pour User et CofProfile
@ -72,7 +104,7 @@ class Account(models.Model):
# Account update # Account update
# Updating User with data # Updating User with data
user = self.cofprofile.user user = self.user
user.first_name = data.get("first_name", user.first_name) user.first_name = data.get("first_name", user.first_name)
user.last_name = data.get("last_name", user.last_name) user.last_name = data.get("last_name", user.last_name)
user.email = data.get("email", user.email) user.email = data.get("email", user.email)
@ -81,12 +113,6 @@ class Account(models.Model):
cof = self.cofprofile cof = self.cofprofile
cof.departement = data.get("departement", cof.departement) cof.departement = data.get("departement", cof.departement)
cof.save() cof.save()
# Nickname is not editable by the user
"""
if not auth_user.has_perm('kfet.change_account'):
account_old = Account.objects.get(pk=self.pk)
self.nickname = account_old.nickname
"""
else: else:
# New account # New account
@ -149,9 +175,20 @@ class Checkout(models.Model):
name = models.CharField(max_length = 45) name = models.CharField(max_length = 45)
valid_from = models.DateTimeField() valid_from = models.DateTimeField()
valid_to = models.DateTimeField() valid_to = models.DateTimeField()
balance = models.DecimalField(max_digits = 6, decimal_places = 2) balance = models.DecimalField(
max_digits = 6, decimal_places = 2,
default = 0)
is_protected = models.BooleanField(default = False) is_protected = models.BooleanField(default = False)
def get_absolute_url(self):
return reverse('kfet.checkout.read', kwargs={'pk': self.pk})
class Meta:
ordering = ['-valid_to']
def __str__(self):
return self.name
class CheckoutTransfer(models.Model): class CheckoutTransfer(models.Model):
from_checkout = models.ForeignKey( from_checkout = models.ForeignKey(
Checkout, on_delete = models.PROTECT, Checkout, on_delete = models.PROTECT,

View file

@ -1,10 +1,9 @@
{% extends "kfet/base.html" %} {% extends "kfet/base.html" %}
{% load static %} {% load staticfiles %}
{% block title %}Création d'un nouveau compte{% endblock %} {% block title %}Création d'un nouveau compte{% endblock %}
{% block extra_head %} {% block extra_head %}
<script src="https://code.jquery.com/jquery-3.1.0.min.js" integrity="sha256-cCueBR6CsyA4/9szpPfrX3s49M9vUU5BgtiJj06wt/s=" crossorigin="anonymous"></script>
<script src="{% static "autocomplete_light/autocomplete.js" %}" type="text/javascript"></script> <script src="{% static "autocomplete_light/autocomplete.js" %}" type="text/javascript"></script>
{% endblock %} {% endblock %}

View file

@ -1,9 +1,19 @@
{% load staticfiles %}
<!DOCTYPE html> <!DOCTYPE html>
<html lang="fr"> <html lang="fr">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>{% block title %}{% endblock %} | K-Fêt - ENS Ulm</title> <title>{% block title %}{% endblock %} | K-Fêt - ENS Ulm</title>
{# jQuery #}
<script src="https://code.jquery.com/jquery-3.1.0.min.js" integrity="sha256-cCueBR6CsyA4/9szpPfrX3s49M9vUU5BgtiJj06wt/s=" crossorigin="anonymous"></script>
{# <script type="text/javascript" src="{% static 'moment.js' %}"></script> #}
{# Bootstrap #}
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
{% block extra_head %}{% endblock %} {% block extra_head %}{% endblock %}
{# Vieux IE pas comprendre HTML5 #} {# Vieux IE pas comprendre HTML5 #}
@ -13,6 +23,7 @@
</head> </head>
<body> <body>
{% include "kfet/base_nav.html" %} {% include "kfet/base_nav.html" %}
{% include "kfet/base_messages.html" %}
<section id="content"> <section id="content">
{% block content %}TGTG{% endblock %} {% block content %}TGTG{% endblock %}
</section> </section>

View file

@ -0,0 +1,7 @@
{% if messages %}
<ul class="messages">
{% for message in messages %}
<li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}

View file

@ -14,6 +14,7 @@
{% if perms.is_team %} {% if perms.is_team %}
<ul> <ul>
<li><a href="{% url "kfet.account" %}">Comptes</a></li> <li><a href="{% url "kfet.account" %}">Comptes</a></li>
<li><a href="{% url "kfet.checkout" %}">Caisses</a></li>
</ul> </ul>
{% endif %} {% endif %}
</nav> </nav>

View file

@ -0,0 +1,15 @@
{% extends "kfet/base.html" %}
{% block title %}Caisses{% endblock %}
{% block content %}
<a href="{% url 'kfet.checkout.create' %}">Nouvelle caisse</a>
<ul>
{% for checkout in checkouts %}
<li><a href="{% url 'kfet.checkout.update' checkout.pk %}">{{ checkout }}</a></li>
{% endfor %}
</ul>
{% endblock %}

View file

@ -0,0 +1,47 @@
{% extends "kfet/base.html" %}
{% block extra_head %}{{ form.media }}{% endblock %}
{% block title %}Création d'une nouvelle caisse{% endblock %}
{% block content %}
<form action="" method="post">
{% csrf_token %}
{% for field in form %}
{{ field.errors }}
{{ field.label_tag }}
<div style="position:relative">{{ field }}</div>
{% if field.help_text %}
<p class="help">{{ field.help_text|safe }}</p>
{% endif %}
{% endfor %}
<input type="submit" value="Enregistrer">
</form>
<script type="text/javascript">
$(document).ready(function() {
$('#id_valid_from').datetimepicker({
format : 'YYYY-MM-DD HH:mm',
stepping : 5,
locale : 'fr',
showTodayButton: true,
});
$('#id_valid_to').datetimepicker({
format : 'YYYY-MM-DD HH:mm',
stepping : 5,
useCurrent: false,
locale : 'fr',
showTodayButton: true,
});
$("#id_valid_from").on("dp.change", function (e) {
$('#id_valid_to').data("DateTimePicker").minDate(e.date);
});
$("#id_valid_to").on("dp.change", function (e) {
$('#id_valid_from').data("DateTimePicker").maxDate(e.date);
});
});
</script>
{% endblock %}

View file

@ -0,0 +1,21 @@
{% extends 'kfet/base.html' %}
{% block title %}Informations sur la caisse {{ checkout }}{% endblock %}
{% block content %}
{% if not checkout.is_protected %}
<p>
<a href="{% url 'kfet.checkout.update' checkout.pk %}">
Modifier les informations
</a>
</p>
{% endif %}
<p>Nom: {{ checkout.name }}</p>
<p>Valide du {{ checkout.valid_from|date:'l j F Y, G:i' }} au {{ checkout.valid_to|date:'l j F Y, G:i' }}</p>
<p>Créée par: {{ checkout.created_by }}</p>
<p>Balance: {{ checkout.balance }} €</p>
<p>Protected: {{ checkout.is_protected }}</p>
{% endblock %}

View file

@ -0,0 +1,48 @@
{% extends 'kfet/base.html' %}
{% block extra_head %}{{ form.media }}{% endblock %}
{% block title %}Edition de la caisse {{ checkout }}{% endblock %}
{% block content %}
<form action="" method="post">
{% csrf_token %}
{% for field in form %}
{{ field.errors }}
{{ field.label_tag }}
<div style="position:relative">{{ field }}</div>
{% if field.help_text %}
<p class="help">{{ field.help_text|safe }}</p>
{% endif %}
{% endfor %}
<input type=submit value="Mettre à jour">
</form>
<script type="text/javascript">
$(document).ready(function() {
$('#id_valid_from').datetimepicker({
//format : 'YYYY-MM-DD HH:mm',
stepping : 5,
locale : 'fr',
showTodayButton: true,
});
$('#id_valid_to').datetimepicker({
//format : 'YYYY-MM-DD HH:mm',
stepping : 5,
useCurrent: false,
locale : 'fr',
showTodayButton: true,
useCurrent: false
});
$("#id_valid_from").on("dp.change", function (e) {
$('#id_valid_to').data("DateTimePicker").minDate(e.date);
});
$("#id_valid_to").on("dp.change", function (e) {
$('#id_valid_from').data("DateTimePicker").maxDate(e.date);
});
});
</script>
{% endblock %}

View file

@ -1,4 +1,5 @@
from django.conf.urls import url from django.conf.urls import url
from django.contrib.auth.decorators import permission_required
from kfet import views from kfet import views
from kfet import autocomplete from kfet import autocomplete
@ -7,10 +8,10 @@ urlpatterns = [
name = 'kfet.home'), name = 'kfet.home'),
# ----- # -----
# Account views # Account urls
# ----- # -----
# General # Account - General
url(r'^account/$', views.account, url(r'^account/$', views.account,
name = 'kfet.account'), name = 'kfet.account'),
url(r'^account/is_validandfree$', views.account_is_validandfree_ajax, url(r'^account/is_validandfree$', views.account_is_validandfree_ajax,
@ -34,5 +35,26 @@ urlpatterns = [
# Account - Update # Account - Update
url(r'^account/(?P<trigramme>.{3})/edit$', views.account_update, url(r'^account/(?P<trigramme>.{3})/edit$', views.account_update,
name = 'kfet.account.update') name = 'kfet.account.update'),
# -----
# Checkout urls
# -----
# Checkout - General
url('^checkout/$',
permission_required('kfet.is_team')(views.CheckoutList.as_view()),
name = 'kfet.checkout'),
# Checkout - Create
url('^checkout/new$',
permission_required('kfet.is_team')(views.CheckoutCreate.as_view()),
name = 'kfet.checkout.create'),
# Checkout - Read
url('^checkout/(?P<pk>\d+)$',
permission_required('kfet.is_team')(views.CheckoutRead.as_view()),
name = 'kfet.checkout.read'),
# Checkout - Update
url('^checkout/(?P<pk>\d+)/edit$',
permission_required('kfet.is_team')(views.CheckoutUpdate.as_view()),
name = 'kfet.checkout.update'),
] ]

View file

@ -1,11 +1,16 @@
from django.shortcuts import render, get_object_or_404 from django.shortcuts import render, get_object_or_404, redirect
from django.core.exceptions import PermissionDenied from django.core.exceptions import PermissionDenied
from django.views.generic import ListView, DetailView
from django.views.generic.edit import CreateView, UpdateView, DeleteView
from django.core.urlresolvers import reverse_lazy
from django.contrib import messages
from django.contrib.messages.views import SuccessMessageMixin
from django.contrib.auth.decorators import login_required, permission_required from django.contrib.auth.decorators import login_required, permission_required
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.http import HttpResponse, Http404 from django.http import HttpResponse, Http404
import json import json
from gestioncof.models import CofProfile, Clipper from gestioncof.models import CofProfile, Clipper
from kfet.models import Account from kfet.models import Account, Checkout
from kfet.forms import * from kfet.forms import *
@login_required @login_required
@ -16,12 +21,29 @@ def put_cleaned_data_in_dict(dict, form):
for field in form.cleaned_data: for field in form.cleaned_data:
dict[field] = form.cleaned_data[field] dict[field] = form.cleaned_data[field]
# -----
# Account views
# -----
# Account - General
@login_required @login_required
@permission_required('account.is_team') @permission_required('account.is_team')
def account(request): def account(request):
accounts = Account.objects.all() accounts = Account.objects.order_by('trigramme')
return render(request, "kfet/account.html", { 'accounts' : accounts }) return render(request, "kfet/account.html", { 'accounts' : accounts })
@login_required
@permission_required('kfet.is_team')
def account_is_validandfree_ajax(request):
if not request.GET.get("trigramme"):
raise Http404
trigramme = request.GET.get("trigramme")
data = Account.is_validandfree(trigramme)
return HttpResponse(json.dumps(data), content_type = 'application/json')
# Account - Create
@login_required @login_required
@permission_required('account.is_team') @permission_required('account.is_team')
def account_create(request): def account_create(request):
@ -29,16 +51,12 @@ def account_create(request):
# A envoyer au template # A envoyer au template
data_template = { data_template = {
'account_trigramme_form': AccountTriForm(), 'account_trigramme_form': AccountTriForm(),
'post' : False, 'errors' : {},
'success' : False,
'trigramme' : '',
'errors' : {},
} }
# Enregistrement # Enregistrement
if request.method == "POST": if request.method == "POST":
# Pour indiquer la tentative d'enregistrement au template # Pour indiquer la tentative d'enregistrement au template
data_template['post'] = True
# Checking permission # Checking permission
if not request.user.has_perm('kfet.add_account'): if not request.user.has_perm('kfet.add_account'):
@ -74,13 +92,10 @@ def account_create(request):
account = trigramme_form.save(data = data) account = trigramme_form.save(data = data)
account_form = AccountNoTriForm(request.POST, instance=account) account_form = AccountNoTriForm(request.POST, instance=account)
account_form.save() account_form.save()
data_template['success'] = True messages.success(request, 'Compte créé : %s' % account.trigramme)
data_template['trigramme'] = account.trigramme
except Account.UserHasAccount as e: except Account.UserHasAccount as e:
data_template['errors']['global'] = \ messages.error(request, \
"Cet utilisateur a déjà un compte K-Fêt : " + e.trigramme "Cet utilisateur a déjà un compte K-Fêt : %s" % e.trigramme)
except PermissionDenied:
print("perm")
return render(request, "kfet/account_create.html", data_template) return render(request, "kfet/account_create.html", data_template)
@ -153,14 +168,7 @@ def account_create_ajax(request, username=None, login_clipper=None):
'user_form' : user_form, 'user_form' : user_form,
}) })
@login_required # Account - Read
@permission_required('kfet.is_team')
def account_is_validandfree_ajax(request):
if not request.GET.get("trigramme"):
raise Http404
trigramme = request.GET.get("trigramme")
data = Account.is_validandfree(trigramme)
return HttpResponse(json.dumps(data), content_type = 'application/json')
@login_required @login_required
def account_read(request, trigramme): def account_read(request, trigramme):
@ -171,11 +179,13 @@ def account_read(request, trigramme):
# Checking permissions # Checking permissions
if not request.user.has_perm('kfet.is_team') \ if not request.user.has_perm('kfet.is_team') \
and request.user != account.cofprofile.user: and request.user != account.user:
raise PermissionDenied raise PermissionDenied
return render(request, "kfet/account_read.html", { 'account' : account }) return render(request, "kfet/account_read.html", { 'account' : account })
# Account - Update
@login_required @login_required
def account_update(request, trigramme): def account_update(request, trigramme):
try: try:
@ -184,24 +194,25 @@ def account_update(request, trigramme):
raise Http404 raise Http404
# Checking permissions # Checking permissions
if not request.user.has_perm('kfet.change_account') \ if not request.user.has_perm('kfet.is_team') \
and request.user != account.cofprofile.user: and request.user != account.user:
raise PermissionDenied raise PermissionDenied
# Pour le template
post = False
success = False
if request.method == "POST": if request.method == "POST":
# Update attempt # Update attempt
post = True
# Checking permissions
if not request.user.has_perm('kfet.change_account') \
and request.user != account.user:
raise PermissionDenied
# Peuplement des forms
if request.user.has_perm('kfet.change_account'): if request.user.has_perm('kfet.change_account'):
account_form = AccountForm(request.POST, instance = account) account_form = AccountForm(request.POST, instance = account)
else: else:
account_form = AccountRestrictForm(request.POST, instance = account) account_form = AccountRestrictForm(request.POST, instance = account)
cof_form = CofRestrictForm(request.POST, instance=account.cofprofile) cof_form = CofRestrictForm(request.POST, instance=account.cofprofile)
user_form = UserRestrictForm(request.POST, instance=account.cofprofile.user) user_form = UserRestrictForm(request.POST, instance=account.user)
if all((account_form.is_valid(), cof_form.is_valid(), user_form.is_valid())): if all((account_form.is_valid(), cof_form.is_valid(), user_form.is_valid())):
data = {} data = {}
@ -211,21 +222,79 @@ def account_update(request, trigramme):
# Updating # Updating
account_form.save(data = data) account_form.save(data = data)
success = True if request.user == account.user:
messages.success(request, \
'Vos informations ont été mises à jour')
else:
messages.success(request, \
'Informations du compte %s mises à jour' % account.trigramme)
return redirect('kfet.account.read', account.trigramme)
else:
messages.error(request, \
'Informations non mises à jour. Corrigez les erreurs')
else: else:
# No update attempt # No update attempt
if request.user.has_perm('kfet.change_account'): if request.user.has_perm('kfet.is_team'):
account_form = AccountForm(instance = account) account_form = AccountForm(instance = account)
else: else:
account_form = AccountRestrictForm(instance = account) account_form = AccountRestrictForm(instance = account)
cof_form = CofRestrictForm(instance = account.cofprofile) cof_form = CofRestrictForm(instance = account.cofprofile)
user_form = UserRestrictForm(instance = account.cofprofile.user) user_form = UserRestrictForm(instance = account.user)
return render(request, "kfet/account_update.html", { return render(request, "kfet/account_update.html", {
'account' : account, 'account' : account,
'account_form' : account_form, 'account_form' : account_form,
'cof_form' : cof_form, 'cof_form' : cof_form,
'user_form' : user_form, 'user_form' : user_form,
'post' : post,
'success' : success,
}) })
# -----
# Checkout views
# -----
# Checkout - General
class CheckoutList(ListView):
model = Checkout
template_name = 'kfet/checkout.html'
context_object_name = 'checkouts'
# Checkout - Create
class CheckoutCreate(SuccessMessageMixin, CreateView):
model = Checkout
template_name = 'kfet/checkout_create.html'
form_class = CheckoutForm
success_message = 'Nouvelle caisse : %(name)s'
# Surcharge de la validation
def form_valid(self, form):
# Checking permission
if not self.request.user.has_perm('add_checkout'):
raise PermissionDenied
# Creating
form.instance.created_by = self.request.user.profile.account_kfet
return super(CheckoutCreate, self).form_valid(form)
# Checkout - Read
class CheckoutRead(DetailView):
model = Checkout
template_name = 'kfet/checkout_read.html'
context_object_name = 'checkout'
# Checkout - Update
class CheckoutUpdate(SuccessMessageMixin, UpdateView):
model = Checkout
template_name = 'kfet/checkout_update.html'
form_class = CheckoutRestrictForm
success_message = 'Informations mises à jour pour la caisse : %(name)s'
# Surcharge de la validation
def form_valid(self, form):
# Checking permission
if not self.request.user.has_perm('change_checkout'):
raise PermissionDenied
# Updating
return super(CheckoutUpdate, self).form_valid(form)

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

64
static/moment-fr.js Normal file
View file

@ -0,0 +1,64 @@
//! moment.js locale configuration
//! locale : French [fr]
//! author : John Fischer : https://github.com/jfroffice
;(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined'
&& typeof require === 'function' ? factory(require('../moment')) :
typeof define === 'function' && define.amd ? define(['../moment'], factory) :
factory(global.moment)
}(this, function (moment) { 'use strict';
var fr = moment.defineLocale('fr', {
months : 'Janvier_Février_Mars_Avril_Mai_Juin_Juillet_Août_Septembre_Octobre_Novembre_Décembre'.split('_'),
monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'),
monthsParseExact : true,
weekdays : 'Dimanche_Lundi_Mardi_Mercredi_Jeudi_Vendredi_Samedi'.split('_'),
weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),
weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),
weekdaysParseExact : true,
longDateFormat : {
LT : 'HH:mm',
LTS : 'HH:mm:ss',
L : 'DD/MM/YYYY',
LL : 'D MMMM YYYY',
LLL : 'D MMMM YYYY HH:mm',
LLLL : 'dddd D MMMM YYYY HH:mm'
},
calendar : {
sameDay: '[Aujourd\'hui à] LT',
nextDay: '[Demain à] LT',
nextWeek: 'dddd [à] LT',
lastDay: '[Hier à] LT',
lastWeek: 'dddd [dernier à] LT',
sameElse: 'L'
},
relativeTime : {
future : 'dans %s',
past : 'il y a %s',
s : 'quelques secondes',
m : 'une minute',
mm : '%d minutes',
h : 'une heure',
hh : '%d heures',
d : 'un jour',
dd : '%d jours',
M : 'un mois',
MM : '%d mois',
y : 'un an',
yy : '%d ans'
},
ordinalParse: /\d{1,2}(er|)/,
ordinal : function (number) {
return number + (number === 1 ? 'er' : '');
},
week : {
dow : 1, // Monday is the first day of the week.
doy : 4 // The week that contains Jan 4th is the first week of the year.
}
});
return fr;
}));

4195
static/moment.js Normal file

File diff suppressed because it is too large Load diff