Skip to content

Commit

Permalink
signage cd30
Browse files Browse the repository at this point in the history
  • Loading branch information
juggler31 committed Nov 10, 2023
1 parent dbec892 commit 0cea4d5
Show file tree
Hide file tree
Showing 22 changed files with 354 additions and 73 deletions.
2 changes: 1 addition & 1 deletion geotrek/api/tests/test_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@
])

SIGNAGE_DETAIL_JSON_STRUCTURE = sorted([
'id', 'attachments', 'blades', 'code', 'condition', 'description', 'eid',
'id', 'attachments', 'blades', 'code', 'conditions', 'description', 'eid',
'geometry', 'implantation_year', 'name', 'printed_elevation', 'sealing',
'provider', 'structure', 'type', 'uuid'
])
Expand Down
2 changes: 1 addition & 1 deletion geotrek/api/v2/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -1414,7 +1414,7 @@ class SignageSerializer(DynamicFieldsMixin, serializers.ModelSerializer):

class Meta:
model = signage_models.Signage
fields = ('id', 'attachments', 'blades', 'code', 'condition', 'description', 'eid',
fields = ('id', 'attachments', 'blades', 'code', 'conditions', 'description', 'eid',
'geometry', 'implantation_year', 'name', 'printed_elevation', 'provider', 'sealing',
'structure', 'type', 'uuid')

Expand Down
6 changes: 3 additions & 3 deletions geotrek/infrastructure/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class BaseInfrastructureForm(TopologyForm):

class Meta(TopologyForm.Meta):
fields = TopologyForm.Meta.fields + \
['structure', 'name', 'description', 'type', 'condition', 'access', 'implantation_year', 'published']
['structure', 'name', 'description', 'type', 'access', 'implantation_year', 'published']
else:
class BaseInfrastructureForm(CommonForm):

Expand All @@ -30,7 +30,7 @@ def __init__(self, *args, **kwargs):

class Meta(CommonForm.Meta):
model = Infrastructure
fields = CommonForm.Meta.fields + ['geom', 'structure', 'name', 'description', 'type', 'condition', 'access',
fields = CommonForm.Meta.fields + ['geom', 'structure', 'name', 'description', 'type', 'access',
'implantation_year', 'published']


Expand All @@ -54,4 +54,4 @@ class InfrastructureForm(BaseInfrastructureForm):

class Meta(BaseInfrastructureForm.Meta):
model = Infrastructure
fields = BaseInfrastructureForm.Meta.fields + ['accessibility', 'maintenance_difficulty', 'usage_difficulty']
fields = BaseInfrastructureForm.Meta.fields + ['accessibility', 'maintenance_difficulty', 'usage_difficulty', 'condition']
7 changes: 3 additions & 4 deletions geotrek/infrastructure/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,6 @@ class BaseInfrastructure(BasePublishableMixin, Topology, StructureRelated):
access = models.ForeignKey(InfrastructureAccessMean,
verbose_name=_("Access mean"), blank=True, null=True,
on_delete=models.PROTECT)
condition = models.ForeignKey(InfrastructureCondition,
verbose_name=_("Condition"), blank=True, null=True,
on_delete=models.PROTECT)
implantation_year = models.PositiveSmallIntegerField(verbose_name=_("Implantation year"), null=True)
eid = models.CharField(verbose_name=_("External id"), max_length=1024, blank=True, null=True)
provider = models.CharField(verbose_name=_("Provider"), db_index=True, max_length=1024, blank=True)
Expand Down Expand Up @@ -176,7 +173,9 @@ class Infrastructure(BaseInfrastructure, GeotrekMapEntityMixin):
on_delete=models.PROTECT,
related_name='infrastructures_set')
accessibility = models.TextField(verbose_name=_("Accessibility"), blank=True)

condition = models.ForeignKey(InfrastructureCondition,
verbose_name=_("Condition"), blank=True, null=True,
on_delete=models.PROTECT)
geometry_types_allowed = ["LINESTRING", "POINT"]

class Meta:
Expand Down
28 changes: 17 additions & 11 deletions geotrek/maintenance/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@
CompetenceEdgeFactory, WorkManagementEdgeFactory,
SignageManagementEdgeFactory)
from geotrek.outdoor.tests.factories import CourseFactory
from geotrek.signage.tests.factories import BladeFactory, SignageFactory
from geotrek.signage.tests.factories import BladeFactory, SignageFactory, SignageConditionFactory, SignageTypeFactory
from geotrek.signage.forms import SignageForm
from geotrek.signage.models import Signage
from geotrek.maintenance.tests.factories import (InterventionFactory, InfrastructureInterventionFactory,
InterventionDisorderFactory, InterventionStatusFactory, ManDayFactory,
Expand Down Expand Up @@ -260,29 +261,34 @@ def test_update_form_on_signage(self):
self.assertEqual(response.status_code, 302)

def test_update_signage(self):
"""Test updating signage also updates intervention"""
target_year = 2017
if settings.TREKKING_TOPOLOGY_ENABLED:
intervention = SignageInterventionFactory.create()
else:
intervention = SignageInterventionFactory.create(geom='SRID=2154;POINT (700000 6600000)')
signa = intervention.target
# Save infrastructure form
response = self.client.get(signa.get_update_url())
form = response.context['form']
data = form.initial
data['name_en'] = 'modified'
data['implantation_year'] = target_year
access_mean = InfrastructureAccessMeanFactory()
data['access'] = access_mean.pk
data = {
'name_en': "modified",
'implantation_year': target_year,
'type': SignageTypeFactory.create(),
"structure": StructureFactory.create(),
'access': access_mean.pk,
'manager': OrganismFactory.create().pk
}
if settings.TREKKING_TOPOLOGY_ENABLED:
data['topology'] = '{"paths": [%s]}' % PathFactory.create().pk
else:
data['geom'] = 'SRID=4326;POINT (2.0 6.6)'
data['manager'] = OrganismFactory.create().pk
response = self.client.post(signa.get_update_url(), data)
self.assertEqual(response.status_code, 302)
self.super_user = SuperUserFactory.create()
form = SignageForm(instance=signa, data=data, user=self.super_user)
self.assertTrue(form.is_valid(), form.errors)
form.save()
intervention.refresh_from_db()

# Check that intervention was not deleted (bug #783)
intervention = Intervention.objects.first()
self.assertFalse(intervention.deleted)
self.assertEqual(str(intervention.target.access), access_mean.label)
self.assertEqual(intervention.target.name, 'modified')
Expand Down
39 changes: 38 additions & 1 deletion geotrek/signage/admin.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from django.contrib import admin
from django.db.models import Q

from geotrek.common.mixins.actions import MergeActionMixin
from geotrek.signage.models import LinePictogram, SignageType, Color, Sealing, Direction, BladeType
from geotrek.signage.models import LinePictogram, SignageType, Color, Sealing, Direction, BladeType, SignageCondition


class ColorBladeAdmin(MergeActionMixin, admin.ModelAdmin):
Expand Down Expand Up @@ -128,9 +129,45 @@ def get_list_filter(self, request):
return ('structure', )


class SignageSimpleFieldAdmin(MergeActionMixin, admin.ModelAdmin):
search_fields = ('label', 'structure__name')
merge_field = "label"

def get_queryset(self, request):
"""
filter objects by structure
"""
qs = super().get_queryset(request)
if not request.user.has_perm('authent.can_bypass_structure'):
qs = qs.filter(Q(structure=request.user.profile.structure) | Q(structure=None))
return qs

def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == 'structure':
if not request.user.has_perm('authent.can_bypass_structure'):
return None
kwargs['initial'] = request.user.profile.structure
return db_field.formfield(**kwargs)

def save_model(self, request, obj, form, change):
if not request.user.has_perm('authent.can_bypass_structure'):
obj.structure = request.user.profile.structure
obj.save()

def get_list_display(self, request):
if not request.user.has_perm('authent.can_bypass_structure'):
return ('label', )
return ('label', 'structure')

def get_list_filter(self, request):
if not request.user.has_perm('authent.can_bypass_structure'):
return ()
return ('structure',)

admin.site.register(SignageType, SignageTypeAdmin)
admin.site.register(Color, ColorBladeAdmin)
admin.site.register(Sealing, SealingAdmin)
admin.site.register(Direction, DirectionBladeAdmin)
admin.site.register(BladeType, BladeTypeAdmin)
admin.site.register(LinePictogram, LinePictogramAdmin)
admin.site.register(SignageCondition, SignageSimpleFieldAdmin)
4 changes: 2 additions & 2 deletions geotrek/signage/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class SignageFilterSet(AltimetryPointFilterSet, ValidTopologyFilterSet, ZoningFi

class Meta(StructureRelatedFilterSet.Meta):
model = Signage
fields = StructureRelatedFilterSet.Meta.fields + ['type', 'condition', 'implantation_year', 'intervention_year',
fields = StructureRelatedFilterSet.Meta.fields + ['type', 'conditions', 'implantation_year', 'intervention_year',
'published', 'code', 'printed_elevation', 'manager',
'sealing', 'access', 'provider']

Expand All @@ -63,4 +63,4 @@ def __init__(self, *args, **kwargs):

class Meta(MapEntityFilterSet.Meta):
model = Blade
fields = MapEntityFilterSet.Meta.fields + ['structure', 'number', 'direction', 'type', 'color', 'condition']
fields = MapEntityFilterSet.Meta.fields + ['structure', 'number', 'direction', 'type', 'color', 'conditions']
10 changes: 5 additions & 5 deletions geotrek/signage/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class BaseBladeForm(CommonForm):
'number',
'direction',
'type',
'condition',
'conditions',
'color',
Fieldset(_('Lines')),
)
Expand All @@ -57,7 +57,7 @@ class BaseBladeForm(CommonForm):
'number',
'direction',
'type',
'condition',
'conditions',
'color',
)
]
Expand Down Expand Up @@ -107,7 +107,7 @@ def _set_number_field_initial_value(self):

class Meta:
model = Blade
fields = ['id', 'number', 'direction', 'type', 'condition', 'color']
fields = ['id', 'number', 'direction', 'type', 'conditions', 'color']


if settings.TREKKING_TOPOLOGY_ENABLED:
Expand Down Expand Up @@ -168,7 +168,7 @@ class SignageForm(BaseSignageForm):
'name',
'description',
'type',
'condition',
'conditions',
'implantation_year',
'published',
'code',
Expand All @@ -181,4 +181,4 @@ class SignageForm(BaseSignageForm):

class Meta(BaseInfrastructureForm.Meta):
model = Signage
fields = BaseInfrastructureForm.Meta.fields + ['code', 'printed_elevation', 'manager', 'sealing', 'access']
fields = BaseInfrastructureForm.Meta.fields + ['code', 'conditions', 'printed_elevation', 'manager', 'sealing', 'access']
15 changes: 10 additions & 5 deletions geotrek/signage/management/commands/loadsignage.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@
from geotrek.authent.models import Structure
from geotrek.common.models import Organism
from geotrek.core.models import Topology
from geotrek.signage.models import Sealing, Signage, SignageType
from geotrek.infrastructure.models import InfrastructureCondition
from geotrek.signage.models import Sealing, Signage, SignageType, SignageCondition
from django.conf import settings


Expand Down Expand Up @@ -109,7 +108,7 @@ def handle(self, *args, **options):
break
if not self.check_fields_available_with_default(available_fields, field_name, default_name, 'name'):
break
if not self.check_fields_available_without_default(available_fields, field_condition_type, 'condition'):
if not self.check_fields_available_without_default(available_fields, field_condition_type, 'conditions'):
break
if not self.check_fields_available_without_default(available_fields, field_manager, 'manager'):
break
Expand Down Expand Up @@ -154,7 +153,7 @@ def handle(self, *args, **options):

condition = feature.get(field_condition_type) if field_condition_type in available_fields else default_condition_type
if condition:
condition_type, created = InfrastructureCondition.objects.get_or_create(label=condition, structure=structure if use_structure else None)
condition_type, created = SignageCondition.objects.get_or_create(label=condition, structure=structure if use_structure else None)
if created and verbosity:
self.stdout.write("- Condition Type '{}' created".format(condition_type))
else:
Expand Down Expand Up @@ -194,7 +193,7 @@ def handle(self, *args, **options):
fields_to_integrate = {
'type': signage_type,
'name': name,
'condition': condition_type,
'conditions': [condition_type] if condition_type else [],
'structure': structure,
'description': description,
'implantation_year': year,
Expand All @@ -217,16 +216,22 @@ def handle(self, *args, **options):
def create_signage(self, geometry, fields_to_integrate, verbosity):

with transaction.atomic():
conditions = fields_to_integrate.pop('conditions')
if fields_to_integrate['eid']:
eid = fields_to_integrate.pop('eid')
infra, created = Signage.objects.update_or_create(
eid=eid,
defaults=fields_to_integrate
)
if conditions:
infra.conditions.add(conditions)
if verbosity > 0 and not created:
self.stdout.write("Update : %s with eid %s" % (fields_to_integrate['name'], eid))
else:
infra = Signage.objects.create(**fields_to_integrate)
if conditions:
for condition in conditions:
infra.conditions.add(condition.pk)
if settings.TREKKING_TOPOLOGY_ENABLED:
try:
geometry = geometry.transform(settings.API_SRID, clone=True)
Expand Down
84 changes: 84 additions & 0 deletions geotrek/signage/migrations/0036_auto_20231013_1326.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# Generated by Django 3.2.21 on 2023-10-13 13:26

from django.db import migrations, models
import django.db.models.deletion


def copy_infrastructure_conditions(apps, schema_editor):

# Get conditions models to use them
InfrastructureCondition = apps.get_model('infrastructure', 'InfrastructureCondition')
SignageCondition = apps.get_model('signage', 'SignageCondition')
BladeCondition = apps.get_model('signage', 'BladeCondition')

Signage = apps.get_model('signage', 'Signage')
Blade = apps.get_model('signage', 'Blade')

# Copy InfrastructureCondition to SignageCondition and BladeCondition
for condition in InfrastructureCondition.objects.all():
SignageCondition.objects.get_or_create(label=condition.label)
BladeCondition.objects.get_or_create(label=condition.label)

# Associate signage condition to signage condition_tmp
for signage in Signage.objects.all():
if (signage.condition is not None):
signage_condition, created = SignageCondition.objects.get_or_create(label=signage.condition.label)
signage.condition_tmp.add(signage_condition)

# Associate blade condition to blade condition_tmp
for blade in Blade.objects.all():
if (blade.condition is not None):
blade_condition, created = BladeCondition.objects.get_or_create(label=blade.condition.label)
blade.condition_tmp.add(blade_condition)


class Migration(migrations.Migration):

dependencies = [
('authent', '0011_alter_userprofile_structure'),
('signage', '0035_delete_pictogramname'),
]

operations = [
migrations.CreateModel(
name='SignageCondition',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('date_insert', models.DateTimeField(auto_now_add=True, verbose_name='Insertion date')),
('date_update', models.DateTimeField(auto_now=True, db_index=True, verbose_name='Update date')),
('label', models.CharField(max_length=250, verbose_name='Name')),
('structure', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='authent.structure', verbose_name='Related structure')),
],
options={
'verbose_name': 'Signage Condition',
'verbose_name_plural': 'Signage Conditions',
'ordering': ('label',),
},
),
migrations.CreateModel(
name='BladeCondition',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('date_insert', models.DateTimeField(auto_now_add=True, verbose_name='Insertion date')),
('date_update', models.DateTimeField(auto_now=True, db_index=True, verbose_name='Update date')),
('label', models.CharField(max_length=250, verbose_name='Name')),
('structure', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='authent.structure', verbose_name='Related structure')),
],
options={
'verbose_name': 'Blade Condition',
'verbose_name_plural': 'Blade Conditions',
'ordering': ('label',),
},
),
migrations.AddField(
model_name='blade',
name='condition_tmp',
field=models.ManyToManyField(blank=True, related_name='blades', to='signage.BladeCondition', verbose_name='Condition'),
),
migrations.AddField(
model_name='signage',
name='condition_tmp',
field=models.ManyToManyField(blank=True, related_name='signages', to='signage.SignageCondition', verbose_name='Condition'),
),
migrations.RunPython(copy_infrastructure_conditions, reverse_code=migrations.RunPython.noop),
]
Loading

0 comments on commit 0cea4d5

Please sign in to comment.