diff --git a/lingo/pricing/forms.py b/lingo/pricing/forms.py
index 1583cdb..a712026 100644
--- a/lingo/pricing/forms.py
+++ b/lingo/pricing/forms.py
@@ -119,10 +119,10 @@ class PricingCriteriaCategoryEditForm(forms.Form):
self.initial['criterias'] = self.pricing.criterias.filter(category=self.category)
-class AgendaPricingForm(forms.ModelForm):
+class NewAgendaPricingForm(forms.ModelForm):
class Meta:
model = AgendaPricing
- fields = ['pricing', 'date_start', 'date_end']
+ fields = ['label', 'pricing', 'date_start', 'date_end']
widgets = {
'date_start': forms.DateInput(attrs={'type': 'date'}, format='%Y-%m-%d'),
'date_end': forms.DateInput(attrs={'type': 'date'}, format='%Y-%m-%d'),
@@ -146,6 +146,24 @@ class AgendaPricingForm(forms.ModelForm):
return cleaned_data
+class AgendaPricingForm(NewAgendaPricingForm):
+ class Meta:
+ model = AgendaPricing
+ fields = ['label', 'slug', 'pricing', 'date_start', 'date_end']
+ widgets = {
+ 'date_start': forms.DateInput(attrs={'type': 'date'}, format='%Y-%m-%d'),
+ 'date_end': forms.DateInput(attrs={'type': 'date'}, format='%Y-%m-%d'),
+ }
+
+ def clean_slug(self):
+ slug = self.cleaned_data['slug']
+
+ if AgendaPricing.objects.filter(slug=slug).exclude(pk=self.instance.pk).exists():
+ raise ValidationError(_('Another pricing exists with the same identifier.'))
+
+ return slug
+
+
class PricingMatrixForm(forms.Form):
def __init__(self, *args, **kwargs):
matrix = kwargs.pop('matrix')
diff --git a/lingo/pricing/migrations/0007_agenda_pricing_slug_and_label.py b/lingo/pricing/migrations/0007_agenda_pricing_slug_and_label.py
new file mode 100644
index 0000000..5466d2a
--- /dev/null
+++ b/lingo/pricing/migrations/0007_agenda_pricing_slug_and_label.py
@@ -0,0 +1,21 @@
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('pricing', '0006_agenda_pricing_m2m'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='agendapricing',
+ name='label',
+ field=models.CharField(max_length=150, null=True, verbose_name='Label'),
+ ),
+ migrations.AddField(
+ model_name='agendapricing',
+ name='slug',
+ field=models.SlugField(max_length=160, null=True, verbose_name='Identifier'),
+ ),
+ ]
diff --git a/lingo/pricing/migrations/0008_agenda_pricing_slug_and_label.py b/lingo/pricing/migrations/0008_agenda_pricing_slug_and_label.py
new file mode 100644
index 0000000..bf4f3bd
--- /dev/null
+++ b/lingo/pricing/migrations/0008_agenda_pricing_slug_and_label.py
@@ -0,0 +1,24 @@
+from django.db import migrations
+from django.utils.text import slugify
+
+from lingo.utils.misc import generate_slug
+
+
+def forwards(apps, schema_editor):
+ AgendaPricing = apps.get_model('pricing', 'AgendaPricing')
+ for agenda_pricing in AgendaPricing.objects.all():
+ agenda_pricing.label = agenda_pricing.pricing.label
+ agenda_pricing.base_slug = slugify(agenda_pricing.label)
+ agenda_pricing.slug = generate_slug(agenda_pricing)
+ agenda_pricing.save()
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('pricing', '0007_agenda_pricing_slug_and_label'),
+ ]
+
+ operations = [
+ migrations.RunPython(forwards, reverse_code=migrations.RunPython.noop),
+ ]
diff --git a/lingo/pricing/models.py b/lingo/pricing/models.py
index c8cc693..95dd5aa 100644
--- a/lingo/pricing/models.py
+++ b/lingo/pricing/models.py
@@ -336,6 +336,8 @@ class PricingMatrix:
class AgendaPricing(models.Model):
+ label = models.CharField(_('Label'), max_length=150, null=True)
+ slug = models.SlugField(_('Identifier'), max_length=160, null=True)
agenda = models.ForeignKey(Agenda, on_delete=models.CASCADE, null=True, related_name='old_agendapricings')
agendas = models.ManyToManyField(Agenda, related_name='agendapricings')
pricing = models.ForeignKey(Pricing, on_delete=models.CASCADE)
@@ -343,8 +345,22 @@ class AgendaPricing(models.Model):
date_end = models.DateField()
pricing_data = JSONField(null=True)
+ def __str__(self):
+ return self.label or self.pricing.label
+
+ def save(self, *args, **kwargs):
+ if not self.slug:
+ self.slug = generate_slug(self)
+ super().save(*args, **kwargs)
+
+ @property
+ def base_slug(self):
+ return slugify(self.label or self.pricing.label)
+
def export_json(self):
return {
+ 'label': self.label,
+ 'slug': self.slug,
'pricing': self.pricing.slug,
'date_start': self.date_start.strftime('%Y-%m-%d'),
'date_end': self.date_end.strftime('%Y-%m-%d'),
@@ -368,12 +384,7 @@ class AgendaPricing(models.Model):
except Pricing.DoesNotExist:
raise AgendaImportError(_('Missing "%s" pricing model') % data['pricing'])
- agenda_pricing, created = cls.objects.update_or_create(
- pricing=data['pricing'],
- date_start=data['date_start'],
- date_end=data['date_end'],
- defaults=data,
- )
+ agenda_pricing, created = cls.objects.update_or_create(slug=data['slug'], defaults=data)
if overwrite and not created:
agenda_pricing.agendas.clear()
agenda_pricing.agendas.add(*agendas)
diff --git a/lingo/pricing/templates/lingo/pricing/manager_agenda_pricing_detail.html b/lingo/pricing/templates/lingo/pricing/manager_agenda_pricing_detail.html
index bcc24c2..908d499 100644
--- a/lingo/pricing/templates/lingo/pricing/manager_agenda_pricing_detail.html
+++ b/lingo/pricing/templates/lingo/pricing/manager_agenda_pricing_detail.html
@@ -3,12 +3,13 @@
{% block breadcrumb %}
{{ block.super }}
-{{ object.pricing }}
+{{ object }}
{% endblock %}
{% block appbar %}
- {{ object.pricing }} ({{ object.date_start|date:'d/m/Y' }} - {{ object.date_end|date:'d/m/Y' }})
+ {{ object }}
+ [{% trans "identifier:" %} {{ object.slug }}]
@@ -20,6 +21,16 @@
{% endblock %}
{% block content %}
+
+
{% trans "Options" %}
+
+
+ - {% trans "Pricing model:" %} {{ object.pricing }}
+ - {% blocktrans with start=object.date_start|date:'d/m/Y' end=object.date_end|date:'d/m/Y' %}From {{ start }} to {{ end }}{% endblocktrans %}
+
+
+
+
{% trans "Test tool" %}
diff --git a/lingo/pricing/templates/lingo/pricing/manager_agenda_pricing_list.html b/lingo/pricing/templates/lingo/pricing/manager_agenda_pricing_list.html
index 3261f82..6ec6937 100644
--- a/lingo/pricing/templates/lingo/pricing/manager_agenda_pricing_list.html
+++ b/lingo/pricing/templates/lingo/pricing/manager_agenda_pricing_list.html
@@ -22,7 +22,12 @@
{% for object in object_list %}
-
- {{ object.pricing }} ({{ object.date_start|date:'d/m/Y' }} - {{ object.date_end|date:'d/m/Y' }})
+
+ {{ object }}
+ ({{ object.pricing }}
+ - {% blocktrans with start=object.date_start|date:'d/m/Y' end=object.date_end|date:'d/m/Y' %}From {{ start }} to {{ end }}{% endblocktrans %})
+
+
{% trans "see" %}
{% endfor %}
diff --git a/lingo/pricing/templates/lingo/pricing/manager_pricing_list.html b/lingo/pricing/templates/lingo/pricing/manager_pricing_list.html
index 4986939..5aa78f8 100644
--- a/lingo/pricing/templates/lingo/pricing/manager_pricing_list.html
+++ b/lingo/pricing/templates/lingo/pricing/manager_pricing_list.html
@@ -22,7 +22,10 @@
diff --git a/lingo/pricing/views.py b/lingo/pricing/views.py
index d3c78fe..e120dd9 100644
--- a/lingo/pricing/views.py
+++ b/lingo/pricing/views.py
@@ -49,6 +49,7 @@ from lingo.pricing.forms import (
CriteriaForm,
ExportForm,
ImportForm,
+ NewAgendaPricingForm,
NewCheckTypeForm,
NewCriteriaForm,
PricingCriteriaCategoryAddForm,
@@ -733,7 +734,7 @@ agenda_pricing_list = AgendaPricingListView.as_view()
class AgendaPricingAddView(CreateView):
template_name = 'lingo/pricing/manager_agenda_pricing_form.html'
model = AgendaPricing
- form_class = AgendaPricingForm
+ form_class = NewAgendaPricingForm
def get_success_url(self):
return reverse('lingo-manager-agenda-pricing-detail', args=[self.object.pk])
diff --git a/tests/pricing/manager/test_agenda_pricing.py b/tests/pricing/manager/test_agenda_pricing.py
index fe4b2a6..15855ac 100644
--- a/tests/pricing/manager/test_agenda_pricing.py
+++ b/tests/pricing/manager/test_agenda_pricing.py
@@ -22,6 +22,7 @@ def test_add_agenda_pricing(app, admin_user):
resp = resp.click('New pricing')
# first pricing, starts on today
assert resp.form['date_start'].value == now().strftime('%Y-%m-%d')
+ resp.form['label'] = 'Pricing for lunch'
resp.form['pricing'] = pricing.pk
resp.form['date_start'] = '2021-09-01'
resp.form['date_end'] = '2021-09-01'
@@ -31,6 +32,8 @@ def test_add_agenda_pricing(app, admin_user):
resp = resp.form.submit()
agenda_pricing = AgendaPricing.objects.latest('pk')
assert resp.location.endswith('/manage/pricing/agenda-pricing/%s/' % agenda_pricing.pk)
+ assert agenda_pricing.label == 'Pricing for lunch'
+ assert agenda_pricing.slug == 'pricing-for-lunch'
assert agenda_pricing.pricing == pricing
assert list(agenda_pricing.agendas.all()) == []
assert agenda_pricing.date_start == datetime.date(2021, 9, 1)
@@ -45,6 +48,13 @@ def test_edit_agenda_pricing(app, admin_user):
pricing = Pricing.objects.create(label='Model')
pricing2 = Pricing.objects.create(label='Model 2')
agenda_pricing = AgendaPricing.objects.create(
+ label='Foo Bar',
+ pricing=pricing,
+ date_start=datetime.date(year=2021, month=9, day=1),
+ date_end=datetime.date(year=2022, month=9, day=1),
+ )
+ agenda_pricing2 = AgendaPricing.objects.create(
+ label='Foo Baz',
pricing=pricing,
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2022, month=9, day=1),
@@ -54,22 +64,25 @@ def test_edit_agenda_pricing(app, admin_user):
resp = app.get('/manage/pricing/agenda-pricing/%s/' % agenda_pricing.pk)
resp = resp.click(href='/manage/pricing/agenda-pricing/%s/edit/' % agenda_pricing.pk)
assert resp.form['date_start'].value == '2021-09-01'
+ resp.form['label'] = 'Foo Baz'
+ resp.form['slug'] = agenda_pricing2.slug
resp.form['pricing'] = pricing2.pk
resp.form['date_start'] = '2021-09-01'
resp.form['date_end'] = '2021-09-01'
resp = resp.form.submit()
+ assert resp.context['form'].errors['slug'] == ['Another pricing exists with the same identifier.']
assert resp.context['form'].errors['date_end'] == ['End date must be greater than start date.']
+ resp.form['slug'] = 'foo-bazz'
resp.form['date_start'] = '2021-08-01'
resp.form['date_end'] = '2022-09-01'
resp = resp.form.submit()
assert resp.location.endswith('/manage/pricing/agenda-pricing/%s/' % agenda_pricing.pk)
agenda_pricing.refresh_from_db()
+ assert agenda_pricing.slug == 'foo-bazz'
assert agenda_pricing.pricing == pricing2
assert agenda_pricing.date_start == datetime.date(2021, 8, 1)
assert agenda_pricing.date_end == datetime.date(2022, 9, 1)
- app.get('/manage/pricing/agenda-pricing/%s/edit/' % 0, status=404)
-
def test_detail_agenda_pricing(app, admin_user):
pricing = Pricing.objects.create(label='Model')
diff --git a/tests/pricing/test_import_export.py b/tests/pricing/test_import_export.py
index 6ccfa3c..70842fc 100644
--- a/tests/pricing/test_import_export.py
+++ b/tests/pricing/test_import_export.py
@@ -96,6 +96,7 @@ def test_import_export_agenda_pricing(app):
pricing = Pricing.objects.create(label='Foo')
agenda = Agenda.objects.create(label='Foo Bar')
agenda_pricing = AgendaPricing.objects.create(
+ label='Bar',
pricing=pricing,
date_start=datetime.date(year=2021, month=9, day=1),
date_end=datetime.date(year=2021, month=10, day=1),
@@ -144,6 +145,8 @@ def test_import_export_agenda_pricing(app):
data['pricings'].append(
{
+ 'slug': 'baz',
+ 'label': 'Baz',
'pricing': 'foo',
'agendas': ['foo-bar', 'baz'],
'date_start': '2022-09-01',
diff --git a/tests/pricing/test_models.py b/tests/pricing/test_models.py
index 5a77b75..90d4a4b 100644
--- a/tests/pricing/test_models.py
+++ b/tests/pricing/test_models.py
@@ -232,6 +232,54 @@ def test_pricing_duplicate():
assert new_pricing.slug == 'bar'
+def test_agenda_pricing_slug():
+ pricing = Pricing.objects.create(label='Foo bar')
+ agenda_pricing = AgendaPricing.objects.create(
+ label='Foo bar',
+ pricing=pricing,
+ date_start=datetime.date(year=2021, month=9, day=1),
+ date_end=datetime.date(year=2021, month=10, day=1),
+ )
+ assert agenda_pricing.slug == 'foo-bar'
+
+
+def test_agenda_pricing_existing_slug():
+ pricing = Pricing.objects.create(label='Foo bar')
+ agenda_pricing = AgendaPricing.objects.create(
+ label='Foo bar',
+ slug='bar',
+ pricing=pricing,
+ date_start=datetime.date(year=2021, month=9, day=1),
+ date_end=datetime.date(year=2021, month=10, day=1),
+ )
+ assert agenda_pricing.slug == 'bar'
+
+
+def test_agenda_pricing_duplicate_slugs():
+ pricing = Pricing.objects.create(label='Foo bar')
+ agenda_pricing = AgendaPricing.objects.create(
+ label='Foo baz',
+ pricing=pricing,
+ date_start=datetime.date(year=2021, month=9, day=1),
+ date_end=datetime.date(year=2021, month=10, day=1),
+ )
+ assert agenda_pricing.slug == 'foo-baz'
+ agenda_pricing = AgendaPricing.objects.create(
+ label='Foo baz',
+ pricing=pricing,
+ date_start=datetime.date(year=2021, month=9, day=1),
+ date_end=datetime.date(year=2021, month=10, day=1),
+ )
+ assert agenda_pricing.slug == 'foo-baz-1'
+ agenda_pricing = AgendaPricing.objects.create(
+ label='Foo baz',
+ pricing=pricing,
+ date_start=datetime.date(year=2021, month=9, day=1),
+ date_end=datetime.date(year=2021, month=10, day=1),
+ )
+ assert agenda_pricing.slug == 'foo-baz-2'
+
+
def test_get_agenda_pricing():
agenda = Agenda.objects.create(label='Foo bar')
pricing = Pricing.objects.create(label='Foo bar')