Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion docs/CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,26 @@ Changelog

.. towncrier release notes start

2.9.17 (2026-04-10)
-------------------

Bug fixes:


- Fix missing import
[jchandelle] (SUP-52327)


2.9.16 (2026-04-09)
-------------------

Bug fixes:


- Fix housing security and local role
[jchandelle] (URB-3573)


2.9.15 (2026-04-02)
-------------------

Expand Down Expand Up @@ -2062,4 +2082,4 @@ bugfixes:
- corrected template "accuse de reception d'une reclamation" (#5168, #5198).
- corrected the display of the specificFeatures for notary letters.
- The "50m area" used in inquiries doesnt crash anymore when finding parcel owner without address (#5376).
- Added warning on inquiry event when parcel owners without adress are found (#5289).
- Added warning on inquiry event when parcel owners without adress are found (#5289).
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import os


version = "2.9.16.dev0"
version = "2.9.18.dev0"

setup(
name="Products.urban",
Expand Down Expand Up @@ -113,4 +113,4 @@
"templates_per_site = Products.urban.templates:per_site",
],
},
)
)
4 changes: 3 additions & 1 deletion src/Products/urban/config.py
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ def section(self, section_name):
"ExplosivesPossession": "urban: Add ExplosivesPossession",
"Inspection": "urban: Add Inspection",
"RoadDecree": "urban: Add RoadDecree",
"Housing": "urban: Add Housing",
}

setDefaultRoles("urban: Add Applicant", ("Manager", "Contributor"))
Expand Down Expand Up @@ -186,6 +187,7 @@ def section(self, section_name):
setDefaultRoles("urban: Add UrbanVocabularyTerm", ("Manager", "Contributor"))
setDefaultRoles("urban: Add ExplosivesPossession", ("Manager", "Contributor"))
setDefaultRoles("urban: Add RoadDecree", ("Manager", "Contributor"))
setDefaultRoles("urban: Add Housing", ("Manager", "Contributor"))

product_globals = globals()

Expand Down Expand Up @@ -513,4 +515,4 @@ def registerClasses():
# Unregister the class
del Products.Archetypes.ATToolModule._types[key]
delattr(klass, "__ac_permissions__")
registerType(klass, PROJECTNAME)
registerType(klass, PROJECTNAME)
3 changes: 2 additions & 1 deletion src/Products/urban/docgen/helper_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from Products.urban.interfaces import IUrbanEventInquiry
from Products.urban.services import cadastre
from Products.urban.utils import get_ws_meetingitem_infos
from Products.urban.utils import get_ws_plonemeeting
from Products.urban.utils import getCurrentFolderManager
from collective.documentgenerator.helper.archetypes import ATDisplayProxyObject
from collective.documentgenerator.helper.archetypes import (
Expand Down Expand Up @@ -1473,4 +1474,4 @@ def format_date(self, folder, date=None, translatemonth=True, long_format=False)
class UrbanBaseProxyObject(ATDisplayProxyObject):
""" """

helper_view = None
helper_view = None
4 changes: 2 additions & 2 deletions src/Products/urban/interfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ class IInspection(IGenericLicence):

class IHousing(IGenericLicence):
"""
Marker interface for inspection
Marker interface for housing
"""


Expand Down Expand Up @@ -760,4 +760,4 @@ class IIntentionToSubmitAmendedPlans(Interface):


class IMissingCapakey(Interface):
""" """
""" """
11 changes: 11 additions & 0 deletions src/Products/urban/migration/update_290.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from Products.urban import UrbanMessage as _
from Products.urban.migration.utils import cook_javascript_resources
from Products.urban.utils import moveElementAfter
from Products.urban.setuphandlers import set_licence_folder_security
from dm.historical import getHistory
from imio.helpers.catalog import reindexIndexes
from plone import api
Expand Down Expand Up @@ -325,3 +326,13 @@ def setup_index_referenceFT(context):
reindexIndexes(None, ["referenceFT"])

logger.info("upgrade step done!")


def fix_housing_roaddecree(context):
logger = logging.getLogger("urban: Fix housing and roaddecree security")
setup_tool = api.portal.get_tool("portal_setup")
setup_tool.runImportStepFromProfile("profile-Products.urban:urbantypes", "factorytool")
portal_types = ["Housing", "RoadDecree"]
for portal_type in portal_types:
set_licence_folder_security(portal_type)
logger.info("upgrade step done!")
10 changes: 9 additions & 1 deletion src/Products/urban/migration/upgrades_290.zcml
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,12 @@
handler=".update_290.setup_index_referenceFT"
profile="Products.urban:default" />

</configure>
<gs:upgradeStep
title="Fix housing and roaddecree security"
description=""
source="2908"
destination="2909"
handler=".update_290.fix_housing_roaddecree"
profile="Products.urban:default" />

</configure>
5 changes: 3 additions & 2 deletions src/Products/urban/notice/parcel.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from Products.urban.notice.base import NoticeElement
from plone import api


class NoticeParcel(NoticeElement):
_excluded_keys = (
"parcel",
Expand Down Expand Up @@ -81,7 +82,7 @@ def resolved_division(self):
code = self._get_data("codeDivision")
if code:
return code
#do mapping
# do mapping
division_name = self.division_text
if not division_name:
return None
Expand All @@ -94,4 +95,4 @@ def resolved_division(self):
for div in divisions
if div.get("alternative_name") and div.get("division")
}
return mapping.get(division_name)
return mapping.get(division_name)
4 changes: 2 additions & 2 deletions src/Products/urban/profiles/default/metadata.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<metadata>
<version>2908</version>
<version>2909</version>
<dependencies>
<dependency>profile-Products.urban:preinstall</dependency>
</dependencies>
</metadata>
</metadata>
3 changes: 2 additions & 1 deletion src/Products/urban/profiles/urban_types/factorytool.xml
Original file line number Diff line number Diff line change
Expand Up @@ -71,5 +71,6 @@
<type portal_type="RoadDecree"/>
<type portal_type="Inspection"/>
<type portal_type="Ticket"/>
<type portal_type="Housing"/>
</factorytypes>
</object>
</object>
39 changes: 37 additions & 2 deletions src/Products/urban/setuphandlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -1862,7 +1862,8 @@ def check_if_type_already_install(urban_type):
def add_new_urban_licence_type(urban_type):
if check_if_type_already_install(urban_type):
return False
add_aplication_folder(urban_type)
licence_folder = add_aplication_folder(urban_type)
set_licence_folder_security(urban_type, licence_folder)
add_imio_dashboard(urban_type)
config_folder = add_urban_config_folder(urban_type)
add_schedule(config_folder, urban_type)
Expand Down Expand Up @@ -1940,6 +1941,40 @@ def add_aplication_folder(urban_type, urban_folder=None):
acquire=0,
)
urban_folder.moveObjectsToBottom([licence_folder_id])
return licence_folder

def set_licence_folder_security(urban_type, urban_folder=None):
if urban_folder is None:
site = api.portal.get()
urban_folder = getattr(site, "urban")
licencesfolder_names = getAllLicenceFolderIds()
urban_folder_names = getUrbanOnlyLicenceFolderIds()
uniquelicences_names = [
getLicenceFolderId("UniqueLicence"),
getLicenceFolderId("CODT_UniqueLicence"),
getLicenceFolderId("IntegratedLicence"),
getLicenceFolderId("CODT_IntegratedLicence"),
]
environment_folder_names = getEnvironmentLicenceFolderIds() + uniquelicences_names
try:
# we try in case we apply the profile again...
urban_folder.manage_addProperty(
"urbanConfigId", urban_type, "string"
)
except BadRequest:
pass
urban_folder.manage_delLocalRoles(["urban_editors"])
urban_folder.manage_delLocalRoles(["environment_editors"])
if getLicenceFolderId(urban_type) in urban_folder_names:
urban_folder.manage_addLocalRoles("urban_readers", ("Reader",))
if urban_type != "CODT_IntegratedLicence":
urban_folder.manage_addLocalRoles("urban_editors", ("Contributor",))
if getLicenceFolderId(urban_type) in environment_folder_names:
urban_folder.manage_addLocalRoles("environment_readers", ("Reader",))
if urban_type != "CODT_IntegratedLicence":
urban_folder.manage_addLocalRoles("environment_editors", ("Contributor",))
if urban_type == "Inspection":
urban_folder.manage_addLocalRoles("inspection_editors", ("Contributor",))


def add_imio_dashboard(urban_type, urban_folder=None):
Expand Down Expand Up @@ -2089,4 +2124,4 @@ def add_vocabularies(config_folder, urban_type):
for voc_folder_id in config_folder.objectIds():
if voc_folder_id in vocabularies_with_HTML_description:
voc_folder = getattr(config_folder, voc_folder_id)
setHTMLContentType(voc_folder, "description")
setHTMLContentType(voc_folder, "description")
9 changes: 8 additions & 1 deletion src/Products/urban/workflows/configure.zcml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@
name="ticket_local_roles"
/>

<adapter
for="Products.urban.interfaces.IHousing"
provides="borg.localrole.interfaces.ILocalRoleProvider"
factory=".housing_workflow.StateRolesMapping"
name="housing_local_roles"
/>

<adapter
for="Products.urban.interfaces.IUrbanEvent"
provides="borg.localrole.interfaces.ILocalRoleProvider"
Expand Down Expand Up @@ -80,4 +87,4 @@
factory=".suspension.SuspensionWorkflowAdaptation"
/>

</configure>
</configure>
66 changes: 66 additions & 0 deletions src/Products/urban/workflows/housing_workflow.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# -*- coding: utf-8 -*-

from Products.urban.workflows.licence_workflow import (
StateRolesMapping as BaseRoleMapping,
)


class StateRolesMapping(BaseRoleMapping):
""" """

mapping = {
"creation": {
BaseRoleMapping.get_readers: ("Reader",),
BaseRoleMapping.get_editors: (
"Editor",
"Reviewer",
"Contributor",
),
BaseRoleMapping.get_opinion_editors: ("Reviewer", "Contributor"),
},
"analysis": {
BaseRoleMapping.get_readers: ("Reader",),
BaseRoleMapping.get_editors: (
"Editor",
"Reviewer",
"Contributor",
),
BaseRoleMapping.get_opinion_editors: ("Reviewer", "Contributor"),
},
"1st_observation": {
BaseRoleMapping.get_readers: ("Reader",),
BaseRoleMapping.get_editors: (
"Editor",
"Reviewer",
"Contributor",
),
BaseRoleMapping.get_opinion_editors: ("Reviewer", "Contributor"),
},
"2nd_observation": {
BaseRoleMapping.get_readers: ("Reader",),
BaseRoleMapping.get_editors: (
"Editor",
"Reviewer",
"Contributor",
),
BaseRoleMapping.get_opinion_editors: ("Reviewer", "Contributor"),
},
"ended": {
BaseRoleMapping.get_readers: ("Reader",),
BaseRoleMapping.get_editors: (
"Editor",
"Reviewer",
"Contributor",
),
BaseRoleMapping.get_opinion_editors: ("Reviewer", "Contributor"),
},
"annual_observation": {
BaseRoleMapping.get_readers: ("Reader",),
BaseRoleMapping.get_editors: (
"Editor",
"Reviewer",
"Contributor",
),
BaseRoleMapping.get_opinion_editors: ("Reviewer", "Contributor"),
},
}