Skip to content
This repository has been archived by the owner on Jun 24, 2024. It is now read-only.

Commit

Permalink
Merge branch 'release/3.0.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexandreJunod committed Jun 28, 2023
2 parents 6a0322d + f21d422 commit 3002850
Show file tree
Hide file tree
Showing 34 changed files with 981 additions and 199 deletions.
160 changes: 97 additions & 63 deletions geocity/apps/api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

from geocity import geometry, settings
from geocity.apps.accounts.models import AdministrativeEntity, UserProfile
from geocity.apps.api.services import convert_string_to_api_key
from geocity.apps.submissions import search
from geocity.apps.submissions.models import (
FieldValue,
Expand All @@ -22,10 +23,10 @@
from geocity.apps.submissions.payments.postfinance.models import PostFinanceTransaction


def get_field_value_based_on_field(prop):
def get_field_value_based_on_field(field):
property_object = FieldValue.objects.get(
field_id=prop["field_values__field_id"],
selected_form_id=prop["id"],
field_id=field["field_values__field_id"],
selected_form_id=field["id"],
)

return property_object.get_value()
Expand All @@ -42,150 +43,181 @@ def get_form_fields(
`value` is a query set of SelectedForm objects.
"""
obj = value.all()
wot_props = obj.values(
form_fields = obj.values(
"field_values__field__name",
"field_values__field__api_name",
"field_values__field_id",
"field_values__field__input_type",
"field_values__value__val",
"form_id",
"id",
"form__name",
"form__api_name",
"form__category__name",
"field_values__field__is_public_when_permitrequest_is_public",
"submission__administrative_entity",
"submission__author",
)

wot_properties = dict()
fields_dict = dict()
property = list()
last_wot = ""
last_field = ""

if wot_props:
# Flat view is used in the api for geocalendar, the WOT shows only the works_object__name and not the type
if form_fields:
# Flat view is used in the api for geocalendar, the form shows only the works_object__name and not the type
if value_with_type:
wot_properties = list()
fields_dict = list()
key_for_form = _("Formulaire")
for prop in wot_props:
wot = prop["form__name"] + (
f' ({prop["form__category__name"]})'
if prop["form__category__name"]
for field in form_fields:
form = field["form__name"] + (
f' ({field["form__category__name"]})'
if field["form__category__name"]
else ""
)

# List of a list, to split wot in objects. Check if last wot changed or never assigned. Means it's first iteration
if property and wot != last_wot:
# Don't add values if there's only the "WOT" without any field
# List of a list, to split form in objects. Check if last form changed or never assigned. Means it's first iteration
if property and form != last_field:
# Don't add values if there's only the "form" without any field
if len(property) > 1:
wot_properties.append(property)
fields_dict.append(property)

property = []
# WOT
# form
property.append(
{
"key": key_for_form,
"value": wot,
"value": form,
"type": "text",
}
)

if not last_wot:
if not last_field:
property.append(
{
"key": key_for_form,
"value": wot,
"value": form,
"type": "text",
}
)

last_wot = wot
last_field = form

# Show fields_values only when the current submission__administrative_entity
# is one of the administrative_entities associated to the user
# or user is the submission__author
# or show field_values that are designed as public in a public permit_request
if prop["field_values__field__input_type"] == "file" and (
if field["field_values__field__input_type"] == "file" and (
(
administrative_entities_associated_to_user_list
and prop["submission__administrative_entity"]
and field["submission__administrative_entity"]
in administrative_entities_associated_to_user_list
)
or (current_user and prop["submission__author"] == current_user.id)
or prop[
or (current_user and field["submission__author"] == current_user.id)
or field[
"field_values__field__is_public_when_permitrequest_is_public"
]
):
# get_property_value return None if file does not exist
file = get_field_value_based_on_field(prop)
file = get_field_value_based_on_field(field)
# Check if file exist
if file:
# Properties of WOT
# Properties of form
property.append(
{
"key": prop["field_values__field__name"],
"key": field["field_values__field__name"],
"value": file.url,
"type": prop["field_values__field__input_type"],
"type": field["field_values__field__input_type"],
}
)
elif prop["field_values__value__val"] and (
elif field["field_values__value__val"] and (
(
administrative_entities_associated_to_user_list
and prop["submission__administrative_entity"]
and field["submission__administrative_entity"]
in administrative_entities_associated_to_user_list
)
or (current_user and prop["submission__author"] == current_user.id)
or prop[
or (current_user and field["submission__author"] == current_user.id)
or field[
"field_values__field__is_public_when_permitrequest_is_public"
]
):
# Properties of WOT
# Properties of form
property.append(
{
"key": prop["field_values__field__name"],
"value": prop["field_values__value__val"],
"type": prop["field_values__field__input_type"],
"key": field["field_values__field__name"],
"value": field["field_values__value__val"],
"type": field["field_values__field__input_type"],
}
)
# Add last wot_properties, or show something when there's only one
# Don't add values if there's only the "WOT" without any field
# Add last fields_dict, or show something when there's only one
# Don't add values if there's only the "form" without any field
if len(property) > 1:
wot_properties.append(property)
fields_dict.append(property)
else:
for prop in wot_props:
wot = f'{prop["form__name"]} ({prop["form__category__name"]})'
wot_properties[wot] = {
prop_i["field_values__field__name"]: get_field_value_based_on_field(
prop_i
).url
# Check this is a file and the file exist
if prop_i["field_values__field__input_type"] == "file"
and get_field_value_based_on_field(prop_i)
else prop_i["field_values__value__val"]
for prop_i in wot_props
if prop_i["form_id"] == prop["form_id"]
and prop_i["field_values__field__name"]
for field in form_fields:
form_category = (
f'{field["form__name"]} ({field["form__category__name"]})'
)

fields_dict[field["form__api_name"]] = {
# Put the title
"title": {
"form": field["form__name"],
"category": field["form__category__name"],
"form_category": form_category,
},
"fields": {
field["field_values__field__api_name"]: {
"name": field["field_values__field__name"],
"value": get_field_value_based_on_field(field).url,
}
# Check this is a file and the file exist
if field["field_values__field__input_type"] == "file"
and get_field_value_based_on_field(field)
else {
"name": field["field_values__field__name"],
"value": field["field_values__value__val"],
}
for field in form_fields
if field["form_id"] == field["form_id"]
and field["field_values__field__name"]
},
}
return wot_properties
return fields_dict


def get_amend_properties(value):
# `value` here is QuerySet[SelectedForm]
obj = value.all()
amend_fields = obj.values(
"amend_fields__field__name",
"amend_fields__field__api_name",
"amend_fields__value",
"form_id",
"form__name",
"form__api_name",
"form__category__name",
)
amend_properties = {}

for field in amend_fields:
amends = f'{field["form__name"]} ({field["form__category__name"]})'
amend_properties[amends] = {
prop_i["amend_fields__field__name"]: prop_i["amend_fields__value"]
for prop_i in amend_fields
if prop_i["form_id"] == field["form_id"]
and prop_i["amend_fields__field__name"]
amend_field = f'{field["form__name"]} ({field["form__category__name"]})'

amend_properties[field["form__api_name"]] = {
# Put the title
"title": {
"form": field["form__name"],
"category": field["form__category__name"],
"form_category": amend_field,
},
"fields": {
field["amend_fields__field__api_name"]: {
"name": field["amend_fields__field__name"],
"value": field["amend_fields__value"],
}
for field in amend_fields
if field["form_id"] == field["form_id"]
and field["amend_fields__field__name"]
},
}

return amend_properties
Expand Down Expand Up @@ -366,7 +398,9 @@ def to_representation(self, value):
contact_object[field.name] = getattr(
submission_contact.contact, field.name
)
rep[submission_contact.get_contact_type_display()] = contact_object
rep[
convert_string_to_api_key(submission_contact.get_contact_type_display())
] = contact_object

return rep

Expand Down Expand Up @@ -649,7 +683,7 @@ def many_init(cls, *args, **kwargs):
def to_representation(self, value):
rep = super().to_representation(value)

# If the WOT has no geometry, we add the centroid of the administrative entity as a square (polygon)
# If the form has no geometry, we add the centroid of the administrative entity as a square (polygon)
if rep["properties"]["geo_envelop"]["geometry"]["coordinates"] == []:
administrative_entity_id = rep["properties"]["submission"][
"administrative_entity"
Expand Down
12 changes: 12 additions & 0 deletions geocity/apps/api/services.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import re

from unidecode import unidecode


def convert_string_to_api_key(string):
# Convert to lower and remove accents
string = unidecode(string.lower())
# Delete special characters and spaces
string = re.sub("[^a-z0-9_ ]", "", string)
string = string.replace(" ", "_")
return string
2 changes: 2 additions & 0 deletions geocity/apps/forms/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ class FormAdmin(SortableAdminMixin, IntegratorFilterMixin, admin.ModelAdmin):
{
"fields": (
"name",
"api_name",
"category",
"administrative_entities",
"can_always_update",
Expand Down Expand Up @@ -399,6 +400,7 @@ class Meta:
model = models.Field
fields = [
"name",
"api_name",
"placeholder",
"help_text",
"input_type",
Expand Down
55 changes: 55 additions & 0 deletions geocity/apps/forms/migrations/0021_field_api_name_form_api_name.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Generated by Django 4.2.1 on 2023-06-14 13:15

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("forms", "0020_map_widget_configuration"),
]

operations = [
migrations.AddField(
model_name="field",
name="api_name",
field=models.CharField(
blank=True,
help_text="Se génère automatiquement lorsque celui-ci est vide.",
max_length=255,
verbose_name="Nom dans l'API",
),
),
migrations.AddField(
model_name="form",
name="api_name",
field=models.CharField(
blank=True,
help_text="Se génère automatiquement lorsque celui-ci est vide.",
max_length=255,
verbose_name="Nom dans l'API",
),
),
migrations.AlterField(
model_name="field",
name="input_type",
field=models.CharField(
choices=[
("address", "Adresse"),
("checkbox", "Case à cocher"),
("list_multiple", "Choix multiple"),
("list_single", "Choix simple"),
("date", "Date"),
("file", "Fichier"),
("file_download", "Fichier (à télécharger)"),
("number", "Nombre"),
("text", "Texte"),
("regex", "Texte (regex)"),
("text_output", "Texte à afficher"),
("title_output", "Titre à afficher"),
],
max_length=30,
verbose_name="type de caractéristique",
),
),
]
Loading

0 comments on commit 3002850

Please sign in to comment.