summaryrefslogtreecommitdiff
path: root/ishtar_common
diff options
context:
space:
mode:
authorÉtienne Loks <etienne.loks@iggdrasil.net>2018-04-18 17:52:48 +0200
committerÉtienne Loks <etienne.loks@iggdrasil.net>2018-06-12 08:41:54 +0200
commit48046732fbbd307906c492344c886da5f713f06d (patch)
treedf039068c6530250f1bcb2d147b00feafcd2a285 /ishtar_common
parent4e6b1d4c2e4948d4269ff7c5734b94c15cb60a7e (diff)
downloadIshtar-48046732fbbd307906c492344c886da5f713f06d.tar.bz2
Ishtar-48046732fbbd307906c492344c886da5f713f06d.zip
Manage groupment of towns with areas (refs #4060)
Diffstat (limited to 'ishtar_common')
-rw-r--r--ishtar_common/admin.py14
-rw-r--r--ishtar_common/migrations/0045_auto_20180418_1231.py40
-rw-r--r--ishtar_common/migrations/0046_create_default_areas.py34
-rw-r--r--ishtar_common/models.py13
-rw-r--r--ishtar_common/utils.py63
5 files changed, 164 insertions, 0 deletions
diff --git a/ishtar_common/admin.py b/ishtar_common/admin.py
index 73f985245..726238f5b 100644
--- a/ishtar_common/admin.py
+++ b/ishtar_common/admin.py
@@ -278,6 +278,8 @@ class ChangeListForChangeView(ChangeList):
params = lookup_params.pop('_changelist_filters')
for param in params.split("&"):
key, value = param.split("=")
+ if key == 'all':
+ continue
filtered_params[key] = value
return filtered_params
@@ -455,6 +457,18 @@ for model in general_models:
admin_site.register(model, GeneralTypeAdmin)
+class AreaAdmin(GeneralTypeAdmin):
+ list_display = ('label', 'parent', 'available')
+ list_filter = ('parent',)
+ model = models.Area
+ form = make_ajax_form(
+ model, {'towns': 'town'}
+ )
+
+
+admin_site.register(models.Area, AreaAdmin)
+
+
class ProfileTypeAdmin(GeneralTypeAdmin):
model = models.ProfileType
filter_vertical = ('groups',)
diff --git a/ishtar_common/migrations/0045_auto_20180418_1231.py b/ishtar_common/migrations/0045_auto_20180418_1231.py
new file mode 100644
index 000000000..6b017e194
--- /dev/null
+++ b/ishtar_common/migrations/0045_auto_20180418_1231.py
@@ -0,0 +1,40 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.10 on 2018-04-18 12:31
+from __future__ import unicode_literals
+
+import django.core.validators
+from django.db import migrations, models
+import django.db.models.deletion
+import ishtar_common.models
+import re
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('ishtar_common', '0044_add_import_group'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='Area',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('label', models.TextField(verbose_name='Label')),
+ ('txt_idx', models.TextField(help_text='The slug is the standardized version of the name. It contains only lowercase letters, numbers and hyphens. Each slug must be unique.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z'), "Enter a valid 'slug' consisting of letters, numbers, underscores or hyphens.", 'invalid')], verbose_name='Textual ID')),
+ ('comment', models.TextField(blank=True, null=True, verbose_name='Comment')),
+ ('available', models.BooleanField(default=True, verbose_name='Available')),
+ ('parent', models.ForeignKey(blank=True, help_text='Be careful, only three level of parent are managed.', null=True, on_delete=django.db.models.deletion.CASCADE, to='ishtar_common.Area', verbose_name='Parent')),
+ ('towns', models.ManyToManyField(blank=True, to='ishtar_common.Town', verbose_name='Towns')),
+ ],
+ options={
+ 'verbose_name': 'Area',
+ 'verbose_name_plural': 'Areas',
+ },
+ bases=(ishtar_common.models.Cached, models.Model),
+ ),
+ migrations.AlterModelOptions(
+ name='operationtype',
+ options={'ordering': ['judiciary', '-preventive', 'order', 'label'], 'verbose_name': 'Operation type', 'verbose_name_plural': 'Operation types'},
+ ),
+ ]
diff --git a/ishtar_common/migrations/0046_create_default_areas.py b/ishtar_common/migrations/0046_create_default_areas.py
new file mode 100644
index 000000000..182b381a3
--- /dev/null
+++ b/ishtar_common/migrations/0046_create_default_areas.py
@@ -0,0 +1,34 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.10 on 2018-04-18 16:10
+from __future__ import unicode_literals
+
+from django.db import migrations
+from django.template.defaultfilters import slugify
+from ishtar_common.utils import create_default_areas
+
+
+def create_default_areas_script(apps, schema):
+ Area = apps.get_model('ishtar_common', 'Area')
+ Town = apps.get_model('ishtar_common', 'Town')
+ Department = apps.get_model('ishtar_common', 'Department')
+ State = apps.get_model('ishtar_common', 'State')
+
+ models = {
+ 'area': Area,
+ 'town': Town,
+ 'department': Department,
+ 'state': State
+ }
+
+ create_default_areas(models)
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('ishtar_common', '0045_auto_20180418_1231'),
+ ]
+
+ operations = [
+ migrations.RunPython(create_default_areas_script)
+ ]
diff --git a/ishtar_common/models.py b/ishtar_common/models.py
index 5d48dd813..1825335fd 100644
--- a/ishtar_common/models.py
+++ b/ishtar_common/models.py
@@ -3130,6 +3130,19 @@ def town_child_changed(sender, **kwargs):
m2m_changed.connect(town_child_changed, sender=Town.children.through)
+class Area(HierarchicalType):
+ towns = models.ManyToManyField(Town, verbose_name=_(u"Towns"), blank=True)
+ parent = models.ForeignKey(
+ 'self', blank=True, null=True, verbose_name=_(u"Parent"),
+ help_text=_(u"Only four level of parent are managed.")
+ )
+
+ class Meta:
+ verbose_name = _(u"Area")
+ verbose_name_plural = _(u"Areas")
+ ordering = ('parent__label', 'label')
+
+
class OperationType(GeneralType):
order = models.IntegerField(_(u"Order"), default=1)
preventive = models.BooleanField(_(u"Is preventive"), default=True)
diff --git a/ishtar_common/utils.py b/ishtar_common/utils.py
index 983ec5830..b03e794d0 100644
--- a/ishtar_common/utils.py
+++ b/ishtar_common/utils.py
@@ -417,3 +417,66 @@ def get_field_labels_from_path(model, path):
else:
labels.append(key)
return labels
+
+
+def create_default_areas(models=None):
+ # can be used on migrations if models are provided
+ if not models:
+ from ishtar_common.models import Area, Town, Department, State
+ else:
+ Area = models['area']
+ Town = models['town']
+ Department = models['department']
+ State = models['state']
+
+ areas = {}
+
+ idx = 0
+ for state in State.objects.all():
+ slug = 'state-' + slugify(state.label)
+ area, created = Area.objects.get_or_create(
+ txt_idx=slug, defaults={'label': state.label})
+ areas['state-{}'.format(state.pk)] = area
+ if created:
+ idx += 1
+ print("\n* {} state areas added".format(idx))
+
+ idx, idx2 = 0, 0
+ for dep in Department.objects.all():
+ slug = 'dep-' + slugify(dep.label)
+ area, created = Area.objects.get_or_create(
+ txt_idx=slug, defaults={'label': dep.label})
+ areas['dep-' + dep.number] = area
+ if created:
+ idx += 1
+ if not dep.state_id:
+ continue
+ state_slug = 'state-{}'.format(dep.state_id)
+ if state_slug not in areas:
+ continue
+ if area.parent and area.parent.pk == areas[state_slug].pk:
+ continue
+ idx2 += 1
+ area.parent = areas[state_slug]
+ area.save()
+ print(
+ "* {} department areas added with {} associations to state".format(
+ idx, idx2)
+ )
+
+ idx = 0
+ for town in Town.objects.all():
+ if not town.numero_insee or len(town.numero_insee) != 5:
+ continue
+ code_dep = 'dep-' + town.numero_insee[:2]
+ code_dep_dom = 'dep-' + town.numero_insee[:3]
+ if code_dep in areas:
+ if not areas[code_dep].towns.filter(pk=town.pk).count():
+ areas[code_dep].towns.add(town)
+ idx += 1
+ elif code_dep_dom in areas:
+ if not areas[code_dep_dom].towns.filter(pk=town.pk).count():
+ areas[code_dep_dom].towns.add(town)
+ idx += 1
+
+ print("* {} town associated to department area".format(idx))