summaryrefslogtreecommitdiff
path: root/archaeological_files/forms.py
diff options
context:
space:
mode:
authorÉtienne Loks <etienne.loks@iggdrasil.net>2022-11-15 16:29:30 +0100
committerÉtienne Loks <etienne.loks@iggdrasil.net>2022-12-12 12:23:19 +0100
commitcda77c979e232386ef24ea7a04600f16f3c32c98 (patch)
tree7d53e762723338913594ccdb42c6fa08c4bfb5ef /archaeological_files/forms.py
parent4746cd2938df3cf87ae338d22eb4f67f35bac960 (diff)
downloadIshtar-cda77c979e232386ef24ea7a04600f16f3c32c98.tar.bz2
Ishtar-cda77c979e232386ef24ea7a04600f16f3c32c98.zip
File module refactoring - more tests for files
Diffstat (limited to 'archaeological_files/forms.py')
-rw-r--r--archaeological_files/forms.py415
1 files changed, 346 insertions, 69 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?")