diff options
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 |
commit | b7db43100c6090937f61929430230ebab5bfbf76 (patch) | |
tree | 7d53e762723338913594ccdb42c6fa08c4bfb5ef | |
parent | 58663c87b11bfe0b60a9861a8fddd5bbb22ca0b4 (diff) | |
download | Ishtar-b7db43100c6090937f61929430230ebab5bfbf76.tar.bz2 Ishtar-b7db43100c6090937f61929430230ebab5bfbf76.zip |
File module refactoring - more tests for files
26 files changed, 953 insertions, 996 deletions
diff --git a/MANIFEST.in b/MANIFEST.in index 3610d1dce..37040b9de 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -24,7 +24,6 @@ recursive-include ishtar_common/templatetags * recursive-include archaeological_operations/templatetags * recursive-include ishtar_common/templates * recursive-include archaeological_files/templates * -recursive-include archaeological_files_pdl/templates * recursive-include archaeological_operations/templates * recursive-include archaeological_context_records/templates * recursive-include archaeological_finds/templates * diff --git a/Makefile.example b/Makefile.example index 346f3cd2f..45185ecb4 100644 --- a/Makefile.example +++ b/Makefile.example @@ -8,7 +8,7 @@ export PATH := $(HOME)/bin/geckodriver:$(PATH) # put name of your current project project=example_project # list used apps -apps="archaeological_operations" "ishtar_common" "archaeological_context_records" "archaeological_files" "archaeological_finds" "archaeological_warehouse" "archaeological_files_pdl" +apps="archaeological_operations" "ishtar_common" "archaeological_context_records" "archaeological_files" "archaeological_finds" "archaeological_warehouse" default_data='fr' version=`head -n 1 version.py | cut -d' ' -f2` branch_name=`git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e "s/* \(.*\)/\1/"` @@ -119,13 +119,13 @@ run_libreoffice: coverage: clean ## launch test coverage cd $(project); coverage run --source="ishtar_common,archaeological_operations,\ - archaeological_context_records,archaeological_files,archaeological_finds,archaeological_warehouse,\ - archaeological_files_pdl" ./manage.py test $(apps) && coverage report -m > ../coverage/result-`date '+%Y-%m-%d-%H%M'` + archaeological_context_records,archaeological_files,archaeological_finds,archaeological_warehouse"\ + ./manage.py test $(apps) && coverage report -m > ../coverage/result-`date '+%Y-%m-%d-%H%M'` soft_coverage: clean ## launch test coverage (no db reinit) cd $(project); coverage run --rcfile=../.coveragerc --source="ishtar_common,archaeological_operations,\ - archaeological_context_records,archaeological_files,archaeological_finds,archaeological_warehouse,\ - archaeological_files_pdl" ./manage.py test -k $(apps) && coverage report -m > ../coverage/result-`date '+%Y-%m-%d-%H%M'` + archaeological_context_records,archaeological_files,archaeological_finds,archaeological_warehouse"\ + ./manage.py test -k $(apps) && coverage report -m > ../coverage/result-`date '+%Y-%m-%d-%H%M'` pep8: pep8 --filename=*.py --ignore=W --exclude="manage.py,settings.py,migrations" --statistics --repeat . 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_pdl/templates/ishtar/blocks/JQueryCorporationPerson.js b/archaeological_files/templates/ishtar/blocks/JQueryCorporationPerson.js index 3eb375167..3eb375167 100644 --- a/archaeological_files_pdl/templates/ishtar/blocks/JQueryCorporationPerson.js +++ b/archaeological_files/templates/ishtar/blocks/JQueryCorporationPerson.js diff --git a/archaeological_files_pdl/templates/ishtar/blocks/JQueryNaturalPerson.js b/archaeological_files/templates/ishtar/blocks/JQueryNaturalPerson.js index fc4b9a90c..fc4b9a90c 100644 --- a/archaeological_files_pdl/templates/ishtar/blocks/JQueryNaturalPerson.js +++ b/archaeological_files/templates/ishtar/blocks/JQueryNaturalPerson.js diff --git a/archaeological_files_pdl/templates/ishtar/blocks/JQueryPersonOrga.js b/archaeological_files/templates/ishtar/blocks/JQueryPersonOrga.js index 1877e4579..1877e4579 100644 --- a/archaeological_files_pdl/templates/ishtar/blocks/JQueryPersonOrga.js +++ b/archaeological_files/templates/ishtar/blocks/JQueryPersonOrga.js diff --git a/archaeological_files_pdl/templates/ishtar/wizard/file_confirm_wizard.html b/archaeological_files/templates/ishtar/wizard/file_confirm_wizard.html index 914a5198b..914a5198b 100644 --- a/archaeological_files_pdl/templates/ishtar/wizard/file_confirm_wizard.html +++ b/archaeological_files/templates/ishtar/wizard/file_confirm_wizard.html diff --git a/archaeological_files_pdl/templates/ishtar/wizard/wizard_instruction.html b/archaeological_files/templates/ishtar/wizard/wizard_instruction.html index 34db944aa..34db944aa 100644 --- a/archaeological_files_pdl/templates/ishtar/wizard/wizard_instruction.html +++ b/archaeological_files/templates/ishtar/wizard/wizard_instruction.html diff --git a/archaeological_files_pdl/templates/ishtar/wizard/wizard_person_orga.html b/archaeological_files/templates/ishtar/wizard/wizard_person_orga.html index 36f1aa4f8..36f1aa4f8 100644 --- a/archaeological_files_pdl/templates/ishtar/wizard/wizard_person_orga.html +++ b/archaeological_files/templates/ishtar/wizard/wizard_person_orga.html 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 diff --git a/archaeological_files_pdl/forms.py b/archaeological_files_pdl/forms.py deleted file mode 100644 index 58480a36b..000000000 --- a/archaeological_files_pdl/forms.py +++ /dev/null @@ -1,515 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -# Copyright (C) 2014-2016 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet> - -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. - -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. - -# See the file COPYING for details. - -import datetime - -from django import forms -from django.core import validators -from django.utils.functional import lazy -from django.utils.safestring import mark_safe -from ishtar_common.utils import ugettext_lazy as _ - -from ishtar_common.models import ( - Person, - Town, - valid_id, - person_type_pk_lazy, - person_type_pks_lazy, - organization_type_pks_lazy, - organization_type_pk_lazy, - get_sra_agent_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_files import models - -from ishtar_common.forms import ( - get_now, - reverse_lazy, - ManageOldType, - CustomForm, - FieldType, - IshtarForm, - FormHeader, -) - -from ishtar_common import widgets -from bootstrap_datepicker.widgets import DatePicker - - -class FileFormGeneral(CustomForm, ManageOldType): - form_label = _("General") - 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, - validators=[ - validators.MinValueValidator(1000), - validators.MaxValueValidator(2100), - ], - ) - creation_date = forms.DateField( - label=_("Creation date"), initial=get_now, widget=DatePicker - ) - reception_date = forms.DateField( - label=_("Reception date"), initial=get_now, widget=DatePicker - ) - - 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 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 PersonOrgaForm(forms.Form): - PERSON_FIELD = "TO BE DEFINED" - PERSON_TYPE_PK = person_type_pk_lazy("general_contractor") - PERSON_LABEL = "" - ORGA_FIELD = "TO BE DEFINED" - ORGA_TYPE_PK = organization_type_pk_lazy("general_contractor") - ORGA_LABEL = "" - - def _media(self): - if self.status == "corporation": - return forms.Media(js=("js/JQueryCorporation.js",)) - - media = property(_media) - - def __init__(self, *args, **kwargs): - # get the status: natural person or corporation - DEFAULT_STATUS = "natural" - current_status = "" - if "data" in kwargs: - # the order is important: PERSON can have an ORGA - for field in [self.ORGA_FIELD, self.PERSON_FIELD]: - current_item_key = ( - (kwargs["prefix"] + "-") if kwargs.get("prefix") else "" - ) + field - if kwargs["data"] and kwargs["data"].get(current_item_key): - model = self.associated_models[field] - try: - model.objects.get(pk=kwargs["data"][current_item_key]) - current_status = ( - "natural" if field == self.PERSON_FIELD else "corporation" - ) - except (model.DoesNotExist, ValueError): - pass - initial = kwargs.get("initial", {}) - if not current_status: - # the order is important: PERSON can have an ORGA - for field in [self.ORGA_FIELD, self.PERSON_FIELD]: - value = initial.get(field) - model = self.associated_models[field] - try: - model.objects.get(pk=value) - current_status = ( - "natural" if field == self.PERSON_FIELD else "corporation" - ) - except (model.DoesNotExist, ValueError): - pass - - status = "" - if "status" in kwargs: - status = kwargs.pop("status") - if current_status != status: - if kwargs.get("data"): - # status is different from the existing - clear fields - kwargs.pop("data") - elif current_status: - status = current_status - else: - status = DEFAULT_STATUS - - self.status = status - - if status not in ("natural", "corporation"): - status = DEFAULT_STATUS - - super(PersonOrgaForm, self).__init__(*args, **kwargs) - - # distinct widget for natural and corporation - if status == "natural": - self.fields[self.PERSON_FIELD] = forms.IntegerField( - label=self.PERSON_LABEL, - required=False, - initial=initial.get(self.PERSON_FIELD, None), - widget=widgets.JQueryPersonOrganization( - reverse_lazy("autocomplete-person", args=[self.PERSON_TYPE_PK]), - reverse_lazy("person_create"), - model=Person, - limit={ - "person_types": [self.PERSON_TYPE_PK], - "attached_to__isnull": True, - }, - js_template="ishtar/blocks/JQueryNaturalPerson.js", - new=True, - ), - validators=[valid_id(Person)], - ) - else: - self.fields[self.ORGA_FIELD] = forms.IntegerField( - label=self.ORGA_LABEL, - required=False, - initial=initial.get(self.ORGA_FIELD, None), - widget=widgets.JQueryPersonOrganization( - reverse_lazy("autocomplete-organization", args=[self.ORGA_TYPE_PK]), - reverse_lazy("organization_create"), - model=models.Organization, - limit={"organization_type": [self.ORGA_TYPE_PK]}, - js_template="ishtar/blocks/JQueryCorporationPerson.js", - new=True, - ), - validators=[valid_id(models.Organization)], - ) - - -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 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 diff --git a/archaeological_files_pdl/urls.py b/archaeological_files_pdl/urls.py deleted file mode 100644 index 186135b93..000000000 --- a/archaeological_files_pdl/urls.py +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -# Copyright (C) 2014 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet> - -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. - -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. - -# See the file COPYING for details. - -from django.conf.urls import url - -from archaeological_files_pdl import views - -urlpatterns = [ - url( - r"file_creation/(?P<step>.+)?$", - views.file_creation_wizard, - name="file_creation", - ), - url( - r"file_modification/(?P<step>.+)?$", - views.file_modification_wizard, - name="file_modification", - ), - 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", - ), -] diff --git a/archaeological_files_pdl/views.py b/archaeological_files_pdl/views.py deleted file mode 100644 index 717f945cf..000000000 --- a/archaeological_files_pdl/views.py +++ /dev/null @@ -1,100 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -# Copyright (C) 2015 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet> - -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. - -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. - -# See the file COPYING for details. - -from ishtar_common.utils import ugettext_lazy as _ - -from archaeological_files_pdl.wizards import FileWizard, FileModificationWizard -from archaeological_operations.wizards import is_preventive, is_not_preventive - -from ishtar_common.views import OrganizationPersonCreate, OrganizationPersonEdit - -from archaeological_files_pdl import forms -from archaeological_files import forms as ref_forms - -from archaeological_files import models - - -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_wizard = FileWizard.as_view( - [ - ("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", ref_forms.FileFormResearch), - ("instruction-file_creation", forms.FileFormInstruction), - ("final-file_creation", ref_forms.FinalForm), - ], - label=_("New file"), - condition_dict={ - "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_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_wizard = FileModificationWizard.as_view( - [ - ("selec-file_modification", ref_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", ref_forms.FileFormResearch), - ("instruction-file_modification", forms.FileFormInstructionEdit), - ("final-file_modification", ref_forms.FinalForm), - ], - label=_("File modification"), - condition_dict={ - "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", -) - - -class TownPlanningEdit(OrganizationPersonEdit): - relative_label = _("File followed by") - - -class TownPlanningCreate(OrganizationPersonCreate): - relative_label = _("File followed by") diff --git a/archaeological_files_pdl/wizards.py b/archaeological_files_pdl/wizards.py deleted file mode 100644 index 211ea84f8..000000000 --- a/archaeological_files_pdl/wizards.py +++ /dev/null @@ -1,144 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# Copyright (C) 2014 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet> - -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. - -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. - -# See the file COPYING for details. - -from django.conf import settings - -from archaeological_files.wizards import FileWizard as BaseFileWizard -from archaeological_files import models - -from ishtar_common.utils import ugettext_lazy as _ - - -class FileWizard(BaseFileWizard): - parcel_step_key = "parcelspdl-" - town_step_keys = ["preventiveplanning-", "researchaddress-"] - town_input_id = "town" - towns_formset = False - multi_towns = True - wizard_templates = { - #'generalcontractor-%(url_name)s': - # 'ishtar/wizard/wizard_generalcontractor.html', - "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_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 self.steps.current.endswith("creation"): # creation only - parcels = [] - parcel_step_key = self.parcel_step_key + self.url_name - - parcel_numbers = ( - self.session_get_value(parcel_step_key, "parcel_number", multi=True) - or [] - ) - sections = ( - self.session_get_value(parcel_step_key, "section", multi=True) or [] - ) - towns = ( - self.session_get_value(parcel_step_key, "town", multi=True) or [] - ) - for idx, parcel_number in enumerate(parcel_numbers): - if not parcel_number or len(sections) <= idx or len(towns) <= idx: - continue - parcels.append( - { - "town": towns[idx], - "section": sections[idx], - "parcel_number": parcel_number, - } - ) - context["similar_files"] = models.File.similar_files(parcels) - else: # edition 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: - pass - - return context - - -class FileModificationWizard(FileWizard): - modification = True diff --git a/archaeological_operations/tests.py b/archaeological_operations/tests.py index 4adda7b19..148ef3ed1 100644 --- a/archaeological_operations/tests.py +++ b/archaeological_operations/tests.py @@ -3577,7 +3577,6 @@ class OperationWizardCreationTest(WizardTest, OperationInitTest, TestCase): self.form_datas[2].set("general", "operation_type", ope_type.pk) self.operation_number = models.Operation.objects.count() - self.parcel_number = models.Parcel.objects.count() super(OperationWizardCreationTest, self).pre_wizard() def post_wizard(self): diff --git a/example_project/settings.py b/example_project/settings.py index e09df3001..d0c7ab476 100644 --- a/example_project/settings.py +++ b/example_project/settings.py @@ -163,7 +163,6 @@ AUTHENTICATION_BACKENDS = ("ishtar_common.backend.ObjectPermBackend",) INSTALLED_APPS = [ "registration", "ishtar_common", - "archaeological_files_pdl", "archaeological_files", "archaeological_operations", "archaeological_context_records", @@ -238,7 +237,6 @@ LOGGING = { }, "ishtar_pdl": default_handler, "ishtar_common": default_handler, - "archaeological_files_pdl": default_handler, "archaeological_files": default_handler, "archaeological_operations": default_handler, "archaeological_context_records": default_handler, diff --git a/example_project/urls.py b/example_project/urls.py index 40e5c36db..9615afd5b 100644 --- a/example_project/urls.py +++ b/example_project/urls.py @@ -11,7 +11,7 @@ admin.autodiscover() urlpatterns = urlpatterns[:] -APP_LIST = ['archaeological_files_pdl', 'archaeological_files', +APP_LIST = ['archaeological_files', 'archaeological_operations', 'archaeological_context_records', 'archaeological_warehouse', 'archaeological_finds'] for app in APP_LIST: diff --git a/ishtar_common/admin.py b/ishtar_common/admin.py index 8e47b33b4..ee23a221e 100644 --- a/ishtar_common/admin.py +++ b/ishtar_common/admin.py @@ -74,7 +74,6 @@ from ishtar_common import forms as common_forms from ishtar_common.serializers import restore_serialized, IMPORT_MODEL_LIST from ishtar_common.serializers_utils import generic_get_results, serialization_info from archaeological_files import forms as file_forms -from archaeological_files_pdl import forms as file_pdl_forms from archaeological_operations import forms as operation_forms from archaeological_context_records import forms as context_record_forms from archaeological_finds import ( @@ -91,7 +90,6 @@ csrf_protect_m = method_decorator(csrf_protect) ISHTAR_FORMS = [ common_forms, - file_pdl_forms, file_forms, operation_forms, context_record_forms, diff --git a/ishtar_common/forms.py b/ishtar_common/forms.py index d15352e64..2e15e907c 100644 --- a/ishtar_common/forms.py +++ b/ishtar_common/forms.py @@ -273,8 +273,6 @@ class CustomForm(BSForm): :return: tuple of choices (id, value) """ app_name = cls.__module__.split(".")[0] - if app_name == "archaeological_files_pdl": - app_name = "archaeological_files" model_name = cls.form_slug.split("-")[0].replace("_", "") ct_class = apps.get_model(app_name, model_name) return ct_class._get_dynamic_choices(key) diff --git a/ishtar_common/models.py b/ishtar_common/models.py index 4ccc1cc0f..727d77fbc 100644 --- a/ishtar_common/models.py +++ b/ishtar_common/models.py @@ -1622,8 +1622,6 @@ class CustomForm(models.Model): for app_form in ISHTAR_FORMS: app_name = app_form.__package__ - if app_name == "archaeological_files_pdl": - app_name = "archaeological_files" for form in dir(app_form): if "Form" not in form and "Select" not in form: # not very clean... but do not treat inappropriate items @@ -1655,8 +1653,6 @@ class CustomForm(models.Model): return [] current_form = register[self.form] app_name = current_form.__module__.split(".")[0] - if app_name == "archaeological_files_pdl": - app_name = "archaeological_files" if app_name not in register_fields: return [] res = [] diff --git a/ishtar_common/tests.py b/ishtar_common/tests.py index f624314e0..d1e4c54b5 100644 --- a/ishtar_common/tests.py +++ b/ishtar_common/tests.py @@ -586,7 +586,7 @@ class WizardTest(object): response, "/{}/{}".format(self.url_uri, next_form), msg_prefix="Dataset n{} Redirection to {} has failed - " - "Error on previous form ({})?".format( + "Error on previous form ({})? Error on the wizard_name?\n".format( data_idx + 1, next_form, current_step ), ) @@ -595,7 +595,7 @@ class WizardTest(object): if not self.redirect_url: redirect_url = "/{}/done".format(self.url_uri) else: - dct = {"url_name": self.url_name, "url_uri": self.url_uri} + dct = {"url_name": self.url_name, "url_uri": self.url_uri, "last_id": 0} form_key = "selec-" + self.url_name if form_key in form_data and self.current_id_key in form_data[form_key]: dct["current_id"] = form_data[form_key][self.current_id_key] |