diff options
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]  | 
