summaryrefslogtreecommitdiff
path: root/archaeological_files
diff options
context:
space:
mode:
Diffstat (limited to 'archaeological_files')
-rw-r--r--archaeological_files/forms.py415
-rw-r--r--archaeological_files/ishtar_menu.py8
-rw-r--r--archaeological_files/models.py31
-rw-r--r--archaeological_files/templates/ishtar/blocks/JQueryCorporationPerson.js2
-rw-r--r--archaeological_files/templates/ishtar/blocks/JQueryNaturalPerson.js2
-rw-r--r--archaeological_files/templates/ishtar/blocks/JQueryPersonOrga.js66
-rw-r--r--archaeological_files/templates/ishtar/wizard/file_confirm_wizard.html27
-rw-r--r--archaeological_files/templates/ishtar/wizard/wizard_instruction.html83
-rw-r--r--archaeological_files/templates/ishtar/wizard/wizard_person_orga.html76
-rw-r--r--archaeological_files/tests.py386
-rw-r--r--archaeological_files/urls.py18
-rw-r--r--archaeological_files/views.py137
-rw-r--r--archaeological_files/wizards.py122
13 files changed, 1201 insertions, 172 deletions
diff --git a/archaeological_files/forms.py b/archaeological_files/forms.py
index a75e5bf34..9466d7d52 100644
--- a/archaeological_files/forms.py
+++ b/archaeological_files/forms.py
@@ -34,12 +34,19 @@ from ishtar_common.utils import ugettext_lazy as _
from ishtar_common.models import (
Person,
Organization,
+ Town,
valid_id,
valid_ids,
person_type_pks_lazy,
person_type_pk_lazy,
organization_type_pks_lazy,
+ organization_type_pk_lazy,
+ get_sra_agent_label,
get_sra_agent_head_scientist_label,
+ get_orga_general_contractor_label,
+ get_general_contractor_label,
+ get_orga_planning_service_label,
+ get_responsible_planning_service_label,
)
from ishtar_common.models_common import Department
from archaeological_operations.models import ActType, AdministrativeAct, OperationType
@@ -65,8 +72,6 @@ from archaeological_operations.forms import (
AdministrativeActForm,
AdministrativeActOpeFormSelection,
AdministrativeActModifForm,
- ParcelForm,
- ParcelFormSet,
)
from ishtar_common import widgets
from bootstrap_datepicker.widgets import DatePicker
@@ -194,25 +199,12 @@ class FileFormMultiSelection(LockForm, MultiSearchForm):
)
-class FileFormGeneral(ManageOldType):
+class FileFormGeneral(CustomForm, ManageOldType):
form_label = _("General")
- associated_models = {
- "in_charge": Person,
- "related_file": models.File,
- "file_type": models.FileType,
- }
- in_charge = forms.IntegerField(
- label=_("Person in charge"),
- widget=widgets.JQueryAutoComplete(
- reverse_lazy(
- "autocomplete-person", args=[person_type_pks_lazy(["sra_agent"])]
- ),
- limit={"person_types": [person_type_pk_lazy("sra_agent")]},
- associated_model=Person,
- new=True,
- ),
- validators=[valid_id(Person)],
- )
+ form_admin_name = _("Archaeological file - 010 - General")
+ form_slug = "file-010-general"
+ associated_models = {"file_type": models.FileType}
+ file_type = forms.ChoiceField(label=_("File type"), choices=[])
year = forms.IntegerField(
label=_("Year"),
initial=lambda: datetime.datetime.now().year,
@@ -221,56 +213,22 @@ class FileFormGeneral(ManageOldType):
validators.MaxValueValidator(2100),
],
)
- numeric_reference = forms.IntegerField(
- label=_("Numeric reference"), widget=forms.HiddenInput, required=False
- )
- internal_reference = forms.CharField(
- label=_("Other reference"), max_length=60, required=False
- )
- name = forms.CharField(label=_("Name"), required=False, max_length=100)
creation_date = forms.DateField(
label=_("Creation date"), initial=get_now, widget=DatePicker
)
- file_type = forms.ChoiceField(label=_("File type"), choices=[])
- related_file = forms.IntegerField(
- label=_("Related file"),
- required=False,
- widget=widgets.JQueryAutoComplete(
- reverse_lazy("autocomplete-file"), associated_model=models.File
- ),
- validators=[valid_id(models.File)],
- )
- comment = forms.CharField(label=_("Comment"), widget=forms.Textarea, required=False)
- total_surface = forms.FloatField(
- required=False,
- widget=widgets.AreaWidget,
- label=_("Total surface (m2)"),
- validators=[
- validators.MinValueValidator(0),
- validators.MaxValueValidator(999999999),
- ],
- )
- address = forms.CharField(label=_("Main address"), widget=forms.Textarea)
- address_complement = forms.CharField(
- label=_("Main address - complement"), required=False
+ reception_date = forms.DateField(
+ label=_("Reception date"), initial=get_now, widget=DatePicker
)
- def __init__(self, *args, **kwargs):
- super(FileFormGeneral, self).__init__(*args, **kwargs)
- if "file_type" in self.fields:
- self.fields["file_type"].choices = models.FileType.get_types(
- initial=self.init_data.get("file_type")
- )
- self.fields["file_type"].help_text = models.FileType.get_help()
- q = (
- models.File.objects.filter(internal_reference__isnull=False)
- .exclude(internal_reference="")
- .order_by("-pk")
- )
- if q.count() and "internal_reference" in self.fields:
- lbl = self.fields["internal_reference"].label
- lbl += _("<br/>(last recorded: %s)") % (q.all()[0].internal_reference)
- self.fields["internal_reference"].label = mark_safe(lbl)
+ TYPES = [
+ FieldType("file_type", models.FileType),
+ ]
+
+ def clean_reception_date(self):
+ value = self.cleaned_data.get("reception_date", None)
+ if value and value > datetime.date.today():
+ raise forms.ValidationError(_("Reception date cannot be after today."))
+ return value
class FileFormGeneralRO(FileFormGeneral):
@@ -295,10 +253,239 @@ class FileFormGeneralRO(FileFormGeneral):
return cleaned_data
-ParcelFormset = formset_factory(ParcelForm, can_delete=True, formset=ParcelFormSet)
-ParcelFormset.form_label = _("Parcels")
-ParcelFormset.form_admin_name = _("Archaeological file - 020 - Parcel")
-ParcelFormset.form_slug = "file-020-parcels"
+class FileFormPreventiveType(CustomForm, ManageOldType, forms.Form):
+ form_label = "Saisine"
+ form_admin_name = _("Archaeological file - 013 - Preventive - Saisine")
+ form_slug = "file-013-preventivesaisine"
+ associated_models = {
+ "saisine_type": models.SaisineType,
+ "permit_type": models.PermitType,
+ }
+ permit_type = forms.ChoiceField(label=_("Permit type"), required=False, choices=[])
+ saisine_type = forms.ChoiceField(label=_("Saisine type"), choices=[])
+ TYPES = [
+ FieldType("saisine_type", models.SaisineType),
+ ]
+
+ def __init__(self, *args, **kwargs):
+ super(FileFormPreventiveType, self).__init__(*args, **kwargs)
+ self.fields["permit_type"].choices = models.PermitType.get_types(
+ default="NP", initial=self.init_data.get("permit_type")
+ )
+ self.fields["permit_type"].help_text = models.PermitType.get_help()
+
+
+class FileFormPlanning(CustomForm, ManageOldType):
+ form_label = _("Planning")
+ form_admin_name = _("Archaeological file - 017 - Preventive - Planning")
+ form_slug = "file-017-preventiveplanning"
+ base_models = ["town", "department"]
+ associated_models = {"town": Town, "department": Department}
+ HEADERS = {}
+ HEADERS["town"] = FormHeader(_("Localisation"))
+ name = forms.CharField(label=_("Planning name"), required=False, max_length=100)
+ town = widgets.Select2MultipleField(
+ model=Town, label=_("Towns"), required=False, remote=True
+ )
+ department = widgets.Select2MultipleField(
+ model=Department,
+ label=_("Departments"),
+ required=False,
+ help_text=_("Only relevant when no town is provided."),
+ )
+ locality = forms.CharField(label=_("Locality"), max_length=100, required=False)
+ address = forms.CharField(
+ label=_("Address (number/street)"),
+ widget=forms.Textarea(attrs={"placeholder": _("Number/street")}),
+ required=False,
+ )
+ postal_code = forms.CharField(label=_("Postal code"), max_length=10, required=False)
+ HEADERS["total_surface"] = FormHeader(_("Surfaces"))
+ total_surface = forms.FloatField(
+ required=False,
+ widget=widgets.AreaWidget,
+ label=_("Total surface (m2)"),
+ validators=[
+ validators.MinValueValidator(0),
+ validators.MaxValueValidator(999999999),
+ ],
+ )
+ total_developed_surface = forms.FloatField(
+ widget=widgets.AreaWidget,
+ label=_("Total developed surface (m2)"),
+ required=False,
+ validators=[
+ validators.MinValueValidator(0),
+ validators.MaxValueValidator(999999999),
+ ],
+ )
+
+
+class FileFormResearchAddress(CustomForm, forms.Form):
+ form_label = _("Address")
+ form_admin_name = _("Archaeological file - 015 - Research - Address")
+ form_slug = "file-015-researchplanning"
+ base_models = ["town", "department"]
+ associated_models = {"town": Town, "department": Department}
+ name = forms.CharField(label=_("Project name"), required=False, max_length=100)
+ town = widgets.Select2MultipleField(
+ model=Town, label=_("Towns"), required=False, remote=True
+ )
+ department = widgets.Select2MultipleField(
+ model=Department, label=_("Departments"), required=False
+ )
+ locality = forms.CharField(label=_("Locality"), max_length=100, required=False)
+ address = forms.CharField(
+ label=_("Address (number/street)"),
+ widget=forms.Textarea(attrs={"placeholder": _("Number/street")}),
+ required=False,
+ )
+ postal_code = forms.CharField(label=_("Postal code"), max_length=10, required=False)
+
+
+class FileFormGeneralContractor(CustomForm, ManageOldType):
+ form_label = _("General contractor")
+ form_admin_name = _("Archaeological file - 030 - General contractor")
+ form_slug = "file-030-generalcontractor"
+
+ associated_models = {
+ "general_contractor": models.Person,
+ "corporation_general_contractor": models.Organization,
+ }
+
+ corporation_general_contractor = forms.IntegerField(
+ label=_("General contractor"),
+ widget=widgets.JQueryAutoComplete(
+ reverse_lazy(
+ "autocomplete-organization",
+ args=[
+ organization_type_pks_lazy(["general_contractor"]),
+ ],
+ ),
+ limit={
+ "organization_type": [organization_type_pk_lazy("general_contractor")]
+ },
+ tips=lazy(get_orga_general_contractor_label),
+ associated_model=models.Organization,
+ new=True,
+ detail=True,
+ modify=True,
+ ),
+ validators=[valid_id(models.Organization)],
+ )
+ general_contractor = forms.IntegerField(
+ label=_("In charge"),
+ required=False,
+ widget=widgets.JQueryAutoComplete(
+ reverse_lazy(
+ "autocomplete-person",
+ args=[person_type_pks_lazy(["general_contractor"])],
+ ),
+ associated_model=Person,
+ limit={"person_types": [person_type_pk_lazy("general_contractor")]},
+ tips=lazy(get_general_contractor_label),
+ detail=True,
+ modify=True,
+ new=True,
+ ),
+ validators=[valid_id(Person)],
+ )
+
+ def clean(self):
+ general_contractor = self.cleaned_data.get("general_contractor", None)
+ corporation_general_contractor = self.cleaned_data.get(
+ "corporation_general_contractor", None
+ )
+ if general_contractor and corporation_general_contractor:
+ try:
+ person = models.Person.objects.get(pk=general_contractor)
+ except models.Person.DoesNotExist:
+ raise forms.ValidationError(_("Non existing person."))
+ if (
+ not person.attached_to
+ or person.attached_to.pk != corporation_general_contractor
+ ):
+ raise forms.ValidationError(
+ _(
+ "The organization of the person in charge differs from the "
+ "general contractor."
+ )
+ )
+ return self.cleaned_data
+
+
+class FileFormPlanningService(CustomForm, IshtarForm):
+ form_label = _("Planning service")
+ form_admin_name = _("Archaeological file - 040 - Planning service")
+ form_slug = "file-040-planningservice"
+ associated_models = {
+ "responsible_town_planning_service": models.Person,
+ "planning_service": models.Organization,
+ }
+
+ planning_service = forms.IntegerField(
+ label=_("Planning service"),
+ required=False,
+ widget=widgets.JQueryAutoComplete(
+ reverse_lazy(
+ "autocomplete-organization",
+ args=[organization_type_pks_lazy(["planning_service"])],
+ ),
+ associated_model=models.Organization,
+ limit={
+ "organization_type": [organization_type_pk_lazy(["planning_service"])],
+ },
+ tips=lazy(get_orga_planning_service_label),
+ new=True,
+ detail=True,
+ modify=True,
+ ),
+ validators=[valid_id(models.Organization)],
+ )
+ responsible_town_planning_service = forms.IntegerField(
+ label=_("In charge"),
+ required=False,
+ widget=widgets.JQueryAutoComplete(
+ reverse_lazy(
+ "autocomplete-person",
+ args=[person_type_pks_lazy(["responsible_planning_service"])],
+ ),
+ associated_model=Person,
+ limit={
+ "person_types": [person_type_pk_lazy("responsible_planning_service")]
+ },
+ dynamic_limit=["planning_service"],
+ tips=lazy(get_responsible_planning_service_label),
+ detail=True,
+ modify=True,
+ new=True,
+ ),
+ validators=[valid_id(Person)],
+ )
+ permit_reference = forms.CharField(
+ label=_("File reference"), required=False, max_length=200
+ )
+ planning_service_date = forms.DateField(
+ label=_("Date of planning service file"), widget=DatePicker, required=False
+ )
+
+ def clean(self):
+ responsible = self.cleaned_data["responsible_town_planning_service"]
+ orga = self.cleaned_data["planning_service"]
+ if responsible:
+ try:
+ person = models.Person.objects.get(pk=responsible)
+ except models.Person.DoesNotExist:
+ raise forms.ValidationError(_("Non existing person."))
+ if not person.attached_to or person.attached_to.pk != orga:
+ raise forms.ValidationError(
+ _(
+ "The organization of the person in charge differs from the "
+ "planning service."
+ )
+ )
+ return self.cleaned_data
+
class FileFormPreventive(ManageOldType, forms.Form):
@@ -447,6 +634,96 @@ class FileFormResearch(CustomForm, ManageOldType, forms.Form):
self.fields["requested_operation_type"].help_text = OperationType.get_help()
+class FileFormInstruction(CustomForm, IshtarForm):
+ form_label = _("Instruction")
+ form_admin_name = _("Archaeological file - 050 - Instruction")
+ form_slug = "file-050-instruction"
+ associated_models = {"in_charge": models.Person, "related_file": models.File}
+ in_charge = forms.IntegerField(
+ label=_("File managed by"),
+ widget=widgets.JQueryAutoComplete(
+ reverse_lazy(
+ "autocomplete-person", args=[person_type_pks_lazy(["sra_agent"])]
+ ),
+ limit={"person_types": [person_type_pk_lazy("sra_agent")]},
+ tips=lazy(get_sra_agent_label),
+ associated_model=Person,
+ new=True,
+ ),
+ validators=[valid_id(Person)],
+ )
+ related_file = forms.IntegerField(
+ label=_("Related file"),
+ required=False,
+ widget=widgets.JQueryAutoComplete(
+ reverse_lazy("autocomplete-file"), associated_model=models.File
+ ),
+ validators=[valid_id(models.File)],
+ )
+ comment = forms.CharField(label=_("Comment"), widget=forms.Textarea, required=False)
+ instruction_deadline = forms.DateField(widget=DatePicker, required=False)
+ year = forms.IntegerField(
+ label=_("Year"),
+ validators=[
+ validators.MinValueValidator(1000),
+ validators.MaxValueValidator(2100),
+ ],
+ )
+ numeric_reference = forms.IntegerField(label=_("Numeric reference"), required=False)
+ numeric_reference_is_readonly = True
+ end_date = forms.DateField(widget=DatePicker, required=False)
+
+ def __init__(self, *args, **kwargs):
+ c_year = datetime.date.today().year
+ if "year" in kwargs:
+ c_year = kwargs.pop("year")
+ saisine_type = None
+ if "saisine_type" in kwargs:
+ saisine_type = kwargs.pop("saisine_type")
+ reception_date = None
+ if "reception_date" in kwargs:
+ reception_date = kwargs.pop("reception_date")
+ if "data" in kwargs and kwargs["data"]:
+ kwargs["data"][kwargs.get("prefix", "") + "-year"] = c_year
+
+ super(FileFormInstruction, self).__init__(*args, **kwargs)
+ self.fields["year"].initial = c_year
+
+ self.fields["year"].widget.attrs.update({"readonly": "readonly"})
+ c_num = 0
+ q = models.File.objects.filter(
+ numeric_reference__isnull=False, year=c_year
+ ).order_by("-numeric_reference")
+ if q.count():
+ c_num = q.all()[0].numeric_reference
+ lbl = self.fields["numeric_reference"].label
+ self.fields["numeric_reference"].label = mark_safe(lbl)
+ self.fields["numeric_reference"].initial = c_num + 1
+ if self.numeric_reference_is_readonly:
+ self.fields["numeric_reference"].widget.attrs["readonly"] = True
+ if reception_date and saisine_type:
+ if type(reception_date) == str:
+ try:
+ reception_date = datetime.datetime.strptime(
+ reception_date, "%d/%m/%Y"
+ )
+ self.fields["instruction_deadline"].initial = (
+ reception_date
+ + datetime.timedelta(days=saisine_type.delay or 0)
+ ).strftime("%Y-%m-%d")
+ except ValueError:
+ pass
+
+ def clean_numeric_reference(self):
+ if self.numeric_reference_is_readonly:
+ return self.fields["numeric_reference"].initial
+ return self.cleaned_data["numeric_reference"]
+
+
+class FileFormInstructionEdit(FileFormInstruction):
+ numeric_reference_is_readonly = False
+
+
class FinalFileClosingForm(FinalForm):
confirm_msg = " "
confirm_end_msg = _("Would you like to close this archaeological file?")
diff --git a/archaeological_files/ishtar_menu.py b/archaeological_files/ishtar_menu.py
index 517b0276d..bfdd72148 100644
--- a/archaeological_files/ishtar_menu.py
+++ b/archaeological_files/ishtar_menu.py
@@ -71,25 +71,25 @@ MENU_SECTIONS = [
_("Administrative act"),
childs=[
MenuItem(
- "file_administrativeactfil_search",
+ "file_administrativeactfile_search",
_("Search"),
model=AdministrativeAct,
access_controls=["change_administrativeact"],
),
MenuItem(
- "file_administrativeactfil",
+ "file_administrativeactfile",
_("Creation"),
model=AdministrativeAct,
access_controls=["change_administrativeact"],
),
MenuItem(
- "file_administrativeactfil_modification",
+ "file_administrativeactfile_modification",
_("Modification"),
model=AdministrativeAct,
access_controls=["change_administrativeact"],
),
MenuItem(
- "file_administrativeactfil_deletion",
+ "file_administrativeactfile_deletion",
_("Deletion"),
model=AdministrativeAct,
access_controls=["change_administrativeact"],
diff --git a/archaeological_files/models.py b/archaeological_files/models.py
index bcc90ab4f..9b878ab35 100644
--- a/archaeological_files/models.py
+++ b/archaeological_files/models.py
@@ -282,10 +282,10 @@ class FileType(GeneralType):
ordering = ("label",)
@classmethod
- def is_preventive(cls, file_type_id, key=""):
+ def is_preventive(cls, file_type_id, key="", force=False):
key = key or "preventive"
try:
- preventive = FileType.get_cache(key).pk
+ preventive = FileType.get_cache(key, force=force).pk
return file_type_id == preventive
except (FileType.DoesNotExist, AttributeError):
return False
@@ -793,6 +793,11 @@ class File(
if not date:
date = datetime.date(2500, 1, 1)
elif settings.COUNTRY == "fr" and self.saisine_type and self.saisine_type.delay:
+ if isinstance(date, str):
+ try:
+ date = datetime.datetime.strptime(date, "%Y-%m-%d").date()
+ except ValueError:
+ date = datetime.date(2500, 1, 1)
date += datetime.timedelta(days=self.saisine_type.delay)
cache.set(cache_key, date, settings.CACHE_TIMEOUT)
return date
@@ -917,13 +922,21 @@ class File(
if not self.file_type.txt_idx == "preventive":
cls = "blue"
elif not self.has_adminact and self.reception_date:
- delta = datetime.date.today() - self.reception_date
- cls = "red"
- if self.saisine_type and self.saisine_type.delay:
- if delta.days <= (self.saisine_type.delay * 2 / 3):
- cls = "green"
- elif delta.days <= self.saisine_type.delay:
- cls = "orange"
+ reception_date = self.reception_date
+ if isinstance(self.reception_date, str):
+ try:
+ reception_date = datetime.datetime.strptime(self.reception_date,
+ "%Y-%m-%d").date()
+ except ValueError:
+ reception_date = None
+ if reception_date:
+ delta = datetime.date.today() - reception_date
+ cls = "red"
+ if self.saisine_type and self.saisine_type.delay:
+ if delta.days <= (self.saisine_type.delay * 2 / 3):
+ cls = "green"
+ elif delta.days <= self.saisine_type.delay:
+ cls = "orange"
cache.set(cache_key, cls, settings.CACHE_TIMEOUT)
return cls
diff --git a/archaeological_files/templates/ishtar/blocks/JQueryCorporationPerson.js b/archaeological_files/templates/ishtar/blocks/JQueryCorporationPerson.js
new file mode 100644
index 000000000..3eb375167
--- /dev/null
+++ b/archaeological_files/templates/ishtar/blocks/JQueryCorporationPerson.js
@@ -0,0 +1,2 @@
+var current_status = 'corporation';
+{% include "ishtar/blocks/JQueryPersonOrga.js" %}
diff --git a/archaeological_files/templates/ishtar/blocks/JQueryNaturalPerson.js b/archaeological_files/templates/ishtar/blocks/JQueryNaturalPerson.js
new file mode 100644
index 000000000..fc4b9a90c
--- /dev/null
+++ b/archaeological_files/templates/ishtar/blocks/JQueryNaturalPerson.js
@@ -0,0 +1,2 @@
+var current_status = 'natural';
+{% include "ishtar/blocks/JQueryPersonOrga.js" %}
diff --git a/archaeological_files/templates/ishtar/blocks/JQueryPersonOrga.js b/archaeological_files/templates/ishtar/blocks/JQueryPersonOrga.js
new file mode 100644
index 000000000..1877e4579
--- /dev/null
+++ b/archaeological_files/templates/ishtar/blocks/JQueryPersonOrga.js
@@ -0,0 +1,66 @@
+person_save_callback = function(item_id, lbl){
+ var url = {{edit_source}};
+ $('#id_{{field_id}}').val(null);
+ $('#id_select_{{field_id}}').val(lbl);
+ if (item_id){
+ url = {{edit_source}}+item_id;
+ $('#id_{{field_id}}').val(item_id);
+ }
+ $("#id_select_{{field_id}}").trigger('autocompletechange');
+ $.get(url , function( data ) {
+ $( "#div-{{field_id}}" ).html( data );
+ });
+};
+
+edit_url = {{edit_source}};
+parent_id = "{{field_id}}";
+
+person_new_callback = function(){
+ var url = {{edit_source}};
+ $('#id_{{field_id}}').val(null);
+ $('#id_select_{{field_id}}').val(null);
+}
+
+$(function() {
+ var $radios = $('input:radio[name=person_type]');
+ if($radios.is(':checked') === false) {
+ $radios.filter('[value='+ current_status +']').prop('checked', true);
+ }
+
+ $radios.change(function(){
+ var loc = window.location;
+ window.location = loc.protocol + '//' + loc.host + loc.pathname + "?status=" + $('input:radio[name=person_type]:checked').val();
+ });
+
+ $("#id_select_{{field_id}}").autocomplete({
+ source: {{source}},
+ select: function( event, ui ) {
+ var url = {{edit_source}};
+ if(ui.item){
+ url = {{edit_source}}+ui.item.id;
+ $('#id_{{field_id}}').val(ui.item.id);
+ $('#id_{{field_id}}').change();
+ } else {
+ $('#id_{{field_id}}').val(null);
+ }
+ $.get(url, function( data ) {
+ $( "#div-{{field_id}}" ).html( data );
+ });
+ },
+ minLength: 2{% if options %},
+ {{options}}
+ {% endif %}
+ });
+
+ $.get( {{edit_source}}{% if selected %}+'{{selected}}'{% endif %}, function( data ) {
+ $( "#div-{{field_id}}" ).html( data );
+ });
+
+ $(document).on("click", '#id_select_{{field_id}}', function(){
+ $('#id_{{field_id}}').val(null);
+ $('#id_select_{{field_id}}').val(null);
+ $.get( {{edit_source}}, function( data ) {
+ $( "#div-{{field_id}}" ).html( data );
+ });
+ });
+});
diff --git a/archaeological_files/templates/ishtar/wizard/file_confirm_wizard.html b/archaeological_files/templates/ishtar/wizard/file_confirm_wizard.html
new file mode 100644
index 000000000..914a5198b
--- /dev/null
+++ b/archaeological_files/templates/ishtar/wizard/file_confirm_wizard.html
@@ -0,0 +1,27 @@
+{% extends "ishtar/wizard/confirm_wizard.html" %}
+{% load i18n %}
+
+{% block "warning_informations" %}
+{% for file in numeric_reference_files %}
+{% if forloop.first %}
+<p class='alert'><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> <label>{% trans "The following files have the same numeric index as this file:" %}</label></p>
+<ul>
+{% endif%}
+ <li>{{file}} <a href='#' onclick='load_window("{% url 'show-file' file.pk '' %}", "{{model_name}}");' class='display_details'><i class="fa fa-info-circle" aria-hidden="true"></i></a></li>
+{% if forloop.last %}
+</ul>
+<hr/>
+{% endif %}
+{% endfor %}
+{% for file in similar_files %}
+{% if forloop.first %}
+<p class='alert'><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> <label>{% trans "The following files are in the same town and have parcels in common with this file:" %}</label></p>
+<ul>
+{% endif%}
+ <li>{{file}} <a href='#' onclick='load_window("{% url 'show-file' file.pk '' %}", "{{model_name}}");' class='display_details'><i class="fa fa-info-circle" aria-hidden="true"></i></a></li>
+{% if forloop.last %}
+</ul>
+<hr/>
+{% endif %}
+{% endfor %}
+{% endblock %}
diff --git a/archaeological_files/templates/ishtar/wizard/wizard_instruction.html b/archaeological_files/templates/ishtar/wizard/wizard_instruction.html
new file mode 100644
index 000000000..34db944aa
--- /dev/null
+++ b/archaeological_files/templates/ishtar/wizard/wizard_instruction.html
@@ -0,0 +1,83 @@
+{% extends "ishtar/wizard/default_wizard.html" %}
+{% load i18n range table_form %}
+{% block form_detail %}
+ <div class="form-row">
+ {% with wizard.form.in_charge as field %}
+ {% include "blocks/bs_field_snippet.html" %}
+ {% endwith %}
+ {% with wizard.form.related_file as field %}
+ {% include "blocks/bs_field_snippet.html" %}
+ {% endwith %}
+ {% with wizard.form.comment as field %}
+ {% include "blocks/bs_field_snippet.html" %}
+ {% endwith %}
+
+ <div class="form-group col-lg-6">
+ <span class="required">
+ <label class="required">{% trans "State of the file:" %}</label>
+ </span>
+ <div class="form-group col-lg-12 mb-0">
+ <span><input type='radio' name='state' value='open' id='state-open'/>
+ <label for='state-open'>Dossier actif</label></span>
+ </div>
+ <div class="form-group col-lg-12">
+ <span>{{wizard.form.end_date.errors}}<input type='radio' name='state' value='closed' id='state-closed'/>
+ <label for='state-closed'>Dossier clos / date de clôture</label> : {{wizard.form.end_date|safe}}</span>
+ </div>
+ </div>
+ {% with wizard.form.instruction_deadline as field %}{% with saisine_type_message as extra_field_label %}
+ {% include "blocks/bs_field_snippet.html" %}
+ {% endwith %}{% endwith %}
+ <div class="form-group col-lg-6">
+ <span class="required">
+ <label>{{wizard.form.numeric_reference.label}}{% trans ":" %}</label>
+ </span>
+ <div class="form-inline">
+ {{wizard.form.numeric_reference.errors}}
+ {% if FILE_PREFIX %}<span class="pr-2">{{FILE_PREFIX}}</span>{% endif %}
+ <span class="pr-2">{{wizard.form.year|safe}}</span> -
+ <span class="pl-2">{{wizard.form.numeric_reference|safe}}</span>
+ </div>
+ </div>
+ </div>
+{% endblock %}
+
+{% block "js_extra_ready" %}
+ if ($('#id_instruction-{{CURRENT_ACTION}}-end_date').val()){
+ $("#state-closed").prop('checked', true);
+ } else {
+ $("#state-open").prop('checked', true);
+ }
+
+ check_state = function(){
+ var state = $("input[name=state]:checked").val();
+ if (state == 'closed'){
+ $('#id_instruction-{{CURRENT_ACTION}}-end_date').focus();
+ $('#id_instruction-{{CURRENT_ACTION}}-end_date').prop('disabled', false);
+ } else if (state == 'open'){
+ $('#id_instruction-{{CURRENT_ACTION}}-end_date').val('');
+ $('#id_instruction-{{CURRENT_ACTION}}-end_date').prop('disabled', true);
+ }
+ };
+
+ $('input[name=state]').click(check_state);
+
+ check_state();
+
+ $('#submit_form').click(function(){
+ var state = $("input[name=state]:checked").val();
+ if (state == 'closed'){
+ if (!$('#id_instruction-{{CURRENT_ACTION}}-end_date').val()){
+ alert("{% trans 'You must select a closing date.' %}")
+ return false;
+ }
+ return true;
+ } else if (state == 'open'){
+ return true;
+ } else {
+ alert("{% trans 'You must select a state for this file.' %}")
+ return false;
+ }
+ return true;
+ });
+ {% endblock %}
diff --git a/archaeological_files/templates/ishtar/wizard/wizard_person_orga.html b/archaeological_files/templates/ishtar/wizard/wizard_person_orga.html
new file mode 100644
index 000000000..36f1aa4f8
--- /dev/null
+++ b/archaeological_files/templates/ishtar/wizard/wizard_person_orga.html
@@ -0,0 +1,76 @@
+{% extends "ishtar/wizard/default_wizard.html" %}
+{% load i18n range table_form %}
+{% block wizard_form %}
+<script type='text/javascript'>
+function update_form(){
+ if ($('input[name="person_type"]:radio:checked').val() == 'corporation'){
+ $('#natural_div').hide();
+ $('#corporation_div').show();
+ $('#orga-form').show();
+ } else {
+ $('#natural_div').show();
+ $('#corporation_div').hide();
+ $('#orga-form').hide();
+ }
+}
+$(function() {
+ update_form();
+});
+</script>
+<form action="." method="post" name='wizard'{% if wizard.form.file_upload %} enctype="multipart/form-data"{% endif %}>{% csrf_token %}
+<div class='form'>
+{% if wizard.form.media %}{{ wizard.form.media }}{% endif %}
+{{ wizard.management_form }}
+
+<table class='formset'>
+ <caption>Statut</caption>
+ <tr>
+ <th><label>{% trans "Corporation" %}</label></th>
+ <td><input type='radio' name='person_type' value='corporation'/></td>
+ </tr>
+ <tr>
+ <th><label>{% trans "Natural person" %}</label></th>
+ <td><input type='radio' name='person_type' value='natural'/></td>
+ </tr>
+</table>
+
+<table id='corporation_div'>
+ {% if wizard.form.non_field_errors %}<tr class='errors'>
+ <td colspan='3'>{{wizard.form.non_field_errors}}</td>
+ </tr>{%endif%}
+
+{% block corporation %}
+{% endblock %}
+</table>
+<div id='natural_div'>
+<table>
+ {% if wizard.form.non_field_errors %}<tr class='errors'>
+ <td colspan='3'>{{wizard.form.non_field_errors}}</td>
+ </tr>{%endif%}
+
+{% block natural %}
+{% endblock %}
+</table>
+</div>
+
+<div>
+{% block otherfields %}
+{% endblock %}
+</div>
+{% block extra_head_po %}
+{% endblock %}
+
+<input type="hidden" name="{{ step_field }}" value="{{ step0 }}" />
+{{ previous_fields|safe }}
+ {% block "footer" %}
+ <div id="footer">
+ {% block "validation_bar" %}
+ {% include 'ishtar/wizard/validation_bar.html' %}
+ {% endblock %}
+ {% include 'ishtar/blocks/footer.html' %}
+ </div>
+ {% endblock %}
+</div>
+</form>
+{% endblock %}
+
diff --git a/archaeological_files/tests.py b/archaeological_files/tests.py
index 7145cb836..f0684c756 100644
--- a/archaeological_files/tests.py
+++ b/archaeological_files/tests.py
@@ -30,10 +30,13 @@ from ishtar_common.tests import (
create_superuser,
AutocompleteTestBase,
AcItem,
+ WizardTest,
+ WizardTestFormData as FormData,
FILE_TOWNS_FIXTURES,
)
-from ishtar_common.models import Town, IshtarSiteProfile
+from ishtar_common.models import Town, IshtarSiteProfile, Person, PersonType, \
+ Organization, OrganizationType
from ishtar_common.utils import ugettext_lazy as _
from archaeological_files import models, views
@@ -45,7 +48,7 @@ from archaeological_operations.models import (
)
from archaeological_operations.tests import OperationInitTest, FileInit
-
+"""
def create_administrativact(user, fle):
act_type, created = ActType.objects.get_or_create(
txt_idx="act_type_F", intented_to="F"
@@ -59,6 +62,7 @@ def create_administrativact(user, fle):
}
adminact, created = AdministrativeAct.objects.get_or_create(**dct)
return [act_type], [adminact]
+"""
class FileTest(TestCase, FileInit):
@@ -754,3 +758,381 @@ class AutocompleteTest(AutocompleteTestBase, TestCase):
name=base_name, file_type=models.FileType.objects.all()[0]
)
return item, None
+
+
+class FileWizardCreationTest(WizardTest, OperationInitTest, TestCase):
+ fixtures = FILE_TOWNS_FIXTURES
+ url_name = "file_creation"
+ wizard_name = "file_wizard"
+ steps = views.file_creation_steps
+ redirect_url = (
+ "/file_modification/selec-file_modification?open_item={last_id}"
+ )
+ model = models.File
+
+ form_datas = [
+ FormData(
+ "Create a research file",
+ form_datas={
+ "general": {
+ "file_type": None,
+ "year": None,
+ "creation_date": None,
+ "reception_date": None
+ },
+ "researchaddress": {},
+ "research": {
+ "requested_operation_type": None,
+ "scientist": None,
+ },
+ "instruction": {
+ "in_charge": None
+ }
+ },
+ ignored=(
+ "preventivetype-file_creation",
+ "preventiveplanning-file_creation",
+ "generalcontractor-file_creation",
+ "planningservice-file_creation",
+ ),
+ ),
+ FormData(
+ "Create a preventive file",
+ form_datas={
+ "general": {
+ "file_type": None,
+ "year": None,
+ "creation_date": None,
+ "reception_date": None
+ },
+ "preventivetype-file_creation": {
+ "saisine_type": None,
+ },
+ "preventiveplanning-file_creation": {},
+ "generalcontractor-file_creation": {
+ "corporation_general_contractor": None
+ },
+ "instruction": {
+ "in_charge": None
+ }
+ },
+ ignored=(
+ "planningservice-file_creation",
+ "researchaddress-file_creation",
+ "research-file_creation",
+ ),
+ ),
+ ]
+
+ def pre_wizard(self):
+ profile, created = IshtarSiteProfile.objects.get_or_create(
+ slug="default", active=True
+ )
+ profile.files = True
+ profile.save()
+
+ if "general" not in self.form_datas[0].form_datas:
+ super().pre_wizard()
+ return
+
+ file_type_pk = models.FileType.objects.get(txt_idx="prog").pk
+ # force cache reinit because previous mess up that - do not know why
+ models.FileType.is_preventive(file_type_pk, force=True)
+ self.form_datas[0].set(
+ "general",
+ "file_type",
+ file_type_pk
+ )
+ file_type_pk = models.FileType.objects.get(txt_idx="preventive").pk
+ models.FileType.is_preventive(file_type_pk, force=True)
+ self.form_datas[1].set(
+ "general",
+ "file_type",
+ file_type_pk
+ )
+
+ responsability = Person.objects.create(name="OK", surname="SuperComputer")
+ responsability.person_types.add(PersonType.objects.get(txt_idx="sra_agent"))
+ for idx in range(2):
+ self.form_datas[idx].set("general", "year", 2022)
+ self.form_datas[idx].set("general", "creation_date", "2022-10-01")
+ self.form_datas[idx].set("general", "reception_date", "2022-10-03")
+ self.form_datas[idx].set("instruction", "in_charge", responsability.pk)
+
+ ope_type = models.OperationType.objects.get(txt_idx="documents_study_research")
+ self.form_datas[0].set("research", "requested_operation_type", ope_type.pk)
+ person = Person.objects.create(name="OK", surname="Computer")
+ person.person_types.add(PersonType.objects.get(txt_idx="head_scientist"))
+ self.form_datas[0].set("research", "scientist", person.pk)
+
+ self.form_datas[1].set(
+ "preventivetype", "saisine_type",
+ models.SaisineType.objects.filter(delay__gt=0).all()[0].pk
+ )
+ self.form_datas[1].set(
+ "preventivetype", "permit_type",
+ models.PermitType.objects.all()[0].pk
+ )
+ orga = Organization.objects.create(
+ name="Big corpo",
+ organization_type=OrganizationType.objects.get(txt_idx="general_contractor")
+ )
+ self.form_datas[1].set(
+ "generalcontractor", "corporation_general_contractor", orga.pk
+ )
+
+ self.file_number = models.File.objects.count()
+ super().pre_wizard()
+
+ def post_wizard(self):
+ self.assertEqual(models.File.objects.count(), self.file_number + 2)
+
+
+class FileWizardModifTest(WizardTest, OperationInitTest, TestCase):
+ fixtures = FILE_TOWNS_FIXTURES
+ url_name = "file_modification"
+ wizard_name = url_name + "_wizard"
+ steps = views.file_modification_steps
+ redirect_url = (
+ "/file_modification/selec-file_modification?open_item={current_id}"
+ )
+ model = models.File
+
+ form_datas = [
+ FormData(
+ "Modify a research file",
+ form_datas={
+ "selec": {},
+ "general": {
+ "year": 2019,
+ },
+ "generalcontractor": {
+ "corporation_general_contractor": None
+ },
+ "instruction": {
+ "in_charge": None
+ }
+ },
+ ignored=(
+ "preventivetype-file_modification",
+ "preventiveplanning-file_modification",
+ "researchaddress-file_modification",
+ "planningservice-file_modification",
+ "research-file_modification",
+ ),
+ ),
+ FormData(
+ "Modify a preventive file",
+ form_datas={
+ "selec": {},
+ "general": {
+ "file_type": None,
+ "year": 2012,
+ "creation_date": None,
+ "reception_date": None
+ },
+ "preventivetype": {
+ "saisine_type": None,
+ },
+ "preventiveplanning": {},
+ "planningservice":{
+ "permit_reference": "XKCD"
+ },
+ "generalcontractor": {
+ "corporation_general_contractor": None
+ },
+ "instruction": {
+ "in_charge": None
+ }
+ },
+ ignored=(
+ "researchaddress-file_modification",
+ "research-file_modification",
+ ),
+ ),
+ ]
+
+ def pre_wizard(self):
+ profile, created = IshtarSiteProfile.objects.get_or_create(
+ slug="default", active=True
+ )
+ profile.files = True
+ profile.save()
+
+ if "general" not in self.form_datas[0].form_datas:
+ super().pre_wizard()
+ return
+
+ responsability = Person.objects.create(name="OK", surname="SuperComputer")
+ responsability.person_types.add(PersonType.objects.get(txt_idx="sra_agent"))
+ ope_type = models.OperationType.objects.get(txt_idx="documents_study_research")
+ person = Person.objects.create(name="OK", surname="Computer")
+ person.person_types.add(PersonType.objects.get(txt_idx="head_scientist"))
+ orga = Organization.objects.create(
+ name="Big corpo",
+ organization_type=OrganizationType.objects.get(txt_idx="general_contractor")
+ )
+
+ file_type_pk = models.FileType.objects.get(txt_idx="prog").pk
+ # force cache reinit because previous mess up that - do not know why
+ models.FileType.is_preventive(file_type_pk, force=True)
+ fle = models.File.objects.create(
+ file_type_id=file_type_pk,
+ year=2022,
+ creation_date="2022-10-01",
+ reception_date="2022-10-03",
+ in_charge=responsability,
+ requested_operation_type=ope_type,
+ scientist=person,
+ corporation_general_contractor=orga,
+ )
+ file_type_pk = models.FileType.objects.get(txt_idx="preventive").pk
+ # force cache reinit because previous mess up that - do not know why
+ models.FileType.is_preventive(file_type_pk, force=True)
+ fle2 = models.File.objects.create(
+ file_type_id=file_type_pk,
+ year=2021,
+ creation_date="2022-09-01",
+ reception_date="2022-10-03",
+ in_charge=responsability,
+ corporation_general_contractor=orga,
+ saisine_type=models.SaisineType.objects.filter(delay__gt=0).all()[0]
+ )
+ self.files = [fle, fle2]
+
+ data = self.form_datas[0].form_datas
+ data["selec"]["pk"] = str(fle.pk)
+ data["general"]["file_type"] = fle.file_type.pk
+ data["general"]["creation_date"] = fle.creation_date
+ data["general"]["reception_date"] = fle.reception_date
+ data["generalcontractor"]["corporation_general_contractor"] = \
+ fle.corporation_general_contractor.pk
+ data["instruction"]["in_charge"] = fle.in_charge.pk
+ data["instruction"]["numeric_reference"] = fle.numeric_reference
+
+ data2 = self.form_datas[1].form_datas
+ data2["selec"]["pk"] = str(fle2.pk)
+ data2["general"]["file_type"] = fle2.file_type.pk
+ data2["general"]["creation_date"] = fle2.creation_date
+ data2["general"]["reception_date"] = fle2.reception_date
+ data2["preventivetype"]["saisine_type"] = fle2.saisine_type.pk
+ data2["generalcontractor"]["corporation_general_contractor"] = \
+ fle2.corporation_general_contractor.pk
+ data2["instruction"]["in_charge"] = fle2.in_charge.pk
+ data2["instruction"]["numeric_reference"] = fle2.numeric_reference
+ self.file_number = models.File.objects.count()
+
+ def post_first_wizard(test_object, final_step_response):
+ fle = models.File.objects.get(pk=test_object.files[0].pk)
+ test_object.assertEqual(fle.year, 2019)
+
+ def post_second_wizard(test_object, final_step_response):
+ fle = models.File.objects.get(pk=test_object.files[1].pk)
+ test_object.assertEqual(fle.year, 2012)
+
+ self.form_datas[0].extra_tests = [post_first_wizard]
+ self.form_datas[1].extra_tests = [post_second_wizard]
+ super().pre_wizard()
+
+ def post_wizard(self):
+ self.assertEqual(models.File.objects.count(), self.file_number)
+
+
+class FileWizardDeleteTest(FileWizardCreationTest):
+ fixtures = FILE_TOWNS_FIXTURES
+ url_name = "file_deletion"
+ wizard_name = url_name + "_wizard"
+ steps = views.file_deletion_steps
+ redirect_url = "/{}/selec-{}".format(url_name, url_name)
+ form_datas = [
+ FormData(
+ "Wizard deletion test",
+ form_datas={
+ "selec": {"pks": None},
+ },
+ )
+ ]
+
+ def pass_test(self):
+ if not settings.TEST_VIEWS:
+ # with no migration the views are not created
+ return True
+
+ def pre_wizard(self):
+ self.file = models.File.objects.create(
+ file_type=models.FileType.objects.get(txt_idx="prog"),
+ year=2022,
+ )
+ self.form_datas[0].form_datas["selec"]["pks"] = self.file.pk
+ self.file_number = models.File.objects.count()
+ super().pre_wizard()
+
+ def post_wizard(self):
+ self.assertEqual(self.file_number - 1, models.File.objects.count())
+
+
+class FileWizardClosingTest(FileWizardCreationTest):
+ fixtures = FILE_TOWNS_FIXTURES
+ url_name = "file_closing"
+ wizard_name = url_name + "_wizard"
+ steps = views.file_closing_steps
+ redirect_url = "/file_closing/done"
+ form_datas = [
+ FormData(
+ "Wizard closing test",
+ form_datas={
+ "selec": {"pk": None},
+ "date": {"end_date": "2016-01-01"},
+ },
+ )
+ ]
+
+ def pre_wizard(self):
+ self.file = models.File.objects.create(
+ file_type=models.FileType.objects.get(txt_idx="prog"),
+ year=2022,
+ )
+ self.form_datas[0].form_datas["selec"]["pk"] = self.file.pk
+ self.assertTrue(self.file.is_active())
+ super().pre_wizard()
+
+ def post_wizard(self):
+ fle = models.File.objects.get(pk=self.file.pk)
+ self.assertFalse(fle.is_active())
+ self.assertEqual(
+ fle.closing()["date"].strftime("%Y-%d-%m"),
+ self.form_datas[0].form_datas["date-" + self.url_name]["end_date"]
+ )
+
+
+class FileAdminActWizardCreationTest(WizardTest, OperationInitTest, TestCase):
+ fixtures = FILE_TOWNS_FIXTURES
+ url_name = "file_administrativeactfile"
+ wizard_name = "file_administrative_act_wizard"
+ steps = views.administrativeact_steps
+ form_datas = [
+ FormData(
+ "Admin act creation",
+ form_datas={
+ "selec": {},
+ "administrativeact": {
+ "signature_date": str(datetime.date.today())
+ },
+ },
+ )
+ ]
+
+ def pre_wizard(self):
+ self.file = models.File.objects.create(
+ file_type=models.FileType.objects.get(txt_idx="prog"),
+ year=2022,
+ )
+ data = self.form_datas[0].form_datas
+ data["selec"]["pk"] = self.file.pk
+ act = ActType.objects.filter(intented_to="F").all()[0].pk
+ data["administrativeact"]["act_type"] = act
+ self.number = AdministrativeAct.objects.count()
+ super().pre_wizard()
+
+ def post_wizard(self):
+ self.assertEqual(AdministrativeAct.objects.count(), self.number + 1)
diff --git a/archaeological_files/urls.py b/archaeological_files/urls.py
index 084f2155f..fd2059bbe 100644
--- a/archaeological_files/urls.py
+++ b/archaeological_files/urls.py
@@ -29,14 +29,14 @@ from archaeological_operations.views import administrativeactfile_document
# forms:
urlpatterns = [
url(
- r"file_administrativeactfil_search/(?P<step>.+)?$",
+ r"file_administrativeactfile_search/(?P<step>.+)?$",
check_rights(["change_administrativeact"])(
views.file_administrativeactfile_search_wizard
),
name="file_administrativeactfile_search",
),
url(
- r"file_administrativeactfil/(?P<step>.+)?$",
+ r"^file_administrativeactfile/(?P<step>.+)?$",
check_rights(["change_administrativeact"])(
views.file_administrativeactfile_wizard
),
@@ -48,14 +48,14 @@ urlpatterns = [
name="file_administrativeactfile_modify",
),
url(
- r"file_administrativeactfil_deletion/(?P<step>.+)?$",
+ r"file_administrativeactfile_deletion/(?P<step>.+)?$",
check_rights(["change_administrativeact"])(
views.file_administrativeactfile_deletion_wizard
),
name="file_administrativeactfile_deletion",
),
url(
- r"file_administrativeactfil_modification/(?P<step>.+)?$",
+ r"file_administrativeactfile_modification/(?P<step>.+)?$",
check_rights(["change_administrativeact"])(
views.file_administrativeactfile_modification_wizard
),
@@ -172,6 +172,16 @@ urlpatterns = [
name="file-edit-preventive-copy-planned",
),
url(
+ r"townplanning-edit/$",
+ views.TownPlanningCreate.as_view(),
+ name="townplanning_create",
+ ),
+ url(
+ r"townplanning-edit/(?P<pk>\d+)$",
+ views.TownPlanningEdit.as_view(),
+ name="townplanning_edit",
+ ),
+ url(
r"api/facets/file/$", views_api.FacetFileAPIView.as_view(),
name="api-facets-file"
),
diff --git a/archaeological_files/views.py b/archaeological_files/views.py
index cbe1a9f96..5988ba1c0 100644
--- a/archaeological_files/views.py
+++ b/archaeological_files/views.py
@@ -29,7 +29,8 @@ from django.urls import reverse
from ishtar_common.utils import ugettext_lazy as _
from archaeological_operations.utils import parse_parcels
-from ishtar_common.views import wizard_is_available
+from ishtar_common.views import wizard_is_available, OrganizationPersonCreate, \
+ OrganizationPersonEdit
from ishtar_common.views_item import get_item, show_item, revert_item, check_permission
from archaeological_operations.wizards import (
@@ -52,7 +53,6 @@ from ishtar_common.views import IshtarMixin, LoginRequiredMixin
from archaeological_operations.wizards import OperationWizard
from archaeological_operations.views import operation_creation_wizard
-from ishtar_common.forms_common import TownFormset
from archaeological_operations.forms import FinalAdministrativeActDeleteForm, \
SelectedParcelGeneralFormSet
from ishtar_common.forms import ClosingDateFormSelection
@@ -137,43 +137,69 @@ file_search_wizard = wizards.FileSearch.as_view(
url_name="file_search",
)
-file_creation_wizard = wizards.FileWizard.as_view(
- [
- ("general-file_creation", forms.FileFormGeneral),
- ("towns-file_creation", TownFormset),
- ("preventive-file_creation", forms.FileFormPreventive),
- ("research-file_creation", forms.FileFormResearch),
- ("final-file_creation", forms.FinalForm),
- ],
+file_creation_wizard_is_preventive = is_preventive(
+ "general-file_creation", models.FileType, type_key="file_type"
+)
+file_creation_wizard_is_not_preventive = is_not_preventive(
+ "general-file_creation", models.FileType, type_key="file_type"
+)
+
+file_creation_steps = [
+ ("general-file_creation", forms.FileFormGeneral),
+ ("preventivetype-file_creation", forms.FileFormPreventiveType),
+ ("preventiveplanning-file_creation", forms.FileFormPlanning),
+ ("researchaddress-file_creation", forms.FileFormResearchAddress),
+ ("generalcontractor-file_creation", forms.FileFormGeneralContractor),
+ ("planningservice-file_creation", forms.FileFormPlanningService),
+ ("research-file_creation", forms.FileFormResearch),
+ ("instruction-file_creation", forms.FileFormInstruction),
+ ("final-file_creation", forms.FinalForm),
+]
+
+file_creation_wizard = FileWizard.as_view(
+ file_creation_steps,
label=_("New file"),
condition_dict={
- "preventive-file_creation": is_preventive(
- "general-file_creation", models.FileType, type_key="file_type"
- ),
- "research-file_creation": is_not_preventive(
- "general-file_creation", models.FileType, type_key="file_type"
- ),
+ "preventivetype-file_creation": file_creation_wizard_is_preventive,
+ "preventiveplanning-file_creation": file_creation_wizard_is_preventive,
+ "generalcontractor-file_creation": file_creation_wizard_is_preventive,
+ "planningservice-file_creation": file_creation_wizard_is_preventive,
+ "researchaddress-file_creation": file_creation_wizard_is_not_preventive,
+ "research-file_creation": file_creation_wizard_is_not_preventive,
},
url_name="file_creation",
)
-file_modification_wizard = wizards.FileModificationWizard.as_view(
- [
- ("selec-file_modification", forms.FileFormSelection),
- ("general-file_modification", forms.FileFormGeneralRO),
- ("towns-file_modification", TownFormset),
- ("preventive-file_modification", forms.FileFormPreventive),
- ("research-file_modification", forms.FileFormResearch),
- ("final-file_modification", forms.FinalForm),
- ],
+file_modification_wizard_is_preventive = is_preventive(
+ "general-file_modification", models.FileType, type_key="file_type"
+)
+file_modification_wizard_is_not_preventive = is_not_preventive(
+ "general-file_modification", models.FileType, type_key="file_type"
+)
+
+file_modification_steps = [
+ ("selec-file_modification", forms.FileFormSelection),
+ ("general-file_modification", forms.FileFormGeneral),
+ ("preventivetype-file_modification", forms.FileFormPreventiveType),
+ ("preventiveplanning-file_modification", forms.FileFormPlanning),
+ ("researchaddress-file_modification", forms.FileFormResearchAddress),
+ ("generalcontractor-file_modification", forms.FileFormGeneralContractor),
+ ("planningservice-file_modification", forms.FileFormPlanningService),
+ ("research-file_modification", forms.FileFormResearch),
+ ("instruction-file_modification", forms.FileFormInstructionEdit),
+ ("final-file_modification", forms.FinalForm),
+]
+
+file_modification_wizard = FileModificationWizard.as_view(
+ file_modification_steps,
label=_("File modification"),
condition_dict={
- "preventive-file_modification": is_preventive(
- "general-file_modification", models.FileType, type_key="file_type"
- ),
- "research-file_modification": is_not_preventive(
- "general-file_modification", models.FileType, type_key="file_type"
- ),
+ "preventivetype-file_modification": file_modification_wizard_is_preventive,
+ "preventiveplanning-file_modification": file_modification_wizard_is_preventive,
+ "generalcontractor-file_modification": file_modification_wizard_is_preventive,
+ "planningservice-file_modification": file_modification_wizard_is_preventive,
+ "researchaddress-file_modification": file_modification_wizard_is_not_preventive,
+ "research-file_modification": file_modification_wizard_is_not_preventive,
},
url_name="file_modification",
)
@@ -191,21 +217,25 @@ def file_modify(request, pk):
)
+file_closing_steps = [
+ ("selec-file_closing", forms.FileFormSelection),
+ ("date-file_closing", ClosingDateFormSelection),
+ ("final-file_closing", forms.FinalFileClosingForm),
+]
+
file_closing_wizard = wizards.FileClosingWizard.as_view(
- [
- ("selec-file_closing", forms.FileFormSelection),
- ("date-file_closing", ClosingDateFormSelection),
- ("final-file_closing", forms.FinalFileClosingForm),
- ],
+ file_closing_steps,
label=_("File closing"),
url_name="file_closing",
)
+file_deletion_steps = [
+ ("selec-file_deletion", forms.FileFormMultiSelection),
+ ("final-file_deletion", forms.FinalFileDeleteForm),
+]
+
file_deletion_wizard = wizards.FileDeletionWizard.as_view(
- [
- ("selec-file_deletion", forms.FileFormMultiSelection),
- ("final-file_deletion", forms.FinalFileDeleteForm),
- ],
+ file_deletion_steps,
label=_("File deletion"),
url_name="file_deletion",
)
@@ -221,6 +251,14 @@ def file_delete(request, pk):
return redirect(reverse("file_deletion", kwargs={"step": "final-file_deletion"}))
+class TownPlanningEdit(OrganizationPersonEdit):
+ relative_label = _("File followed by")
+
+
+class TownPlanningCreate(OrganizationPersonCreate):
+ relative_label = _("File followed by")
+
+
file_administrativeactfile_search_wizard = SearchWizard.as_view(
[
(
@@ -232,15 +270,18 @@ file_administrativeactfile_search_wizard = SearchWizard.as_view(
url_name="file_administrativeactfile_search",
)
+
+administrativeact_steps = [
+ ("selec-file_administrativeactfile", forms.FileFormSelection),
+ (
+ "administrativeact-file_administrativeactfile",
+ forms.AdministrativeActFileForm,
+ ),
+ ("final-file_administrativeactfile", forms.FinalForm),
+]
+
file_administrativeactfile_wizard = wizards.FileAdministrativeActWizard.as_view(
- [
- ("selec-file_administrativeactfile", forms.FileFormSelection),
- (
- "administrativeact-file_administrativeactfile",
- forms.AdministrativeActFileForm,
- ),
- ("final-file_administrativeactfile", forms.FinalForm),
- ],
+ administrativeact_steps,
label=_("File: new administrative act"),
url_name="file_administrativeactfile",
)
diff --git a/archaeological_files/wizards.py b/archaeological_files/wizards.py
index 1538a984a..569b01a56 100644
--- a/archaeological_files/wizards.py
+++ b/archaeological_files/wizards.py
@@ -39,10 +39,23 @@ class FileSearch(SearchWizard):
class FileWizard(OperationWizard):
model = models.File
object_parcel_type = "associated_file"
- parcel_step_key = "parcels-"
- town_step_keys = ["towns-"]
+ parcel_step_key = "parcelspdl-"
+ town_step_keys = ["preventiveplanning-", "researchaddress-"]
wizard_done_window = reverse_lazy("show-file")
redirect_url = "file_modification"
+ town_input_id = "town"
+ towns_formset = False
+ multi_towns = True
+ wizard_templates = {
+ "planningservice-%(url_name)s": "ishtar/wizard/wizard_planningservice.html",
+ "instruction-%(url_name)s": "ishtar/wizard/wizard_instruction.html",
+ "preventiveplanning-%(url_name)s": "ishtar/wizard/wizard_preventiveplanning.html",
+ }
+ wizard_confirm = "ishtar/wizard/file_confirm_wizard.html"
+
+ def get_current_year(self):
+ general_form_key = "general-" + self.url_name
+ return self.session_get_value(general_form_key, "year")
def get_extra_model(self, dct, m2m, form_list):
dct = super(FileWizard, self).get_extra_model(dct, m2m, form_list)
@@ -53,9 +66,79 @@ class FileWizard(OperationWizard):
dct["numeric_reference"] = current_ref and current_ref + 1 or 1
return dct
+ def get_form_kwargs(self, *args, **kwargs):
+ returned = super(FileWizard, self).get_form_kwargs(*args, **kwargs)
+ if args and args[0].startswith("generalcontractor-"):
+ if "status" in self.request.GET:
+ returned["status"] = self.request.GET["status"]
+ if args and args[0].startswith("instruction-"):
+ returned["year"] = self.get_current_year()
+ returned["saisine_type"] = self.get_saisine_type()
+ returned["reception_date"] = self.session_get_value(
+ "general-" + self.url_name, "reception_date"
+ )
+ return returned
+
+ def get_saisine_type(self):
+ try:
+ idx = int(
+ self.session_get_value(
+ "preventivetype-" + self.url_name, "saisine_type"
+ )
+ )
+ return models.SaisineType.objects.get(pk=idx)
+ except (TypeError, ValueError, models.PermitType.DoesNotExist):
+ pass
+
+ def get_context_data(self, form, **kwargs):
+ context = super(FileWizard, self).get_context_data(form)
+ formplanning = "planningservice-" + self.url_name
+ forminstruction = "instruction-" + self.url_name
+ formfinal = "final-" + self.url_name
+ if self.steps.current == formplanning:
+ try:
+ idx = int(
+ self.session_get_value(
+ "preventivetype-" + self.url_name, "permit_type"
+ )
+ )
+ permit_type = models.PermitType.objects.get(pk=idx)
+ context["permit_type"] = str(permit_type)
+ context["permit_type_code"] = str(permit_type.txt_idx)
+ except (TypeError, ValueError, models.PermitType.DoesNotExist):
+ pass
+ elif self.steps.current == forminstruction:
+ saisine_type = self.get_saisine_type()
+ context["FILE_PREFIX"] = settings.ISHTAR_FILE_PREFIX
+ if saisine_type:
+ context["saisine_type"] = str(saisine_type)
+ context["saisine_type_message"] = str(saisine_type)
+ if saisine_type.delay:
+ context["saisine_type_message"] += str(
+ _(": delay of {} days")
+ ).format(saisine_type.delay)
+ elif self.steps.current == formfinal:
+ if not self.steps.current.endswith("creation"): # modification only
+ try:
+ numeric_reference = int(
+ self.session_get_value(
+ "instruction-" + self.url_name, "numeric_reference"
+ )
+ )
+
+ q = models.File.objects.filter(
+ numeric_reference=numeric_reference,
+ year=self.get_current_year(),
+ ).exclude(pk=self.get_current_object().pk)
+ context["numeric_reference_files"] = q.all()
+ except (ValueError, TypeError):
+ pass
+
+ return context
+
def done(self, form_list, **kwargs):
"""
- Save parcels and make numeric_reference unique
+ Make numeric_reference unique
"""
r = super(FileWizard, self).done(form_list, return_object=True, **kwargs)
if type(r) not in (list, tuple) or len(r) != 2:
@@ -77,39 +160,6 @@ class FileWizard(OperationWizard):
if changed:
obj.numeric_reference = numeric_reference
obj.save()
- obj.parcels.clear()
- for form in form_list:
- if (
- not hasattr(form, "prefix")
- or not form.prefix.startswith(self.parcel_step_key)
- or not hasattr(form, "forms")
- ):
- continue
- for frm in form.forms:
- if not frm.is_valid():
- continue
- dct = frm.cleaned_data.copy()
- if "parcel" in dct:
- try:
- parcel = Parcel.objects.get(pk=dct["parcel"])
- setattr(parcel, self.object_parcel_type, obj)
- parcel.save()
- except (ValueError, ObjectDoesNotExist):
- continue
- continue
- try:
- dct["town"] = models.Town.objects.get(pk=int(dct["town"]))
- except (ValueError, ObjectDoesNotExist, KeyError):
- continue
- dct["associated_file"], dct["operation"] = None, None
- dct[self.object_parcel_type] = obj
- if "DELETE" in dct:
- dct.pop("DELETE")
- parcel = Parcel.objects.filter(**dct).count()
- if not parcel:
- dct["history_modifier"] = self.request.user
- parcel = Parcel(**dct)
- parcel.save()
return res