mirror of
https://github.com/ae-utbm/sith.git
synced 2025-07-10 11:59:23 +00:00
Add support for product buying groups + many cosmetics and form pimping
This commit is contained in:
36
counter/migrations/0016_auto_20160820_1923.py
Normal file
36
counter/migrations/0016_auto_20160820_1923.py
Normal file
@ -0,0 +1,36 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('core', '0007_auto_20160813_0522'),
|
||||
('counter', '0015_auto_20160820_0158'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='product',
|
||||
name='buying_group',
|
||||
field=models.ForeignKey(blank=True, on_delete=django.db.models.deletion.SET_NULL, verbose_name='buying group', related_name='products', to='core.Group', null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='product',
|
||||
name='club',
|
||||
field=models.ForeignKey(verbose_name='club', to='club.Club', related_name='products'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='product',
|
||||
name='icon',
|
||||
field=models.ImageField(blank=True, null=True, upload_to='products', verbose_name='icon'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='product',
|
||||
name='product_type',
|
||||
field=models.ForeignKey(blank=True, on_delete=django.db.models.deletion.SET_NULL, verbose_name='parent product', related_name='children_products', to='counter.Product', null=True),
|
||||
),
|
||||
]
|
25
counter/migrations/0017_auto_20160820_2047.py
Normal file
25
counter/migrations/0017_auto_20160820_2047.py
Normal file
@ -0,0 +1,25 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('counter', '0016_auto_20160820_1923'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='product',
|
||||
name='parent_product',
|
||||
field=models.ForeignKey(to='counter.Product', null=True, related_name='children_products', on_delete=django.db.models.deletion.SET_NULL, verbose_name='parent product', blank=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='product',
|
||||
name='product_type',
|
||||
field=models.ForeignKey(to='counter.ProductType', null=True, related_name='products', on_delete=django.db.models.deletion.SET_NULL, verbose_name='product type', blank=True),
|
||||
),
|
||||
]
|
24
counter/migrations/0018_auto_20160820_2051.py
Normal file
24
counter/migrations/0018_auto_20160820_2051.py
Normal file
@ -0,0 +1,24 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('core', '0007_auto_20160813_0522'),
|
||||
('counter', '0017_auto_20160820_2047'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='product',
|
||||
name='buying_group',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='product',
|
||||
name='buying_group',
|
||||
field=models.ManyToManyField(related_name='products', to='core.Group', verbose_name='buying group'),
|
||||
),
|
||||
]
|
19
counter/migrations/0019_auto_20160820_2053.py
Normal file
19
counter/migrations/0019_auto_20160820_2053.py
Normal file
@ -0,0 +1,19 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('counter', '0018_auto_20160820_2051'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RenameField(
|
||||
model_name='product',
|
||||
old_name='buying_group',
|
||||
new_name='buying_groups',
|
||||
),
|
||||
]
|
@ -76,15 +76,19 @@ class Product(models.Model):
|
||||
"""
|
||||
name = models.CharField(_('name'), max_length=64)
|
||||
description = models.TextField(_('description'), blank=True)
|
||||
product_type = models.ForeignKey(ProductType, related_name='products', null=True, blank=True)
|
||||
product_type = models.ForeignKey(ProductType, related_name='products', verbose_name=_("product type"), null=True, blank=True,
|
||||
on_delete=models.SET_NULL)
|
||||
code = models.CharField(_('code'), max_length=16, blank=True)
|
||||
purchase_price = CurrencyField(_('purchase price'))
|
||||
selling_price = CurrencyField(_('selling price'))
|
||||
special_selling_price = CurrencyField(_('special selling price'))
|
||||
icon = models.ImageField(upload_to='products', null=True, blank=True)
|
||||
club = models.ForeignKey(Club, related_name="products")
|
||||
icon = models.ImageField(upload_to='products', null=True, blank=True, verbose_name=_("icon"))
|
||||
club = models.ForeignKey(Club, related_name="products", verbose_name=_("club"))
|
||||
limit_age = models.IntegerField(_('limit age'), default=0)
|
||||
tray = models.BooleanField(_('tray price'), default=False)
|
||||
parent_product = models.ForeignKey('self', related_name='children_products', verbose_name=_("parent product"), null=True,
|
||||
blank=True, on_delete=models.SET_NULL)
|
||||
buying_groups = models.ManyToManyField(Group, related_name='products', verbose_name=_("buying groups"))
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('product')
|
||||
|
@ -46,6 +46,9 @@
|
||||
{% if request.session['too_young'] %}
|
||||
<p><strong>{% trans %}Too young for that product{% endtrans %}</strong></p>
|
||||
{% endif %}
|
||||
{% if request.session['not_allowed'] %}
|
||||
<p><strong>{% trans %}Not allowed for that product{% endtrans %}</strong></p>
|
||||
{% endif %}
|
||||
{% if request.session['not_enough'] %}
|
||||
<p><strong>{% trans %}Not enough money{% endtrans %}</strong></p>
|
||||
{% endif %}
|
||||
@ -79,11 +82,16 @@
|
||||
<input type="hidden" name="action" value="cancel">
|
||||
<input type="submit" value="{% trans %}Cancel{% endtrans %}" />
|
||||
</form>
|
||||
<p><strong>{% trans %}Products: {% endtrans %}</strong>
|
||||
{% for p in counter.products.all() %}
|
||||
{{ add_product(p.id, p.name) }}
|
||||
<div><strong>{% trans %}Products: {% endtrans %}</strong>
|
||||
{% for t in categories %}
|
||||
{% if counter.products.filter(product_type=t).exists() %}
|
||||
<h5>{{ t }}</h5>
|
||||
{% for p in counter.products.filter(product_type=t).all() %}
|
||||
{{ add_product(p.id, p.name) }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
@ -123,6 +123,7 @@ class CounterClick(DetailView):
|
||||
request.session['basket_total'] = 0
|
||||
request.session['not_enough'] = False
|
||||
request.session['too_young'] = False
|
||||
request.session['not_allowed'] = False
|
||||
self.refill_form = None
|
||||
ret = super(CounterClick, self).get(request, *args, **kwargs)
|
||||
if ((self.object.type != "BAR" and not request.user.is_authenticated()) or
|
||||
@ -145,6 +146,7 @@ class CounterClick(DetailView):
|
||||
request.session['basket_total'] = 0
|
||||
request.session['not_enough'] = False
|
||||
request.session['too_young'] = False
|
||||
request.session['not_allowed'] = False
|
||||
if self.object.type != "BAR":
|
||||
self.operator = request.user
|
||||
elif self.is_barman_price():
|
||||
@ -208,6 +210,13 @@ class CounterClick(DetailView):
|
||||
price = self.get_price(pid)
|
||||
total = self.sum_basket(request)
|
||||
product = self.get_product(pid)
|
||||
can_buy = False
|
||||
for g in product.buying_groups.all():
|
||||
if request.user.is_in_group(g.name):
|
||||
can_buy = True
|
||||
if not can_buy:
|
||||
request.session['not_allowed'] = True
|
||||
return False
|
||||
bq = 0 # Bonus quantity, for trays
|
||||
if product.tray: # Handle the tray to adjust the quantity q to add and the bonus quantity bq
|
||||
total_qty_mod_6 = self.get_total_quantity_for_pid(request, pid) % 6
|
||||
@ -224,8 +233,6 @@ class CounterClick(DetailView):
|
||||
request.session['basket'][pid]['bonus_qty'] += bq
|
||||
else: # or create if not
|
||||
request.session['basket'][pid] = {'qty': q, 'price': int(price*100), 'bonus_qty': bq}
|
||||
request.session['not_enough'] = False # Reset not_enough to save the session
|
||||
request.session['too_young'] = False
|
||||
request.session.modified = True
|
||||
return True
|
||||
|
||||
@ -321,6 +328,7 @@ class CounterClick(DetailView):
|
||||
kwargs['customer'] = self.customer
|
||||
kwargs['basket_total'] = self.sum_basket(self.request)
|
||||
kwargs['refill_form'] = self.refill_form or RefillForm()
|
||||
kwargs['categories'] = ProductType.objects.all()
|
||||
return kwargs
|
||||
|
||||
class CounterLogin(RedirectView):
|
||||
@ -451,23 +459,42 @@ class ProductListView(CanEditPropMixin, ListView):
|
||||
model = Product
|
||||
template_name = 'counter/product_list.jinja'
|
||||
|
||||
class ProductEditForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Product
|
||||
fields = ['name', 'description', 'product_type', 'code', 'parent_product', 'buying_groups', 'purchase_price',
|
||||
'selling_price', 'special_selling_price', 'icon', 'club', 'limit_age', 'tray']
|
||||
parent_product = AutoCompleteSelectField('products', show_help_text=False, label=_("Parent product"), required=False)
|
||||
buying_groups = AutoCompleteSelectMultipleField('groups', show_help_text=False, help_text="", label=_("Buying groups"))
|
||||
club = AutoCompleteSelectField('clubs', show_help_text=False)
|
||||
counters = AutoCompleteSelectMultipleField('counters', show_help_text=False, help_text="", label=_("Counters"), required=False)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(ProductEditForm, self).__init__(*args, **kwargs)
|
||||
if self.instance.id:
|
||||
self.fields['counters'].initial = [str(c.id) for c in self.instance.counters.all()]
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
ret = super(ProductEditForm, self).save(*args, **kwargs)
|
||||
if self.fields['counters'].initial:
|
||||
for cid in self.fields['counters'].initial:
|
||||
c = Counter.objects.filter(id=int(cid)).first()
|
||||
c.products.remove(self.instance)
|
||||
c.save()
|
||||
for cid in self.cleaned_data['counters']:
|
||||
c = Counter.objects.filter(id=int(cid)).first()
|
||||
c.products.add(self.instance)
|
||||
c.save()
|
||||
return ret
|
||||
|
||||
class ProductCreateView(CanCreateMixin, CreateView):
|
||||
"""
|
||||
A create view for the admins
|
||||
"""
|
||||
model = Product
|
||||
fields = ['name', 'description', 'product_type', 'code', 'purchase_price',
|
||||
'selling_price', 'special_selling_price', 'icon', 'club']
|
||||
form_class = ProductEditForm
|
||||
template_name = 'core/create.jinja'
|
||||
|
||||
class ProductEditForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Product
|
||||
fields = ['name', 'description', 'product_type', 'code', 'purchase_price',
|
||||
'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",
|
||||
required=False) # TODO FIXME
|
||||
|
||||
class ProductEditView(CanEditPropMixin, UpdateView):
|
||||
"""
|
||||
An edit view for the admins
|
||||
@ -476,8 +503,6 @@ class ProductEditView(CanEditPropMixin, UpdateView):
|
||||
form_class = ProductEditForm
|
||||
pk_url_kwarg = "product_id"
|
||||
template_name = 'core/edit.jinja'
|
||||
# TODO: add management of the 'counters' ForeignKey
|
||||
|
||||
|
||||
class RefillingDeleteView(CanEditPropMixin, DeleteView):
|
||||
"""
|
||||
|
Reference in New Issue
Block a user