Commit 84efcd87 authored by Skia's avatar Skia

Translate datepicker and add age limit to products

parent 7e90e657
...@@ -7,6 +7,8 @@ from django.core.exceptions import ValidationError ...@@ -7,6 +7,8 @@ from django.core.exceptions import ValidationError
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.conf import settings from django.conf import settings
from django.db import transaction from django.db import transaction
from django.contrib.staticfiles.storage import staticfiles_storage
from django.utils.html import escape
from phonenumber_field.modelfields import PhoneNumberField from phonenumber_field.modelfields import PhoneNumberField
from datetime import datetime, timedelta, date from datetime import datetime, timedelta, date
...@@ -281,6 +283,12 @@ class User(AbstractBaseUser): ...@@ -281,6 +283,12 @@ class User(AbstractBaseUser):
return "%s (%s)" % (self.get_full_name(), self.nick_name) return "%s (%s)" % (self.get_full_name(), self.nick_name)
return self.get_full_name() return self.get_full_name()
def get_age(self):
"""
Returns the age
"""
return timezone.now().year - self.date_of_birth.year
def email_user(self, subject, message, from_email=None, **kwargs): def email_user(self, subject, message, from_email=None, **kwargs):
""" """
Sends an email to this User. Sends an email to this User.
...@@ -360,9 +368,9 @@ class User(AbstractBaseUser): ...@@ -360,9 +368,9 @@ class User(AbstractBaseUser):
<em>%s</em> <em>%s</em>
</a> </a>
""" % ( """ % (
self.profile_pict.get_download_url() if self.profile_pict else "/static/core/img/na.gif", self.profile_pict.get_download_url() if self.profile_pict else staticfiles_storage.url("core/img/na.gif"),
_("Profile"), _("Profile"),
self.get_display_name(), escape(self.get_display_name()),
) )
......
...@@ -35,8 +35,4 @@ $( function() { ...@@ -35,8 +35,4 @@ $( function() {
popup.html('<iframe src="/file/popup" width="100%" height="95%"></iframe><div id="file_id" value="null" />'); popup.html('<iframe src="/file/popup" width="100%" height="95%"></iframe><div id="file_id" value="null" />');
popup.dialog({title: $(this).text()}).dialog( "open" ); popup.dialog({title: $(this).text()}).dialog( "open" );
}); });
$('.select_date').datepicker({
changeMonth: true,
changeYear: true
});
} ); } );
/* French initialisation for the jQuery UI date picker plugin. */
/* Written by Keith Wood (kbwood{at}iinet.com.au),
Stéphane Nahmani (sholby@sholby.net),
Stéphane Raimbault <stephane.raimbault@gmail.com> */
( function( factory ) {
if ( typeof define === "function" && define.amd ) {
// AMD. Register as an anonymous module.
define( [ "../widgets/datepicker" ], factory );
} else {
// Browser globals
factory( jQuery.datepicker );
}
}( function( datepicker ) {
datepicker.regional.fr = {
closeText: "Fermer",
prevText: "Précédent",
nextText: "Suivant",
currentText: "Aujourd'hui",
monthNames: [ "janvier", "février", "mars", "avril", "mai", "juin",
"juillet", "août", "septembre", "octobre", "novembre", "décembre" ],
monthNamesShort: [ "janv.", "févr.", "mars", "avr.", "mai", "juin",
"juil.", "août", "sept.", "oct.", "nov.", "déc." ],
dayNames: [ "dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi" ],
dayNamesShort: [ "dim.", "lun.", "mar.", "mer.", "jeu.", "ven.", "sam." ],
dayNamesMin: [ "D","L","M","M","J","V","S" ],
weekHeader: "Sem.",
dateFormat: "dd/mm/yy",
firstDay: 1,
isRTL: false,
showMonthAfterYear: false,
yearSuffix: "" };
datepicker.setDefaults( datepicker.regional.fr );
return datepicker.regional.fr;
} ) );
...@@ -69,6 +69,7 @@ ...@@ -69,6 +69,7 @@
{% block script %} {% block script %}
<script src="{{ static('core/js/jquery-3.1.0.min.js') }}"></script> <script src="{{ static('core/js/jquery-3.1.0.min.js') }}"></script>
<script src="{{ static('core/js/ui/jquery-ui.min.js') }}"></script> <script src="{{ static('core/js/ui/jquery-ui.min.js') }}"></script>
<script src="{{ static('core/js/ui/i18n/datepicker-fr.js') }}"></script>
<script src="{{ static('core/js/multiple-select.js') }}"></script> <script src="{{ static('core/js/multiple-select.js') }}"></script>
<script src="{{ static('ajax_select/js/ajax_select.js') }}"></script> <script src="{{ static('ajax_select/js/ajax_select.js') }}"></script>
<script src="{{ static('core/js/script.js') }}"></script> <script src="{{ static('core/js/script.js') }}"></script>
...@@ -85,6 +86,14 @@ $('.select_multiple').multipleSelect({ ...@@ -85,6 +86,14 @@ $('.select_multiple').multipleSelect({
position: 'top', position: 'top',
{% endif %} {% endif %}
}); });
$('.select_date').datepicker({
changeMonth: true,
changeYear: true,
dayNamesShort: $.datepicker.regional[ "{{ request.LANGUAGE_CODE }}" ].dayNamesShort,
dayNames: $.datepicker.regional[ "{{ request.LANGUAGE_CODE }}" ].dayNames,
monthNamesShort: $.datepicker.regional[ "{{ request.LANGUAGE_CODE }}" ].monthNamesShort,
monthNames: $.datepicker.regional[ "{{ request.LANGUAGE_CODE }}" ].monthNames,
}).datepicker( $.datepicker.regional[ "{{ request.LANGUAGE_CODE }}"] );
</script> </script>
{% endblock %} {% endblock %}
</body> </body>
......
...@@ -4,15 +4,8 @@ ...@@ -4,15 +4,8 @@
{% macro user_link_with_pict(user) -%} {% macro user_link_with_pict(user) -%}
<a href="{{ url("core:user_profile", user_id=user.id) }}" class="mini_profile_link" > <a href="{{ url("core:user_profile", user_id=user.id) }}" class="mini_profile_link" >
<span> {{ user.get_mini_item()|safe }}
{% if user.profile_pict %} </a>
<img src="{{ user.profile_pict.get_download_url() }}" alt="{% trans %}Profile{% endtrans %}" />
{% else %}
<img src="{{ static('core/img/na.gif') }}" alt="{% trans %}Profile{% endtrans %}" />
{% endif %}
</span>
<em>{{ user.get_display_name() }}</em>
</a>
{%- endmacro %} {%- endmacro %}
{% macro user_mini_profile(user) %} {% macro user_mini_profile(user) %}
...@@ -27,7 +20,7 @@ ...@@ -27,7 +20,7 @@
<p id="nickname">&laquo; {{ user.nick_name }} &raquo;</p> <p id="nickname">&laquo; {{ user.nick_name }} &raquo;</p>
{% endif %} {% endif %}
{% if user.date_of_birth %} {% if user.date_of_birth %}
<p>{% trans %}Born: {% endtrans %}{{ user.date_of_birth|date("d/m/Y") }}</p> <p>{% trans %}Born: {% endtrans %}{{ user.date_of_birth|date("d/m/Y") }} ({{ user.get_age() }})</p>
{% endif %} {% endif %}
{% if user.promo %} {% if user.promo %}
<p><img src="{{ static('core/img/promo_%02d.png' % user.promo) }}" alt="Promo {{ user.promo }}" class="promo_pict" /> <p><img src="{{ static('core/img/promo_%02d.png' % user.promo) }}" alt="Promo {{ user.promo }}" class="promo_pict" />
......
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('counter', '0014_auto_20160819_1650'),
]
operations = [
migrations.AddField(
model_name='product',
name='limit_age',
field=models.IntegerField(default=0, verbose_name='limit age'),
),
migrations.AddField(
model_name='product',
name='tray',
field=models.BooleanField(default=False, verbose_name='tray price'),
),
]
...@@ -83,6 +83,8 @@ class Product(models.Model): ...@@ -83,6 +83,8 @@ class Product(models.Model):
special_selling_price = CurrencyField(_('special selling price')) special_selling_price = CurrencyField(_('special selling price'))
icon = models.ImageField(upload_to='products', null=True, blank=True) icon = models.ImageField(upload_to='products', null=True, blank=True)
club = models.ForeignKey(Club, related_name="products") club = models.ForeignKey(Club, related_name="products")
limit_age = models.IntegerField(_('limit age'), default=0)
tray = models.BooleanField(_('tray price'), default=False)
class Meta: class Meta:
verbose_name = _('product') verbose_name = _('product')
......
...@@ -43,6 +43,9 @@ ...@@ -43,6 +43,9 @@
{% endif %} {% endif %}
<div> <div>
<h5>{% trans %}Selling{% endtrans %}</h5> <h5>{% trans %}Selling{% endtrans %}</h5>
{% if request.session['too_young'] %}
<p><strong>{% trans %}Too young for that product{% endtrans %}</strong></p>
{% endif %}
{% if request.session['not_enough'] %} {% if request.session['not_enough'] %}
<p><strong>{% trans %}Not enough money{% endtrans %}</strong></p> <p><strong>{% trans %}Not enough money{% endtrans %}</strong></p>
{% endif %} {% endif %}
......
...@@ -8,6 +8,10 @@ ...@@ -8,6 +8,10 @@
</form> </form>
{% endmacro %} {% endmacro %}
{% block title %}
{% trans counter_name=counter %}{{ counter_name }} counter{% endtrans %}
{% endblock %}
{% block content %} {% block content %}
<h3>{% trans counter_name=counter %}{{ counter_name }} counter{% endtrans %}</h3> <h3>{% trans counter_name=counter %}{{ counter_name }} counter{% endtrans %}</h3>
......
...@@ -117,6 +117,7 @@ class CounterClick(DetailView): ...@@ -117,6 +117,7 @@ class CounterClick(DetailView):
request.session['basket'] = {} request.session['basket'] = {}
request.session['basket_total'] = 0 request.session['basket_total'] = 0
request.session['not_enough'] = False request.session['not_enough'] = False
request.session['too_young'] = False
self.refill_form = None self.refill_form = None
ret = super(CounterClick, self).get(request, *args, **kwargs) ret = super(CounterClick, self).get(request, *args, **kwargs)
if ((self.object.type != "BAR" and not request.user.is_authenticated()) or if ((self.object.type != "BAR" and not request.user.is_authenticated()) or
...@@ -138,6 +139,7 @@ class CounterClick(DetailView): ...@@ -138,6 +139,7 @@ class CounterClick(DetailView):
request.session['basket'] = {} request.session['basket'] = {}
request.session['basket_total'] = 0 request.session['basket_total'] = 0
request.session['not_enough'] = False request.session['not_enough'] = False
request.session['too_young'] = False
if self.object.type != "BAR": if self.object.type != "BAR":
self.operator = request.user self.operator = request.user
elif self.is_barman_price(): elif self.is_barman_price():
...@@ -166,8 +168,11 @@ class CounterClick(DetailView): ...@@ -166,8 +168,11 @@ class CounterClick(DetailView):
else: else:
return False return False
def get_product(self, pid):
return Product.objects.filter(pk=int(pid)).first()
def get_price(self, pid): def get_price(self, pid):
p = Product.objects.filter(pk=pid).first() p = self.get_product(pid)
if self.is_barman_price(): if self.is_barman_price():
price = p.special_selling_price price = p.special_selling_price
else: else:
...@@ -181,7 +186,11 @@ class CounterClick(DetailView): ...@@ -181,7 +186,11 @@ class CounterClick(DetailView):
return total / 100 return total / 100
def add_product(self, request, q = 1, p=None): def add_product(self, request, q = 1, p=None):
""" Add a product to the basket """ """
Add a product to the basket
q is the quantity passed as integer
p is the product id, passed as an integer
"""
pid = p or request.POST['product_id'] pid = p or request.POST['product_id']
pid = str(pid) pid = str(pid)
price = self.get_price(pid) price = self.get_price(pid)
...@@ -189,11 +198,15 @@ class CounterClick(DetailView): ...@@ -189,11 +198,15 @@ class CounterClick(DetailView):
if self.customer.amount < (total + q*float(price)): if self.customer.amount < (total + q*float(price)):
request.session['not_enough'] = True request.session['not_enough'] = True
return False return False
if self.customer.user.get_age() < self.get_product(pid).limit_age:
request.session['too_young'] = True
return False
if pid in request.session['basket']: if pid in request.session['basket']:
request.session['basket'][pid]['qty'] += q request.session['basket'][pid]['qty'] += q
else: else:
request.session['basket'][pid] = {'qty': q, 'price': int(price*100)} request.session['basket'][pid] = {'qty': q, 'price': int(price*100)}
request.session['not_enough'] = False # Reset not_enough to save the session request.session['not_enough'] = False # Reset not_enough to save the session
request.session['too_young'] = False
request.session.modified = True request.session.modified = True
return True return True
...@@ -421,7 +434,7 @@ class ProductEditForm(forms.ModelForm): ...@@ -421,7 +434,7 @@ class ProductEditForm(forms.ModelForm):
class Meta: class Meta:
model = Product model = Product
fields = ['name', 'description', 'product_type', 'code', 'purchase_price', fields = ['name', 'description', 'product_type', 'code', 'purchase_price',
'selling_price', 'special_selling_price', 'icon', 'club'] 'selling_price', 'special_selling_price', 'icon', 'club', 'limit_age', 'tray']
counters = make_ajax_field(Product, 'counters', 'counters', show_help_text=False, label='Counters', help_text="Guy", counters = make_ajax_field(Product, 'counters', 'counters', show_help_text=False, label='Counters', help_text="Guy",
required=False) # TODO FIXME required=False) # TODO FIXME
......
...@@ -452,6 +452,8 @@ def migrate_products(): ...@@ -452,6 +452,8 @@ def migrate_products():
selling_price=r['prix_vente_prod']/100, selling_price=r['prix_vente_prod']/100,
special_selling_price=r['prix_vente_barman_prod']/100, special_selling_price=r['prix_vente_barman_prod']/100,
club=club, club=club,
limit_age=r['mineur'] or 0,
tray=bool(r['plateau']),
) )
new.save() new.save()
except Exception as e: except Exception as e:
...@@ -554,7 +556,9 @@ def migrate_sellings(): ...@@ -554,7 +556,9 @@ def migrate_sellings():
) )
new.save() new.save()
except ValidationError as e: except ValidationError as e:
print(repr(e) + " for %s (%s)" % (customer, customer.user.id)) print(repr(e) + " for %s (%s), assigning to root" % (customer, customer.user.id))
new.customer = root.customer
new.save()
except Exception as e: except Exception as e:
print("FAIL to migrate selling %s: %s" % (r['id_facture'], repr(e))) print("FAIL to migrate selling %s: %s" % (r['id_facture'], repr(e)))
cur.close() cur.close()
...@@ -592,12 +596,12 @@ def main(): ...@@ -592,12 +596,12 @@ def main():
# migrate_counters() # migrate_counters()
# migrate_permanencies() # migrate_permanencies()
# migrate_typeproducts() # migrate_typeproducts()
# migrate_products() migrate_products()
# migrate_products_to_counter() migrate_products_to_counter()
# reset_customer_amount() # reset_customer_amount()
# migrate_invoices() # migrate_invoices()
migrate_refillings() # migrate_refillings()
migrate_sellings() # migrate_sellings()
reset_index('core', 'counter') reset_index('core', 'counter')
if __name__ == "__main__": if __name__ == "__main__":
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment