From 4716b4938aa5914990591aad995594b651cf9ae8 Mon Sep 17 00:00:00 2001 From: Andrea Cecchi Date: Mon, 5 Sep 2022 11:29:29 +0200 Subject: [PATCH 001/487] remove dexteritytextindexer dependency --- CHANGES.rst | 4 +-- README.md | 4 +-- setup.py | 3 +-- src/design/plone/contenttypes/__init__.py | 2 +- .../adapters/searchabletext_indexers.py | 4 +-- .../behaviors/additional_help_infos.py | 4 +-- .../plone/contenttypes/behaviors/address.py | 8 +++--- .../plone/contenttypes/behaviors/argomenti.py | 4 +-- .../plone/contenttypes/behaviors/contatti.py | 10 +++---- .../behaviors/descrizione_estesa.py | 4 +-- .../plone/contenttypes/behaviors/evento.py | 4 +-- .../plone/contenttypes/behaviors/luogo.py | 4 +-- .../behaviors/news_additional_fields.py | 4 +-- .../contenttypes/indexers/pagina_argomento.py | 6 ++--- .../plone/contenttypes/interfaces/bando.py | 4 +-- .../interfaces/pagina_argomento.py | 6 ++--- .../plone/contenttypes/interfaces/persona.py | 16 ++++++------ .../plone/contenttypes/interfaces/servizio.py | 26 +++++++++---------- .../interfaces/unita_organizzativa.py | 10 +++---- .../profiles/default/metadata.xml | 2 +- .../profiles/default/types/Bando.xml | 2 +- .../profiles/default/types/Documento.xml | 2 +- .../profiles/default/types/Event.xml | 2 +- .../profiles/default/types/News_Item.xml | 2 +- .../default/types/Pagina_Argomento.xml | 2 +- .../profiles/default/types/Persona.xml | 2 +- .../profiles/default/types/Servizio.xml | 2 +- .../default/types/UnitaOrganizzativa.xml | 2 +- .../profiles/default/types/Venue.xml | 2 +- src/design/plone/contenttypes/testing.py | 3 --- .../contenttypes/tests/test_behavior_luogo.py | 4 +-- .../contenttypes/tests/test_ct_documento.py | 2 +- .../plone/contenttypes/tests/test_ct_event.py | 2 +- .../plone/contenttypes/tests/test_ct_luogo.py | 2 +- .../plone/contenttypes/tests/test_ct_news.py | 2 +- .../tests/test_ct_pagina_argomento.py | 2 +- .../contenttypes/tests/test_ct_persona.py | 2 +- .../contenttypes/tests/test_ct_servizio.py | 2 +- .../tests/test_ct_unita_organizzativa.py | 2 +- .../contenttypes/upgrades/configure.zcml | 10 +++++++ .../plone/contenttypes/upgrades/upgrades.py | 16 ++++++++++++ 41 files changed, 109 insertions(+), 87 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index ef5abedb..04c27343 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -5,8 +5,8 @@ Changelog 4.4.3 (unreleased) ------------------ -- Nothing changed yet. - +- Remove collective.dexteritytextindexer dependency (it's in core). + [cekk] 4.4.2 (2022-07-01) ------------------ diff --git a/README.md b/README.md index 76e274bf..0c0a1e08 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ - [Campi indicizzati nel SearchableText](#campi-indicizzati-nel-searchabletext-2) - [Servizio](#servizio) - [Campi indicizzati nel SearchableText](#campi-indicizzati-nel-searchabletext-3) - - [Unità Organizzativa](#unit%C3%A0-organizzativa) + - [Unità Organizzativa](#unità-organizzativa) - [Campi indicizzati nel SearchableText](#campi-indicizzati-nel-searchabletext-4) - [Pannello di controllo](#pannello-di-controllo) - [Gestione modulistica](#gestione-modulistica) @@ -267,7 +267,7 @@ Ha 3 campi file: uno per il modulo principale, e gli altri due per eventuali for Le pagine argomento hanno i blocchi. plone.restapi ha un indexer per _SearchableText_ per poter indicizzare i blocchi. -Questo va in conflitto con le personalizzazioni fatte con `collective.dexteritytextindexer` perché Plone prende come buono il primo +Questo va in conflitto con le personalizzazioni fatte con `plone.app.dexterity.textindexer` perché Plone prende come buono il primo adapter di SearchableText che trova. Per ovviare a questo problema, abbiamo messo la behavior "volto.blocks" come ultima, in modo che venisse ignorato il suo indexer, e poi abbiamo registrato un adapter per `IDynamicTextIndexExtender` per replicare l'indicizzazione dei blocchi anche per le pagine argomento. diff --git a/setup.py b/setup.py index 9bade866..5b751a92 100644 --- a/setup.py +++ b/setup.py @@ -56,8 +56,7 @@ # -*- Extra requirements: -*- "z3c.jbot", "plone.api>=1.8.4", - "plone.app.dexterity", - "collective.dexteritytextindexer", + "plone.app.dexterity>2.6.9", "collective.venue[geolocation]", "collective.volto.blocksfield", "plone.formwidget.geolocation", diff --git a/src/design/plone/contenttypes/__init__.py b/src/design/plone/contenttypes/__init__.py index fb1af71a..233bbeca 100644 --- a/src/design/plone/contenttypes/__init__.py +++ b/src/design/plone/contenttypes/__init__.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """Init and utils.""" from collective.address.behaviors import IAddress -from collective.dexteritytextindexer import utils +from plone.app.dexterity.textindexer import utils from zope.i18nmessageid import MessageFactory _ = MessageFactory("design.plone.contenttypes") diff --git a/src/design/plone/contenttypes/adapters/searchabletext_indexers.py b/src/design/plone/contenttypes/adapters/searchabletext_indexers.py index 7d124341..193d3df7 100644 --- a/src/design/plone/contenttypes/adapters/searchabletext_indexers.py +++ b/src/design/plone/contenttypes/adapters/searchabletext_indexers.py @@ -1,8 +1,8 @@ # -*- coding: utf-8 -*- -from collective.dexteritytextindexer.converters import ( +from plone.app.dexterity.textindexer.converters import ( DefaultDexterityTextIndexFieldConverter, ) -from collective.dexteritytextindexer.interfaces import IDexterityTextIndexFieldConverter +from plone.app.dexterity.textindexer.interfaces import IDexterityTextIndexFieldConverter from plone.dexterity.interfaces import IDexterityContent from plone.restapi.interfaces import IBlockSearchableText from z3c.form.interfaces import IWidget diff --git a/src/design/plone/contenttypes/behaviors/additional_help_infos.py b/src/design/plone/contenttypes/behaviors/additional_help_infos.py index 3e5af20c..143243e4 100644 --- a/src/design/plone/contenttypes/behaviors/additional_help_infos.py +++ b/src/design/plone/contenttypes/behaviors/additional_help_infos.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from collective import dexteritytextindexer +from plone.app.dexterity import textindexer from design.plone.contenttypes import _ from collective.volto.blocksfield.field import BlocksField from plone.autoform.interfaces import IFormFieldProvider @@ -29,7 +29,7 @@ class IAdditionalHelpInfos(model.Schema): fields=["ulteriori_informazioni"], ) - dexteritytextindexer.searchable("ulteriori_informazioni") + textindexer.searchable("ulteriori_informazioni") @implementer(IAdditionalHelpInfos) diff --git a/src/design/plone/contenttypes/behaviors/address.py b/src/design/plone/contenttypes/behaviors/address.py index 09ed1e3d..cab6c221 100644 --- a/src/design/plone/contenttypes/behaviors/address.py +++ b/src/design/plone/contenttypes/behaviors/address.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from collective import dexteritytextindexer +from plone.app.dexterity import textindexer from collective.address.behaviors import IAddress from plone.dexterity.interfaces import IDexterityContent from design.plone.contenttypes import _ @@ -21,7 +21,7 @@ class IAddressNomeSede(model.Schema): ), required=False, ) - dexteritytextindexer.searchable("nome_sede") + textindexer.searchable("nome_sede") class IAddressLocal(model.Schema): @@ -40,8 +40,8 @@ class IAddressLocal(model.Schema): ) # searchabletext indexer - dexteritytextindexer.searchable("quartiere") - dexteritytextindexer.searchable("circoscrizione") + textindexer.searchable("quartiere") + textindexer.searchable("circoscrizione") @provider(IFormFieldProvider) diff --git a/src/design/plone/contenttypes/behaviors/argomenti.py b/src/design/plone/contenttypes/behaviors/argomenti.py index eb058ee4..22a8fcca 100644 --- a/src/design/plone/contenttypes/behaviors/argomenti.py +++ b/src/design/plone/contenttypes/behaviors/argomenti.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from collective import dexteritytextindexer +from plone.app.dexterity import textindexer from design.plone.contenttypes import _ from design.plone.contenttypes.interfaces.bando import IBandoAgidSchema from design.plone.contenttypes.interfaces.documento import IDocumento @@ -62,7 +62,7 @@ class IArgomentiSchema(model.Schema): pattern_options={"maximumSelectionSize": 1}, ) - dexteritytextindexer.searchable("tassonomia_argomenti") + textindexer.searchable("tassonomia_argomenti") @provider(IFormFieldProvider) diff --git a/src/design/plone/contenttypes/behaviors/contatti.py b/src/design/plone/contenttypes/behaviors/contatti.py index b4b15a5e..7e5d13b9 100644 --- a/src/design/plone/contenttypes/behaviors/contatti.py +++ b/src/design/plone/contenttypes/behaviors/contatti.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from collective import dexteritytextindexer +from plone.app.dexterity import textindexer from collective.venue.interfaces import IVenue from design.plone.contenttypes import _ from collective.volto.blocksfield.field import BlocksField @@ -63,10 +63,10 @@ class IContatti(model.Schema): required=False, ) - dexteritytextindexer.searchable("orario_pubblico") - dexteritytextindexer.searchable("email") - dexteritytextindexer.searchable("pec") - dexteritytextindexer.searchable("web") + textindexer.searchable("orario_pubblico") + textindexer.searchable("email") + textindexer.searchable("pec") + textindexer.searchable("web") @provider(IFormFieldProvider) diff --git a/src/design/plone/contenttypes/behaviors/descrizione_estesa.py b/src/design/plone/contenttypes/behaviors/descrizione_estesa.py index 520cc235..b0d3d789 100644 --- a/src/design/plone/contenttypes/behaviors/descrizione_estesa.py +++ b/src/design/plone/contenttypes/behaviors/descrizione_estesa.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from collective import dexteritytextindexer +from plone.app.dexterity import textindexer from design.plone.contenttypes import _ from design.plone.contenttypes.interfaces.documento import IDocumento from collective.volto.blocksfield.field import BlocksField @@ -21,7 +21,7 @@ class IDescrizioneEstesaSchema(model.Schema): ), ) - dexteritytextindexer.searchable("descrizione_estesa") + textindexer.searchable("descrizione_estesa") @provider(IFormFieldProvider) diff --git a/src/design/plone/contenttypes/behaviors/evento.py b/src/design/plone/contenttypes/behaviors/evento.py index fbc7bf24..20ea7db3 100644 --- a/src/design/plone/contenttypes/behaviors/evento.py +++ b/src/design/plone/contenttypes/behaviors/evento.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from collective import dexteritytextindexer +from plone.app.dexterity import textindexer from design.plone.contenttypes import _ from collective.volto.blocksfield.field import BlocksField from plone.app.z3cform.widget import RelatedItemsFieldWidget @@ -230,7 +230,7 @@ class IEvento(model.Schema): fields=["patrocinato_da"], ) - dexteritytextindexer.searchable("descrizione_estesa") + textindexer.searchable("descrizione_estesa") @implementer(IEvento) diff --git a/src/design/plone/contenttypes/behaviors/luogo.py b/src/design/plone/contenttypes/behaviors/luogo.py index 8355a5f3..dea99b39 100644 --- a/src/design/plone/contenttypes/behaviors/luogo.py +++ b/src/design/plone/contenttypes/behaviors/luogo.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from collective import dexteritytextindexer +from plone.app.dexterity import textindexer from design.plone.contenttypes import _ from collective.volto.blocksfield.field import BlocksField from plone.app.z3cform.widget import RelatedItemsFieldWidget @@ -197,7 +197,7 @@ class ILuogo(model.Schema): ) # searchabletext indexer - dexteritytextindexer.searchable("descrizione_completa") + textindexer.searchable("descrizione_completa") @implementer(ILuogo) diff --git a/src/design/plone/contenttypes/behaviors/news_additional_fields.py b/src/design/plone/contenttypes/behaviors/news_additional_fields.py index 4bd2b8cd..113f959c 100644 --- a/src/design/plone/contenttypes/behaviors/news_additional_fields.py +++ b/src/design/plone/contenttypes/behaviors/news_additional_fields.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from collective import dexteritytextindexer +from plone.app.dexterity import textindexer from collective.volto.blocksfield.field import BlocksField from design.plone.contenttypes import _ from plone.app.z3cform.widget import RelatedItemsFieldWidget @@ -133,7 +133,7 @@ class INewsAdditionalFields(model.Schema): form.order_before(numero_progressivo_cs="ILeadImageBehavior.image") form.order_before(a_cura_di="ILeadImageBehavior.image") - dexteritytextindexer.searchable("descrizione_estesa") + textindexer.searchable("descrizione_estesa") @implementer(INewsAdditionalFields) diff --git a/src/design/plone/contenttypes/indexers/pagina_argomento.py b/src/design/plone/contenttypes/indexers/pagina_argomento.py index 526a80d3..839ad4a1 100644 --- a/src/design/plone/contenttypes/indexers/pagina_argomento.py +++ b/src/design/plone/contenttypes/indexers/pagina_argomento.py @@ -1,13 +1,13 @@ # -*- coding: utf-8 -*- -from collective import dexteritytextindexer from design.plone.contenttypes.interfaces.pagina_argomento import IPaginaArgomento +from plone.app.dexterity.textindexer.interfaces import IDynamicTextIndexExtender +from plone.restapi.indexers import SearchableText_blocks from zope.component import adapter from zope.interface import implementer -from plone.restapi.indexers import SearchableText_blocks @adapter(IPaginaArgomento) -@implementer(dexteritytextindexer.IDynamicTextIndexExtender) +@implementer(IDynamicTextIndexExtender) class SearchableTextExtender(object): def __init__(self, context): self.context = context diff --git a/src/design/plone/contenttypes/interfaces/bando.py b/src/design/plone/contenttypes/interfaces/bando.py index 47b18250..94e4c7bd 100644 --- a/src/design/plone/contenttypes/interfaces/bando.py +++ b/src/design/plone/contenttypes/interfaces/bando.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from collective import dexteritytextindexer +from plone.app.dexterity import textindexer from collective.volto.blocksfield.field import BlocksField from design.plone.contenttypes.interfaces import IDesignPloneContentType from plone.app.event.base import default_timezone @@ -172,4 +172,4 @@ class IBandoAgidSchema(IBandoSchema, IDesignPloneContentType): fields=["area_responsabile", "ufficio_responsabile"], ) - dexteritytextindexer.searchable("text") + textindexer.searchable("text") diff --git a/src/design/plone/contenttypes/interfaces/pagina_argomento.py b/src/design/plone/contenttypes/interfaces/pagina_argomento.py index 17df704a..3544f800 100644 --- a/src/design/plone/contenttypes/interfaces/pagina_argomento.py +++ b/src/design/plone/contenttypes/interfaces/pagina_argomento.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from collective import dexteritytextindexer +from plone.app.dexterity import textindexer from design.plone.contenttypes import _ from design.plone.contenttypes.interfaces import IDesignPloneContentType from plone.app.textfield import RichText @@ -72,5 +72,5 @@ class IPaginaArgomento(model.Schema, IDesignPloneContentType): ) # SearchableText fields - dexteritytextindexer.searchable("ulteriori_informazioni") - dexteritytextindexer.searchable("unita_amministrative_responsabili") + textindexer.searchable("ulteriori_informazioni") + textindexer.searchable("unita_amministrative_responsabili") diff --git a/src/design/plone/contenttypes/interfaces/persona.py b/src/design/plone/contenttypes/interfaces/persona.py index 9da18bd4..95f21df2 100644 --- a/src/design/plone/contenttypes/interfaces/persona.py +++ b/src/design/plone/contenttypes/interfaces/persona.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from collective import dexteritytextindexer +from plone.app.dexterity import textindexer from collective.volto.blocksfield.field import BlocksField from design.plone.contenttypes import _ from design.plone.contenttypes.interfaces import IDesignPloneContentType @@ -200,10 +200,10 @@ class IPersona(model.Schema, IDesignPloneContentType): fields=["curriculum_vitae", "atto_nomina"], ) # SearchableText fields - dexteritytextindexer.searchable("ruolo") - dexteritytextindexer.searchable("competenze") - dexteritytextindexer.searchable("deleghe") - dexteritytextindexer.searchable("tipologia_persona") - dexteritytextindexer.searchable("telefono") - dexteritytextindexer.searchable("fax") - dexteritytextindexer.searchable("email") + textindexer.searchable("ruolo") + textindexer.searchable("competenze") + textindexer.searchable("deleghe") + textindexer.searchable("tipologia_persona") + textindexer.searchable("telefono") + textindexer.searchable("fax") + textindexer.searchable("email") diff --git a/src/design/plone/contenttypes/interfaces/servizio.py b/src/design/plone/contenttypes/interfaces/servizio.py index 90b8994c..0b97721b 100644 --- a/src/design/plone/contenttypes/interfaces/servizio.py +++ b/src/design/plone/contenttypes/interfaces/servizio.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from collective import dexteritytextindexer +from plone.app.dexterity import textindexer from collective.volto.blocksfield.field import BlocksField from design.plone.contenttypes import _ from design.plone.contenttypes.interfaces import IDesignPloneContentType @@ -431,15 +431,15 @@ class IServizio(model.Schema, IDesignPloneContentType): ) # SearchableText fields - dexteritytextindexer.searchable("sottotitolo") - dexteritytextindexer.searchable("a_chi_si_rivolge") - dexteritytextindexer.searchable("chi_puo_presentare") - dexteritytextindexer.searchable("come_si_fa") - dexteritytextindexer.searchable("cosa_si_ottiene") - dexteritytextindexer.searchable("cosa_serve") - dexteritytextindexer.searchable("area") - dexteritytextindexer.searchable("ufficio_responsabile") - dexteritytextindexer.searchable("copertura_geografica") - dexteritytextindexer.searchable("costi") - dexteritytextindexer.searchable("servizi_collegati") - dexteritytextindexer.searchable("link_siti_esterni") + textindexer.searchable("sottotitolo") + textindexer.searchable("a_chi_si_rivolge") + textindexer.searchable("chi_puo_presentare") + textindexer.searchable("come_si_fa") + textindexer.searchable("cosa_si_ottiene") + textindexer.searchable("cosa_serve") + textindexer.searchable("area") + textindexer.searchable("ufficio_responsabile") + textindexer.searchable("copertura_geografica") + textindexer.searchable("costi") + textindexer.searchable("servizi_collegati") + textindexer.searchable("link_siti_esterni") diff --git a/src/design/plone/contenttypes/interfaces/unita_organizzativa.py b/src/design/plone/contenttypes/interfaces/unita_organizzativa.py index cff0166a..f184a052 100644 --- a/src/design/plone/contenttypes/interfaces/unita_organizzativa.py +++ b/src/design/plone/contenttypes/interfaces/unita_organizzativa.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from collective import dexteritytextindexer +from plone.app.dexterity import textindexer from collective.volto.blocksfield.field import BlocksField from design.plone.contenttypes import _ from design.plone.contenttypes.interfaces import IDesignPloneContentType @@ -230,7 +230,7 @@ class IUnitaOrganizzativa(model.Schema, IDesignPloneContentType): form.order_after(contact_info="sedi_secondarie") # SearchableText indexers - dexteritytextindexer.searchable("competenze") - dexteritytextindexer.searchable("tipologia_organizzazione") - dexteritytextindexer.searchable("assessore_riferimento") - dexteritytextindexer.searchable("responsabile") + textindexer.searchable("competenze") + textindexer.searchable("tipologia_organizzazione") + textindexer.searchable("assessore_riferimento") + textindexer.searchable("responsabile") diff --git a/src/design/plone/contenttypes/profiles/default/metadata.xml b/src/design/plone/contenttypes/profiles/default/metadata.xml index 37d1898d..8ed839e3 100644 --- a/src/design/plone/contenttypes/profiles/default/metadata.xml +++ b/src/design/plone/contenttypes/profiles/default/metadata.xml @@ -1,6 +1,6 @@ - 5310 + 6000 profile-redturtle.bandi:default profile-collective.venue:default diff --git a/src/design/plone/contenttypes/profiles/default/types/Bando.xml b/src/design/plone/contenttypes/profiles/default/types/Bando.xml index 35429720..9971c971 100644 --- a/src/design/plone/contenttypes/profiles/default/types/Bando.xml +++ b/src/design/plone/contenttypes/profiles/default/types/Bando.xml @@ -7,7 +7,7 @@ - + diff --git a/src/design/plone/contenttypes/profiles/default/types/Documento.xml b/src/design/plone/contenttypes/profiles/default/types/Documento.xml index e130d1d1..934e30bc 100644 --- a/src/design/plone/contenttypes/profiles/default/types/Documento.xml +++ b/src/design/plone/contenttypes/profiles/default/types/Documento.xml @@ -47,7 +47,7 @@ - + diff --git a/src/design/plone/contenttypes/profiles/default/types/Event.xml b/src/design/plone/contenttypes/profiles/default/types/Event.xml index e4c32f55..93b6e741 100644 --- a/src/design/plone/contenttypes/profiles/default/types/Event.xml +++ b/src/design/plone/contenttypes/profiles/default/types/Event.xml @@ -29,7 +29,7 @@ - + diff --git a/src/design/plone/contenttypes/profiles/default/types/News_Item.xml b/src/design/plone/contenttypes/profiles/default/types/News_Item.xml index efe97fb3..c5132466 100644 --- a/src/design/plone/contenttypes/profiles/default/types/News_Item.xml +++ b/src/design/plone/contenttypes/profiles/default/types/News_Item.xml @@ -12,7 +12,7 @@ - + diff --git a/src/design/plone/contenttypes/profiles/default/types/Pagina_Argomento.xml b/src/design/plone/contenttypes/profiles/default/types/Pagina_Argomento.xml index af230b8f..d3107e86 100644 --- a/src/design/plone/contenttypes/profiles/default/types/Pagina_Argomento.xml +++ b/src/design/plone/contenttypes/profiles/default/types/Pagina_Argomento.xml @@ -50,7 +50,7 @@ - + diff --git a/src/design/plone/contenttypes/profiles/default/types/Persona.xml b/src/design/plone/contenttypes/profiles/default/types/Persona.xml index fff2006a..bf2d0fb3 100644 --- a/src/design/plone/contenttypes/profiles/default/types/Persona.xml +++ b/src/design/plone/contenttypes/profiles/default/types/Persona.xml @@ -49,7 +49,7 @@ - + diff --git a/src/design/plone/contenttypes/profiles/default/types/Servizio.xml b/src/design/plone/contenttypes/profiles/default/types/Servizio.xml index 1c3858fa..118f1ad7 100644 --- a/src/design/plone/contenttypes/profiles/default/types/Servizio.xml +++ b/src/design/plone/contenttypes/profiles/default/types/Servizio.xml @@ -50,7 +50,7 @@ - + diff --git a/src/design/plone/contenttypes/profiles/default/types/UnitaOrganizzativa.xml b/src/design/plone/contenttypes/profiles/default/types/UnitaOrganizzativa.xml index 9db895b2..bb5582e7 100644 --- a/src/design/plone/contenttypes/profiles/default/types/UnitaOrganizzativa.xml +++ b/src/design/plone/contenttypes/profiles/default/types/UnitaOrganizzativa.xml @@ -51,7 +51,7 @@ - + diff --git a/src/design/plone/contenttypes/profiles/default/types/Venue.xml b/src/design/plone/contenttypes/profiles/default/types/Venue.xml index d6fce8c8..7cd76eaa 100644 --- a/src/design/plone/contenttypes/profiles/default/types/Venue.xml +++ b/src/design/plone/contenttypes/profiles/default/types/Venue.xml @@ -24,7 +24,7 @@ - + diff --git a/src/design/plone/contenttypes/testing.py b/src/design/plone/contenttypes/testing.py index 207e2f5a..2e5669e9 100644 --- a/src/design/plone/contenttypes/testing.py +++ b/src/design/plone/contenttypes/testing.py @@ -9,7 +9,6 @@ import collective.address -import collective.dexteritytextindexer import collective.folderishtypes import collective.venue import collective.volto.blocksfield @@ -29,7 +28,6 @@ def setUpZope(self, app, configurationContext): # The z3c.autoinclude feature is disabled in the Plone fixture base # layer. super().setUpZope(app, configurationContext) - self.loadZCML(package=collective.dexteritytextindexer) self.loadZCML(package=collective.venue) self.loadZCML(package=collective.volto.blocksfield) self.loadZCML(package=design.plone.contenttypes, context=configurationContext) @@ -66,7 +64,6 @@ def setUpPloneSite(self, portal): class DesignPloneContenttypesRestApiLayer(RedturtleVoltoRestApiLayer): def setUpZope(self, app, configurationContext): super().setUpZope(app, configurationContext) - self.loadZCML(package=collective.dexteritytextindexer) self.loadZCML(package=collective.venue) self.loadZCML(package=collective.volto.blocksfield) self.loadZCML(package=design.plone.contenttypes, context=configurationContext) diff --git a/src/design/plone/contenttypes/tests/test_behavior_luogo.py b/src/design/plone/contenttypes/tests/test_behavior_luogo.py index 579df13a..5942c631 100644 --- a/src/design/plone/contenttypes/tests/test_behavior_luogo.py +++ b/src/design/plone/contenttypes/tests/test_behavior_luogo.py @@ -34,7 +34,7 @@ def setUp(self): "volto.preview_image", "collective.address.behaviors.IAddress", "design.plone.contenttypes.behavior.luogo", - "collective.dexteritytextindexer", + "plone.textindexer", ) self.fti = fti @@ -44,7 +44,7 @@ def setUp(self): def test_luogo_behavior_fields_inexed_for_venue(self): # Non sembra deterministico il testing delle cose indicizzate con - # collective.dexteritytextindexer. Per ora togliamo. Poi se capiamo + # plone.textindexer. Per ora togliamo. Poi se capiamo # come gestire lo rimetteremo. return self.assertTrue(True) diff --git a/src/design/plone/contenttypes/tests/test_ct_documento.py b/src/design/plone/contenttypes/tests/test_ct_documento.py index e1054fe5..3d254e71 100644 --- a/src/design/plone/contenttypes/tests/test_ct_documento.py +++ b/src/design/plone/contenttypes/tests/test_ct_documento.py @@ -42,7 +42,7 @@ def test_behaviors_enabled_for_documento(self): "design.plone.contenttypes.behavior.argomenti_documento", "design.plone.contenttypes.behavior.descrizione_estesa_documento", # noqa "design.plone.contenttypes.behavior.additional_help_infos", - "collective.dexteritytextindexer", + "plone.textindexer", "plone.translatable", "kitconcept.seo", "plone.versioning", diff --git a/src/design/plone/contenttypes/tests/test_ct_event.py b/src/design/plone/contenttypes/tests/test_ct_event.py index 1b031cc7..57b79ba2 100644 --- a/src/design/plone/contenttypes/tests/test_ct_event.py +++ b/src/design/plone/contenttypes/tests/test_ct_event.py @@ -48,7 +48,7 @@ def test_behaviors_enabled_for_event(self): "plone.versioning", "plone.locking", "plone.constraintypes", - "collective.dexteritytextindexer", + "plone.textindexer", "plone.translatable", "kitconcept.seo", ), diff --git a/src/design/plone/contenttypes/tests/test_ct_luogo.py b/src/design/plone/contenttypes/tests/test_ct_luogo.py index 62bf1e3e..39552d0c 100644 --- a/src/design/plone/contenttypes/tests/test_ct_luogo.py +++ b/src/design/plone/contenttypes/tests/test_ct_luogo.py @@ -44,7 +44,7 @@ def test_behaviors_enabled_for_luogo(self): "design.plone.contenttypes.behavior.address_venue", "design.plone.contenttypes.behavior.geolocation_venue", "design.plone.contenttypes.behavior.additional_help_infos", - "collective.dexteritytextindexer", + "plone.textindexer", "plone.translatable", "kitconcept.seo", "plone.versioning", diff --git a/src/design/plone/contenttypes/tests/test_ct_news.py b/src/design/plone/contenttypes/tests/test_ct_news.py index ba607d4b..067fbffc 100644 --- a/src/design/plone/contenttypes/tests/test_ct_news.py +++ b/src/design/plone/contenttypes/tests/test_ct_news.py @@ -44,7 +44,7 @@ def test_behaviors_enabled_for_news(self): "design.plone.contenttypes.behavior.news", "design.plone.contenttypes.behavior.argomenti", "plone.constraintypes", - "collective.dexteritytextindexer", + "plone.textindexer", "plone.translatable", "kitconcept.seo", ), diff --git a/src/design/plone/contenttypes/tests/test_ct_pagina_argomento.py b/src/design/plone/contenttypes/tests/test_ct_pagina_argomento.py index 8a03bdaf..155f4ea5 100644 --- a/src/design/plone/contenttypes/tests/test_ct_pagina_argomento.py +++ b/src/design/plone/contenttypes/tests/test_ct_pagina_argomento.py @@ -31,7 +31,7 @@ def test_behaviors_enabled_for_pagina_argomento(self): "plone.locking", "plone.leadimage", "volto.preview_image", - "collective.dexteritytextindexer", + "plone.textindexer", "volto.blocks", "plone.translatable", "kitconcept.seo", diff --git a/src/design/plone/contenttypes/tests/test_ct_persona.py b/src/design/plone/contenttypes/tests/test_ct_persona.py index 0315898a..88e5fb9d 100644 --- a/src/design/plone/contenttypes/tests/test_ct_persona.py +++ b/src/design/plone/contenttypes/tests/test_ct_persona.py @@ -44,7 +44,7 @@ def test_behaviors_enabled_for_persona(self): "plone.basic", "plone.locking", "design.plone.contenttypes.behavior.additional_help_infos", - "collective.dexteritytextindexer", + "plone.textindexer", "plone.translatable", "kitconcept.seo", "plone.versioning", diff --git a/src/design/plone/contenttypes/tests/test_ct_servizio.py b/src/design/plone/contenttypes/tests/test_ct_servizio.py index 1abcc2c8..e9a31b0f 100644 --- a/src/design/plone/contenttypes/tests/test_ct_servizio.py +++ b/src/design/plone/contenttypes/tests/test_ct_servizio.py @@ -71,7 +71,7 @@ def test_behaviors_enabled_for_servizio(self): "plone.relateditems", "design.plone.contenttypes.behavior.argomenti", "design.plone.contenttypes.behavior.additional_help_infos", - "collective.dexteritytextindexer", + "plone.textindexer", "plone.translatable", "kitconcept.seo", "plone.versioning", diff --git a/src/design/plone/contenttypes/tests/test_ct_unita_organizzativa.py b/src/design/plone/contenttypes/tests/test_ct_unita_organizzativa.py index 4da712c8..11bbbbef 100644 --- a/src/design/plone/contenttypes/tests/test_ct_unita_organizzativa.py +++ b/src/design/plone/contenttypes/tests/test_ct_unita_organizzativa.py @@ -112,7 +112,7 @@ def test_behaviors_enabled_for_uo(self): "design.plone.contenttypes.behavior.geolocation_uo", "design.plone.contenttypes.behavior.contatti_uo", "design.plone.contenttypes.behavior.argomenti", - "collective.dexteritytextindexer", + "plone.textindexer", "design.plone.contenttypes.behavior.additional_help_infos", "plone.translatable", "kitconcept.seo", diff --git a/src/design/plone/contenttypes/upgrades/configure.zcml b/src/design/plone/contenttypes/upgrades/configure.zcml index 995f0370..b3ef4735 100644 --- a/src/design/plone/contenttypes/upgrades/configure.zcml +++ b/src/design/plone/contenttypes/upgrades/configure.zcml @@ -551,4 +551,14 @@ handler=".upgrades.to_5310" /> + + + diff --git a/src/design/plone/contenttypes/upgrades/upgrades.py b/src/design/plone/contenttypes/upgrades/upgrades.py index beb2eb03..b7dd9cde 100644 --- a/src/design/plone/contenttypes/upgrades/upgrades.py +++ b/src/design/plone/contenttypes/upgrades/upgrades.py @@ -925,3 +925,19 @@ def to_5310(context): if i % 500 == 0: logger.info("Progress: {}/{}".format(i, tot)) brain.getObject().reindexObject(idxs=["SearchableText"]) + + +def to_6000(context): + """ """ + logger.info( + "Convert behavior: collective.dexteritytextindexer => plone.textindexer" + ) + portal_types = api.portal.get_tool(name="portal_types") + for fti in portal_types.values(): + behaviors = [] + for behavior in getattr(fti, "behaviors", ()): + if behavior == "collective.dexteritytextindexer": + behavior = "plone.textindexer" + behaviors.append(behavior) + + fti.behaviors = tuple(behaviors) From a56b88498a99c5215469a3532b9fd61f42c80980 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Mon, 12 Dec 2022 18:27:32 +0100 Subject: [PATCH 002/487] [fix] fixed taxonomies + fix upgrade step --- .gitignore | 1 + README.md | 1 - .../contenttypes/controlpanels/settings.py | 52 ++++--------------- .../plone/contenttypes/interfaces/persona.py | 13 ----- .../plone/contenttypes/upgrades/upgrades.py | 13 +++-- .../all_life_events_vocabulary.py | 44 +++++++--------- .../controlapanel_vocabularies.py | 12 ----- 7 files changed, 39 insertions(+), 97 deletions(-) diff --git a/.gitignore b/.gitignore index 6c9c2ba5..15f86be8 100644 --- a/.gitignore +++ b/.gitignore @@ -30,6 +30,7 @@ log.html output.xml pip-selfcheck.json report.html +.idea/ .vscode/ .tox/ reports/ diff --git a/README.md b/README.md index 76e274bf..20a7ad01 100644 --- a/README.md +++ b/README.md @@ -309,7 +309,6 @@ Alla creazione di una Persona, viene creata anche una struttura predefinita per - ruolo - competenze - deleghe -- tipologia_persona - telefono - email - informazioni_di_contatto diff --git a/src/design/plone/contenttypes/controlpanels/settings.py b/src/design/plone/contenttypes/controlpanels/settings.py index 352509ed..fe84d58b 100644 --- a/src/design/plone/contenttypes/controlpanels/settings.py +++ b/src/design/plone/contenttypes/controlpanels/settings.py @@ -23,7 +23,7 @@ class IDesignPloneSettings(Interface): " a seconda delle lingue del sito.", ), required=True, - default=json.dumps({"it": ["Avviso", "Comunicato stampa", "Novità"]}), + default=json.dumps({"it": ["Avviso", "Comunicato (stampa)", "Notizia"]}), ) tipologie_unita_organizzativa = SourceText( @@ -53,50 +53,16 @@ class IDesignPloneSettings(Interface): default=json.dumps( { "it": [ - "Accordi tra enti", - "Atti normativi", + "Accordo tra enti", + "Atto normativo", "Dataset", - "Documenti (tecnici) di supporto", - "Documenti albo pretorio", - "Documenti attività politica", - "Documenti funzionamento interno", - "Istanze", + "Documento (tecnico) di supporto", + "Documento albo pretorio", + "Documento attività politica", + "Documento funzionamento interno", + "Istanza", "Modulistica", - ] - } - ), - ) - - tipologie_persona = SourceText( - title=_("tipologie_persona_label", default="Tipologie Persona"), - description=_( - "tipologie_persona_help", - default="Inserisci i valori utilizzabili per le tipologie di " - "una Persona. Se il sito è multilingua, puoi inserire " - "valori diversi a seconda delle lingue del sito.", - ), - required=True, - default=json.dumps({"it": ["Amministrativa", "Politica", "Altro tipo"]}), - ) - - ruoli_persona = SourceText( - title=_("ruoli_persona_label", default="Ruoli Persona"), - description=_( - "ruoli_persona_help", - default="Inserisci i valori utilizzabili per il ruolo di " - "una Persona. Se il sito è multilingua, puoi inserire " - "valori diversi a seconda delle lingue del sito.", - ), - required=True, - default=json.dumps( - { - "it": [ - "Assessore", - "Sindaco", - "Consigliere", - "Referente ufficio", - "Responsabile", - "Presidente", + "Documento di programmazione e rendicontazione", ] } ), diff --git a/src/design/plone/contenttypes/interfaces/persona.py b/src/design/plone/contenttypes/interfaces/persona.py index 9da18bd4..a98f22ca 100644 --- a/src/design/plone/contenttypes/interfaces/persona.py +++ b/src/design/plone/contenttypes/interfaces/persona.py @@ -81,17 +81,6 @@ class IPersona(model.Schema, IDesignPloneContentType): required=False, ) - tipologia_persona = schema.Choice( - title=_("tipologia_persona_label", default="Tipologia persona"), - description=_( - "tipologia_persona_help", - default="Seleziona la tipologia di persona: politica," - " amministrativa o di altro tipo.", - ), - vocabulary="design.plone.contenttypes.TipologiaPersona", - required=True, - ) - data_insediamento = schema.Date( title=_("data_insediamento_label", default="Data insediamento"), description=_( @@ -184,7 +173,6 @@ class IPersona(model.Schema, IDesignPloneContentType): "data_conclusione_incarico", "competenze", "deleghe", - "tipologia_persona", "data_insediamento", "biografia", ], @@ -203,7 +191,6 @@ class IPersona(model.Schema, IDesignPloneContentType): dexteritytextindexer.searchable("ruolo") dexteritytextindexer.searchable("competenze") dexteritytextindexer.searchable("deleghe") - dexteritytextindexer.searchable("tipologia_persona") dexteritytextindexer.searchable("telefono") dexteritytextindexer.searchable("fax") dexteritytextindexer.searchable("email") diff --git a/src/design/plone/contenttypes/upgrades/upgrades.py b/src/design/plone/contenttypes/upgrades/upgrades.py index e39bc127..04729c41 100644 --- a/src/design/plone/contenttypes/upgrades/upgrades.py +++ b/src/design/plone/contenttypes/upgrades/upgrades.py @@ -410,7 +410,7 @@ def to_2002(context): fixed_total = 0 for brain in api.content.find(portal_type="Persona"): item = brain.getObject() - if item.tipologia_persona in type_mapping: + if hasattr(item, "tipologia_persona") and item.tipologia_persona in type_mapping: # noqa item.tipologia_persona = type_mapping[item.tipologia_persona] fixed_total += 1 commit() @@ -751,9 +751,14 @@ def to_4000(context): if ruolo not in ruoli[lang]: ruoli[lang].append(ruolo) - api.portal.set_registry_record( - "ruoli_persona", json.dumps(ruoli), interface=IDesignPloneSettings - ) + if api.portal.get_registry_record( + "ruoli_persona", + interface=IDesignPloneSettings, + default=None + ): + api.portal.set_registry_record( + "ruoli_persona", json.dumps(ruoli), interface=IDesignPloneSettings + ) def to_4100(context): diff --git a/src/design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py b/src/design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py index da62ce23..b0f9e2f4 100644 --- a/src/design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py +++ b/src/design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py @@ -23,7 +23,7 @@ def __call__(self, context): items = [ ( "L1.0", - _("Iscrizione scuola/università e/o richiesta borsa di studio"), + _("Iscrizione Scuola/Università e/o richiesta borsa di studio"), # noqa ), ("L2.0", _("Invalidità")), ( @@ -37,13 +37,13 @@ def __call__(self, context): ( "L8.0", _( - "Compravendita/affitto casa/edifici/terreni, costruzione o ristrutturazione casa/edificio " + "Compravendita/affitto casa/edifici/terreni, costruzione o ristrutturazione casa/edificio" # noqa ), ), ("L9.0", _("Cambio di residenza/domicilio")), ( "L11.0", - _("Richiesta passaporto, visto e assistenza viaggi internazionali"), + _("Richiesta passaporto, visto e assistenza viaggi internazionali"), # noqa ), ("L12.0", _("Nascita di un bambino, richiesta adozioni")), ("L13.0", _("Matrimonio e/o cambio stato civile")), @@ -53,32 +53,28 @@ def __call__(self, context): ( "L17.0", _( - "Dichiarazione dei redditi, versamento e riscossione tributi/imposte e contributi" + "Dichiarazione dei redditi, versamento e riscossione tributi/imposte e contributi" # noqa ), ), ("L18.0", _("Accesso luoghi della cultura")), ("L19.0", _("Possesso, cura, smarrimento animale da compagnia")), + ("B1.0", _("Avvio impresa")), + ("B2.0", _("Avvio nuova attività professionale")), + ("B3.0", _("Richiesta licenze, permessi e certificati")), + ("B4.0", _("Registrazione impresa transfrontaliera")), + ("B5.0", _("Avvio e registrazione filiale")), + ("B6.0", _("Finanziamento impresa")), + ("B7.0", _("Gestione personale")), + ("B8.0", _("Pagamento tasse, iva e dogane")), + ("B9.0", _("Notifiche autorità")), + ("B10.0", _("Chiusura impresa e attività professionale")), + ("B11.0", _("Chiusura filiale")), + ("B12.0", _("Ristrutturazione impresa")), + ("B13.0", _("Vendita impresa")), + ("B14.0", _("Bancarotta")), ( - "B1.0", - _("Iscrizione scuola/università e/o richiesta borsa di studio"), - ), - ("B2.0", _("Avvio impresa")), - ("B3.0", _("Avvio nuova attività professionale")), - ("B4.0", _("Richiesta licenze/permessi/certificati")), - ("B5.0", _("Registrazione impresa transfrontalier")), - ("B6.0", _("Avvio/registrazione filiale")), - ("B7.0", _("Finanziamento impresa")), - ("B8.0", _("Gestione personale")), - ("B9.0", _("Pagamento tasse, iva e dogane")), - ("B10.0", _("Notifiche autorità")), - ("B11.0", _("Chiusura impresa e attività professionale")), - ("B12.0", _("Chiusura filiale")), - ("B13.0", _("Ristrutturazione impresa")), - ("B14.0", _("Vendita impresa")), - ("B15.0", _("Bancarotta")), - ( - "B16.0", - _("Partecipazione ad appalti pubblici nazionali e trasfrontalieri"), + "B15.0", + _("Partecipazione ad appalti pubblici nazionali e trasfrontalieri"), # noqa ), ] req = getRequest() diff --git a/src/design/plone/contenttypes/vocabularies/controlapanel_vocabularies.py b/src/design/plone/contenttypes/vocabularies/controlapanel_vocabularies.py index c2f172a8..1e84bbfe 100644 --- a/src/design/plone/contenttypes/vocabularies/controlapanel_vocabularies.py +++ b/src/design/plone/contenttypes/vocabularies/controlapanel_vocabularies.py @@ -44,16 +44,6 @@ class TipologieDocumento(BaseVocabulary): field = "tipologie_documento" -@implementer(IVocabularyFactory) -class TipologiePersona(BaseVocabulary): - field = "tipologie_persona" - - -@implementer(IVocabularyFactory) -class RuoliPersona(BaseVocabulary): - field = "ruoli_persona" - - @implementer(IVocabularyFactory) class LeadImageDimension(BaseVocabulary): field = "lead_image_dimension" @@ -76,6 +66,4 @@ def __call__(self, context): LeadImageDimensionFactory = LeadImageDimension() TipologieNotiziaFactory = TipologieNotizia() TipologieDocumentoFactory = TipologieDocumento() -TipologiePersonaFactory = TipologiePersona() -RuoliPersonaFactory = RuoliPersona() TipologieUnitaOrganizzativaVocabularyFactory = TipologieUnitaOrganizzativaVocabulary() From d0fa0429a97c28f891c6511e6605954fd214ab83 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Tue, 13 Dec 2022 16:47:22 +0100 Subject: [PATCH 003/487] [fix] fix taxonomies --- README.md | 1 - .../contenttypes/indexers/configure.zcml | 8 -- .../plone/contenttypes/indexers/metadata.py | 9 -- .../plone/contenttypes/indexers/persona.py | 5 - .../plone/contenttypes/interfaces/persona.py | 11 -- .../contenttypes/profiles/default/catalog.xml | 6 +- .../profiles/default/registry/criteria.xml | 14 --- .../restapi/services/types/get.py | 1 - .../plone/contenttypes/upgrades/upgrades.py | 2 +- .../contenttypes/vocabularies/dataset.py | 5 +- .../vocabularies/tags_vocabulary.py | 101 ++++++++++++------ 11 files changed, 72 insertions(+), 91 deletions(-) delete mode 100644 src/design/plone/contenttypes/indexers/metadata.py diff --git a/README.md b/README.md index 20a7ad01..5c5124cb 100644 --- a/README.md +++ b/README.md @@ -306,7 +306,6 @@ Alla creazione di una Persona, viene creata anche una struttura predefinita per ### Campi indicizzati nel SearchableText -- ruolo - competenze - deleghe - telefono diff --git a/src/design/plone/contenttypes/indexers/configure.zcml b/src/design/plone/contenttypes/indexers/configure.zcml index 720f52fb..c55a6392 100644 --- a/src/design/plone/contenttypes/indexers/configure.zcml +++ b/src/design/plone/contenttypes/indexers/configure.zcml @@ -52,14 +52,6 @@ factory=".uo.uo_location" name="uo_location" /> - - - - - - + @@ -42,9 +42,6 @@ - - - @@ -56,7 +53,6 @@ - diff --git a/src/design/plone/contenttypes/profiles/default/registry/criteria.xml b/src/design/plone/contenttypes/profiles/default/registry/criteria.xml index 41575193..ddcca239 100644 --- a/src/design/plone/contenttypes/profiles/default/registry/criteria.xml +++ b/src/design/plone/contenttypes/profiles/default/registry/criteria.xml @@ -83,20 +83,6 @@ Bando - - Ruolo - Ruolo - True - False - - plone.app.querystring.operation.selection.any - plone.app.querystring.operation.selection.all - - design.plone.contenttypes.RuoliPersona - Metadata - - Data conclusione incarico diff --git a/src/design/plone/contenttypes/restapi/services/types/get.py b/src/design/plone/contenttypes/restapi/services/types/get.py index 99207c61..c1038049 100644 --- a/src/design/plone/contenttypes/restapi/services/types/get.py +++ b/src/design/plone/contenttypes/restapi/services/types/get.py @@ -79,7 +79,6 @@ class FieldsetsMismatchError(Exception): ], "Persona": [ "default", - "ruolo", "contatti", "documenti", "informazioni", diff --git a/src/design/plone/contenttypes/upgrades/upgrades.py b/src/design/plone/contenttypes/upgrades/upgrades.py index 04729c41..7673392c 100644 --- a/src/design/plone/contenttypes/upgrades/upgrades.py +++ b/src/design/plone/contenttypes/upgrades/upgrades.py @@ -780,7 +780,7 @@ def to_4200(context): brains = api.content.find(portal_type="Persona") for brain in brains: persona = brain.getObject() - persona.reindexObject(idxs=["ruolo", "data_conclusione_incarico"]) + persona.reindexObject(idxs=["data_conclusione_incarico"]) def to_5000(context): diff --git a/src/design/plone/contenttypes/vocabularies/dataset.py b/src/design/plone/contenttypes/vocabularies/dataset.py index 74317004..e3a83e6e 100644 --- a/src/design/plone/contenttypes/vocabularies/dataset.py +++ b/src/design/plone/contenttypes/vocabularies/dataset.py @@ -34,16 +34,17 @@ def __call__(self, context): ), VocabItem("energia", _("Energia")), VocabItem("ambiente", _("Ambiente")), - VocabItem("governo_e_settore_pubblico", _("Governo e settore pubblico")), + VocabItem("governo_e_settore_pubblico", _("Governo e settore pubblico")), # noqa VocabItem("salute", _("Salute")), VocabItem("tematiche_internazionali", _("Tematiche internazionali")), VocabItem( "giustizia_sistema_giuridico_e_sicurezza_pubblica", _("Giustizia, sistema giuridico e sicurezza pubblica"), ), - VocabItem("regioni_e_citta", _("Regioni e città")), VocabItem("popolazione_e_societa", _("Popolazione e società")), + VocabItem("regioni_e_citta", _("Regioni e città")), VocabItem("scienza_e_tecnologia", _("Scienza e tecnologia")), + VocabItem("trasporti", _("Trasporti")), ] if not IDexterityContent.providedBy(context): diff --git a/src/design/plone/contenttypes/vocabularies/tags_vocabulary.py b/src/design/plone/contenttypes/vocabularies/tags_vocabulary.py index 1978c145..a4be0110 100644 --- a/src/design/plone/contenttypes/vocabularies/tags_vocabulary.py +++ b/src/design/plone/contenttypes/vocabularies/tags_vocabulary.py @@ -22,47 +22,80 @@ def __call__(self, context): # Just an example list of content for our vocabulary, # this can be any static or dynamic data, a catalog result for example. items = [ - VocabItem("anziano", _("Anziano")), - VocabItem("fanciullo", _("Fanciullo")), - VocabItem("giovane", _("Giovane")), - VocabItem("famiglia", _("Famiglia")), - VocabItem("studente", _("Studente")), - VocabItem("associazione", _("Associazione")), - VocabItem("istruzione", _("Istruzione")), - VocabItem("abitazione", _("Abitazione")), - VocabItem("animale-domestico", _("Animale domestico")), - VocabItem("integrazione-sociale", _("Integrazione sociale")), - VocabItem("protezione-sociale", _("Protezione sociale")), - VocabItem("comunicazione", _("Comunicazione")), - VocabItem("urbanistica-edilizia", _("Urbanistica ed edilizia")), - VocabItem("formazione-professionale", _("Formazione professionale")), VocabItem( - "condizioni-organizzazione-lavoro", - _("Condizioni e organizzazione del lavoro"), + "accesso_all_informazione", + _("Accesso all'informazione") ), - VocabItem("trasporto", _("Trasporto")), - VocabItem("matrimonio", _("Matrimonio")), - VocabItem("elezione", _("Elezione")), - VocabItem("tempo-libero", _("Tempo libero")), - VocabItem("cultura", _("Cultura")), + VocabItem("acqua", _("Acqua")), + VocabItem("agricoltura", _("Agricoltura")), + VocabItem("animale_domestico", _("Animale domestico")), + VocabItem("aria", _("Aria")), + VocabItem( + "assistenza_agli_anziani", _("Assistenza agli invalidi") + ), + VocabItem("assistenza_sociale", _("Assistenza sociale")), + VocabItem("associazioni", _("Associazioni")), + VocabItem("bilancio", _("Bilancio")), + VocabItem("commercio_all_ingresso", _("Commercio all'ingrosso")), + VocabItem("commercio_al_minuto", _("Commercio al minuto")), + VocabItem("commercio_ambulante", _("Commercio ambulante")), + VocabItem( + "comunicazione_istituzionale", + _("Comunicazione istituzionale") + ), + VocabItem("comunicazione_politica", _("Comunicazione politica")), + VocabItem("concordi", _("Concorsi")), + VocabItem("covid_19", _("Covid - 19")), + VocabItem("elezioni", _("Elezioni")), + VocabItem("energie_rinnovabili", _("Energie rinnovabili")), + VocabItem("estero", _("Estero")), + VocabItem("foreste", _("Foreste")), + VocabItem( + "formazione_professionale", _("Formazione professionale") + ), + VocabItem("gemellaggi", _("Gemellaggi")), + VocabItem("gestione_rifiuti", _("Gestione rifiuti")), + VocabItem("giustizia", _("Giustizia")), + VocabItem("igiene_pubblica", _("Igiene pubblica")), VocabItem("immigrazione", _("Immigrazione")), + VocabItem("imposte", _("Imposte")), + VocabItem("imprese", _("Imprese")), VocabItem("inquinamento", _("Inquinamento")), - VocabItem("area-parcheggio", _("Area di parcheggio")), - VocabItem("traffico-urbano", _("Traffico urbano")), - VocabItem("acqua", _("Acqua")), - VocabItem("gestione-rifiuti", _("Gestione dei rifiuti")), - VocabItem("salute", _("Salute")), - VocabItem("sicurezza-pubblica", _("Sicurezza pubblica")), - VocabItem("sicurezza-internazionale", _("Sicurezza internazionale")), - VocabItem("spazio-verde", _("Spazio verde")), + VocabItem("integrazione_sociale", _("Integrazione sociale")), + VocabItem("isolamento_termico", _("Isolamento termico")), + VocabItem("istruzione", _("Istruzione")), + VocabItem("lavoro", _("Lavoro")), + VocabItem("matrimonio", _("Matrimonio")), + VocabItem("mercato", _("Mercato")), + VocabItem("mobilita_sostenibile", _("Mobilità sostenibile")), + VocabItem("morte", _("Morte")), + VocabItem("nascita", _("Nascita")), + VocabItem("parcheggi", _("Parcheggi")), + VocabItem("patrimonio_culturale", _("Patrimonio culturale")), + VocabItem("pesca", _("Pesca")), + VocabItem("piano_di_sviluppo", _("Piano di sviluppo")), + VocabItem("pista_ciclabile", _("Pista ciclabile")), + VocabItem("politica_commerciale", _("Politica commerciale")), + VocabItem("polizia", _("Polizia")), + VocabItem("prodotti_alimentari", _("Prodotti alimentari")), + VocabItem("protezione_civile", _("Protezione civile")), + VocabItem("residenza", _("Residenza")), + VocabItem("risposta_alle_emergenze", _("Risposta alle emergenze")), + VocabItem("sistema_giuridico", _("Sistema giuridico")), + VocabItem("spazio_verde", _("Spazio Verde")), VocabItem("sport", _("Sport")), - VocabItem("trasporto-stradale", _("Trasporto stradale")), - VocabItem("turismo", _("Turismo")), - VocabItem("energia", _("Energia")), + VocabItem("sviluppo_sostenibile", _("Sviluppo sostenibile")), + VocabItem("tassa_sui_servizi", _("Tassa sui servizi")), + VocabItem("tempo_libero", _("Tempo libero")), VocabItem( - "informatica-trattamento-dati", - _("Informatica e trattamento dei dati"), + "trasparenza_amministrativa", _("Trasparenza amministrativa") ), + VocabItem("trasporto_pubblico", _("Trasporto pubblico")), + VocabItem("turismo", _("Turismo")), + VocabItem("urbanizzazione", _("Urbanizzazione")), + VocabItem("viaggi", _("Viaggi")), + VocabItem("zone_pedonali", _("Zone pedonali")), + VocabItem("ztl", _("ZTL")), ] # Fix context if you are using the vocabulary in DataGridField. From bf9a419a9a7b8f0fd21688b33edcbf88ae64f0f6 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Fri, 16 Dec 2022 16:28:23 +0100 Subject: [PATCH 004/487] [dev] taxonomies --- .../plone/contenttypes/interfaces/documento.py | 18 +++++++++--------- .../plone/contenttypes/upgrades/configure.zcml | 1 + .../contenttypes/vocabularies/configure.zcml | 10 ---------- 3 files changed, 10 insertions(+), 19 deletions(-) diff --git a/src/design/plone/contenttypes/interfaces/documento.py b/src/design/plone/contenttypes/interfaces/documento.py index 565bac9a..d6891a08 100644 --- a/src/design/plone/contenttypes/interfaces/documento.py +++ b/src/design/plone/contenttypes/interfaces/documento.py @@ -25,15 +25,15 @@ class IDocumento(model.Schema, IDesignPloneContentType): required=False, ) - tipologia_documento = schema.Choice( - title=_("tipologia_documento_label", default="Tipologia del documento"), - description=_( - "tipologia_documento_help", - default="Seleziona la tipologia del documento.", - ), - required=True, - vocabulary="design.plone.vocabularies.tipologie_documento", - ) + # tipologia_documento = schema.Choice( + # title=_("tipologia_documento_label", default="Tipologia del documento"), + # description=_( + # "tipologia_documento_help", + # default="Seleziona la tipologia del documento.", + # ), + # required=True, + # vocabulary="design.plone.vocabularies.tipologie_documento", + # ) ufficio_responsabile = RelationList( title=_( diff --git a/src/design/plone/contenttypes/upgrades/configure.zcml b/src/design/plone/contenttypes/upgrades/configure.zcml index bec66296..24871bac 100644 --- a/src/design/plone/contenttypes/upgrades/configure.zcml +++ b/src/design/plone/contenttypes/upgrades/configure.zcml @@ -570,6 +570,7 @@ title="Updated plone.volto: remove plone.tableofcontents behavior" handler=".upgrades.to_5410" /> + - - - - Date: Mon, 19 Dec 2022 18:19:41 +0100 Subject: [PATCH 005/487] [dev] started work on tipologia_documento --- .../contenttypes/controlpanels/settings.py | 27 -------- .../contenttypes/interfaces/documento.py | 10 --- .../contenttypes/interfaces/messaggio.py | 8 --- .../profiles/default/registry/criteria.xml | 7 +- .../plone/contenttypes/upgrades/upgrades.py | 2 +- .../contenttypes/vocabularies/configure.zcml | 13 ---- .../controlapanel_vocabularies.py | 6 -- .../vocabularies/document_types_vocabulary.py | 66 ------------------- 8 files changed, 5 insertions(+), 134 deletions(-) delete mode 100644 src/design/plone/contenttypes/vocabularies/document_types_vocabulary.py diff --git a/src/design/plone/contenttypes/controlpanels/settings.py b/src/design/plone/contenttypes/controlpanels/settings.py index fe84d58b..fd2c53e4 100644 --- a/src/design/plone/contenttypes/controlpanels/settings.py +++ b/src/design/plone/contenttypes/controlpanels/settings.py @@ -41,33 +41,6 @@ class IDesignPloneSettings(Interface): default=json.dumps({"it": ["Politica", "Amministrativa", "Altro"]}), ) - tipologie_documento = SourceText( - title=_("tipologie_documento_label", default="Tipologie Documento"), - description=_( - "tipologie_documento_help", - default="Inserisci i valori utilizzabili per le tipologie di un " - "Documento. Se il sito è multilingua, puoi inserire " - "valori diversi a seconda delle lingue del sito.", - ), - required=True, - default=json.dumps( - { - "it": [ - "Accordo tra enti", - "Atto normativo", - "Dataset", - "Documento (tecnico) di supporto", - "Documento albo pretorio", - "Documento attività politica", - "Documento funzionamento interno", - "Istanza", - "Modulistica", - "Documento di programmazione e rendicontazione", - ] - } - ), - ) - lead_image_dimension = List( title=_( "lead_image_dimension_label", diff --git a/src/design/plone/contenttypes/interfaces/documento.py b/src/design/plone/contenttypes/interfaces/documento.py index d6891a08..85320ce3 100644 --- a/src/design/plone/contenttypes/interfaces/documento.py +++ b/src/design/plone/contenttypes/interfaces/documento.py @@ -25,16 +25,6 @@ class IDocumento(model.Schema, IDesignPloneContentType): required=False, ) - # tipologia_documento = schema.Choice( - # title=_("tipologia_documento_label", default="Tipologia del documento"), - # description=_( - # "tipologia_documento_help", - # default="Seleziona la tipologia del documento.", - # ), - # required=True, - # vocabulary="design.plone.vocabularies.tipologie_documento", - # ) - ufficio_responsabile = RelationList( title=_( "ufficio_responsabile_documento_label", diff --git a/src/design/plone/contenttypes/interfaces/messaggio.py b/src/design/plone/contenttypes/interfaces/messaggio.py index 41c8d49c..46ce393d 100644 --- a/src/design/plone/contenttypes/interfaces/messaggio.py +++ b/src/design/plone/contenttypes/interfaces/messaggio.py @@ -44,14 +44,6 @@ class IMessaggio(model.Schema): required=False, ) - # TODO: inserire tassonomia contenente le tipologie di documenti - tipologia_documento = schema.Choice( - title=_("tipologia_documento", default="Tipologia documento"), - required=False, - vocabulary="design.plone.contenttypes.Mockup", - missing_value=(), - ) - documenti_allegati = field.NamedFile( title=_("documenti_allegati", default="Documenti allegati"), required=False, diff --git a/src/design/plone/contenttypes/profiles/default/registry/criteria.xml b/src/design/plone/contenttypes/profiles/default/registry/criteria.xml index ddcca239..417c60d0 100644 --- a/src/design/plone/contenttypes/profiles/default/registry/criteria.xml +++ b/src/design/plone/contenttypes/profiles/default/registry/criteria.xml @@ -27,8 +27,9 @@ design.plone.vocabularies.argomenti Metadata + + prefix="plone.app.querystring.field.tassonomia_tipologia_documento"> Tipologia documento True @@ -37,8 +38,8 @@ plone.app.querystring.operation.selection.any plone.app.querystring.operation.selection.all - design.plone.vocabularies.tipologie_documento - Metadata + Metadata + collective.taxonomy.tipologie_documento - - - - - - - Date: Tue, 20 Dec 2022 13:02:13 +0100 Subject: [PATCH 006/487] feat: new CTs Incarico and PuntoDiContatto --- .../plone/contenttypes/content/incarico.py | 9 + .../contenttypes/content/punto_di_contatto.py | 9 + .../plone/contenttypes/interfaces/incarico.py | 173 ++++++++++++++++++ .../interfaces/punto_di_contatto.py | 51 ++++++ .../profiles/default/metadata.xml | 2 +- .../contenttypes/profiles/default/types.xml | 2 + .../profiles/default/types/Incarico.xml | 107 +++++++++++ .../default/types/PuntoDiContatto.xml | 106 +++++++++++ .../restapi/services/types/get.py | 8 + .../contenttypes/upgrades/configure.zcml | 10 + .../plone/contenttypes/upgrades/upgrades.py | 7 + 11 files changed, 483 insertions(+), 1 deletion(-) create mode 100644 src/design/plone/contenttypes/content/incarico.py create mode 100644 src/design/plone/contenttypes/content/punto_di_contatto.py create mode 100644 src/design/plone/contenttypes/interfaces/incarico.py create mode 100644 src/design/plone/contenttypes/interfaces/punto_di_contatto.py create mode 100644 src/design/plone/contenttypes/profiles/default/types/Incarico.xml create mode 100644 src/design/plone/contenttypes/profiles/default/types/PuntoDiContatto.xml diff --git a/src/design/plone/contenttypes/content/incarico.py b/src/design/plone/contenttypes/content/incarico.py new file mode 100644 index 00000000..3c536b06 --- /dev/null +++ b/src/design/plone/contenttypes/content/incarico.py @@ -0,0 +1,9 @@ +# -*- coding: utf-8 -*- +from plone.dexterity.content import Container +from zope.interface import implementer +from design.plone.contenttypes.interfaces.incarico import IIncarico + + +@implementer(IIncarico) +class Incarico(Container): + """ """ diff --git a/src/design/plone/contenttypes/content/punto_di_contatto.py b/src/design/plone/contenttypes/content/punto_di_contatto.py new file mode 100644 index 00000000..1bbdaf3c --- /dev/null +++ b/src/design/plone/contenttypes/content/punto_di_contatto.py @@ -0,0 +1,9 @@ +# -*- coding: utf-8 -*- +from plone.dexterity.content import Container +from zope.interface import implementer +from design.plone.contenttypes.interfaces.punto_di_contatto import IPuntoDiContatto + + +@implementer(IPuntoDiContatto) +class PuntoDiContatto(Container): + """ """ diff --git a/src/design/plone/contenttypes/interfaces/incarico.py b/src/design/plone/contenttypes/interfaces/incarico.py new file mode 100644 index 00000000..20e2c3aa --- /dev/null +++ b/src/design/plone/contenttypes/interfaces/incarico.py @@ -0,0 +1,173 @@ +# -*- coding: utf-8 -*- +from collective.volto.blocksfield.field import BlocksField +from design.plone.contenttypes import _ +from design.plone.contenttypes.interfaces import IDesignPloneContentType +from plone.app.z3cform.widget import RelatedItemsFieldWidget +from plone.autoform import directives as form +from plone.supermodel import model +from z3c.relationfield.schema import RelationChoice +from z3c.relationfield.schema import RelationList +from zope import schema + + +class IIncarico(model.Schema, IDesignPloneContentType): + """Marker interface for content type Incarico""" + + compensi = BlocksField( + title=_( + "compensi_incarico_label", + default="Compensi", + ), + description=_( + "compensi_incarico_help", + default="Solo per incarico politico: compensi di qualsiasi natura" + " connessi all'assunzione della carica.", + ), + required=False, + ) + + importi_viaggio_servizio = BlocksField( + title=_( + "importi_viaggio_servizio_incarico_label", + default="Importi di viaggio e/o servizio", + ), + description=_( + "importi_viaggio_servizio_incarico_help", + default="Solo per incarico politico: importi di viaggi di servizio" + " e missioni pagati con fondi pubblici.", + ), + required=False, + ) + + persona = RelationList( + title=_( + "persona_incarico_label", + default="Persona", + ), + description=_( + "persona_incarico_help", + default="Seleziona la/e persona/e che ha/hanno la carica e l'incarico.", + ), + value_type=RelationChoice(vocabulary="plone.app.vocabularies.Catalog"), + required=True, + default=[], + ) + + unita_organizzativa = RelationList( + title=_( + "unita_organizzativa_incarico_label", + default="Unità organizzativa", + ), + description=_( + "unita_organizzativa_incarico_help", + default="Seleziona l'organizzazione presso la quale svolge l'incarico.", + ), + required=False, + default=[], + value_type=RelationChoice( + title=_("Unità organizzativa"), + vocabulary="plone.app.vocabularies.Catalog", + ), + ) + + responsabile_struttura = RelationList( + title=_( + "responsabile_struttura_incarico_label", + default="Responsabile della struttura", + ), + description=_( + "responsabile_struttura_incarico_help", + default="Se è un incarico di responsabilità, specificare l'organizzazione " + "della quale è responsabile in base all'incarico", + ), + required=False, + default=[], + value_type=RelationChoice( + title=_("Responsabile della struttura"), + vocabulary="plone.app.vocabularies.Catalog", + ), + ) + + data_inizio_incarico = schema.Date( + title=_("data_inizio_incarico", default="Data inizio incarico"), + required=True, + ) + + data_conclusione_incarico = schema.Date( + title=_("data_conclusione_incarico", default="Data conclusione incarico"), + required=False, + ) + + data_insediamento = schema.Date( + title=_("data_insediamento", default="Data insediamento"), + required=False, + ) + + atto_nomina = RelationList( + title=_( + "atto_nomina_incarico_label", + default="Atto di nomina", + ), + description=_( + "atto_nomina_incarico_help", + default="Inserire riferimento all'atto di nomina della persona", + ), + required=False, + default=[], + value_type=RelationChoice( + title=_("Atto di nomina"), + vocabulary="plone.app.vocabularies.Catalog", + ), + ) + + # custom widgets + form.widget( + "unita_organizzativa", + RelatedItemsFieldWidget, + vocabulary="plone.app.vocabularies.Catalog", + pattern_options={ + "maximumSelectionSize": 1, + "selectableTypes": ["UnitaOrganizzativa"], + }, + ) + + form.widget( + "persona", + RelatedItemsFieldWidget, + vocabulary="plone.app.vocabularies.Catalog", + pattern_options={ + "maximumSelectionSize": 1, + "selectableTypes": ["Persona"], + }, + ) + form.widget( + "responsabile_struttura", + RelatedItemsFieldWidget, + vocabulary="plone.app.vocabularies.Catalog", + pattern_options={ + "maximumSelectionSize": 1, + "selectableTypes": ["UnitaOrganizzativa"], + }, + ) + + form.widget( + "atto_nomina", + RelatedItemsFieldWidget, + vocabulary="plone.app.vocabularies.Catalog", + pattern_options={ + "maximumSelectionSize": 1, + "selectableTypes": ["Documento"], + }, + ) + + #  custom fieldsets + model.fieldset( + "informazioni_compensi", + label=_("informazioni_compensi_label", default="Compensi e trasparenza"), + fields=["compensi", "importi_viaggio_servizio"], + ) + model.fieldset( + "date_e_informazioni", + label=_("date_e_informazioni_label", default="Date e informazioni"), + fields=["data_conclusione_incarico", "data_insediamento", "atto_nomina"], + ) diff --git a/src/design/plone/contenttypes/interfaces/punto_di_contatto.py b/src/design/plone/contenttypes/interfaces/punto_di_contatto.py new file mode 100644 index 00000000..f5a8dae1 --- /dev/null +++ b/src/design/plone/contenttypes/interfaces/punto_di_contatto.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +from collective.volto.blocksfield.field import BlocksField +from design.plone.contenttypes import _ +from design.plone.contenttypes.interfaces import IDesignPloneContentType +from plone.app.z3cform.widget import RelatedItemsFieldWidget +from plone.autoform import directives as form +from plone.supermodel import model +from z3c.relationfield.schema import RelationChoice +from z3c.relationfield.schema import RelationList +# from zope import schema + + +class IPuntoDiContatto(model.Schema, IDesignPloneContentType): + """Marker interface for content type PuntoDiContatto""" + + value = BlocksField( + title=_( + "value_pdc_label", + default="Valore punto di contatto", + ), + description=_( + "value_pdc_help", + default="Il valore del punto di contatto: il numero compreso di prefisso " + "internazionale (se telefono), l'account (se social network), l'URL (se sito o pagina web), l'indirizzo email (se email).", + ), + required=False, + ) + + persona = RelationList( + title=_( + "persona_incarico_label", + default="Persona", + ), + description=_( + "persona_incarico_help", + default="Seleziona la/e persona/e che ha/hanno la carica e l'incarico.", + ), + value_type=RelationChoice(vocabulary="plone.app.vocabularies.Catalog"), + required=True, + default=[], + ) + + form.widget( + "persona", + RelatedItemsFieldWidget, + vocabulary="plone.app.vocabularies.Catalog", + pattern_options={ + "maximumSelectionSize": 1, + "selectableTypes": ["Persona"], + }, + ) diff --git a/src/design/plone/contenttypes/profiles/default/metadata.xml b/src/design/plone/contenttypes/profiles/default/metadata.xml index 8ed839e3..fcf9af17 100644 --- a/src/design/plone/contenttypes/profiles/default/metadata.xml +++ b/src/design/plone/contenttypes/profiles/default/metadata.xml @@ -1,6 +1,6 @@ - 6000 + 6010 profile-redturtle.bandi:default profile-collective.venue:default diff --git a/src/design/plone/contenttypes/profiles/default/types.xml b/src/design/plone/contenttypes/profiles/default/types.xml index cdc991e8..6bfe5e5c 100644 --- a/src/design/plone/contenttypes/profiles/default/types.xml +++ b/src/design/plone/contenttypes/profiles/default/types.xml @@ -13,4 +13,6 @@ + + diff --git a/src/design/plone/contenttypes/profiles/default/types/Incarico.xml b/src/design/plone/contenttypes/profiles/default/types/Incarico.xml new file mode 100644 index 00000000..10862784 --- /dev/null +++ b/src/design/plone/contenttypes/profiles/default/types/Incarico.xml @@ -0,0 +1,107 @@ + + + + + Incarico + + + False + Incarico + + + + + True + False + + + + + design.plone.contenttypes.AddIncarico + design.plone.contenttypes.content.incarico.Incarico + + + design.plone.contenttypes.interfaces.incarico.IIncarico + + + + + + + + + + + + + + + + + + + + + + + string:${folder_url}/++add++Incarico + view + False + view + + + + + + + + + + + + + + + + + + + diff --git a/src/design/plone/contenttypes/profiles/default/types/PuntoDiContatto.xml b/src/design/plone/contenttypes/profiles/default/types/PuntoDiContatto.xml new file mode 100644 index 00000000..cfe4b273 --- /dev/null +++ b/src/design/plone/contenttypes/profiles/default/types/PuntoDiContatto.xml @@ -0,0 +1,106 @@ + + + + + Punto di Contatto + + + False + PuntoDiContatto + + + + + True + False + + + + + design.plone.contenttypes.AddPuntoDiContatto + design.plone.contenttypes.content.punto_di_contatto.PuntoDiContatto + + + design.plone.contenttypes.interfaces.punto_di_contatto.IPuntoDiContatto + + + + + + + + + + + + + + + + + + + + + + string:${folder_url}/++add++PuntoDiContatto + view + False + view + + + + + + + + + + + + + + + + + + + diff --git a/src/design/plone/contenttypes/restapi/services/types/get.py b/src/design/plone/contenttypes/restapi/services/types/get.py index c1038049..f7ce952e 100644 --- a/src/design/plone/contenttypes/restapi/services/types/get.py +++ b/src/design/plone/contenttypes/restapi/services/types/get.py @@ -51,6 +51,11 @@ class FieldsetsMismatchError(Exception): "settings", "ownership", ], + "Incarico": [ + 'default', + 'informazioni_compensi', + 'date_e_informazioni', + ], "News Item": [ "default", "dates", @@ -88,6 +93,9 @@ class FieldsetsMismatchError(Exception): "ownership", "settings", ], + "PuntoDiContatto": [ + 'default', + ], "Servizio": [ "default", "cose", diff --git a/src/design/plone/contenttypes/upgrades/configure.zcml b/src/design/plone/contenttypes/upgrades/configure.zcml index 24871bac..f3512207 100644 --- a/src/design/plone/contenttypes/upgrades/configure.zcml +++ b/src/design/plone/contenttypes/upgrades/configure.zcml @@ -581,4 +581,14 @@ handler=".upgrades.to_6000" /> + + + diff --git a/src/design/plone/contenttypes/upgrades/upgrades.py b/src/design/plone/contenttypes/upgrades/upgrades.py index a840a6f7..195252c6 100644 --- a/src/design/plone/contenttypes/upgrades/upgrades.py +++ b/src/design/plone/contenttypes/upgrades/upgrades.py @@ -965,3 +965,10 @@ def to_6000(context): behaviors.append(behavior) fti.behaviors = tuple(behaviors) + + +def to_6010(context): + """ """ + update_types(context) + update_registry(context) + update_catalog(context) From d07c46fb0b141220bc7cec12ab6325dea6071576 Mon Sep 17 00:00:00 2001 From: Martina Bustacchini Date: Tue, 20 Dec 2022 14:39:21 +0100 Subject: [PATCH 007/487] feat: CTs Incarico and PuntoDiContatto integration with existing CTs --- .../contenttypes/behaviors/configure.zcml | 24 +++ .../plone/contenttypes/behaviors/contatti.py | 204 +++++++++++++----- .../plone/contenttypes/interfaces/persona.py | 70 +----- .../interfaces/punto_di_contatto.py | 2 +- .../interfaces/unita_organizzativa.py | 18 +- .../profiles/default/types/Event.xml | 3 +- .../profiles/default/types/Persona.xml | 1 + .../profiles/default/types/Servizio.xml | 1 + 8 files changed, 182 insertions(+), 141 deletions(-) diff --git a/src/design/plone/contenttypes/behaviors/configure.zcml b/src/design/plone/contenttypes/behaviors/configure.zcml index c8a8a8ca..94e740ca 100644 --- a/src/design/plone/contenttypes/behaviors/configure.zcml +++ b/src/design/plone/contenttypes/behaviors/configure.zcml @@ -208,6 +208,30 @@ provides=".contatti.IContattiVenue" marker=".contatti.IContattiVenue" /> + + + - + + diff --git a/src/design/plone/contenttypes/profiles/default/types/Persona.xml b/src/design/plone/contenttypes/profiles/default/types/Persona.xml index bf2d0fb3..1760e335 100644 --- a/src/design/plone/contenttypes/profiles/default/types/Persona.xml +++ b/src/design/plone/contenttypes/profiles/default/types/Persona.xml @@ -49,6 +49,7 @@ + diff --git a/src/design/plone/contenttypes/profiles/default/types/Servizio.xml b/src/design/plone/contenttypes/profiles/default/types/Servizio.xml index 118f1ad7..28301b53 100644 --- a/src/design/plone/contenttypes/profiles/default/types/Servizio.xml +++ b/src/design/plone/contenttypes/profiles/default/types/Servizio.xml @@ -50,6 +50,7 @@ + From 56501fe6c19c9d6c3cd4250be834ad7c00a42106 Mon Sep 17 00:00:00 2001 From: Martina Bustacchini Date: Tue, 20 Dec 2022 17:47:09 +0100 Subject: [PATCH 008/487] feat: working DatagridField field for pdc value, tested in volto. Next step: migration upgrade steps --- setup.py | 1 + .../plone/contenttypes/behaviors/evento.py | 52 ++------------- .../plone/contenttypes/behaviors/luogo.py | 57 ++--------------- .../plone/contenttypes/interfaces/persona.py | 17 +++-- .../interfaces/punto_di_contatto.py | 47 +++++++++++--- .../interfaces/unita_organizzativa.py | 6 ++ .../profiles/default/types/Event.xml | 2 +- .../contenttypes/restapi/types/adapters.py | 64 +++++++++++++++++++ .../contenttypes/restapi/types/configure.zcml | 3 + .../contenttypes/vocabularies/configure.zcml | 5 ++ .../vocabularies/pdc_value_type.py | 48 ++++++++++++++ 11 files changed, 189 insertions(+), 113 deletions(-) create mode 100644 src/design/plone/contenttypes/vocabularies/pdc_value_type.py diff --git a/setup.py b/setup.py index 6c8ed181..6b3f2a98 100644 --- a/setup.py +++ b/setup.py @@ -59,6 +59,7 @@ "plone.app.dexterity>2.6.9", "collective.venue[geolocation]", "collective.volto.blocksfield", + "collective.z3cform.datagridfield", "plone.formwidget.geolocation", "redturtle.volto", "redturtle.bandi", diff --git a/src/design/plone/contenttypes/behaviors/evento.py b/src/design/plone/contenttypes/behaviors/evento.py index 20ea7db3..ebdb93d0 100644 --- a/src/design/plone/contenttypes/behaviors/evento.py +++ b/src/design/plone/contenttypes/behaviors/evento.py @@ -100,47 +100,7 @@ class IEvento(model.Schema): " indicare il nome del contatto.", ), ) - telefono = schema.TextLine( - title=_("telefono_event_help", default="Telefono"), - description=_( - "telefono_event_label", - default="Indicare un riferimento telefonico per poter contattare" - " gli organizzatori.", - ), - required=False, - ) - fax = schema.TextLine( - title=_("fax_event_help", default="Fax"), - description=_("fax_event_label", default="Indicare un numero di fax."), - required=False, - ) - reperibilita = schema.TextLine( - title=_("reperibilita", default="Reperibilità organizzatore"), - required=False, - description=_( - "reperibilita_help", - default="Indicare gli orari in cui l'organizzatore è" - " telefonicamente reperibile.", - ), - ) - email = schema.TextLine( - title=_("email_event_label", default="E-mail"), - description=_( - "email_event_help", - default="Indicare un indirizzo mail per poter contattare" - " gli organizzatori.", - ), - required=False, - ) - web = schema.TextLine( - title=_("web_event_label", default="Sito web"), - description=_( - "web_event_help", - default="Indicare un indirizzo web di riferimento a " "questo evento.", - ), - required=False, - ) supportato_da = RelationList( title=_("supportato_da_label", default="Evento supportato da"), required=False, @@ -210,17 +170,19 @@ class IEvento(model.Schema): fields=["orari"], ) model.fieldset("costi", label=_("costi_label", default="Costi"), fields=["prezzo"]) + + # TODO: migration script for these commented fields towards PDC model.fieldset( "contatti", label=_("contatti_label", default="Contatti"), fields=[ "organizzato_da_interno", "organizzato_da_esterno", - "telefono", - "fax", - "reperibilita", - "email", - "web", + # "telefono", + # "fax", + # "reperibilita", + # "email", + # "web", "supportato_da", ], ) diff --git a/src/design/plone/contenttypes/behaviors/luogo.py b/src/design/plone/contenttypes/behaviors/luogo.py index dea99b39..f3ea73f5 100644 --- a/src/design/plone/contenttypes/behaviors/luogo.py +++ b/src/design/plone/contenttypes/behaviors/luogo.py @@ -88,54 +88,6 @@ class ILuogo(model.Schema): ), ) - riferimento_telefonico_struttura = schema.TextLine( - title=_( - "riferimento_telefonico_struttura", - default="Telefono della struttura responsabile", - ), - description=_( - "help_riferimento_telefonico_struttura", - default="Indicare il riferimento telefonico per poter contattare" - " i referenti della struttura responsabile.", - ), - required=False, - ) - riferimento_fax_struttura = schema.TextLine( - title=_( - "riferimento_fax_struttura", - default="Fax della struttura responsabile", - ), - description=_( - "help_riferimento_fax_struttura", - default="Indicare un numero di fax della struttura responsabile.", - ), - required=False, - ) - riferimento_mail_struttura = schema.TextLine( - title=_( - "riferimento_mail_struttura", - default="E-mail struttura responsabile", - ), - description=_( - "help_riferimento_mail_struttura", - default="Indicare un indirizzo mail per poter contattare" - " i referenti della struttura responsabile.", - ), - required=False, - ) - - riferimento_pec_struttura = schema.TextLine( - title=_( - "riferimento_pec_struttura", - default="Pec della struttura responsabile", - ), - description=_( - "help_riferimento_pec_struttura", - default="Indicare un indirizzo pec per poter contattare" - " i referenti della struttura responsabile.", - ), - required=False, - ) # Decisono con Baio di toglierlo: visto il vocabolario, che in realtà sta # qui: https://github.com/italia/daf-ontologie-vocabolari-controllati/tree/master/VocabolariControllati/classifications-for-culture/subject-disciplines @@ -172,16 +124,17 @@ class ILuogo(model.Schema): fields=["modalita_accesso"], ) + # TODO: migration script for these commented fields towards PDC model.fieldset( "contatti", label=_("contatti_label", default="Contatti"), fields=[ "struttura_responsabile_correlati", "struttura_responsabile", - "riferimento_telefonico_struttura", - "riferimento_fax_struttura", - "riferimento_mail_struttura", - "riferimento_pec_struttura", + # "riferimento_telefonico_struttura", + # "riferimento_fax_struttura", + # "riferimento_mail_struttura", + # "riferimento_pec_struttura", ], ) diff --git a/src/design/plone/contenttypes/interfaces/persona.py b/src/design/plone/contenttypes/interfaces/persona.py index de5d137f..0c44c9e8 100644 --- a/src/design/plone/contenttypes/interfaces/persona.py +++ b/src/design/plone/contenttypes/interfaces/persona.py @@ -9,9 +9,16 @@ from plone.supermodel import model from z3c.relationfield.schema import RelationChoice from z3c.relationfield.schema import RelationList -from zope import schema +# TODO: migration script for these commented fields towards PDC +# telefono +# fax +# email +# TODO: migration script for these commented fields towards Incarico +# atto_nomina +# data_conclusione_incarico +# data_insediamento class IPersona(model.Schema, IDesignPloneContentType): """Marker interface for contenttype Persona""" @@ -81,7 +88,6 @@ class IPersona(model.Schema, IDesignPloneContentType): ), ) - # custom widgets form.widget( "organizzazione_riferimento", @@ -113,6 +119,7 @@ class IPersona(model.Schema, IDesignPloneContentType): # SearchableText fields textindexer.searchable("competenze") textindexer.searchable("deleghe") - textindexer.searchable("telefono") - textindexer.searchable("fax") - textindexer.searchable("email") + # TODO: migration script for these commented fields towards PDC + # textindexer.searchable("telefono") + # textindexer.searchable("fax") + # textindexer.searchable("email") diff --git a/src/design/plone/contenttypes/interfaces/punto_di_contatto.py b/src/design/plone/contenttypes/interfaces/punto_di_contatto.py index 2f55f26a..1df36d9e 100644 --- a/src/design/plone/contenttypes/interfaces/punto_di_contatto.py +++ b/src/design/plone/contenttypes/interfaces/punto_di_contatto.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- -from collective.volto.blocksfield.field import BlocksField from design.plone.contenttypes import _ from design.plone.contenttypes.interfaces import IDesignPloneContentType from plone.app.z3cform.widget import RelatedItemsFieldWidget @@ -7,23 +6,46 @@ from plone.supermodel import model from z3c.relationfield.schema import RelationChoice from z3c.relationfield.schema import RelationList -# from zope import schema +from zope import schema +from collective.z3cform.datagridfield.datagridfield import DataGridFieldFactory +from collective.z3cform.datagridfield.row import DictRow + + +class IPDCValueSchema(model.Schema): + pdc_type = schema.Choice( + title=_("pdc_type_label", default="Tipo"), + description=_( + "type_help", + default="Tipo", + ), + vocabulary="design.plone.contenttypes.pdc_value_type", + required=True, + default="", + ) + pdc_value = schema.TextLine( + title=_("pdc_value_label", default="Contatto"), + description=_( + "pdc_value_help", + default="Contatto", + ), + required=True, + default="", + ) class IPuntoDiContatto(model.Schema, IDesignPloneContentType): """Marker interface for content type PuntoDiContatto""" - value = BlocksField( - title=_( - "value_pdc_label", - default="Valore punto di contatto", - ), + value_punto_contatto = schema.List( + title="Valore punto di contatto", + default=[], + value_type=DictRow(schema=IPDCValueSchema), description=_( - "value_pdc_help", + "value_punto_contatto_help", default="Il valore del punto di contatto: il numero compreso di prefisso " "internazionale (se telefono), l'account (se social network), l'URL (se sito o pagina web), l'indirizzo email (se email).", ), - required=False, + required=True, ) persona = RelationList( @@ -33,13 +55,18 @@ class IPuntoDiContatto(model.Schema, IDesignPloneContentType): ), description=_( "persona_incarico_help", - default="Seleziona la/e persona/e che ha/hanno la carica e l'incarico.", + default="Seleziona la persona che ha la carica e l'incarico.", ), value_type=RelationChoice(vocabulary="plone.app.vocabularies.Catalog"), required=False, default=[], ) + form.widget( + "value_punto_contatto", + DataGridFieldFactory, + ) + form.widget( "persona", RelatedItemsFieldWidget, diff --git a/src/design/plone/contenttypes/interfaces/unita_organizzativa.py b/src/design/plone/contenttypes/interfaces/unita_organizzativa.py index 29efa3cc..42a1128a 100644 --- a/src/design/plone/contenttypes/interfaces/unita_organizzativa.py +++ b/src/design/plone/contenttypes/interfaces/unita_organizzativa.py @@ -11,6 +11,11 @@ from zope import schema +# TODO: migration script for these commented fields towards PDC +# contact_info +# Probabilmente non possibile trattandosi di un campo a blocchi +# preferirei si arrangiassero le redazioni. Altrimenti si defaulta +# ad un tipo a caso + tutto il testo e poi si arrangiano comunque class IUnitaOrganizzativa(model.Schema, IDesignPloneContentType): """Marker interface for content type UnitaOrganizzativa""" @@ -133,6 +138,7 @@ class IUnitaOrganizzativa(model.Schema, IDesignPloneContentType): required=False, ) + #  custom widgets form.widget( "persone_struttura", diff --git a/src/design/plone/contenttypes/profiles/default/types/Event.xml b/src/design/plone/contenttypes/profiles/default/types/Event.xml index 5f3b86d7..e21af13c 100644 --- a/src/design/plone/contenttypes/profiles/default/types/Event.xml +++ b/src/design/plone/contenttypes/profiles/default/types/Event.xml @@ -17,7 +17,7 @@ - + diff --git a/src/design/plone/contenttypes/restapi/types/adapters.py b/src/design/plone/contenttypes/restapi/types/adapters.py index 35a96361..38d4f3cb 100644 --- a/src/design/plone/contenttypes/restapi/types/adapters.py +++ b/src/design/plone/contenttypes/restapi/types/adapters.py @@ -6,6 +6,15 @@ from zope.interface import implementer from zope.interface import Interface from zope.schema.interfaces import IField, IVocabularyFactory +from collective.z3cform.datagridfield.interfaces import IRow +from plone import api +from plone.restapi.types.adapters import ListJsonSchemaProvider +from plone.restapi.types.utils import get_fieldsets +from plone.restapi.types.utils import get_jsonschema_properties +from plone.restapi.types.utils import iter_fields +from zope.schema.interfaces import IList +from design.plone.contenttypes.interfaces import IDesignPloneContenttypesLayer + from design.plone.contenttypes import _ @@ -36,3 +45,58 @@ def get_schema(self): schema["description"] = translate(msgid, context=self.request) return schema + + +@adapter(IList, Interface, IDesignPloneContenttypesLayer) +@implementer(IJsonSchemaProvider) +class DataGridFieldJsonSchemaProvider(ListJsonSchemaProvider): + def get_widget(self): + if self.field.getName() == "value_punto_contatto": + return "data_grid" + return super().get_widget() + + +@adapter(IRow, Interface, Interface) +@implementer(IJsonSchemaProvider) +class DataGridRowJsonSchemaProvider(ObjectJsonSchemaProvider): + def __init__(self, field, context, request): + super().__init__(field, context, request) + self.fieldsets = get_fieldsets(context, request, self.field.schema) + + def get_factory(self): + return "DataGridField Row" + + def get_properties(self): + if self.prefix: + prefix = ".".join([self.prefix, self.field.__name__]) + else: + prefix = self.field.__name__ + return get_jsonschema_properties( + self.context, self.request, self.fieldsets, prefix + ) + + def additional(self): + info = super().additional() + properties = self.get_properties() + required = [] + for field in iter_fields(self.fieldsets): + name = field.field.getName() + + # Determine required fields + if field.field.required: + required.append(name) + + # Include field modes + if field.mode: + properties[name]["mode"] = field.mode + + info["fieldsets"] = [ + { + "id": "default", + "title": "Default", + "fields": [x for x in properties.keys()], + }, + ] + info["required"] = required + info["properties"] = properties + return info diff --git a/src/design/plone/contenttypes/restapi/types/configure.zcml b/src/design/plone/contenttypes/restapi/types/configure.zcml index b3b754d1..b56c3e96 100644 --- a/src/design/plone/contenttypes/restapi/types/configure.zcml +++ b/src/design/plone/contenttypes/restapi/types/configure.zcml @@ -8,5 +8,8 @@ factory=".adapters.LeadImageJsonSchemaProvider" name="ILeadImageBehavior.image" /> + + + diff --git a/src/design/plone/contenttypes/vocabularies/configure.zcml b/src/design/plone/contenttypes/vocabularies/configure.zcml index 0daf55eb..c0b67b33 100644 --- a/src/design/plone/contenttypes/vocabularies/configure.zcml +++ b/src/design/plone/contenttypes/vocabularies/configure.zcml @@ -74,5 +74,10 @@ name="design.plone.vocabularies.uo_locations" component=".reference_vocabularies.UOLocationVocabularyFactory" /> + + diff --git a/src/design/plone/contenttypes/vocabularies/pdc_value_type.py b/src/design/plone/contenttypes/vocabularies/pdc_value_type.py new file mode 100644 index 00000000..95f64ef3 --- /dev/null +++ b/src/design/plone/contenttypes/vocabularies/pdc_value_type.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +from design.plone.contenttypes import _ +from plone.dexterity.interfaces import IDexterityContent +from zope.globalrequest import getRequest +from zope.interface import implementer +from zope.schema.interfaces import IVocabularyFactory +from zope.schema.vocabulary import SimpleTerm +from zope.schema.vocabulary import SimpleVocabulary + + +class VocabItem(object): + def __init__(self, token, value): + self.token = token + self.value = value + + +@implementer(IVocabularyFactory) +class PDCValueType(object): + """ """ + + def __call__(self, context): + # Just an example list of content for our vocabulary, + # this can be any static or dynamic data, a catalog result for example. + items = [ + VocabItem("phone", _("Telefono")), + VocabItem("web", _("URL")), + VocabItem("email", _("Email")), + VocabItem("social", _("Social")), + VocabItem("fax", _("Fax")), + + ] + # Fix context if you are using the vocabulary in DataGridField. + # See https://github.com/collective/collective.z3cform.datagridfield/issues/31: # NOQA: 501 + if not IDexterityContent.providedBy(context): + req = getRequest() + context = req.PARENTS[0] + + # create a list of SimpleTerm items: + terms = [] + for item in items: + terms.append( + SimpleTerm(value=item.token, token=str(item.token), title=item.value) + ) + # Create a SimpleVocabulary from the terms list and return it: + return SimpleVocabulary(terms) + + +PDCValueTypeFactory = PDCValueType() From c386affeeea4ce8b0491b421378434d71be85c9c Mon Sep 17 00:00:00 2001 From: Martina Bustacchini Date: Wed, 21 Dec 2022 12:00:50 +0100 Subject: [PATCH 009/487] fix, wip: fix cts not addable, wip migration upgradestep --- .../contenttypes/profiles/default/rolemap.xml | 12 ++ .../plone/contenttypes/upgrades/upgrades.py | 108 ++++++++++++++++++ .../vocabularies/pdc_value_type.py | 1 + 3 files changed, 121 insertions(+) diff --git a/src/design/plone/contenttypes/profiles/default/rolemap.xml b/src/design/plone/contenttypes/profiles/default/rolemap.xml index 33aa1b71..6629737a 100644 --- a/src/design/plone/contenttypes/profiles/default/rolemap.xml +++ b/src/design/plone/contenttypes/profiles/default/rolemap.xml @@ -117,6 +117,18 @@ + + + + + + + + + + + + diff --git a/src/design/plone/contenttypes/upgrades/upgrades.py b/src/design/plone/contenttypes/upgrades/upgrades.py index 195252c6..63f41eb8 100644 --- a/src/design/plone/contenttypes/upgrades/upgrades.py +++ b/src/design/plone/contenttypes/upgrades/upgrades.py @@ -17,6 +17,9 @@ from zope.intid.interfaces import IIntIds from zope.lifecycleevent import ObjectModifiedEvent from zope.schema import getFields +from zope.component import getUtility +from zope.intid.interfaces import IIntIds +from z3c.relationfield import RelationValue import logging import json @@ -972,3 +975,108 @@ def to_6010(context): update_types(context) update_registry(context) update_catalog(context) + update_rolemap(context) + + +def migrate_pdc_and_incarico(context): + # Cannot test rn, blid coding + update_types(context) + update_registry(context) + update_catalog(context) + update_rolemap(context) + type_mapping = { + "Persona": { + 'PDC': { + "telefono": "phone", + "fax": "fax", + "email": "email", + "pec": "pec", + }, + "Incarico": { + "atto_nomina": "atto_nomina", + "data_conclusione_incarico": "data_conclusione_incarico", + "data_insediamento": "data_insediamento", + } + }, + "UnitaOrganizzativa": { + 'PDC': { + "telefono": "phone", + "fax": "fax", + "email": "email", + "pec": "pec", + }, + }, + # TODO: tbc + "Event": { + 'PDC': { + "telefono": "phone", + "fax": "fax", + "email": "email", + "pec": "pec", + }, + }, + # TODO: tbc + "Venue": { + 'PDC': { + "telefono": "phone", + "fax": "fax", + "email": "email", + "pec": "pec", + }, + }, + # TODO: tbc + "Servizio": { + 'PDC': { + "telefono": "phone", + "fax": "fax", + "email": "email", + "pec": "pec", + }, + }, + } + + def createIncaricoAndMigratePersona(portal_type): + # Taxonomies work needs to be completed before + if portal_type != 'Persona': + return + pass + + def createPDCandMigrateOldCTs(portal_type): + logger.info(f"Fixing Punto di Contatto for '{portal_type}'...") # noqa + fixed_total = 0 + mapping = type_mapping[portal_type]["PDC"] + if not mapping: + logger.info(f"No need to fix Punto di Contatto for '{portal_type}: DONE") + return + for brain in api.content.find(portal_type=portal_type): + item = brain.getObject() + kwargs = { + "value_punto_contatto": [], + "persona": [] + } + for key, value in mapping.items(): + import pdb; pdb.set_trace() + + if hasattr(item, key): + kwargs["value_punto_contatto"].append({ + 'pdc_type': value, + 'pdc_value': item[key] + }) + + new_pdc = api.content.create( + type='PuntoDiContatto', + title=f"Punto di Contatto {item.id}", + container=item + ) + intids = getUtility(IIntIds) + import pdb; pdb.set_trace() + item.contact_info = [RelationValue(intids.getId(new_pdc))] + fixed_total += 1 + + logger.info(f"Fixing Punto di Contatto for '{portal_type}: DONE") + logger.info("Updated {} objects".format(fixed_total)) + + for pt in type_mapping: + logger.info("Migrating existing CTs for use with new Incarico and PDC Content Types") + createPDCandMigrateOldCTs(pt) + createIncaricoAndMigratePersona(pt) diff --git a/src/design/plone/contenttypes/vocabularies/pdc_value_type.py b/src/design/plone/contenttypes/vocabularies/pdc_value_type.py index 95f64ef3..fafe5d07 100644 --- a/src/design/plone/contenttypes/vocabularies/pdc_value_type.py +++ b/src/design/plone/contenttypes/vocabularies/pdc_value_type.py @@ -25,6 +25,7 @@ def __call__(self, context): VocabItem("phone", _("Telefono")), VocabItem("web", _("URL")), VocabItem("email", _("Email")), + VocabItem("pec", _("PEC")), VocabItem("social", _("Social")), VocabItem("fax", _("Fax")), From a9c8eb439b1221bda2b73037d31d4aa350ed7863 Mon Sep 17 00:00:00 2001 From: Martina Bustacchini Date: Thu, 22 Dec 2022 12:03:33 +0100 Subject: [PATCH 010/487] wip: contatti e incarichi refinement --- .../plone/contenttypes/events/configure.zcml | 6 +++- .../plone/contenttypes/events/incarico.py | 36 +++++++++++++++++++ .../plone/contenttypes/events/persona.py | 6 ---- .../plone/contenttypes/interfaces/persona.py | 27 ++++++++++++++ .../restapi/serializers/summary.py | 12 ++++++- 5 files changed, 79 insertions(+), 8 deletions(-) create mode 100644 src/design/plone/contenttypes/events/incarico.py diff --git a/src/design/plone/contenttypes/events/configure.zcml b/src/design/plone/contenttypes/events/configure.zcml index 4f12581e..51a38130 100644 --- a/src/design/plone/contenttypes/events/configure.zcml +++ b/src/design/plone/contenttypes/events/configure.zcml @@ -58,7 +58,11 @@ zope.lifecycleevent.interfaces.IObjectAddedEvent" handler=".bando.bandoCreateHandler" /> - + Date: Thu, 22 Dec 2022 12:30:46 +0100 Subject: [PATCH 011/487] reverting to initial state, moved pdc and incarico wips to another branch --- setup.py | 1 - .../contenttypes/behaviors/configure.zcml | 24 --- .../plone/contenttypes/behaviors/contatti.py | 204 +++++------------- .../plone/contenttypes/behaviors/evento.py | 52 ++++- .../plone/contenttypes/behaviors/luogo.py | 57 ++++- .../plone/contenttypes/content/incarico.py | 9 - .../contenttypes/content/punto_di_contatto.py | 9 - .../plone/contenttypes/interfaces/incarico.py | 173 --------------- .../plone/contenttypes/interfaces/persona.py | 87 ++++++-- .../interfaces/punto_di_contatto.py | 78 ------- .../interfaces/unita_organizzativa.py | 22 +- .../profiles/default/metadata.xml | 2 +- .../contenttypes/profiles/default/rolemap.xml | 12 -- .../contenttypes/profiles/default/types.xml | 2 - .../profiles/default/types/Event.xml | 3 +- .../profiles/default/types/Incarico.xml | 107 --------- .../profiles/default/types/Persona.xml | 1 - .../default/types/PuntoDiContatto.xml | 106 --------- .../profiles/default/types/Servizio.xml | 1 - .../restapi/services/types/get.py | 8 - .../contenttypes/restapi/types/adapters.py | 64 ------ .../contenttypes/restapi/types/configure.zcml | 3 - .../contenttypes/upgrades/configure.zcml | 10 - .../plone/contenttypes/upgrades/upgrades.py | 115 ---------- .../contenttypes/vocabularies/configure.zcml | 5 - .../vocabularies/pdc_value_type.py | 49 ----- 26 files changed, 242 insertions(+), 962 deletions(-) delete mode 100644 src/design/plone/contenttypes/content/incarico.py delete mode 100644 src/design/plone/contenttypes/content/punto_di_contatto.py delete mode 100644 src/design/plone/contenttypes/interfaces/incarico.py delete mode 100644 src/design/plone/contenttypes/interfaces/punto_di_contatto.py delete mode 100644 src/design/plone/contenttypes/profiles/default/types/Incarico.xml delete mode 100644 src/design/plone/contenttypes/profiles/default/types/PuntoDiContatto.xml delete mode 100644 src/design/plone/contenttypes/vocabularies/pdc_value_type.py diff --git a/setup.py b/setup.py index 6b3f2a98..6c8ed181 100644 --- a/setup.py +++ b/setup.py @@ -59,7 +59,6 @@ "plone.app.dexterity>2.6.9", "collective.venue[geolocation]", "collective.volto.blocksfield", - "collective.z3cform.datagridfield", "plone.formwidget.geolocation", "redturtle.volto", "redturtle.bandi", diff --git a/src/design/plone/contenttypes/behaviors/configure.zcml b/src/design/plone/contenttypes/behaviors/configure.zcml index 94e740ca..c8a8a8ca 100644 --- a/src/design/plone/contenttypes/behaviors/configure.zcml +++ b/src/design/plone/contenttypes/behaviors/configure.zcml @@ -208,30 +208,6 @@ provides=".contatti.IContattiVenue" marker=".contatti.IContattiVenue" /> - - - - 6010 + 6000 profile-redturtle.bandi:default profile-collective.venue:default diff --git a/src/design/plone/contenttypes/profiles/default/rolemap.xml b/src/design/plone/contenttypes/profiles/default/rolemap.xml index 6629737a..33aa1b71 100644 --- a/src/design/plone/contenttypes/profiles/default/rolemap.xml +++ b/src/design/plone/contenttypes/profiles/default/rolemap.xml @@ -117,18 +117,6 @@ - - - - - - - - - - - - diff --git a/src/design/plone/contenttypes/profiles/default/types.xml b/src/design/plone/contenttypes/profiles/default/types.xml index 6bfe5e5c..cdc991e8 100644 --- a/src/design/plone/contenttypes/profiles/default/types.xml +++ b/src/design/plone/contenttypes/profiles/default/types.xml @@ -13,6 +13,4 @@ - - diff --git a/src/design/plone/contenttypes/profiles/default/types/Event.xml b/src/design/plone/contenttypes/profiles/default/types/Event.xml index e21af13c..93b6e741 100644 --- a/src/design/plone/contenttypes/profiles/default/types/Event.xml +++ b/src/design/plone/contenttypes/profiles/default/types/Event.xml @@ -17,10 +17,9 @@ - + - diff --git a/src/design/plone/contenttypes/profiles/default/types/Incarico.xml b/src/design/plone/contenttypes/profiles/default/types/Incarico.xml deleted file mode 100644 index 10862784..00000000 --- a/src/design/plone/contenttypes/profiles/default/types/Incarico.xml +++ /dev/null @@ -1,107 +0,0 @@ - - - - - Incarico - - - False - Incarico - - - - - True - False - - - - - design.plone.contenttypes.AddIncarico - design.plone.contenttypes.content.incarico.Incarico - - - design.plone.contenttypes.interfaces.incarico.IIncarico - - - - - - - - - - - - - - - - - - - - - - - string:${folder_url}/++add++Incarico - view - False - view - - - - - - - - - - - - - - - - - - - diff --git a/src/design/plone/contenttypes/profiles/default/types/Persona.xml b/src/design/plone/contenttypes/profiles/default/types/Persona.xml index 1760e335..bf2d0fb3 100644 --- a/src/design/plone/contenttypes/profiles/default/types/Persona.xml +++ b/src/design/plone/contenttypes/profiles/default/types/Persona.xml @@ -49,7 +49,6 @@ - diff --git a/src/design/plone/contenttypes/profiles/default/types/PuntoDiContatto.xml b/src/design/plone/contenttypes/profiles/default/types/PuntoDiContatto.xml deleted file mode 100644 index cfe4b273..00000000 --- a/src/design/plone/contenttypes/profiles/default/types/PuntoDiContatto.xml +++ /dev/null @@ -1,106 +0,0 @@ - - - - - Punto di Contatto - - - False - PuntoDiContatto - - - - - True - False - - - - - design.plone.contenttypes.AddPuntoDiContatto - design.plone.contenttypes.content.punto_di_contatto.PuntoDiContatto - - - design.plone.contenttypes.interfaces.punto_di_contatto.IPuntoDiContatto - - - - - - - - - - - - - - - - - - - - - - string:${folder_url}/++add++PuntoDiContatto - view - False - view - - - - - - - - - - - - - - - - - - - diff --git a/src/design/plone/contenttypes/profiles/default/types/Servizio.xml b/src/design/plone/contenttypes/profiles/default/types/Servizio.xml index 28301b53..118f1ad7 100644 --- a/src/design/plone/contenttypes/profiles/default/types/Servizio.xml +++ b/src/design/plone/contenttypes/profiles/default/types/Servizio.xml @@ -50,7 +50,6 @@ - diff --git a/src/design/plone/contenttypes/restapi/services/types/get.py b/src/design/plone/contenttypes/restapi/services/types/get.py index f7ce952e..c1038049 100644 --- a/src/design/plone/contenttypes/restapi/services/types/get.py +++ b/src/design/plone/contenttypes/restapi/services/types/get.py @@ -51,11 +51,6 @@ class FieldsetsMismatchError(Exception): "settings", "ownership", ], - "Incarico": [ - 'default', - 'informazioni_compensi', - 'date_e_informazioni', - ], "News Item": [ "default", "dates", @@ -93,9 +88,6 @@ class FieldsetsMismatchError(Exception): "ownership", "settings", ], - "PuntoDiContatto": [ - 'default', - ], "Servizio": [ "default", "cose", diff --git a/src/design/plone/contenttypes/restapi/types/adapters.py b/src/design/plone/contenttypes/restapi/types/adapters.py index 38d4f3cb..35a96361 100644 --- a/src/design/plone/contenttypes/restapi/types/adapters.py +++ b/src/design/plone/contenttypes/restapi/types/adapters.py @@ -6,15 +6,6 @@ from zope.interface import implementer from zope.interface import Interface from zope.schema.interfaces import IField, IVocabularyFactory -from collective.z3cform.datagridfield.interfaces import IRow -from plone import api -from plone.restapi.types.adapters import ListJsonSchemaProvider -from plone.restapi.types.utils import get_fieldsets -from plone.restapi.types.utils import get_jsonschema_properties -from plone.restapi.types.utils import iter_fields -from zope.schema.interfaces import IList -from design.plone.contenttypes.interfaces import IDesignPloneContenttypesLayer - from design.plone.contenttypes import _ @@ -45,58 +36,3 @@ def get_schema(self): schema["description"] = translate(msgid, context=self.request) return schema - - -@adapter(IList, Interface, IDesignPloneContenttypesLayer) -@implementer(IJsonSchemaProvider) -class DataGridFieldJsonSchemaProvider(ListJsonSchemaProvider): - def get_widget(self): - if self.field.getName() == "value_punto_contatto": - return "data_grid" - return super().get_widget() - - -@adapter(IRow, Interface, Interface) -@implementer(IJsonSchemaProvider) -class DataGridRowJsonSchemaProvider(ObjectJsonSchemaProvider): - def __init__(self, field, context, request): - super().__init__(field, context, request) - self.fieldsets = get_fieldsets(context, request, self.field.schema) - - def get_factory(self): - return "DataGridField Row" - - def get_properties(self): - if self.prefix: - prefix = ".".join([self.prefix, self.field.__name__]) - else: - prefix = self.field.__name__ - return get_jsonschema_properties( - self.context, self.request, self.fieldsets, prefix - ) - - def additional(self): - info = super().additional() - properties = self.get_properties() - required = [] - for field in iter_fields(self.fieldsets): - name = field.field.getName() - - # Determine required fields - if field.field.required: - required.append(name) - - # Include field modes - if field.mode: - properties[name]["mode"] = field.mode - - info["fieldsets"] = [ - { - "id": "default", - "title": "Default", - "fields": [x for x in properties.keys()], - }, - ] - info["required"] = required - info["properties"] = properties - return info diff --git a/src/design/plone/contenttypes/restapi/types/configure.zcml b/src/design/plone/contenttypes/restapi/types/configure.zcml index b56c3e96..b3b754d1 100644 --- a/src/design/plone/contenttypes/restapi/types/configure.zcml +++ b/src/design/plone/contenttypes/restapi/types/configure.zcml @@ -8,8 +8,5 @@ factory=".adapters.LeadImageJsonSchemaProvider" name="ILeadImageBehavior.image" /> - - - diff --git a/src/design/plone/contenttypes/upgrades/configure.zcml b/src/design/plone/contenttypes/upgrades/configure.zcml index f3512207..24871bac 100644 --- a/src/design/plone/contenttypes/upgrades/configure.zcml +++ b/src/design/plone/contenttypes/upgrades/configure.zcml @@ -581,14 +581,4 @@ handler=".upgrades.to_6000" /> - - - diff --git a/src/design/plone/contenttypes/upgrades/upgrades.py b/src/design/plone/contenttypes/upgrades/upgrades.py index 63f41eb8..a840a6f7 100644 --- a/src/design/plone/contenttypes/upgrades/upgrades.py +++ b/src/design/plone/contenttypes/upgrades/upgrades.py @@ -17,9 +17,6 @@ from zope.intid.interfaces import IIntIds from zope.lifecycleevent import ObjectModifiedEvent from zope.schema import getFields -from zope.component import getUtility -from zope.intid.interfaces import IIntIds -from z3c.relationfield import RelationValue import logging import json @@ -968,115 +965,3 @@ def to_6000(context): behaviors.append(behavior) fti.behaviors = tuple(behaviors) - - -def to_6010(context): - """ """ - update_types(context) - update_registry(context) - update_catalog(context) - update_rolemap(context) - - -def migrate_pdc_and_incarico(context): - # Cannot test rn, blid coding - update_types(context) - update_registry(context) - update_catalog(context) - update_rolemap(context) - type_mapping = { - "Persona": { - 'PDC': { - "telefono": "phone", - "fax": "fax", - "email": "email", - "pec": "pec", - }, - "Incarico": { - "atto_nomina": "atto_nomina", - "data_conclusione_incarico": "data_conclusione_incarico", - "data_insediamento": "data_insediamento", - } - }, - "UnitaOrganizzativa": { - 'PDC': { - "telefono": "phone", - "fax": "fax", - "email": "email", - "pec": "pec", - }, - }, - # TODO: tbc - "Event": { - 'PDC': { - "telefono": "phone", - "fax": "fax", - "email": "email", - "pec": "pec", - }, - }, - # TODO: tbc - "Venue": { - 'PDC': { - "telefono": "phone", - "fax": "fax", - "email": "email", - "pec": "pec", - }, - }, - # TODO: tbc - "Servizio": { - 'PDC': { - "telefono": "phone", - "fax": "fax", - "email": "email", - "pec": "pec", - }, - }, - } - - def createIncaricoAndMigratePersona(portal_type): - # Taxonomies work needs to be completed before - if portal_type != 'Persona': - return - pass - - def createPDCandMigrateOldCTs(portal_type): - logger.info(f"Fixing Punto di Contatto for '{portal_type}'...") # noqa - fixed_total = 0 - mapping = type_mapping[portal_type]["PDC"] - if not mapping: - logger.info(f"No need to fix Punto di Contatto for '{portal_type}: DONE") - return - for brain in api.content.find(portal_type=portal_type): - item = brain.getObject() - kwargs = { - "value_punto_contatto": [], - "persona": [] - } - for key, value in mapping.items(): - import pdb; pdb.set_trace() - - if hasattr(item, key): - kwargs["value_punto_contatto"].append({ - 'pdc_type': value, - 'pdc_value': item[key] - }) - - new_pdc = api.content.create( - type='PuntoDiContatto', - title=f"Punto di Contatto {item.id}", - container=item - ) - intids = getUtility(IIntIds) - import pdb; pdb.set_trace() - item.contact_info = [RelationValue(intids.getId(new_pdc))] - fixed_total += 1 - - logger.info(f"Fixing Punto di Contatto for '{portal_type}: DONE") - logger.info("Updated {} objects".format(fixed_total)) - - for pt in type_mapping: - logger.info("Migrating existing CTs for use with new Incarico and PDC Content Types") - createPDCandMigrateOldCTs(pt) - createIncaricoAndMigratePersona(pt) diff --git a/src/design/plone/contenttypes/vocabularies/configure.zcml b/src/design/plone/contenttypes/vocabularies/configure.zcml index c0b67b33..0daf55eb 100644 --- a/src/design/plone/contenttypes/vocabularies/configure.zcml +++ b/src/design/plone/contenttypes/vocabularies/configure.zcml @@ -74,10 +74,5 @@ name="design.plone.vocabularies.uo_locations" component=".reference_vocabularies.UOLocationVocabularyFactory" /> - - diff --git a/src/design/plone/contenttypes/vocabularies/pdc_value_type.py b/src/design/plone/contenttypes/vocabularies/pdc_value_type.py deleted file mode 100644 index fafe5d07..00000000 --- a/src/design/plone/contenttypes/vocabularies/pdc_value_type.py +++ /dev/null @@ -1,49 +0,0 @@ -# -*- coding: utf-8 -*- -from design.plone.contenttypes import _ -from plone.dexterity.interfaces import IDexterityContent -from zope.globalrequest import getRequest -from zope.interface import implementer -from zope.schema.interfaces import IVocabularyFactory -from zope.schema.vocabulary import SimpleTerm -from zope.schema.vocabulary import SimpleVocabulary - - -class VocabItem(object): - def __init__(self, token, value): - self.token = token - self.value = value - - -@implementer(IVocabularyFactory) -class PDCValueType(object): - """ """ - - def __call__(self, context): - # Just an example list of content for our vocabulary, - # this can be any static or dynamic data, a catalog result for example. - items = [ - VocabItem("phone", _("Telefono")), - VocabItem("web", _("URL")), - VocabItem("email", _("Email")), - VocabItem("pec", _("PEC")), - VocabItem("social", _("Social")), - VocabItem("fax", _("Fax")), - - ] - # Fix context if you are using the vocabulary in DataGridField. - # See https://github.com/collective/collective.z3cform.datagridfield/issues/31: # NOQA: 501 - if not IDexterityContent.providedBy(context): - req = getRequest() - context = req.PARENTS[0] - - # create a list of SimpleTerm items: - terms = [] - for item in items: - terms.append( - SimpleTerm(value=item.token, token=str(item.token), title=item.value) - ) - # Create a SimpleVocabulary from the terms list and return it: - return SimpleVocabulary(terms) - - -PDCValueTypeFactory = PDCValueType() From 180659b4e5ce147d88a56038132ee1525002572b Mon Sep 17 00:00:00 2001 From: Martina Bustacchini Date: Thu, 22 Dec 2022 13:10:45 +0100 Subject: [PATCH 012/487] wip: comments and fix permissions --- src/design/plone/contenttypes/permissions.zcml | 10 ++++++++++ .../plone/contenttypes/upgrades/upgrades.py | 17 +++++++++++++---- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/design/plone/contenttypes/permissions.zcml b/src/design/plone/contenttypes/permissions.zcml index b99b090b..300d7f52 100644 --- a/src/design/plone/contenttypes/permissions.zcml +++ b/src/design/plone/contenttypes/permissions.zcml @@ -96,6 +96,16 @@ title="design.plone.contenttypes: Add Modulo" /> + + + + diff --git a/src/design/plone/contenttypes/upgrades/upgrades.py b/src/design/plone/contenttypes/upgrades/upgrades.py index 63f41eb8..dd6290da 100644 --- a/src/design/plone/contenttypes/upgrades/upgrades.py +++ b/src/design/plone/contenttypes/upgrades/upgrades.py @@ -979,11 +979,12 @@ def to_6010(context): def migrate_pdc_and_incarico(context): - # Cannot test rn, blid coding + # Cannot test rn, blind coding update_types(context) update_registry(context) update_catalog(context) update_rolemap(context) + # "field name in original ct": "field name in new ct" type_mapping = { "Persona": { 'PDC': { @@ -993,6 +994,12 @@ def migrate_pdc_and_incarico(context): "pec": "pec", }, "Incarico": { + # HOW? Need taxonomies also + # We could do: + # persona.ruolo.title = incarico.title + # persona.items.compensi = incarico.items.compensi? + "ruolo?": "incarico?", + # BlobFile to relation with Documento "atto_nomina": "atto_nomina", "data_conclusione_incarico": "data_conclusione_incarico", "data_insediamento": "data_insediamento", @@ -1037,14 +1044,16 @@ def migrate_pdc_and_incarico(context): def createIncaricoAndMigratePersona(portal_type): # Taxonomies work needs to be completed before - if portal_type != 'Persona': + if portal_type == 'Persona': return pass def createPDCandMigrateOldCTs(portal_type): logger.info(f"Fixing Punto di Contatto for '{portal_type}'...") # noqa fixed_total = 0 - mapping = type_mapping[portal_type]["PDC"] + mapping = None + # mapping = type_mapping[portal_type]["PDC"] + # Reenable mapping to use if not mapping: logger.info(f"No need to fix Punto di Contatto for '{portal_type}: DONE") return @@ -1066,7 +1075,7 @@ def createPDCandMigrateOldCTs(portal_type): new_pdc = api.content.create( type='PuntoDiContatto', title=f"Punto di Contatto {item.id}", - container=item + container=item, ) intids = getUtility(IIntIds) import pdb; pdb.set_trace() From 4a5f1e53826f61a34282e49d03147be0b5e4e3c5 Mon Sep 17 00:00:00 2001 From: Martina Bustacchini Date: Thu, 22 Dec 2022 15:10:54 +0100 Subject: [PATCH 013/487] fix: ct Incarico and PDC fields --- .../plone/contenttypes/interfaces/incarico.py | 22 --------- .../interfaces/punto_di_contatto.py | 23 --------- .../plone/contenttypes/upgrades/upgrades.py | 48 ++++++++++++++++--- 3 files changed, 42 insertions(+), 51 deletions(-) diff --git a/src/design/plone/contenttypes/interfaces/incarico.py b/src/design/plone/contenttypes/interfaces/incarico.py index 20e2c3aa..dbf3d3ea 100644 --- a/src/design/plone/contenttypes/interfaces/incarico.py +++ b/src/design/plone/contenttypes/interfaces/incarico.py @@ -39,19 +39,6 @@ class IIncarico(model.Schema, IDesignPloneContentType): required=False, ) - persona = RelationList( - title=_( - "persona_incarico_label", - default="Persona", - ), - description=_( - "persona_incarico_help", - default="Seleziona la/e persona/e che ha/hanno la carica e l'incarico.", - ), - value_type=RelationChoice(vocabulary="plone.app.vocabularies.Catalog"), - required=True, - default=[], - ) unita_organizzativa = RelationList( title=_( @@ -131,15 +118,6 @@ class IIncarico(model.Schema, IDesignPloneContentType): }, ) - form.widget( - "persona", - RelatedItemsFieldWidget, - vocabulary="plone.app.vocabularies.Catalog", - pattern_options={ - "maximumSelectionSize": 1, - "selectableTypes": ["Persona"], - }, - ) form.widget( "responsabile_struttura", RelatedItemsFieldWidget, diff --git a/src/design/plone/contenttypes/interfaces/punto_di_contatto.py b/src/design/plone/contenttypes/interfaces/punto_di_contatto.py index 1df36d9e..deb10582 100644 --- a/src/design/plone/contenttypes/interfaces/punto_di_contatto.py +++ b/src/design/plone/contenttypes/interfaces/punto_di_contatto.py @@ -48,31 +48,8 @@ class IPuntoDiContatto(model.Schema, IDesignPloneContentType): required=True, ) - persona = RelationList( - title=_( - "persona_incarico_label", - default="Persona", - ), - description=_( - "persona_incarico_help", - default="Seleziona la persona che ha la carica e l'incarico.", - ), - value_type=RelationChoice(vocabulary="plone.app.vocabularies.Catalog"), - required=False, - default=[], - ) - form.widget( "value_punto_contatto", DataGridFieldFactory, ) - form.widget( - "persona", - RelatedItemsFieldWidget, - vocabulary="plone.app.vocabularies.Catalog", - pattern_options={ - "maximumSelectionSize": 1, - "selectableTypes": ["Persona"], - }, - ) diff --git a/src/design/plone/contenttypes/upgrades/upgrades.py b/src/design/plone/contenttypes/upgrades/upgrades.py index dd6290da..f69ddafb 100644 --- a/src/design/plone/contenttypes/upgrades/upgrades.py +++ b/src/design/plone/contenttypes/upgrades/upgrades.py @@ -1025,14 +1025,15 @@ def migrate_pdc_and_incarico(context): # TODO: tbc "Venue": { 'PDC': { - "telefono": "phone", - "fax": "fax", - "email": "email", - "pec": "pec", + "riferimento_telefonico_struttura": "phone", + "riferimento_fax_struttura": "fax", + "riferimento_mail_struttura": "email", + "riferimento_pec_struttura": "pec", }, }, # TODO: tbc "Servizio": { + # questi non sono presenti sul ct originale 'PDC': { "telefono": "phone", "fax": "fax", @@ -1043,9 +1044,43 @@ def migrate_pdc_and_incarico(context): } def createIncaricoAndMigratePersona(portal_type): - # Taxonomies work needs to be completed before + # Taxonomies work needs to be completed before, blind coding ahead if portal_type == 'Persona': - return + fixed_total = 0 + for brain in api.content.find(portal_type=portal_type): + item = brain.getObject() + atto_nomina = item.atto_nomina + logger.info(f"Fixing Punto di Contatto for '{item.title}'...") # noqa + file_bog = api.content.find(context=item, depth=1, id='atti-nomina') + if not file_bog: + try: + file_bog = api.content.create( + type="Document", id="atti-nomina", title="Atti Nomina", container=item + ) + except Exception: + logger.error("Error", Exception) + + try: + new_atto_nomina = api.content.create( + type="File", + id=atto_nomina.id, + title=atto_nomina.title, + container=item, + **{'file': atto_nomina} + ) + intids = getUtility(IIntIds) + relation = [RelationValue(intids.getId(new_atto_nomina))] + incarico = api.content.create( + type="Incarico", title=item.ruolo.title, container=item + ) + incarico.atto_nomina = relation + item.atto_nomina = None + fixed_total += 1 + logger.info(f"Fixing Punto di Contatto for '{item.title}'...:DONE") # noqa + except Exception: + logger.error("Error", Exception) + logger.info("Updated {} objects".format(fixed_total)) + pass def createPDCandMigrateOldCTs(portal_type): @@ -1076,6 +1111,7 @@ def createPDCandMigrateOldCTs(portal_type): type='PuntoDiContatto', title=f"Punto di Contatto {item.id}", container=item, + **kwargs, ) intids = getUtility(IIntIds) import pdb; pdb.set_trace() From 1160daafcb64c6f0d2c2fe0d867f3aa016557c46 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Fri, 23 Dec 2022 16:13:35 +0100 Subject: [PATCH 014/487] cambiato lo schema del servizio --- .gitignore | 1 + .../plone/contenttypes/behaviors/argomenti.py | 32 ++- .../contenttypes/behaviors/configure.zcml | 9 + .../behaviors/descrizione_estesa.py | 13 +- .../plone/contenttypes/interfaces/servizio.py | 48 +++-- .../profiles/default/metadata.xml | 2 +- .../profiles/default/types/Servizio.xml | 3 +- .../restapi/deserializers/configure.zcml | 1 + .../restapi/deserializers/servizio.py | 193 ++++++++++++++++++ .../restapi/services/types/get.py | 6 + .../contenttypes/upgrades/configure.zcml | 8 + .../plone/contenttypes/upgrades/upgrades.py | 5 + 12 files changed, 304 insertions(+), 17 deletions(-) create mode 100644 src/design/plone/contenttypes/restapi/deserializers/servizio.py diff --git a/.gitignore b/.gitignore index 15f86be8..e376ec3b 100644 --- a/.gitignore +++ b/.gitignore @@ -44,3 +44,4 @@ reports/ !src/design pyvenv.cfg .Python +.history/ diff --git a/src/design/plone/contenttypes/behaviors/argomenti.py b/src/design/plone/contenttypes/behaviors/argomenti.py index 22a8fcca..60697470 100644 --- a/src/design/plone/contenttypes/behaviors/argomenti.py +++ b/src/design/plone/contenttypes/behaviors/argomenti.py @@ -3,6 +3,7 @@ from design.plone.contenttypes import _ from design.plone.contenttypes.interfaces.bando import IBandoAgidSchema from design.plone.contenttypes.interfaces.documento import IDocumento +from design.plone.contenttypes.interfaces.servizio import IServizio from plone.app.contenttypes.interfaces import IDocument from plone.app.z3cform.widget import RelatedItemsFieldWidget from plone.autoform import directives as form @@ -18,7 +19,7 @@ class IArgomentiSchema(model.Schema): """Marker interface for Argomenti""" tassonomia_argomenti = RelationList( - title=_("tassonomia_argomenti_label", default="Tassonomia argomenti"), + title=_("tassonomia_argomenti_label", default="Argomenti"), description=_( "tassonomia_argomenti_help", default="Seleziona una lista di argomenti d'interesse per questo" @@ -65,6 +66,8 @@ class IArgomentiSchema(model.Schema): textindexer.searchable("tassonomia_argomenti") + + @provider(IFormFieldProvider) class IArgomenti(IArgomentiSchema): """ """ @@ -77,6 +80,24 @@ class IArgomenti(IArgomentiSchema): form.order_after(correlato_in_evidenza="IRelatedItems.relatedItems") +@provider(IFormFieldProvider) +class IArgomentiServizio(IArgomentiSchema): + + tassonomia_argomenti = RelationList( + title=_("tassonomia_argomenti_label", default="Argomenti"), + description=_( + "tassonomia_argomenti_help", + default="Seleziona una lista di argomenti d'interesse per questo" + " contenuto.", + ), + value_type=RelationChoice( + title=_("Argomenti correlati"), + vocabulary="plone.app.vocabularies.Catalog", + ), + required=True, + default=[], + ) + @provider(IFormFieldProvider) class IArgomentiDocumento(IArgomentiSchema): """ """ @@ -155,3 +176,12 @@ class ArgomentiDocument(object): def __init__(self, context): self.context = context + + +@implementer(IArgomentiServizio) +@adapter(IServizio) +class ArgomentiServizio(object): + """""" + + def __init__(self, context): + self.context = context diff --git a/src/design/plone/contenttypes/behaviors/configure.zcml b/src/design/plone/contenttypes/behaviors/configure.zcml index 94e740ca..a2870264 100644 --- a/src/design/plone/contenttypes/behaviors/configure.zcml +++ b/src/design/plone/contenttypes/behaviors/configure.zcml @@ -74,6 +74,15 @@ for="plone.dexterity.interfaces.IDexterityContent" marker=".argomenti.IArgomentiBando" /> + - 6010 + 6011 profile-redturtle.bandi:default profile-collective.venue:default diff --git a/src/design/plone/contenttypes/profiles/default/types/Servizio.xml b/src/design/plone/contenttypes/profiles/default/types/Servizio.xml index 28301b53..b6e6df02 100644 --- a/src/design/plone/contenttypes/profiles/default/types/Servizio.xml +++ b/src/design/plone/contenttypes/profiles/default/types/Servizio.xml @@ -48,7 +48,8 @@ - + + diff --git a/src/design/plone/contenttypes/restapi/deserializers/configure.zcml b/src/design/plone/contenttypes/restapi/deserializers/configure.zcml index ec490e85..a859e49e 100644 --- a/src/design/plone/contenttypes/restapi/deserializers/configure.zcml +++ b/src/design/plone/contenttypes/restapi/deserializers/configure.zcml @@ -4,6 +4,7 @@ > + diff --git a/src/design/plone/contenttypes/restapi/deserializers/servizio.py b/src/design/plone/contenttypes/restapi/deserializers/servizio.py new file mode 100644 index 00000000..ea294183 --- /dev/null +++ b/src/design/plone/contenttypes/restapi/deserializers/servizio.py @@ -0,0 +1,193 @@ +# -*- coding: utf-8 -*- +from design.plone.contenttypes.interfaces.servizio import IServizio +from plone.restapi.deserializer import json_body +from plone.restapi.interfaces import IDeserializeFromJson +from zope.interface import implementer +from zope.component import adapter +from zope.interface import Interface +from plone.restapi.deserializer.dxcontent import DeserializeFromJson +from zExceptions import BadRequest +from plone.restapi.behaviors import IBlocks +from plone.restapi.indexers import SearchableText_blocks + + +TITLE_MAX_LEN = 160 +DESCRIPTION_MAX_LEN = 160 +EMPTY_BLOCK_MARKER = {'@type': 'text'} +MANDATORY_RICH_TEXT_FIELDS = [ + "motivo_stato_servizio", + "a_chi_si_rivolge", + "come_si_fa", + "cosa_serve", + "cosa_si_ottiene", + "tempi_e_scadenze", +] + + +def new_error(message): + return { + "error": "ValidationError", + "message": message + } + + +def text_in_block(blocks): + + @implementer(IBlocks) + class FakeObject(object): + """ + We use a fake object to use SearchableText Indexer + """ + def Subject(self): + return "" + + def __init__(self, blocks, blocks_layout): + self.blocks = blocks + self.blocks_layout = blocks_layout + self.id = "" + self.title = "" + self.description = "" + + if not blocks: + return None + + fakeObj = FakeObject( + blocks.get("blocks", ""), + blocks.get("blocks_layout", "") + ) + return SearchableText_blocks(fakeObj)() + + +@implementer(IDeserializeFromJson) +@adapter(IServizio, Interface) +class DeserializeServizioFromJson(DeserializeFromJson): + def __call__( + self, validate_all=False, data=None, create=False + ): # noqa: ignore=C901 + + if data is None: + data = json_body(self.request) + + method = self.request.get('method') + is_post = method == 'POST' + is_patch = method == 'PATCH' + errors = [] + + title = data.get('title') + description = data.get('description') + # stato_servizio = data.get('stato_servizio') + # motivo_stato_servizio = data.get('motivo_stato_servizio') + + if is_post: + # Title validation + if not title: + errors.append( + new_error( + "Il titolo del servizio è obbligatorio" + ) + ) + elif len(title) > TITLE_MAX_LEN: + errors.append( + new_error( + "Il titolo può avere una lunghezza di massimo {} caratteri".format(TITLE_MAX_LEN) + ) + ) + + # description validation + if not description: + errors.append( + new_error( + "La descrizione del servizio è obbligatorio" + ) + ) + elif len(description) > DESCRIPTION_MAX_LEN: + errors.append( + new_error( + "La descrizione del servizio deve avere una lunghezza di massimo {} caratteri".format(DESCRIPTION_MAX_LEN) + ) + ) + + for field in MANDATORY_RICH_TEXT_FIELDS: + if field == 'motivo_stato_servizio': + if (data.get('stato_servizio') and not data.get("motivo_stato_servizio")) or\ + (data.get('stato_servizio') and not text_in_block(data.get("motivo_stato_servizio"))): + errors.append( + new_error( + "Indicare il motivo per cui il servizio non è fruibile" + ) + ) + elif field not in data: + errors.append( + new_error( + "Il campo {} è obbligatorio".format(field) + ) + ) + elif field in data and not text_in_block(data.get(field)): + errors.append( + new_error( + "Il campo {} è obbligatorio".format(field) + ) + ) + + if is_patch: + # Title validation + if "title" in data and not title: + errors.append( + new_error( + "Il titolo del servizio è obbligatorio" + ) + ) + if title and len(title) > TITLE_MAX_LEN: + errors.append( + new_error( + "Il titolo può avere una lunghezza di massimo {} caratteri".format(TITLE_MAX_LEN) + ) + ) + # description validation + if "description" in data and not description: + errors.append( + new_error( + "La descrizione del servizio è obbligatorio" + ) + ) + if description and len(description) > DESCRIPTION_MAX_LEN: + errors.append( + new_error( + "La descrizione del servizio deve avere una lunghezza di massimo {} caratteri".format(DESCRIPTION_MAX_LEN) + ) + ) + + for field in MANDATORY_RICH_TEXT_FIELDS: + if field == 'motivo_stato_servizio': + if 'stato_servizio' in data and\ + data.get('stato_servizio') and not\ + text_in_block(data.get(field)): + errors.append( + new_error( + "Indicare il motivo per cui il servizio non è fruibile" + ) + ) + elif field in data and not text_in_block(data.get(field)): + errors.append( + new_error( + "Il campo {} è obbligatorio".format(field) + ) + ) + + # Per questo campo dobbiamo controllare anche il contesto: potrei aver + # già scritto sull'oggetto che il servizio non è fruibile e modificare + # solo lo stato + if "stato_servizio" not in data and getattr(self.context, "stato_servizio") and\ + data.get('motivo_stato_servizio') and not\ + text_in_block(data.get('motivo_stato_servizio')): + errors.append( + new_error( + "Indicare il motivo per cui il servizio non è fruibile" + ) + ) + + if errors: + raise BadRequest(errors) + return super(DeserializeServizioFromJson, self).__call__( + validate_all=False, data=data, create=False + ) diff --git a/src/design/plone/contenttypes/restapi/services/types/get.py b/src/design/plone/contenttypes/restapi/services/types/get.py index f7ce952e..7851b99a 100644 --- a/src/design/plone/contenttypes/restapi/services/types/get.py +++ b/src/design/plone/contenttypes/restapi/services/types/get.py @@ -230,6 +230,10 @@ def customize_versioning_fields_fieldset(self, result): return result + def customize_servizio_schema(self, result): + result.get('required').append('description') + return result + def reply(self): result = super(TypesGet, self).reply() @@ -248,6 +252,8 @@ def reply(self): result = self.customize_venue_schema(result) if pt == "Document": result = self.customize_document_schema(result) + if pt == "Servizio": + result = self.customize_servizio_schema(result) result = self.customize_versioning_fields_fieldset(result) return result diff --git a/src/design/plone/contenttypes/upgrades/configure.zcml b/src/design/plone/contenttypes/upgrades/configure.zcml index f3512207..73dbeaf4 100644 --- a/src/design/plone/contenttypes/upgrades/configure.zcml +++ b/src/design/plone/contenttypes/upgrades/configure.zcml @@ -591,4 +591,12 @@ handler=".upgrades.to_6010" /> + diff --git a/src/design/plone/contenttypes/upgrades/upgrades.py b/src/design/plone/contenttypes/upgrades/upgrades.py index 195252c6..59cd7343 100644 --- a/src/design/plone/contenttypes/upgrades/upgrades.py +++ b/src/design/plone/contenttypes/upgrades/upgrades.py @@ -972,3 +972,8 @@ def to_6010(context): update_types(context) update_registry(context) update_catalog(context) + + +def to_6011(context): + """ """ + update_types(context) From dc2f349155ce9e2d9e88c70e7ba4e5c288719fa9 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Fri, 23 Dec 2022 16:31:41 +0100 Subject: [PATCH 015/487] some code clean --- src/design/plone/contenttypes/behaviors/argomenti.py | 3 +-- src/design/plone/contenttypes/behaviors/contatti.py | 2 ++ src/design/plone/contenttypes/behaviors/luogo.py | 1 - .../plone/contenttypes/interfaces/unita_organizzativa.py | 1 - src/design/plone/contenttypes/restapi/types/adapters.py | 1 - 5 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/design/plone/contenttypes/behaviors/argomenti.py b/src/design/plone/contenttypes/behaviors/argomenti.py index 60697470..ec1d4ff3 100644 --- a/src/design/plone/contenttypes/behaviors/argomenti.py +++ b/src/design/plone/contenttypes/behaviors/argomenti.py @@ -66,8 +66,6 @@ class IArgomentiSchema(model.Schema): textindexer.searchable("tassonomia_argomenti") - - @provider(IFormFieldProvider) class IArgomenti(IArgomentiSchema): """ """ @@ -98,6 +96,7 @@ class IArgomentiServizio(IArgomentiSchema): default=[], ) + @provider(IFormFieldProvider) class IArgomentiDocumento(IArgomentiSchema): """ """ diff --git a/src/design/plone/contenttypes/behaviors/contatti.py b/src/design/plone/contenttypes/behaviors/contatti.py index ddaf8ff0..d72479d0 100644 --- a/src/design/plone/contenttypes/behaviors/contatti.py +++ b/src/design/plone/contenttypes/behaviors/contatti.py @@ -164,6 +164,7 @@ class IContattiEvent(model.Schema): fields=["contact_info"], ) + @implementer(IContattiEvent) @adapter(IContattiEvent) class ContattiEvent(object): @@ -181,6 +182,7 @@ class ContattiPersona(object): def __init__(self, context): self.context = context + @implementer(IContattiServizio) @adapter(IServizio) class ContattiServizio(object): diff --git a/src/design/plone/contenttypes/behaviors/luogo.py b/src/design/plone/contenttypes/behaviors/luogo.py index f3ea73f5..b6cd4895 100644 --- a/src/design/plone/contenttypes/behaviors/luogo.py +++ b/src/design/plone/contenttypes/behaviors/luogo.py @@ -88,7 +88,6 @@ class ILuogo(model.Schema): ), ) - # Decisono con Baio di toglierlo: visto il vocabolario, che in realtà sta # qui: https://github.com/italia/daf-ontologie-vocabolari-controllati/tree/master/VocabolariControllati/classifications-for-culture/subject-disciplines # riteniamo che possa non fregare nulla a nessuno di questa categorizzazione. diff --git a/src/design/plone/contenttypes/interfaces/unita_organizzativa.py b/src/design/plone/contenttypes/interfaces/unita_organizzativa.py index 42a1128a..d75353e2 100644 --- a/src/design/plone/contenttypes/interfaces/unita_organizzativa.py +++ b/src/design/plone/contenttypes/interfaces/unita_organizzativa.py @@ -138,7 +138,6 @@ class IUnitaOrganizzativa(model.Schema, IDesignPloneContentType): required=False, ) - #  custom widgets form.widget( "persone_struttura", diff --git a/src/design/plone/contenttypes/restapi/types/adapters.py b/src/design/plone/contenttypes/restapi/types/adapters.py index 38d4f3cb..545e1fda 100644 --- a/src/design/plone/contenttypes/restapi/types/adapters.py +++ b/src/design/plone/contenttypes/restapi/types/adapters.py @@ -7,7 +7,6 @@ from zope.interface import Interface from zope.schema.interfaces import IField, IVocabularyFactory from collective.z3cform.datagridfield.interfaces import IRow -from plone import api from plone.restapi.types.adapters import ListJsonSchemaProvider from plone.restapi.types.utils import get_fieldsets from plone.restapi.types.utils import get_jsonschema_properties From 4bc0047d16ab8d553676a7af1364ea848f7a440d Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Fri, 23 Dec 2022 16:37:48 +0100 Subject: [PATCH 016/487] some code clean --- .../plone/contenttypes/behaviors/contatti.py | 25 +++- .../plone/contenttypes/interfaces/servizio.py | 7 +- .../restapi/deserializers/servizio.py | 116 ++++++++---------- .../restapi/services/types/get.py | 10 +- .../plone/contenttypes/upgrades/upgrades.py | 9 +- .../all_life_events_vocabulary.py | 14 ++- .../contenttypes/vocabularies/dataset.py | 4 +- .../vocabularies/pdc_value_type.py | 1 - .../vocabularies/tags_vocabulary.py | 22 +--- 9 files changed, 101 insertions(+), 107 deletions(-) diff --git a/src/design/plone/contenttypes/behaviors/contatti.py b/src/design/plone/contenttypes/behaviors/contatti.py index d72479d0..2666bb32 100644 --- a/src/design/plone/contenttypes/behaviors/contatti.py +++ b/src/design/plone/contenttypes/behaviors/contatti.py @@ -36,7 +36,10 @@ class IContattiUnitaOrganizzativa(model.Schema): "contact_info", RelatedItemsFieldWidget, vocabulary="plone.app.vocabularies.Catalog", - pattern_options={"maximumSelectionSize": 10, "selectableTypes": ["PuntoDiContatto"]}, + pattern_options={ + "maximumSelectionSize": 10, + "selectableTypes": ["PuntoDiContatto"], + }, ) @@ -63,7 +66,10 @@ class IContattiPersona(model.Schema): "contact_info", RelatedItemsFieldWidget, vocabulary="plone.app.vocabularies.Catalog", - pattern_options={"maximumSelectionSize": 10, "selectableTypes": ["PuntoDiContatto"]}, + pattern_options={ + "maximumSelectionSize": 10, + "selectableTypes": ["PuntoDiContatto"], + }, ) model.fieldset( "contatti", @@ -94,7 +100,10 @@ class IContattiServizio(model.Schema): "contact_info", RelatedItemsFieldWidget, vocabulary="plone.app.vocabularies.Catalog", - pattern_options={"maximumSelectionSize": 10, "selectableTypes": ["PuntoDiContatto"]}, + pattern_options={ + "maximumSelectionSize": 10, + "selectableTypes": ["PuntoDiContatto"], + }, ) model.fieldset( "contatti", @@ -125,7 +134,10 @@ class IContattiVenue(model.Schema): "contact_info", RelatedItemsFieldWidget, vocabulary="plone.app.vocabularies.Catalog", - pattern_options={"maximumSelectionSize": 10, "selectableTypes": ["PuntoDiContatto"]}, + pattern_options={ + "maximumSelectionSize": 10, + "selectableTypes": ["PuntoDiContatto"], + }, ) model.fieldset( "contatti", @@ -156,7 +168,10 @@ class IContattiEvent(model.Schema): "contact_info", RelatedItemsFieldWidget, vocabulary="plone.app.vocabularies.Catalog", - pattern_options={"maximumSelectionSize": 10, "selectableTypes": ["PuntoDiContatto"]}, + pattern_options={ + "maximumSelectionSize": 10, + "selectableTypes": ["PuntoDiContatto"], + }, ) model.fieldset( "contatti", diff --git a/src/design/plone/contenttypes/interfaces/servizio.py b/src/design/plone/contenttypes/interfaces/servizio.py index a04df040..1c7d4486 100644 --- a/src/design/plone/contenttypes/interfaces/servizio.py +++ b/src/design/plone/contenttypes/interfaces/servizio.py @@ -228,7 +228,10 @@ class IServizio(model.Schema, IDesignPloneContentType): # vocabolario dalle unita' organizzative presenti a catalogo? ufficio_responsabile = RelationList( - title=_("ufficio_responsabile_erogazione", default="Unità organizzativa responsabile"), + title=_( + "ufficio_responsabile_erogazione", + default="Unità organizzativa responsabile", + ), description=_( "ufficio_responsabile_help", default="Seleziona gli uffici responsabili dell'erogazione" @@ -312,7 +315,7 @@ class IServizio(model.Schema, IDesignPloneContentType): condizioni_di_servizio = field.NamedBlobFile( title=_("condizioni_di_servizio", default="Condizioni di servizio"), - required=True + required=True, ) servizi_collegati = RelationList( diff --git a/src/design/plone/contenttypes/restapi/deserializers/servizio.py b/src/design/plone/contenttypes/restapi/deserializers/servizio.py index ea294183..342ff998 100644 --- a/src/design/plone/contenttypes/restapi/deserializers/servizio.py +++ b/src/design/plone/contenttypes/restapi/deserializers/servizio.py @@ -13,7 +13,7 @@ TITLE_MAX_LEN = 160 DESCRIPTION_MAX_LEN = 160 -EMPTY_BLOCK_MARKER = {'@type': 'text'} +EMPTY_BLOCK_MARKER = {"@type": "text"} MANDATORY_RICH_TEXT_FIELDS = [ "motivo_stato_servizio", "a_chi_si_rivolge", @@ -25,19 +25,16 @@ def new_error(message): - return { - "error": "ValidationError", - "message": message - } + return {"error": "ValidationError", "message": message} def text_in_block(blocks): - @implementer(IBlocks) class FakeObject(object): """ We use a fake object to use SearchableText Indexer """ + def Subject(self): return "" @@ -51,10 +48,7 @@ def __init__(self, blocks, blocks_layout): if not blocks: return None - fakeObj = FakeObject( - blocks.get("blocks", ""), - blocks.get("blocks_layout", "") - ) + fakeObj = FakeObject(blocks.get("blocks", ""), blocks.get("blocks_layout", "")) return SearchableText_blocks(fakeObj)() @@ -68,122 +62,110 @@ def __call__( if data is None: data = json_body(self.request) - method = self.request.get('method') - is_post = method == 'POST' - is_patch = method == 'PATCH' + method = self.request.get("method") + is_post = method == "POST" + is_patch = method == "PATCH" errors = [] - title = data.get('title') - description = data.get('description') + title = data.get("title") + description = data.get("description") # stato_servizio = data.get('stato_servizio') # motivo_stato_servizio = data.get('motivo_stato_servizio') if is_post: # Title validation if not title: - errors.append( - new_error( - "Il titolo del servizio è obbligatorio" - ) - ) + errors.append(new_error("Il titolo del servizio è obbligatorio")) elif len(title) > TITLE_MAX_LEN: errors.append( new_error( - "Il titolo può avere una lunghezza di massimo {} caratteri".format(TITLE_MAX_LEN) + "Il titolo può avere una lunghezza di massimo {} caratteri".format( + TITLE_MAX_LEN + ) ) ) # description validation if not description: - errors.append( - new_error( - "La descrizione del servizio è obbligatorio" - ) - ) + errors.append(new_error("La descrizione del servizio è obbligatorio")) elif len(description) > DESCRIPTION_MAX_LEN: errors.append( new_error( - "La descrizione del servizio deve avere una lunghezza di massimo {} caratteri".format(DESCRIPTION_MAX_LEN) + "La descrizione del servizio deve avere una lunghezza di massimo {} caratteri".format( + DESCRIPTION_MAX_LEN + ) ) ) for field in MANDATORY_RICH_TEXT_FIELDS: - if field == 'motivo_stato_servizio': - if (data.get('stato_servizio') and not data.get("motivo_stato_servizio")) or\ - (data.get('stato_servizio') and not text_in_block(data.get("motivo_stato_servizio"))): + if field == "motivo_stato_servizio": + if ( + data.get("stato_servizio") + and not data.get("motivo_stato_servizio") + ) or ( + data.get("stato_servizio") + and not text_in_block(data.get("motivo_stato_servizio")) + ): errors.append( new_error( "Indicare il motivo per cui il servizio non è fruibile" ) ) elif field not in data: - errors.append( - new_error( - "Il campo {} è obbligatorio".format(field) - ) - ) + errors.append(new_error("Il campo {} è obbligatorio".format(field))) elif field in data and not text_in_block(data.get(field)): - errors.append( - new_error( - "Il campo {} è obbligatorio".format(field) - ) - ) + errors.append(new_error("Il campo {} è obbligatorio".format(field))) if is_patch: # Title validation if "title" in data and not title: - errors.append( - new_error( - "Il titolo del servizio è obbligatorio" - ) - ) + errors.append(new_error("Il titolo del servizio è obbligatorio")) if title and len(title) > TITLE_MAX_LEN: errors.append( new_error( - "Il titolo può avere una lunghezza di massimo {} caratteri".format(TITLE_MAX_LEN) + "Il titolo può avere una lunghezza di massimo {} caratteri".format( + TITLE_MAX_LEN + ) ) ) # description validation if "description" in data and not description: - errors.append( - new_error( - "La descrizione del servizio è obbligatorio" - ) - ) + errors.append(new_error("La descrizione del servizio è obbligatorio")) if description and len(description) > DESCRIPTION_MAX_LEN: errors.append( new_error( - "La descrizione del servizio deve avere una lunghezza di massimo {} caratteri".format(DESCRIPTION_MAX_LEN) + "La descrizione del servizio deve avere una lunghezza di massimo {} caratteri".format( + DESCRIPTION_MAX_LEN + ) ) ) for field in MANDATORY_RICH_TEXT_FIELDS: - if field == 'motivo_stato_servizio': - if 'stato_servizio' in data and\ - data.get('stato_servizio') and not\ - text_in_block(data.get(field)): + if field == "motivo_stato_servizio": + if ( + "stato_servizio" in data + and data.get("stato_servizio") + and not text_in_block(data.get(field)) + ): errors.append( new_error( "Indicare il motivo per cui il servizio non è fruibile" ) ) elif field in data and not text_in_block(data.get(field)): - errors.append( - new_error( - "Il campo {} è obbligatorio".format(field) - ) - ) + errors.append(new_error("Il campo {} è obbligatorio".format(field))) # Per questo campo dobbiamo controllare anche il contesto: potrei aver # già scritto sull'oggetto che il servizio non è fruibile e modificare # solo lo stato - if "stato_servizio" not in data and getattr(self.context, "stato_servizio") and\ - data.get('motivo_stato_servizio') and not\ - text_in_block(data.get('motivo_stato_servizio')): + if ( + "stato_servizio" not in data + and getattr(self.context, "stato_servizio") + and data.get("motivo_stato_servizio") + and not text_in_block(data.get("motivo_stato_servizio")) + ): errors.append( - new_error( - "Indicare il motivo per cui il servizio non è fruibile" - ) + new_error("Indicare il motivo per cui il servizio non è fruibile") ) if errors: diff --git a/src/design/plone/contenttypes/restapi/services/types/get.py b/src/design/plone/contenttypes/restapi/services/types/get.py index 7851b99a..d98826b2 100644 --- a/src/design/plone/contenttypes/restapi/services/types/get.py +++ b/src/design/plone/contenttypes/restapi/services/types/get.py @@ -52,9 +52,9 @@ class FieldsetsMismatchError(Exception): "ownership", ], "Incarico": [ - 'default', - 'informazioni_compensi', - 'date_e_informazioni', + "default", + "informazioni_compensi", + "date_e_informazioni", ], "News Item": [ "default", @@ -94,7 +94,7 @@ class FieldsetsMismatchError(Exception): "settings", ], "PuntoDiContatto": [ - 'default', + "default", ], "Servizio": [ "default", @@ -231,7 +231,7 @@ def customize_versioning_fields_fieldset(self, result): return result def customize_servizio_schema(self, result): - result.get('required').append('description') + result.get("required").append("description") return result def reply(self): diff --git a/src/design/plone/contenttypes/upgrades/upgrades.py b/src/design/plone/contenttypes/upgrades/upgrades.py index 59cd7343..dbe85db0 100644 --- a/src/design/plone/contenttypes/upgrades/upgrades.py +++ b/src/design/plone/contenttypes/upgrades/upgrades.py @@ -410,7 +410,10 @@ def to_2002(context): fixed_total = 0 for brain in api.content.find(portal_type="Persona"): item = brain.getObject() - if hasattr(item, "tipologia_persona") and item.tipologia_persona in type_mapping: # noqa + if ( + hasattr(item, "tipologia_persona") + and item.tipologia_persona in type_mapping + ): # noqa item.tipologia_persona = type_mapping[item.tipologia_persona] fixed_total += 1 commit() @@ -752,9 +755,7 @@ def to_4000(context): ruoli[lang].append(ruolo) if api.portal.get_registry_record( - "ruoli_persona", - interface=IDesignPloneSettings, - default=None + "ruoli_persona", interface=IDesignPloneSettings, default=None ): api.portal.set_registry_record( "ruoli_persona", json.dumps(ruoli), interface=IDesignPloneSettings diff --git a/src/design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py b/src/design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py index b0f9e2f4..0141b0d0 100644 --- a/src/design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py +++ b/src/design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py @@ -23,7 +23,7 @@ def __call__(self, context): items = [ ( "L1.0", - _("Iscrizione Scuola/Università e/o richiesta borsa di studio"), # noqa + _("Iscrizione Scuola/Università e/o richiesta borsa di studio"), # noqa ), ("L2.0", _("Invalidità")), ( @@ -37,13 +37,15 @@ def __call__(self, context): ( "L8.0", _( - "Compravendita/affitto casa/edifici/terreni, costruzione o ristrutturazione casa/edificio" # noqa + "Compravendita/affitto casa/edifici/terreni, costruzione o ristrutturazione casa/edificio" # noqa ), ), ("L9.0", _("Cambio di residenza/domicilio")), ( "L11.0", - _("Richiesta passaporto, visto e assistenza viaggi internazionali"), # noqa + _( + "Richiesta passaporto, visto e assistenza viaggi internazionali" + ), # noqa ), ("L12.0", _("Nascita di un bambino, richiesta adozioni")), ("L13.0", _("Matrimonio e/o cambio stato civile")), @@ -53,7 +55,7 @@ def __call__(self, context): ( "L17.0", _( - "Dichiarazione dei redditi, versamento e riscossione tributi/imposte e contributi" # noqa + "Dichiarazione dei redditi, versamento e riscossione tributi/imposte e contributi" # noqa ), ), ("L18.0", _("Accesso luoghi della cultura")), @@ -74,7 +76,9 @@ def __call__(self, context): ("B14.0", _("Bancarotta")), ( "B15.0", - _("Partecipazione ad appalti pubblici nazionali e trasfrontalieri"), # noqa + _( + "Partecipazione ad appalti pubblici nazionali e trasfrontalieri" + ), # noqa ), ] req = getRequest() diff --git a/src/design/plone/contenttypes/vocabularies/dataset.py b/src/design/plone/contenttypes/vocabularies/dataset.py index e3a83e6e..0228ccbb 100644 --- a/src/design/plone/contenttypes/vocabularies/dataset.py +++ b/src/design/plone/contenttypes/vocabularies/dataset.py @@ -34,7 +34,9 @@ def __call__(self, context): ), VocabItem("energia", _("Energia")), VocabItem("ambiente", _("Ambiente")), - VocabItem("governo_e_settore_pubblico", _("Governo e settore pubblico")), # noqa + VocabItem( + "governo_e_settore_pubblico", _("Governo e settore pubblico") + ), # noqa VocabItem("salute", _("Salute")), VocabItem("tematiche_internazionali", _("Tematiche internazionali")), VocabItem( diff --git a/src/design/plone/contenttypes/vocabularies/pdc_value_type.py b/src/design/plone/contenttypes/vocabularies/pdc_value_type.py index 95f64ef3..21203159 100644 --- a/src/design/plone/contenttypes/vocabularies/pdc_value_type.py +++ b/src/design/plone/contenttypes/vocabularies/pdc_value_type.py @@ -27,7 +27,6 @@ def __call__(self, context): VocabItem("email", _("Email")), VocabItem("social", _("Social")), VocabItem("fax", _("Fax")), - ] # Fix context if you are using the vocabulary in DataGridField. # See https://github.com/collective/collective.z3cform.datagridfield/issues/31: # NOQA: 501 diff --git a/src/design/plone/contenttypes/vocabularies/tags_vocabulary.py b/src/design/plone/contenttypes/vocabularies/tags_vocabulary.py index a4be0110..4df59b1a 100644 --- a/src/design/plone/contenttypes/vocabularies/tags_vocabulary.py +++ b/src/design/plone/contenttypes/vocabularies/tags_vocabulary.py @@ -22,27 +22,19 @@ def __call__(self, context): # Just an example list of content for our vocabulary, # this can be any static or dynamic data, a catalog result for example. items = [ - VocabItem( - "accesso_all_informazione", - _("Accesso all'informazione") - ), + VocabItem("accesso_all_informazione", _("Accesso all'informazione")), VocabItem("acqua", _("Acqua")), VocabItem("agricoltura", _("Agricoltura")), VocabItem("animale_domestico", _("Animale domestico")), VocabItem("aria", _("Aria")), - VocabItem( - "assistenza_agli_anziani", _("Assistenza agli invalidi") - ), + VocabItem("assistenza_agli_anziani", _("Assistenza agli invalidi")), VocabItem("assistenza_sociale", _("Assistenza sociale")), VocabItem("associazioni", _("Associazioni")), VocabItem("bilancio", _("Bilancio")), VocabItem("commercio_all_ingresso", _("Commercio all'ingrosso")), VocabItem("commercio_al_minuto", _("Commercio al minuto")), VocabItem("commercio_ambulante", _("Commercio ambulante")), - VocabItem( - "comunicazione_istituzionale", - _("Comunicazione istituzionale") - ), + VocabItem("comunicazione_istituzionale", _("Comunicazione istituzionale")), VocabItem("comunicazione_politica", _("Comunicazione politica")), VocabItem("concordi", _("Concorsi")), VocabItem("covid_19", _("Covid - 19")), @@ -50,9 +42,7 @@ def __call__(self, context): VocabItem("energie_rinnovabili", _("Energie rinnovabili")), VocabItem("estero", _("Estero")), VocabItem("foreste", _("Foreste")), - VocabItem( - "formazione_professionale", _("Formazione professionale") - ), + VocabItem("formazione_professionale", _("Formazione professionale")), VocabItem("gemellaggi", _("Gemellaggi")), VocabItem("gestione_rifiuti", _("Gestione rifiuti")), VocabItem("giustizia", _("Giustizia")), @@ -87,9 +77,7 @@ def __call__(self, context): VocabItem("sviluppo_sostenibile", _("Sviluppo sostenibile")), VocabItem("tassa_sui_servizi", _("Tassa sui servizi")), VocabItem("tempo_libero", _("Tempo libero")), - VocabItem( - "trasparenza_amministrativa", _("Trasparenza amministrativa") - ), + VocabItem("trasparenza_amministrativa", _("Trasparenza amministrativa")), VocabItem("trasporto_pubblico", _("Trasporto pubblico")), VocabItem("turismo", _("Turismo")), VocabItem("urbanizzazione", _("Urbanizzazione")), From 3f26c70c981be15d252b4a50a9c4f885784ca024 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Fri, 23 Dec 2022 16:41:29 +0100 Subject: [PATCH 017/487] update package buildout for test --- buildout.cfg | 2 +- test_plone52.cfg => test_plone60.cfg | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename test_plone52.cfg => test_plone60.cfg (100%) diff --git a/buildout.cfg b/buildout.cfg index bb635cbf..d7db0388 100644 --- a/buildout.cfg +++ b/buildout.cfg @@ -2,4 +2,4 @@ # use this extend one of the buildout configuration: extends = - test_plone52.cfg + test_plone60.cfg diff --git a/test_plone52.cfg b/test_plone60.cfg similarity index 100% rename from test_plone52.cfg rename to test_plone60.cfg From 09b8b6b42600a3f354e100f77038d6131120e008 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Tue, 3 Jan 2023 15:47:27 +0100 Subject: [PATCH 018/487] remove checks on stato servizio --- .../restapi/deserializers/servizio.py | 44 +------------------ 1 file changed, 2 insertions(+), 42 deletions(-) diff --git a/src/design/plone/contenttypes/restapi/deserializers/servizio.py b/src/design/plone/contenttypes/restapi/deserializers/servizio.py index 342ff998..d316af07 100644 --- a/src/design/plone/contenttypes/restapi/deserializers/servizio.py +++ b/src/design/plone/contenttypes/restapi/deserializers/servizio.py @@ -15,7 +15,6 @@ DESCRIPTION_MAX_LEN = 160 EMPTY_BLOCK_MARKER = {"@type": "text"} MANDATORY_RICH_TEXT_FIELDS = [ - "motivo_stato_servizio", "a_chi_si_rivolge", "come_si_fa", "cosa_serve", @@ -69,8 +68,6 @@ def __call__( title = data.get("title") description = data.get("description") - # stato_servizio = data.get('stato_servizio') - # motivo_stato_servizio = data.get('motivo_stato_servizio') if is_post: # Title validation @@ -98,20 +95,7 @@ def __call__( ) for field in MANDATORY_RICH_TEXT_FIELDS: - if field == "motivo_stato_servizio": - if ( - data.get("stato_servizio") - and not data.get("motivo_stato_servizio") - ) or ( - data.get("stato_servizio") - and not text_in_block(data.get("motivo_stato_servizio")) - ): - errors.append( - new_error( - "Indicare il motivo per cui il servizio non è fruibile" - ) - ) - elif field not in data: + if field not in data: errors.append(new_error("Il campo {} è obbligatorio".format(field))) elif field in data and not text_in_block(data.get(field)): errors.append(new_error("Il campo {} è obbligatorio".format(field))) @@ -141,33 +125,9 @@ def __call__( ) for field in MANDATORY_RICH_TEXT_FIELDS: - if field == "motivo_stato_servizio": - if ( - "stato_servizio" in data - and data.get("stato_servizio") - and not text_in_block(data.get(field)) - ): - errors.append( - new_error( - "Indicare il motivo per cui il servizio non è fruibile" - ) - ) - elif field in data and not text_in_block(data.get(field)): + if field in data and not text_in_block(data.get(field)): errors.append(new_error("Il campo {} è obbligatorio".format(field))) - # Per questo campo dobbiamo controllare anche il contesto: potrei aver - # già scritto sull'oggetto che il servizio non è fruibile e modificare - # solo lo stato - if ( - "stato_servizio" not in data - and getattr(self.context, "stato_servizio") - and data.get("motivo_stato_servizio") - and not text_in_block(data.get("motivo_stato_servizio")) - ): - errors.append( - new_error("Indicare il motivo per cui il servizio non è fruibile") - ) - if errors: raise BadRequest(errors) return super(DeserializeServizioFromJson, self).__call__( From ceaab062bd5d3a1239880e22b77870bb69c6b9e5 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Wed, 28 Dec 2022 19:00:46 +0100 Subject: [PATCH 019/487] [dev] add some taxonomies --- setup.py | 1 + .../behaviors/news_additional_fields.py | 12 +-- src/design/plone/contenttypes/configure.zcml | 1 + .../interfaces/unita_organizzativa.py | 16 +-- src/design/plone/contenttypes/overrides.zcml | 1 - .../contenttypes/patches/baseserializer.py | 11 ++ .../plone/contenttypes/patches/configure.zcml | 14 +++ .../profiles/default/metadata.xml | 1 + .../profiles/default/registry/criteria.xml | 39 ++++++- .../restapi/serializers/summary.py | 11 +- .../all_life_events_vocabulary.py | 100 ------------------ .../contenttypes/vocabularies/configure.zcml | 22 +--- .../controlapanel_vocabularies.py | 12 --- 13 files changed, 73 insertions(+), 168 deletions(-) create mode 100644 src/design/plone/contenttypes/patches/configure.zcml delete mode 100644 src/design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py diff --git a/setup.py b/setup.py index 6b3f2a98..98e4bb76 100644 --- a/setup.py +++ b/setup.py @@ -64,6 +64,7 @@ "redturtle.volto", "redturtle.bandi", "z3c.unconfigure", + "eea.api.taxonomy", ], extras_require={ "test": [ diff --git a/src/design/plone/contenttypes/behaviors/news_additional_fields.py b/src/design/plone/contenttypes/behaviors/news_additional_fields.py index 113f959c..9b79166d 100644 --- a/src/design/plone/contenttypes/behaviors/news_additional_fields.py +++ b/src/design/plone/contenttypes/behaviors/news_additional_fields.py @@ -24,16 +24,6 @@ class INewsAdditionalFields(model.Schema): ), ) - tipologia_notizia = schema.Choice( - title=_("tipologia_notizia_label", default="Tipologia notizia"), - description=_( - "tipologia_notizia_help", - default="Seleziona la tipologia della notizia.", - ), - required=True, - vocabulary="design.plone.vocabularies.tipologie_notizia", - ) - numero_progressivo_cs = schema.TextLine( title=_( "numero_progressivo_cs_label", @@ -129,7 +119,7 @@ class INewsAdditionalFields(model.Schema): # custom fieldsets and order form.order_before(descrizione_estesa="ILeadImageBehavior.image") - form.order_before(tipologia_notizia="ILeadImageBehavior.image") + # form.order_before(tipologia_notizia="ILeadImageBehavior.image") form.order_before(numero_progressivo_cs="ILeadImageBehavior.image") form.order_before(a_cura_di="ILeadImageBehavior.image") diff --git a/src/design/plone/contenttypes/configure.zcml b/src/design/plone/contenttypes/configure.zcml index 26e71640..fdb2bd9f 100644 --- a/src/design/plone/contenttypes/configure.zcml +++ b/src/design/plone/contenttypes/configure.zcml @@ -23,6 +23,7 @@ + diff --git a/src/design/plone/contenttypes/interfaces/unita_organizzativa.py b/src/design/plone/contenttypes/interfaces/unita_organizzativa.py index 42a1128a..81277aeb 100644 --- a/src/design/plone/contenttypes/interfaces/unita_organizzativa.py +++ b/src/design/plone/contenttypes/interfaces/unita_organizzativa.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- from plone.app.dexterity import textindexer +from collective.taxonomy import generated from collective.volto.blocksfield.field import BlocksField from design.plone.contenttypes import _ from design.plone.contenttypes.interfaces import IDesignPloneContentType @@ -8,7 +9,6 @@ from plone.supermodel import model from z3c.relationfield.schema import RelationChoice from z3c.relationfield.schema import RelationList -from zope import schema # TODO: migration script for these commented fields towards PDC @@ -58,18 +58,6 @@ class IUnitaOrganizzativa(model.Schema, IDesignPloneContentType): required=False, ) - tipologia_organizzazione = schema.Choice( - title=_("tipologia_organizzazione_label", default="Tipologia organizzazione"), - # vocabolario di rif sara' la lista delle tipologie di organizzazione - vocabulary="" "design.plone.vocabularies.tipologie_unita_organizzativa", - description=_( - "tipologia_organizzazione_help", - default="Specificare la tipologia di organizzazione: politica," - " amminsitrativa o di altro tipo.", - ), - required=True, - ) - assessore_riferimento = RelationList( title="Assessore di riferimento", # vocabolario di riferimento sara' dinamico con i content type @@ -204,7 +192,6 @@ class IUnitaOrganizzativa(model.Schema, IDesignPloneContentType): fields=[ "legami_con_altre_strutture", "responsabile", - "tipologia_organizzazione", "assessore_riferimento", ], ) @@ -223,6 +210,5 @@ class IUnitaOrganizzativa(model.Schema, IDesignPloneContentType): # SearchableText indexers textindexer.searchable("competenze") - textindexer.searchable("tipologia_organizzazione") textindexer.searchable("assessore_riferimento") textindexer.searchable("responsabile") diff --git a/src/design/plone/contenttypes/overrides.zcml b/src/design/plone/contenttypes/overrides.zcml index d0b6cdbb..ffeb130d 100644 --- a/src/design/plone/contenttypes/overrides.zcml +++ b/src/design/plone/contenttypes/overrides.zcml @@ -25,5 +25,4 @@ /> - diff --git a/src/design/plone/contenttypes/patches/baseserializer.py b/src/design/plone/contenttypes/patches/baseserializer.py index 8ffe4e8a..6f30e437 100644 --- a/src/design/plone/contenttypes/patches/baseserializer.py +++ b/src/design/plone/contenttypes/patches/baseserializer.py @@ -10,6 +10,8 @@ SerializeToJson and SerializeFolderToJson classes """ +from collective.taxonomy.vocabulary import Vocabulary +from collective.taxonomy.utility import Taxonomy from plone.restapi.serializer.dxcontent import ( SerializeToJson, SerializeFolderToJson, @@ -87,3 +89,12 @@ def design_italia_serialize_folder_to_json_call(self, version=None, include_item def patch_base_folder_serializer(): SerializeFolderToJson.__call__ = design_italia_serialize_folder_to_json_call + + +def eea_api_taxonomy_taxonomy_call(self, context): + if not self.data: + return Vocabulary(self.name, {}, {}, {}, 2) + + request = getattr(context, "REQUEST", None) + language = self.getCurrentLanguage(request) + return self.makeVocabulary(language) diff --git a/src/design/plone/contenttypes/patches/configure.zcml b/src/design/plone/contenttypes/patches/configure.zcml new file mode 100644 index 00000000..6f70898b --- /dev/null +++ b/src/design/plone/contenttypes/patches/configure.zcml @@ -0,0 +1,14 @@ + + + + + + + diff --git a/src/design/plone/contenttypes/profiles/default/metadata.xml b/src/design/plone/contenttypes/profiles/default/metadata.xml index fcf9af17..363713a1 100644 --- a/src/design/plone/contenttypes/profiles/default/metadata.xml +++ b/src/design/plone/contenttypes/profiles/default/metadata.xml @@ -5,5 +5,6 @@ profile-redturtle.bandi:default profile-collective.venue:default profile-redturtle.volto:default + profile-eea.api.taxonomy:default diff --git a/src/design/plone/contenttypes/profiles/default/registry/criteria.xml b/src/design/plone/contenttypes/profiles/default/registry/criteria.xml index 417c60d0..2b70bc1a 100644 --- a/src/design/plone/contenttypes/profiles/default/registry/criteria.xml +++ b/src/design/plone/contenttypes/profiles/default/registry/criteria.xml @@ -11,7 +11,7 @@ plone.app.querystring.operation.selection.any plone.app.querystring.operation.selection.all - design.plone.vocabularies.tipologie_notizia + collective.taxonomy.tipologia_notizia Metadata + prefix="plone.app.querystring.field.tipologia_documento"> Tipologia documento True @@ -39,7 +39,8 @@ plone.app.querystring.operation.selection.all Metadata - collective.taxonomy.tipologie_documento + collective.taxonomy.tipologia_documento + True Dates - Tipologia organizzazione @@ -114,10 +116,37 @@ plone.app.querystring.operation.selection.any plone.app.querystring.operation.selection.all - design.plone.vocabularies.tipologie_unita_organizzativa + collective.taxonomy.tipologia_organizzazione Metadata + + Eventi della vita delle imprese + + True + False + + plone.app.querystring.operation.selection.any + plone.app.querystring.operation.selection.all + + collective.taxonomy.business_events + Metadata + + + + Eventi della vita delle persone + + True + False + + plone.app.querystring.operation.selection.any + plone.app.querystring.operation.selection.all + + collective.taxonomy.person_life_events + Metadata + - - - - - - - - + + + Date: Thu, 29 Dec 2022 13:15:19 +0100 Subject: [PATCH 020/487] [dev] tipologia notizia + temi di un dataset --- .../behaviors/news_additional_fields.py | 1 - .../plone/contenttypes/interfaces/dataset.py | 7 -- .../contenttypes/patches/baseserializer.py | 6 +- .../contenttypes/profiles/default/catalog.xml | 7 +- .../profiles/default/registry/criteria.xml | 14 ++++ .../restapi/serializers/dxcontent.py | 12 +--- .../contenttypes/vocabularies/configure.zcml | 5 -- .../contenttypes/vocabularies/dataset.py | 68 ------------------- 8 files changed, 21 insertions(+), 99 deletions(-) delete mode 100644 src/design/plone/contenttypes/vocabularies/dataset.py diff --git a/src/design/plone/contenttypes/behaviors/news_additional_fields.py b/src/design/plone/contenttypes/behaviors/news_additional_fields.py index 9b79166d..416afbec 100644 --- a/src/design/plone/contenttypes/behaviors/news_additional_fields.py +++ b/src/design/plone/contenttypes/behaviors/news_additional_fields.py @@ -119,7 +119,6 @@ class INewsAdditionalFields(model.Schema): # custom fieldsets and order form.order_before(descrizione_estesa="ILeadImageBehavior.image") - # form.order_before(tipologia_notizia="ILeadImageBehavior.image") form.order_before(numero_progressivo_cs="ILeadImageBehavior.image") form.order_before(a_cura_di="ILeadImageBehavior.image") diff --git a/src/design/plone/contenttypes/interfaces/dataset.py b/src/design/plone/contenttypes/interfaces/dataset.py index 8c4c6493..4fab5b91 100644 --- a/src/design/plone/contenttypes/interfaces/dataset.py +++ b/src/design/plone/contenttypes/interfaces/dataset.py @@ -9,13 +9,6 @@ class IDataset(model.Schema): """Marker interface for Dataset""" - # TODO: aggiungere tassonomia e vocabolario rilevante fornito nelle linee guida # noqa - temi = schema.Choice( - title=_("temi", default="Temi"), - vocabulary="design.plone.contenttypes.temi_dataset", - required=True, - ) - # TODO: identificativo dataset distribuzione = BlocksField( diff --git a/src/design/plone/contenttypes/patches/baseserializer.py b/src/design/plone/contenttypes/patches/baseserializer.py index 6f30e437..1bfc2862 100644 --- a/src/design/plone/contenttypes/patches/baseserializer.py +++ b/src/design/plone/contenttypes/patches/baseserializer.py @@ -35,11 +35,7 @@ def design_italia_serialize_to_json_call(self, version=None, include_items=True) self, version=version, include_items=include_items ) if self.context.portal_type == "News Item": - result["design_italia_meta_type"] = translate( - self.context.tipologia_notizia, - domain=_._domain, - context=self.request, - ) + result["design_italia_meta_type"] = self.context.tipologia_notizia else: result["design_italia_meta_type"] = translate( ttool[self.context.portal_type].Title(), context=self.request diff --git a/src/design/plone/contenttypes/profiles/default/catalog.xml b/src/design/plone/contenttypes/profiles/default/catalog.xml index 964447ab..5fe69663 100644 --- a/src/design/plone/contenttypes/profiles/default/catalog.xml +++ b/src/design/plone/contenttypes/profiles/default/catalog.xml @@ -18,15 +18,15 @@ - - - + + + @@ -64,4 +64,5 @@ + diff --git a/src/design/plone/contenttypes/profiles/default/registry/criteria.xml b/src/design/plone/contenttypes/profiles/default/registry/criteria.xml index 2b70bc1a..2864887c 100644 --- a/src/design/plone/contenttypes/profiles/default/registry/criteria.xml +++ b/src/design/plone/contenttypes/profiles/default/registry/criteria.xml @@ -148,6 +148,20 @@ Metadata + + Temi del dataset + + True + False + + plone.app.querystring.operation.selection.any + plone.app.querystring.operation.selection.all + + collective.taxonomy.temi_dataset + Metadata + + - - Date: Thu, 29 Dec 2022 18:58:57 +0100 Subject: [PATCH 021/487] [dev] add criteria + add taxonomies file + add new profile for taxonomies --- src/design/plone/contenttypes/configure.zcml | 9 + .../behaviors/taxonomies/business_events.cfg | 8 + .../behaviors/taxonomies/business_events.xml | 98 ++++ .../taxonomies/person_life_events.cfg | 8 + .../taxonomies/person_life_events.xml | 116 ++++ .../behaviors/taxonomies/temi_dataset.cfg | 10 + .../behaviors/taxonomies/temi_dataset.xml | 86 +++ .../tipologia_documenti_albopretorio.cfg | 9 + .../tipologia_documenti_albopretorio.xml | 238 ++++++++ .../taxonomies/tipologia_documento.cfg | 10 + .../taxonomies/tipologia_documento.xml | 56 ++ .../behaviors/taxonomies/tipologia_evento.cfg | 10 + .../behaviors/taxonomies/tipologia_evento.xml | 436 ++++++++++++++ .../tipologia_frequenza_aggiornamento.cfg | 10 + .../tipologia_frequenza_aggiornamento.xml | 182 ++++++ .../taxonomies/tipologia_incarico.cfg | 10 + .../taxonomies/tipologia_incarico.xml | 26 + .../taxonomies/tipologia_licenze.cfg | 10 + .../taxonomies/tipologia_licenze.xml | 63 ++ .../behaviors/taxonomies/tipologia_luogo.cfg | 8 + .../behaviors/taxonomies/tipologia_luogo.xml | 543 ++++++++++++++++++ .../taxonomies/tipologia_notizia.cfg | 11 + .../taxonomies/tipologia_notizia.xml | 26 + .../taxonomies/tipologia_organizzazione.cfg | 10 + .../taxonomies/tipologia_organizzazione.xml | 99 ++++ .../behaviors/taxonomies/tipologia_pdc.cfg | 10 + .../behaviors/taxonomies/tipologia_pdc.xml | 69 +++ .../taxonomies/tipologia_stati_pratica.cfg | 10 + .../taxonomies/tipologia_stati_pratica.xml | 63 ++ .../profiles/default/registry/criteria.xml | 112 ++++ .../plone/contenttypes/setuphandlers.py | 4 + .../vocabularies/lista_azioni_pratica.py | 1 + 32 files changed, 2361 insertions(+) create mode 100644 src/design/plone/contenttypes/profiles/behaviors/taxonomies/business_events.cfg create mode 100644 src/design/plone/contenttypes/profiles/behaviors/taxonomies/business_events.xml create mode 100644 src/design/plone/contenttypes/profiles/behaviors/taxonomies/person_life_events.cfg create mode 100644 src/design/plone/contenttypes/profiles/behaviors/taxonomies/person_life_events.xml create mode 100644 src/design/plone/contenttypes/profiles/behaviors/taxonomies/temi_dataset.cfg create mode 100644 src/design/plone/contenttypes/profiles/behaviors/taxonomies/temi_dataset.xml create mode 100644 src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_documenti_albopretorio.cfg create mode 100644 src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_documenti_albopretorio.xml create mode 100644 src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_documento.cfg create mode 100644 src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_documento.xml create mode 100644 src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_evento.cfg create mode 100644 src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_evento.xml create mode 100644 src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_frequenza_aggiornamento.cfg create mode 100644 src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_frequenza_aggiornamento.xml create mode 100644 src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_incarico.cfg create mode 100644 src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_incarico.xml create mode 100644 src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_licenze.cfg create mode 100644 src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_licenze.xml create mode 100644 src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_luogo.cfg create mode 100644 src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_luogo.xml create mode 100644 src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_notizia.cfg create mode 100644 src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_notizia.xml create mode 100644 src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_organizzazione.cfg create mode 100644 src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_organizzazione.xml create mode 100644 src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_pdc.cfg create mode 100644 src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_pdc.xml create mode 100644 src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_stati_pratica.cfg create mode 100644 src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_stati_pratica.xml diff --git a/src/design/plone/contenttypes/configure.zcml b/src/design/plone/contenttypes/configure.zcml index fdb2bd9f..e0fc79a0 100644 --- a/src/design/plone/contenttypes/configure.zcml +++ b/src/design/plone/contenttypes/configure.zcml @@ -36,6 +36,14 @@ post_handler=".setuphandlers.post_install" /> + + + + + + Eventi della vita delle imprese + + business_events + + avvio_impresa + + Avvio impresa + + + + avvio_nuova_attivita_professionale + + Avvio nuova attività professionale + + + + richiesta_licenze_permessi_certificati + + Richiesta licenze, permessi e certificati + + + + registrazione_impresa_transfrontaliera + + Registrazione impresa transfrontaliera + + + + avvio_e_registrazione_filiale + + Avvio e registrazione filiale + + + + finanziamento_impresa + + Finanziamento impresa + + + + gestione_personale + + Gestione personale + + + + pagamento_tasse_iva_e_dogane + + Pagamento tasse, iva e dogane + + + + notifiche_autorita + + Notifiche autorità + + + + chiusura_impresa_e_attivita_professionale + + Chiusura impresa e attività professionale + + + + chiusura_filiale + + Chiusura filiale + + + + ristrutturazione_impresa + + Ristrutturazione impresa + + + + vendita_impresa + + Vendita impresa + + + + bancarotta + + Bancarotta + + + + partecipazione_ad_appalti_pubblici_nazionali_e_trasfrontalieri + + + Partecipazione ad appalti pubblici nazionali e trasfrontalieri + + + \ No newline at end of file diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/person_life_events.cfg b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/person_life_events.cfg new file mode 100644 index 00000000..8ea3a44b --- /dev/null +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/person_life_events.cfg @@ -0,0 +1,8 @@ +[taxonomy] +name = person_life_events +title = Eventi della vita delle persone +description = Il sistema di gestione contenuti basato su React +default_language = it +field_title = Eventi della vita delle persone +taxonomy_fieldset = default + diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/person_life_events.xml b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/person_life_events.xml new file mode 100644 index 00000000..09a10281 --- /dev/null +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/person_life_events.xml @@ -0,0 +1,116 @@ + + + + Eventi della vita delle persone + + person_life_events + + iscrizione_scuola_universita_richiesta_borsa_di_studio + + Iscrizione Scuola/Università e/o richiesta borsa di studio + + + + invalidita + + Invalidità + + + + ricerca_di_lavoro_avvio_nuovo_lavoro_disoccupazione + + Ricerca di lavoro, avvio nuovo lavoro, disoccupazione + + + + pensionamento + + Pensionamento + + + + richiesta_o_rinnovo_patente + + Richiesta o rinnovo patente + + + + registrazione_o_possesso_veicolo + + Registrazione o possesso veicolo + + + + accesso_al_trasporto_pubblico + + Accesso al trasporto pubblico + + + + compravendita_affitto_casa_edifici_terreni_costruzione_o_ristrutturazione_casa_edificio + + Compravendita/affitto casa/edifici/terreni, costruzione o ristrutturazione casa/edificio + + + + cambio_di_residenza_domicilio + + Cambio di residenza/domicilio + + + + richiesta_passaporto_visto_e_assistenza_viaggi_internazionali + + Richiesta passaporto, visto e assistenza viaggi internazionali + + + + nascita_di_un_bambino_richiesta_adozioni + + Nascita di un bambino, richiesta adozioni + + + + matrimonio_cambio_stato_civile + + Matrimonio e/o cambio stato civile + + + + morte_ed_eredita + + Morte ed eredità + + + + prenotazione_e_disdetta_visite_esami + + Prenotazione e disdetta visite/esami + + + + denuncia_crimini + + Denuncia crimini + + + + dichiarazione_dei_redditi_versamento_e_riscossione_tributi_imposte_e_contributi + + Dichiarazione dei redditi, versamento e riscossione tributi/imposte e contributi + + + + accesso_luoghi_della_cultura + + Accesso luoghi della cultura + + + + possesso_cura_smarrimento_animale_da_compagnia + + + Possesso, cura, smarrimento animale da compagnia + + + \ No newline at end of file diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/temi_dataset.cfg b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/temi_dataset.cfg new file mode 100644 index 00000000..78934c7e --- /dev/null +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/temi_dataset.cfg @@ -0,0 +1,10 @@ +[taxonomy] +name = temi_dataset +title = Temi di un dataset +description = Il sistema di gestione contenuti basato su React +default_language = it +field_title = Temi di un dataset +field_description = Scegli i temi di un dataset +taxonomy_fieldset = default +is_required = true + diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/temi_dataset.xml b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/temi_dataset.xml new file mode 100644 index 00000000..def9bc3b --- /dev/null +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/temi_dataset.xml @@ -0,0 +1,86 @@ + + + + Temi di un dataset + + temi_dataset + + agricoltura_pesca_silvicoltura_e_prodotti_alimentari + + Agricoltura, pesca, silvicoltura e prodotti alimentari + + + + economia_e_finanze + + Economia e Finanze + + + + istruzione_cultura_e_sport + + Istruzione, cultura e sport + + + + energia + + Energia + + + + ambiente + + Ambiente + + + + governo_e_settore_pubblico + + Governo e settore pubblico + + + + salute + + Salute + + + + tematiche_internazionali + + Tematiche internazionali + + + + giustizia_sistema_giuridico_e_sicurezza_pubblica + + Giustizia, sistema giuridico e sicurezza pubblica + + + + popolazione_e_societa + + Popolazione e società + + + + regioni_e_citta + + Regioni e città + + + + scienza_e_tecnologia + + Scienza e tecnologia + + + + trasporti + + + Trasporti + + + \ No newline at end of file diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_documenti_albopretorio.cfg b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_documenti_albopretorio.cfg new file mode 100644 index 00000000..7e3e47f2 --- /dev/null +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_documenti_albopretorio.cfg @@ -0,0 +1,9 @@ +[taxonomy] +name = tipologia_documenti_albopretorio +title = Tipologia di Documento albo pretorio +description = Il sistema di gestione contenuti basato su React +default_language = it +field_title = Tipologia di Documento albo pretorio +taxonomy_fieldset = default +is_single_select = true + diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_documenti_albopretorio.xml b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_documenti_albopretorio.xml new file mode 100644 index 00000000..2e426342 --- /dev/null +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_documenti_albopretorio.xml @@ -0,0 +1,238 @@ + + + + Tipologia di Documento albo pretorio + + tipologia_documenti_albopretorio + + atto_amministrativo + + Atto amministrativo + + + decreto + + Decreto + + + decreto_del_dirigente + + Decreto del Dirigente + + + + decreto_del_sindaco + + Decreto del Sindaco + + + + + deliberazione + + Deliberazione + + + deliberazione_consiglio_comunale + + Deliberazione del Consiglio comunale + + + + deliberazione_giunta_comunale + + Deliberazione della Giunta comunale + + + + deliberazione_commissario_ad_acta + + Deliberazione del Commissario ad acta + + + + deliberazione_consiglio_circoscrizionale + + Deliberazione del Consiglio circoscrizionale + + + + deliberazione_esecutivo_circoscrizionale + + Deliberazione dell'Esecutivo circoscrizionale + + + + deliberazione_altri_organi + + Deliberazione di altri Organi + + + + + determinazione + + Determinazione + + + determinazione_sindaco + + Determinazione del Sindaco + + + + determinazione_dirigente + + Determinazione del Dirigente + + + + + ordinanza + + Ordinanza + + + ordinanza_dirigente + + Ordinanza del Dirigente + + + + ordinanza_sindaco + + Ordinanza del Sindaco + + + + + + atto_autorizzativo + + Atto autorizzativo + + + permesso_costruire + + Permesso a costruire + + + permesso_costruire_2 + + Permesso a costruire + + + + + + atto_stato_civile + + Atto dello stato civile + + + provvidemento_cancellazione_irreperibilita + + Provvedimento di cancellazione per irreperibilità + + + provvidemento_cancellazione_irreperibilita_2 + + Provvedimento di cancellazione per irreperibilità + + + + + pubblicazione_cambio_nome + + Pubblicazione cambio nome + + + pubblicazione_cambio_nome_2 + + Pubblicazione cambio nome + + + + + pubblicazione_matrimonio + + Pubblicazione di matrimonio + + + pubblicazione_matrimonio_2 + + Pubblicazione di matrimonio + + + + + + atto_generico + + Atto generico + + + avviso + + Avviso + + + avviso_deposito_casa_comunale + + Avviso di deposito in casa comunale + + + + avviso_manifesto + + Avviso/Manifesto + + + + + bando + + Bando + + + bando_concorso + + Bando di concorso + + + + bando_gara + + Bando di gara + + + + bando_contributi + + Bando di contributi e vantaggi economici + + + + + + pubblicazione_esterna + + + Pubblicazione esterna + + + atto_terzi + + + Atto di terzi + + + atto_terzi_2 + + + Atto di terzi + + + + + \ No newline at end of file diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_documento.cfg b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_documento.cfg new file mode 100644 index 00000000..985aa66b --- /dev/null +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_documento.cfg @@ -0,0 +1,10 @@ +[taxonomy] +name = tipologia_documento +title = Tipologia del documento +description = Seleziona la tipologia del documento +default_language = it +field_title = Tipologia del documento +field_description = Seleziona la tipologia del documento +taxonomy_fieldset = default +is_required = true + diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_documento.xml b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_documento.xml new file mode 100644 index 00000000..3205e4ea --- /dev/null +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_documento.xml @@ -0,0 +1,56 @@ + + + + Tipologia del documento + + tipologia_documento + + documenti_albo_pretorio + + Documenti albo pretorio + + + + modulistica + + Modulistica + + + + documento_funzionamento_interno + + Documento funzionamento interno + + + + atto_normativo + + Atto normativo + + + + accordo_tra_enti + + Accordo tra enti + + + + documento_attivita_politica + + Documento attivita politica + + + + documento_tecnico_di_supporto + + Documento (tecnico) di supporto + + + + istanza + + + Istanza + + + \ No newline at end of file diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_evento.cfg b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_evento.cfg new file mode 100644 index 00000000..0f4893ee --- /dev/null +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_evento.cfg @@ -0,0 +1,10 @@ +[taxonomy] +name = tipologia_evento +title = Tipo di evento +description = Il sistema di gestione contenuti basato su React +default_language = it +field_title = Tipo di evento +taxonomy_fieldset = default +is_single_select = true +is_required = true + diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_evento.xml b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_evento.xml new file mode 100644 index 00000000..1387cbb8 --- /dev/null +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_evento.xml @@ -0,0 +1,436 @@ + + + + Tipo di evento + + tipologia_evento + + evento_culturale + + Evento culturale + + + manifestazione_artistica + + Manifestazione artistica + + + festival + + Festival + + + + mostra + + Mostra + + + + spettacolo_teatrale + + Spettacolo teatrale + + + + maifestazione_musicale + + Manifestazione musicale + + + + visita_guidata + + Visita guidata + + + + lettura_pubblica + + Lettura (pubblica) + + + + proiezione_cinematografia + + Proiezione cinematografica + + + + visita_libera + + Visita libera + + + + + evento_di_formazione + + Evento di formazione + + + scuola_estiva_invernale + + Scuola estiva/invernale + + + + webinar + + Webinar + + + + seminario + + Seminario + + + + laboratorio + + Laboratorio + + + + presentazione_libro + + Presentazione libro + + + + corso + + Corso + + + + + conferenza_summit + + Conferenza e Summit + + + convegno + + Convegno + + + + vertice + + Vertice + + + + congresso + + Congresso + + + + + giornata_informativa + + Giornata informativa + + + giornata_aperta + + Giornata aperta + + + + + + eventi_sociali + + Eventi sociali + + + concordo_e_cerimonia + + Concorso e cerimonia + + + cerimonia + + Cerimonia + + + + concorso_competizione + + Concorco/competizione + + + + + dibattito_politico + + Dibattito politico + + + dibattito_dialogo_pubblico + + Dibattito/dialogo pubblico + + + + forum + + Forum + + + + + incontro_con_esperti + + Incontro con esperti + + + riunione_esperti + + Riunione esperti + + + + hackathon_datathon + + Hackathon / Datathon + + + + + raduno_di_comunita + + Raduno di comunità + + + sfilata + + Sfilata + + + + sagra + + Sagra + + + + torneo_storico_o_palio + + Torneo storico o Palio + + + + festa_patronale_o_dei_santi + + Festa Patronale o dei santi + + + + mercatino + + Mercatino + + + + commemorazione + + Commemorazione + + + + + evento_religioso + + Evento religioso + + + giubileo + + Giubileo + + + + udienza_giubiliare + + Udienza giubiliare + + + + processione + + Processione + + + + celebrazione_religiosa + + Celebrazione religiosa + + + + lettura_religiosa + + Lettura religiosa + + + + raduno_religioso + + Raduno religioso + + + + santificazione + + Sanntificazione + + + + + + eventi_politici + + Eventi politici + + + incontro_pubblico + + Incontro pubblico + + + congresso_o_riunione_partito + + Congresso o riunione partito + + + + corteo_o_sciopero + + Corteo o sciopero + + + + comizio_elettorale + + Comizio elettorale + + + + + + eventi_di_affari_o_commerciali + + Eventi di affari o commerciali + + + fiera_o_salone + + Fiera o salone + + + fiera_o_salone_2 + + Fiera o salone + + + + esposizione_o_esposizione_globale + + Esposizione o Esposizione globale + + + + + riunione_affari + + Riunione d'affari + + + riunione_affari_2 + + Riunione d'affari + + + + convention + + Convention + + + + tavola_rotonda + + Tavola rotonda + + + + + evento_stagionale_commerciale + + Evento stagionale commerciale + + + vendita_di_fine_stagione + + Vendita di fine stagione + + + + + + eventi_sportivi + + + Eventi sportivi + + + manifestazione_sportiva + + + Manifestazione sportiva + + + partita + + Partita + + + + gara_torneo_competizione + + Gara o Torneo o Competizione + + + + escursione + + Escursione + + + + gala_sportivo + + Galà sportivo + + + + corsa + + Corsa + + + + raduno_sportivo + + + Raduno sportivo + + + + + \ No newline at end of file diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_frequenza_aggiornamento.cfg b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_frequenza_aggiornamento.cfg new file mode 100644 index 00000000..c5a194d2 --- /dev/null +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_frequenza_aggiornamento.cfg @@ -0,0 +1,10 @@ +[taxonomy] +name = tipologia_frequenza_aggiornamento +title = Tipologia di Frequenza di aggiornamento +description = Il sistema di gestione contenuti basato su React +default_language = it +field_title = Tipologia di Frequenza di aggiornamento +taxonomy_fieldset = default +is_single_select = true +is_required = true + diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_frequenza_aggiornamento.xml b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_frequenza_aggiornamento.xml new file mode 100644 index 00000000..fa33ad36 --- /dev/null +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_frequenza_aggiornamento.xml @@ -0,0 +1,182 @@ + + + + Tipologia di Frequenza di aggiornamento + + tipologia_frequenza_aggiornamento + + altro + + Altro + + + + annuale + + Annuale + + + + bidecennale + + Bidecennale + + + + biennale + + Biennale + + + + bimestrale + + Bimestrale + + + + bisettimanale + + Bisettimanale + + + + continuo + + Continuo + + + + decennale + + Decennale + + + + due_volto_giorno + + Due volto al giorno + + + + in_continuo_aggiornamento + + In continuo aggiornamento + + + + irregolare + + Irregolare + + + + mai + + Mai + + + + mensile + + Mensile + + + + ogni_cinque_anni + + Ogni cinque anni + + + + ogni_due_ore + + Ogni due ore + + + + ogni_ora + + Ogni ora + + + + ogni_quattro_anni + + Ogni quattro anni + + + + ogni_tre_ore + + Ogni tre ore + + + + quindicinale + + Quindicinale + + + + quotidiano + + Quotidiano + + + + sconosciuto + + Sconosciuto + + + + semestrale + + Semestrale + + + + settimanale + + Settimanale + + + + tre_volte_a_settimana + + Tre volte a settimana + + + + tre_volte_al_mese + + Tre volte al mese + + + + tre_volte_anno + + Tre volte l'anno + + + + tridecennale + + Tridecennale + + + + triennale + + Triennale + + + + trimestrale + + + Trimestrale + + + \ No newline at end of file diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_incarico.cfg b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_incarico.cfg new file mode 100644 index 00000000..565f2f96 --- /dev/null +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_incarico.cfg @@ -0,0 +1,10 @@ +[taxonomy] +name = tipologia_incarico +title = Tipo di incarico +description = Il sistema di gestione contenuti basato su React +default_language = it +field_title = Tipo di incarico +taxonomy_fieldset = default +is_single_select = true +is_required = true + diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_incarico.xml b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_incarico.xml new file mode 100644 index 00000000..8a08402f --- /dev/null +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_incarico.xml @@ -0,0 +1,26 @@ + + + + Tipo di incarico + + tipologia_incarico + + politico + + Politico + + + + amministrativo + + Amministrativo + + + + altro + + + Altro + + + \ No newline at end of file diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_licenze.cfg b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_licenze.cfg new file mode 100644 index 00000000..9950e92d --- /dev/null +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_licenze.cfg @@ -0,0 +1,10 @@ +[taxonomy] +name = tipologia_licenze +title = Licenze +description = Il sistema di gestione contenuti basato su React +default_language = it +field_title = Licenze +taxonomy_fieldset = default +is_single_select = true +is_required = true + diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_licenze.xml b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_licenze.xml new file mode 100644 index 00000000..ca265e58 --- /dev/null +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_licenze.xml @@ -0,0 +1,63 @@ + + + + Licenze + + tipologia_licenze + + licenza_aperta + + Licenza aperta + + + pubblico_dominio + + Pubblico dominio + + + + attribuzione + + Attribuzione + + + + effetto_virale + + Effetto virale + + + + condivisione + + condivisione allo stesso modo - copyleft non compatibile + + + + + non_aperta + + Non aperta + + + uso_non_commerciale + + Solo uso non commerciale + + + + non_opere_derivate + + + Non opere derivate + + + + + licenza_sconosciuta + + + Licenza sconosciuta + + + \ No newline at end of file diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_luogo.cfg b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_luogo.cfg new file mode 100644 index 00000000..17a79526 --- /dev/null +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_luogo.cfg @@ -0,0 +1,8 @@ +[taxonomy] +name = tipologia_luogo +title = Tipo di luogo +description = Il sistema di gestione contenuti basato su React +default_language = it +field_title = Tipo di luogo +taxonomy_fieldset = default + diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_luogo.xml b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_luogo.xml new file mode 100644 index 00000000..4a79b874 --- /dev/null +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_luogo.xml @@ -0,0 +1,543 @@ + + + + Tipo di luogo + + tipologia_luogo + + architettura_militare_e_fortificata + + Architettura Militare e fortificata + + + castello + + Castello + + + + fortezza + + Fortezza + + + + mura + + Mura + + + + roccaforte + + Roccaforte + + + + torre + + Torre + + + + + architettura_residenziale + + Architettura Residenziale + + + sito_archeologico + + Sito archeologico + + + + parco_archeologico + + Parco archeologico + + + + + centro_per_la_cultura + + Centro per la cultura + + + acquario + + Acquario + + + + anfiteatro + + Anfiteatro + + + + archivio + + Archivio + + + + auditorium + + Auditorium + + + + biblioteca + + Biblioteca + + + + cinema + + Cinema + + + + museo + + Museo + + + + osservatorio + + Osservatorio + + + + pinacoteca + + Pinacoteca + + + + planetario + + Planetario + + + + scuola + + Scuola + + + + teatro + + Teatro + + + + universita_facolta + + Università/Facoltà + + + + parco_archeologico_2 + + Parco Archeologico + + + + + edificio_di_culto + + Edificio di culto + + + abbazia + + Abbazia + + + + chiesa + + Chiesa + + + + campanile + + Campanile + + + + battistero + + Battistero + + + + convento + + Convento + + + + duomo + + Duomo + + + + edicola + + Edicola + + + + eremo + + Eremo + + + + mausoleo + + Mausoleo + + + + monastero + + Monastero + + + + santuario + + Santuario + + + + sinagoga + + Sinagoga + + + + tempio + + Tempio + + + + sepolcro + + Sepolcro + + + + basilica + + Basilica + + + + cappella + + Cappella + + + + catacomba + + Catacomba + + + + cattedrale + + Cattedrale + + + + cimitero + + Cimitero + + + + + monumento_complesso_monumentale + + Monumento o complesso munumentale + + + archi + + Archi + + + + colonna + + Colonna + + + + complesso_monumentale + + Complesso monumentale + + + + monumento + + Monumento + + + + obelisco + + Obelisco + + + + + parco_e_giardino + + Parco e giardino + + + belvedere + + Belvedere + + + + giardino + + Giardino + + + + parco + + Parco + + + + viale + + Viale + + + + + bellezza_naturale + + Bellezza naturale + + + costa_marittima + + Costa marittima + + + + lago + + Lago + + + + Corso_acqua + + Corso d'acqua + + + + montagna + + Montagna + + + + ghiacciaio + + Ghiacciaio + + + + riserva_naturale + + Riserva Natuale + + + + foresta_e_bosco + + Foresta e bosco + + + + vulcano + + Vulcano + + + + + luogo_per_lo_sport_e_il_tempo_libero + + Luogo per lo sport e il tempo libero + + + campo_sportivo + + Campo sportivo + + + + piscina + + Piscina + + + + stadio + + Stadio + + + + terme + + Terme + + + + casino + + Casinò + + + + circolo_sportivo + + Circolo sportivo + + + + piazza + + Piazza + + + + + architettura_commerciale + + Architettura commerciale + + + mercati + + Mercati + + + + farmacie + + Farmacie + + + + + centro_assistenza_e_tutela + + Centro per l'assistenza e la tutela sociale + + + casa_di_riposo + + Casa di riposo + + + + centro_di_accoglienza + + Centro di accoglienza + + + + ospedale + + Ospedale + + + + + infrastruttura_e_impianto + + Infrastruttura e impianto + + + centro_di_raccolta + + Centro di raccolta + + + + acquedotto + + Acquedotto + + + + aeroporto + + Aeroporto + + + + porto + + Porto + + + + + struttura_ricettiva + + + Struttura ricettiva + + + albergo + + Albergo + + + + foresteria + + Foresteria + + + + rifugio + + Rifugio + + + + rifugio_per_animali + + + Rifugio per animali + + + + \ No newline at end of file diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_notizia.cfg b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_notizia.cfg new file mode 100644 index 00000000..b67329db --- /dev/null +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_notizia.cfg @@ -0,0 +1,11 @@ +[taxonomy] +name = tipologia_notizia +title = Tipologia notizia +description = Il sistema di gestione contenuti basato su React +default_language = it +field_title = Tipologia notizia +field_description = Seleziona la tipologia della notizia +taxonomy_fieldset = default +is_single_select = true +is_required = true + diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_notizia.xml b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_notizia.xml new file mode 100644 index 00000000..ace0d9a6 --- /dev/null +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_notizia.xml @@ -0,0 +1,26 @@ + + + + Tipologia notizia + + tipologia_notizia + + notizia + + Notizia + + + + comunicato_stampa + + Comunicato (stampa) + + + + avviso + + + Avviso + + + \ No newline at end of file diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_organizzazione.cfg b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_organizzazione.cfg new file mode 100644 index 00000000..06d0ea2c --- /dev/null +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_organizzazione.cfg @@ -0,0 +1,10 @@ +[taxonomy] +name = tipologia_organizzazione +title = Tipologia organizzazione +description = Selezione la tipologia dell'unità organizzativa +default_language = it +field_title = Tipologia organizzazione +field_description = Selezione la tipologia dell'unità organizzativa +taxonomy_fieldset = struttura +is_required = true + diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_organizzazione.xml b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_organizzazione.xml new file mode 100644 index 00000000..3936c3bd --- /dev/null +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_organizzazione.xml @@ -0,0 +1,99 @@ + + + + Tipologia organizzazione + + tipologia_organizzazione + + struttura_amministrativa + + Struttura amministrativa + + + zona + + Zona + + + + ufficio + + Ufficio + + + + + struttura_politica + + Struttura politica + + + giunta_comunale + + Giunta comunale + + + + consiglio_comunale + + Consiglio comunale + + + + commisione + + Commissione + + + + + altra_struttura + + + Altra struttura + + + biblioteca + + Biblioteca + + + + Museo + + museo + + + + azienda_municipalizzata + + Azienda municipalizzata + + + + ente + + Ente + + + + fondazione + + Fondazione + + + + centro_culturale + + Centro culturale + + + + scuola + + + Scuola + + + + \ No newline at end of file diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_pdc.cfg b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_pdc.cfg new file mode 100644 index 00000000..3d0abb96 --- /dev/null +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_pdc.cfg @@ -0,0 +1,10 @@ +[taxonomy] +name = tipologia_pdc +title = Tipo di punto di contatto +description = Il sistema di gestione contenuti basato su React +default_language = it +field_title = Tipo di punto di contatto +taxonomy_fieldset = default +is_single_select = true +is_required = true + diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_pdc.xml b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_pdc.xml new file mode 100644 index 00000000..f2c8ffb6 --- /dev/null +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_pdc.xml @@ -0,0 +1,69 @@ + + + + Tipo di punto di contatto + + tipologia_pdc + + email + + Email + + + + telefono + + Telefono + + + + url + + URL + + + + pec + + PEC + + + + account + + + Accout + + + whatsapp + + Whatsapp + + + + telegram + + Telegram + + + + skype + + Skype + + + + linkedin + + Linkedin + + + + twitter + + + Twitter + + + + \ No newline at end of file diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_stati_pratica.cfg b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_stati_pratica.cfg new file mode 100644 index 00000000..c0743186 --- /dev/null +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_stati_pratica.cfg @@ -0,0 +1,10 @@ +[taxonomy] +name = tipologia_stati_pratica +title = Stati di una Pratica +description = Il sistema di gestione contenuti basato su React +default_language = it +field_title = Stati di una Pratica +taxonomy_fieldset = default +is_single_select = true +is_required = true + diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_stati_pratica.xml b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_stati_pratica.xml new file mode 100644 index 00000000..9e6aa514 --- /dev/null +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_stati_pratica.xml @@ -0,0 +1,63 @@ + + + + Stati di una Pratica + + tipologia_stati_pratica + + processo_non_avviato + + Processo non avviato + + + in_bozza + + In bozza + + + + + processo_in_corso + + Processo in corso + + + + processo_sospeso + + Processo sospeso + + + azione_da_parte_dell'utente + + Si richiede un'azione da parte dell'utente + + + + anzione_da_parte_della_pubblica_amministrazione + + Si richiede un'azione da parte della Pubblica Amministrazione + + + + + processo_concluso + + + Processo concluso + + + esito_positivo + + Esito positivo + + + + esito_negativo + + + Esito negativo + + + + \ No newline at end of file diff --git a/src/design/plone/contenttypes/profiles/default/registry/criteria.xml b/src/design/plone/contenttypes/profiles/default/registry/criteria.xml index 2864887c..48716fc0 100644 --- a/src/design/plone/contenttypes/profiles/default/registry/criteria.xml +++ b/src/design/plone/contenttypes/profiles/default/registry/criteria.xml @@ -162,6 +162,118 @@ Metadata + + Tipologia di incarico + + True + False + + plone.app.querystring.operation.selection.any + plone.app.querystring.operation.selection.all + + collective.taxonomy.tipologia_incarico + Metadata + + + + Tipologia di luogo + + True + False + + plone.app.querystring.operation.selection.any + plone.app.querystring.operation.selection.all + + collective.taxonomy.tipologia_luogo + Metadata + + + + Tipologia di evento + + True + False + + plone.app.querystring.operation.selection.any + plone.app.querystring.operation.selection.all + + collective.taxonomy.tipologia_evento + Metadata + + + + Tipologia di punto di contatto + + True + False + + plone.app.querystring.operation.selection.any + plone.app.querystring.operation.selection.all + + collective.taxonomy.tipologia_pdc + Metadata + + + + Tipologia di documento albo pretorio + + True + False + + plone.app.querystring.operation.selection.any + plone.app.querystring.operation.selection.all + + collective.taxonomy.tipologia_documenti_albopretorio + Metadata + + + + Tipologia di frequenza di aggiornamento + + True + False + + plone.app.querystring.operation.selection.any + plone.app.querystring.operation.selection.all + + collective.taxonomy.tipologia_frequenza_aggiornamento + Metadata + + + + Tipologia di stati di una pratica + + True + False + + plone.app.querystring.operation.selection.any + plone.app.querystring.operation.selection.all + + collective.taxonomy.tipologia_stati_pratica + Metadata + + + + Tipologia di licenze + + True + False + + plone.app.querystring.operation.selection.any + plone.app.querystring.operation.selection.all + + collective.taxonomy.tipologia_licenze + Metadata + + Date: Fri, 30 Dec 2022 12:15:26 +0100 Subject: [PATCH 022/487] [dev] add behaviors on install --- src/design/plone/contenttypes/configure.zcml | 1 + .../profiles/default/metadata.xml | 1 + .../profiles/default/types/Dataset.xml | 3 ++ .../profiles/default/types/Documento.xml | 5 ++ .../profiles/default/types/Event.xml | 1 + .../profiles/default/types/News_Item.xml | 8 +++- .../profiles/default/types/Pratica.xml | 1 + .../profiles/default/types/Servizio.xml | 2 + .../default/types/UnitaOrganizzativa.xml | 1 + .../profiles/default/types/Venue.xml | 1 + .../plone/contenttypes/setuphandlers.py | 47 ++++++++++--------- .../plone/contenttypes/upgrades/upgrades.py | 8 +++- 12 files changed, 55 insertions(+), 24 deletions(-) diff --git a/src/design/plone/contenttypes/configure.zcml b/src/design/plone/contenttypes/configure.zcml index e0fc79a0..0f7d2ef6 100644 --- a/src/design/plone/contenttypes/configure.zcml +++ b/src/design/plone/contenttypes/configure.zcml @@ -42,6 +42,7 @@ directory="profiles/behaviors" description="Registers taxonomies." provides="Products.GenericSetup.interfaces.EXTENSION" + post_handler=".setuphandlers.post_install_taxonomy" /> profile-collective.venue:default profile-redturtle.volto:default profile-eea.api.taxonomy:default + profile-design.plone.contenttypes:taxonomy diff --git a/src/design/plone/contenttypes/profiles/default/types/Dataset.xml b/src/design/plone/contenttypes/profiles/default/types/Dataset.xml index d1ead400..b1631523 100644 --- a/src/design/plone/contenttypes/profiles/default/types/Dataset.xml +++ b/src/design/plone/contenttypes/profiles/default/types/Dataset.xml @@ -48,6 +48,9 @@ + + + diff --git a/src/design/plone/contenttypes/profiles/default/types/Documento.xml b/src/design/plone/contenttypes/profiles/default/types/Documento.xml index 934e30bc..13d09a41 100644 --- a/src/design/plone/contenttypes/profiles/default/types/Documento.xml +++ b/src/design/plone/contenttypes/profiles/default/types/Documento.xml @@ -51,6 +51,11 @@ + + + + + diff --git a/src/design/plone/contenttypes/profiles/default/types/Event.xml b/src/design/plone/contenttypes/profiles/default/types/Event.xml index e21af13c..a691211c 100644 --- a/src/design/plone/contenttypes/profiles/default/types/Event.xml +++ b/src/design/plone/contenttypes/profiles/default/types/Event.xml @@ -33,6 +33,7 @@ + diff --git a/src/design/plone/contenttypes/profiles/default/types/News_Item.xml b/src/design/plone/contenttypes/profiles/default/types/News_Item.xml index c5132466..ac55c50c 100644 --- a/src/design/plone/contenttypes/profiles/default/types/News_Item.xml +++ b/src/design/plone/contenttypes/profiles/default/types/News_Item.xml @@ -1,12 +1,17 @@ -Notizie e comunicati stampa + + + Notizie e comunicati stampa + + + @@ -15,6 +20,7 @@ + diff --git a/src/design/plone/contenttypes/profiles/default/types/Pratica.xml b/src/design/plone/contenttypes/profiles/default/types/Pratica.xml index a5630d36..0bd44799 100644 --- a/src/design/plone/contenttypes/profiles/default/types/Pratica.xml +++ b/src/design/plone/contenttypes/profiles/default/types/Pratica.xml @@ -48,6 +48,7 @@ + diff --git a/src/design/plone/contenttypes/profiles/default/types/Servizio.xml b/src/design/plone/contenttypes/profiles/default/types/Servizio.xml index 28301b53..7d8fcba9 100644 --- a/src/design/plone/contenttypes/profiles/default/types/Servizio.xml +++ b/src/design/plone/contenttypes/profiles/default/types/Servizio.xml @@ -55,6 +55,8 @@ + + diff --git a/src/design/plone/contenttypes/profiles/default/types/UnitaOrganizzativa.xml b/src/design/plone/contenttypes/profiles/default/types/UnitaOrganizzativa.xml index bb5582e7..bdd243af 100644 --- a/src/design/plone/contenttypes/profiles/default/types/UnitaOrganizzativa.xml +++ b/src/design/plone/contenttypes/profiles/default/types/UnitaOrganizzativa.xml @@ -56,6 +56,7 @@ + diff --git a/src/design/plone/contenttypes/profiles/default/types/Venue.xml b/src/design/plone/contenttypes/profiles/default/types/Venue.xml index 7cd76eaa..19982107 100644 --- a/src/design/plone/contenttypes/profiles/default/types/Venue.xml +++ b/src/design/plone/contenttypes/profiles/default/types/Venue.xml @@ -28,6 +28,7 @@ + diff --git a/src/design/plone/contenttypes/setuphandlers.py b/src/design/plone/contenttypes/setuphandlers.py index 244ae9b8..d5a08711 100644 --- a/src/design/plone/contenttypes/setuphandlers.py +++ b/src/design/plone/contenttypes/setuphandlers.py @@ -3,6 +3,8 @@ from redturtle.bandi.interfaces.settings import IBandoSettings from Products.CMFPlone.interfaces import INonInstallable from zope.interface import implementer +from design.plone.contenttypes.upgrades.upgrades import remove_blocks_behavior +from design.plone.contenttypes.upgrades.upgrades import update_types @implementer(INonInstallable) @@ -20,35 +22,36 @@ def post_install(context): remove_blocks_behavior(context) + # update behaviors portal_types = api.portal.get_tool(name="portal_types") - # add image fields at the end of document behaviors and remove tableofcontents - document_behaviors = [ - x - for x in portal_types["Document"].behaviors - if x - not in [ - "plone.leadimage", - "volto.preview_image", - "plone.tableofcontents", + BEHAVIORS = { + "Document": { + "in": [ + "plone.leadimage", + "volto.preview_image", + ], + "out": [ + "plone.leadimage", + "volto.preview_image", + "plone.tableofcontents", + ] + }, + } + for ct in BEHAVIORS.keys(): + ct_behaviors = [ + x for x in portal_types[ct].behaviors if x not in BEHAVIORS[ct]["out"] # noqa ] - ] - document_behaviors.extend(["plone.leadimage", "volto.preview_image"]) - portal_types["Document"].behaviors = tuple(document_behaviors) + ct_behaviors.extend( + [x for x in BEHAVIORS[ct]["in"] if x not in ct_behaviors] + ) + portal_types[ct].behaviors = tuple(ct_behaviors) # remove default ente api.portal.set_registry_record("default_ente", (), interface=IBandoSettings) - # TODO - # fargli caricare le tassonomie all'installazione - # assegnazione delle varie behavior ai tipi di contenuto - -def remove_blocks_behavior(context): - portal_types = api.portal.get_tool(name="portal_types") - for ptype in ["News Item", "Event"]: - portal_types[ptype].behaviors = tuple( - [x for x in portal_types[ptype].behaviors if x != "volto.blocks"] - ) +def post_install_taxonomy(context): + update_types(context) def uninstall(context): diff --git a/src/design/plone/contenttypes/upgrades/upgrades.py b/src/design/plone/contenttypes/upgrades/upgrades.py index f69ddafb..268b66e1 100644 --- a/src/design/plone/contenttypes/upgrades/upgrades.py +++ b/src/design/plone/contenttypes/upgrades/upgrades.py @@ -4,7 +4,6 @@ from copy import deepcopy from design.plone.contenttypes.controlpanels.settings import IDesignPloneSettings from design.plone.contenttypes.upgrades.draftjs_converter import to_draftjs -from design.plone.contenttypes.setuphandlers import remove_blocks_behavior from plone import api from plone.app.textfield.value import RichTextValue from plone.app.upgrade.utils import installOrReinstallProduct @@ -56,6 +55,13 @@ def update_controlpanel(context): update_profile(context, "controlpanel") +def remove_blocks_behavior(context): + portal_types = api.portal.get_tool(name="portal_types") + for ptype in ["News Item", "Event"]: + portal_types[ptype].behaviors = tuple( + [x for x in portal_types[ptype].behaviors if x != "volto.blocks"] + ) + def remap_fields(mapping): pc = api.portal.get_tool(name="portal_catalog") brains = pc() From 1c84bb46d3d979f121957c70d73b42173afd8cc0 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Fri, 30 Dec 2022 13:19:38 +0100 Subject: [PATCH 023/487] [dev] add pre-commit --- .gitattributes | 2 +- .pre-commit-config.yaml | 51 ++ CHANGES.rst | 2 +- DEVELOP.rst | 1 - docs/conf.py | 126 ++-- setup.cfg | 1 - setup.py | 1 - src/design/plone/contenttypes/__init__.py | 1 + .../adapters/searchabletext_indexers.py | 8 +- .../adapters/servizi_correlati.py | 3 +- .../behaviors/additional_help_infos.py | 7 +- .../plone/contenttypes/behaviors/address.py | 11 +- .../plone/contenttypes/behaviors/argomenti.py | 8 +- .../behaviors/dataset_correlati.py | 6 +- .../behaviors/descrizione_estesa.py | 7 +- .../plone/contenttypes/behaviors/evento.py | 9 +- .../contenttypes/behaviors/geolocation.py | 7 +- .../behaviors/luoghi_correlati.py | 6 +- .../plone/contenttypes/behaviors/luogo.py | 9 +- .../contenttypes/behaviors/multi_file.py | 7 +- .../behaviors/news_additional_fields.py | 10 +- .../behaviors/servizi_correlati.py | 6 +- .../contenttypes/behaviors/show_modified.py | 3 +- .../behaviors/strutture_correlate.py | 6 +- .../contenttypes/behaviors/trasparenza.py | 19 +- .../contenttypes/behaviors/update_note.py | 7 +- ...contenttypes.browser.templates.newsitem.pt | 46 +- src/design/plone/contenttypes/configure.zcml | 2 +- .../content/cartella_modulistica.py | 4 +- .../plone/contenttypes/content/dataset.py | 2 +- .../plone/contenttypes/content/documento.py | 2 +- .../content/documento_personale.py | 4 +- .../plone/contenttypes/content/evento.py | 2 +- .../contenttypes/content/pagina_argomento.py | 4 +- .../content/ricevuta_pagamento.py | 4 +- .../content/unita_organizzativa.py | 4 +- .../controlpanels/geolocation_defaults.py | 2 +- .../contenttypes/controlpanels/settings.py | 5 +- .../plone/contenttypes/events/documento.py | 2 +- .../plone/contenttypes/events/evento.py | 2 +- .../events/notizie_e_comunicati_stampa.py | 2 +- .../events/unita_organizzativa.py | 1 + .../plone/contenttypes/indexers/common.py | 2 +- .../plone/contenttypes/indexers/events.py | 2 +- .../plone/contenttypes/indexers/news.py | 2 +- .../plone/contenttypes/indexers/servizio.py | 2 +- src/design/plone/contenttypes/indexers/uo.py | 2 +- .../plone/contenttypes/interfaces/bando.py | 5 +- .../plone/contenttypes/interfaces/dataset.py | 2 +- .../interfaces/documento_personale.py | 2 +- .../interfaces/pagina_argomento.py | 2 +- .../plone/contenttypes/interfaces/persona.py | 4 +- .../plone/contenttypes/interfaces/pratica.py | 4 +- .../plone/contenttypes/interfaces/servizio.py | 2 +- .../interfaces/unita_organizzativa.py | 3 +- .../collective.geolocationbehavior.po | 1 - .../locales/it/LC_MESSAGES/plone.po | 1 - .../plone/contenttypes/patches/__init__.py | 4 +- .../contenttypes/patches/baseserializer.py | 9 +- .../plone/contenttypes/patches/configure.zcml | 22 +- .../behaviors/taxonomies/business_events.cfg | 1 - .../behaviors/taxonomies/business_events.xml | 14 +- .../taxonomies/person_life_events.cfg | 1 - .../taxonomies/person_life_events.xml | 14 +- .../behaviors/taxonomies/temi_dataset.cfg | 1 - .../behaviors/taxonomies/temi_dataset.xml | 14 +- .../tipologia_documenti_albopretorio.cfg | 1 - .../tipologia_documenti_albopretorio.xml | 18 +- .../taxonomies/tipologia_documento.cfg | 1 - .../taxonomies/tipologia_documento.xml | 14 +- .../behaviors/taxonomies/tipologia_evento.cfg | 1 - .../behaviors/taxonomies/tipologia_evento.xml | 18 +- .../tipologia_frequenza_aggiornamento.cfg | 1 - .../tipologia_frequenza_aggiornamento.xml | 14 +- .../taxonomies/tipologia_incarico.cfg | 1 - .../taxonomies/tipologia_incarico.xml | 14 +- .../taxonomies/tipologia_licenze.cfg | 1 - .../taxonomies/tipologia_licenze.xml | 16 +- .../behaviors/taxonomies/tipologia_luogo.cfg | 1 - .../behaviors/taxonomies/tipologia_luogo.xml | 16 +- .../taxonomies/tipologia_notizia.cfg | 1 - .../taxonomies/tipologia_notizia.xml | 14 +- .../taxonomies/tipologia_organizzazione.cfg | 1 - .../taxonomies/tipologia_organizzazione.xml | 16 +- .../behaviors/taxonomies/tipologia_pdc.cfg | 1 - .../behaviors/taxonomies/tipologia_pdc.xml | 16 +- .../taxonomies/tipologia_stati_pratica.cfg | 1 - .../taxonomies/tipologia_stati_pratica.xml | 16 +- .../profiles/default/browserlayer.xml | 9 +- .../contenttypes/profiles/default/catalog.xml | 166 +++-- .../profiles/default/controlpanel.xml | 59 +- .../profiles/default/diff_tool.xml | 70 +- .../profiles/default/metadata.xml | 2 +- .../profiles/default/registry/criteria.xml | 608 +++++++++++------- .../profiles/default/registry/settings.xml | 12 +- .../profiles/default/repositorytool.xml | 68 +- .../contenttypes/profiles/default/rolemap.xml | 184 +++--- .../contenttypes/profiles/default/types.xml | 6 +- .../profiles/default/types/Bando.xml | 51 +- .../default/types/Bando_Folder_Deepening.xml | 25 +- .../default/types/CartellaModulistica.xml | 115 ++-- .../profiles/default/types/Dataset.xml | 111 ++-- .../profiles/default/types/Document.xml | 39 +- .../profiles/default/types/Documento.xml | 103 ++- .../default/types/Documento_Personale.xml | 111 ++-- .../profiles/default/types/Event.xml | 52 +- .../profiles/default/types/Link.xml | 22 +- .../profiles/default/types/Messaggio.xml | 113 ++-- .../profiles/default/types/Modulo.xml | 95 ++- .../profiles/default/types/News_Item.xml | 43 +- .../default/types/Pagina_Argomento.xml | 117 ++-- .../profiles/default/types/Persona.xml | 109 ++-- .../profiles/default/types/Pratica.xml | 111 ++-- .../default/types/RicevutaPagamento.xml | 109 ++-- .../profiles/default/types/Servizio.xml | 109 ++-- .../default/types/UnitaOrganizzativa.xml | 131 ++-- .../profiles/default/types/Venue.xml | 77 ++- .../profiles/to_3000/controlpanel.xml | 23 +- .../profiles/to_3000/registry.xml | 11 +- .../profiles/uninstall/browserlayer.xml | 9 +- .../restapi/deserializers/dxfields.py | 1 + .../restapi/deserializers/persona.py | 6 +- .../contenttypes/restapi/serializers/bando.py | 2 +- .../serializers/cartella_modulistica.py | 19 +- .../restapi/serializers/documento.py | 6 +- .../restapi/serializers/dxcontent.py | 11 +- .../restapi/serializers/dxfields.py | 1 + .../restapi/serializers/modulo.py | 2 +- .../restapi/serializers/persona.py | 6 +- .../serializers/related_news_serializer.py | 6 +- .../restapi/serializers/summary.py | 7 +- .../serializers/unita_organizzativa.py | 23 +- .../contenttypes/restapi/serializers/venue.py | 8 +- .../restapi/services/content/add.py | 2 +- .../restapi/services/controlpanel.py | 4 +- .../restapi/services/modulistica_items/get.py | 2 +- .../restapi/services/scadenziario/post.py | 1 + .../restapi/services/trasparenza/get.py | 8 +- .../restapi/services/types/get.py | 10 +- .../contenttypes/restapi/types/adapters.py | 4 +- .../plone/contenttypes/setuphandlers.py | 16 +- src/design/plone/contenttypes/testing.py | 3 +- .../contenttypes/tests/test_argomenti.py | 10 +- .../tests/test_base_serializer.py | 17 +- .../tests/test_behavior_descrizione_estesa.py | 14 +- .../tests/test_behavior_show_modified.py | 20 +- .../tests/test_behavior_update_note.py | 16 +- .../contenttypes/tests/test_ct_document.py | 1 + .../contenttypes/tests/test_ct_documento.py | 10 +- .../tests/test_ct_documento_personale.py | 1 + .../plone/contenttypes/tests/test_ct_event.py | 9 +- .../plone/contenttypes/tests/test_ct_luogo.py | 4 +- .../contenttypes/tests/test_ct_modulo.py | 1 + .../plone/contenttypes/tests/test_ct_news.py | 8 +- .../tests/test_ct_pagina_argomento.py | 1 + .../contenttypes/tests/test_ct_persona.py | 15 +- .../contenttypes/tests/test_ct_servizio.py | 9 +- .../tests/test_ct_unita_organizzativa.py | 10 +- .../tests/test_relateditems_with_dates.py | 5 +- .../plone/contenttypes/tests/test_setup.py | 2 +- .../tests/test_summary_serializer.py | 2 +- .../contenttypes/tests/test_vocabularies.py | 8 +- .../upgrades/draftjs_converter.py | 5 +- .../plone/contenttypes/upgrades/upgrades.py | 13 +- src/design/plone/contenttypes/utils.py | 6 +- .../vocabularies/tags_vocabulary.py | 22 +- 166 files changed, 2173 insertions(+), 1765 deletions(-) create mode 100644 .pre-commit-config.yaml diff --git a/.gitattributes b/.gitattributes index af469010..6f9ff673 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1 @@ -CHANGES.rst merge=union \ No newline at end of file +CHANGES.rst merge=union diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 00000000..2d36b143 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,51 @@ +# See https://pre-commit.com for more information +# See https://pre-commit.com/hooks.html for more hooks + +default_language_version: + python: python3.8 + +default_stages: [commit, push] + +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.3.0 + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-yaml + - repo: https://github.com/psf/black + rev: 22.6.0 + hooks: + - id: black + args: ["--line-length=88", "--check", "--diff", "--force-exclude=migrations", "src/"] +# args: ["--line-length=88", "--force-exclude=migrations", "src/"] + types: [python] + entry: black + - repo: https://gitlab.com/pycqa/flake8 + rev: "3.9.2" + hooks: + - id: flake8 + name: flake8 + entry: flake8 + additional_dependencies: ["flake8-django==0.0.4", "pylint-django==2.0.11"] + types: [python] + args: ["--max-complexity=30", "--max-line-length=88", "--ignore=DJ01,DJ08,W503,ANN101", "--exclude=docs/*", "src/", "setup.py"] + - repo: https://github.com/pycqa/isort + rev: 5.10.1 + hooks: + - id: isort + name: isort (python) + args: ["--multi-line=3", "--lbt=1", "--trailing-comma", "--force-grid-wrap=0", "--use-parentheses", "--ensure-newline-before-comments", "--line-length=88"] + - repo: local + hooks: + - id: python-check-pdb + name: check pdb + description: 'PDB check inside code' + entry: '^\s?[^#]+\.set_trace\(\)' + language: pygrep + types: [python] + - repo: https://github.com/collective/zpretty + rev: 2.4.1 + hooks: + - id: zpretty + name: zpretty diff --git a/CHANGES.rst b/CHANGES.rst index 1c51c5b4..6a851953 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -85,7 +85,7 @@ Changelog ------------------ - Add custom expand_events method in scadenziario endpoints, because in plone.app.events >= 3.2.13 - that method changed and breaks our integration. We keep previous version of that method to + that method changed and breaks our integration. We keep previous version of that method to not re-implement scadenziario endpoints. [cekk] diff --git a/DEVELOP.rst b/DEVELOP.rst index cd8979a3..33e64802 100644 --- a/DEVELOP.rst +++ b/DEVELOP.rst @@ -39,4 +39,3 @@ list all tox environments: run a specific tox env: $ tox -e py37-Plone52 - diff --git a/docs/conf.py b/docs/conf.py index 80f42ec9..5da02528 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -9,18 +9,19 @@ # All configuration values have a default; values that are commented out # serve to show the default. -import sys import os +import sys + # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. -#sys.path.insert(0, os.path.abspath('.')) +# sys.path.insert(0, os.path.abspath('.')) # -- General configuration ------------------------------------------------ # If your documentation needs a minimal Sphinx version, state it here. -#needs_sphinx = '1.0' +# needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom @@ -28,32 +29,32 @@ extensions = [] # Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] +templates_path = ["_templates"] # The suffix(es) of source filenames. # You can specify multiple suffix as a list of string: # source_suffix = ['.rst', '.md'] -source_suffix = '.rst' +source_suffix = ".rst" # The encoding of source files. -#source_encoding = 'utf-8-sig' +# source_encoding = 'utf-8-sig' # The master toctree document. -master_doc = 'index' +master_doc = "index" # General information about the project. -project = u'design.plone.contenttypes' -copyright = u'RedTurtle (RedTurtle)' -author = u'RedTurtle (RedTurtle)' +project = "design.plone.contenttypes" +copyright = "RedTurtle (RedTurtle)" +author = "RedTurtle (RedTurtle)" # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. -version = u'3.0' +version = "3.0" # The full version, including alpha/beta/rc tags. -release = u'3.0' +release = "3.0" # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. @@ -64,38 +65,38 @@ # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: -#today = '' +# today = '' # Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' +# today_fmt = '%B %d, %Y' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This patterns also effect to html_static_path and html_extra_path -exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] +exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] # The reST default role (used for this markup: `text`) to use for all # documents. -#default_role = None +# default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True +# add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). -#add_module_names = True +# add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. -#show_authors = False +# show_authors = False # The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' +pygments_style = "sphinx" # A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] +# modindex_common_prefix = [] # If true, keep warnings as "system message" paragraphs in the built documents. -#keep_warnings = False +# keep_warnings = False # If true, `todo` and `todoList` produce output, else they produce nothing. todo_include_todos = False @@ -105,135 +106,132 @@ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_theme = 'alabaster' +html_theme = "alabaster" # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. -#html_theme_options = {} +# html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] +# html_theme_path = [] # The name for this set of Sphinx documents. # " v documentation" by default. -#html_title = u'bobtemplates.plone v3.0' +# html_title = u'bobtemplates.plone v3.0' # A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None +# html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. -#html_logo = None +# html_logo = None # The name of an image file (relative to this directory) to use as a favicon of # the docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. -#html_favicon = None +# html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] +html_static_path = ["_static"] # Add any extra paths that contain custom files (such as robots.txt or # .htaccess) here, relative to this directory. These files are copied # directly to the root of the documentation. -#html_extra_path = [] +# html_extra_path = [] # If not None, a 'Last updated on:' timestamp is inserted at every page # bottom, using the given strftime format. # The empty string is equivalent to '%b %d, %Y'. -#html_last_updated_fmt = None +# html_last_updated_fmt = None # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. -#html_use_smartypants = True +# html_use_smartypants = True # Custom sidebar templates, maps document names to template names. -#html_sidebars = {} +# html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. -#html_additional_pages = {} +# html_additional_pages = {} # If false, no module index is generated. -#html_domain_indices = True +# html_domain_indices = True # If false, no index is generated. -#html_use_index = True +# html_use_index = True # If true, the index is split into individual pages for each letter. -#html_split_index = False +# html_split_index = False # If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True +# html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -#html_show_sphinx = True +# html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True +# html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. -#html_use_opensearch = '' +# html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = None +# html_file_suffix = None # Language to be used for generating the HTML full-text search index. # Sphinx supports the following languages: # 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja' # 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr', 'zh' -#html_search_language = 'en' +# html_search_language = 'en' # A dictionary with options for the search language support, empty by default. # 'ja' uses this config value. # 'zh' user can custom change `jieba` dictionary path. -#html_search_options = {'type': 'default'} +# html_search_options = {'type': 'default'} # The name of a javascript file (relative to the configuration directory) that # implements a search results scorer. If empty, the default will be used. -#html_search_scorer = 'scorer.js' +# html_search_scorer = 'scorer.js' # Output file base name for HTML help builder. -htmlhelp_basename = 'design.plone.contenttypesdoc' +htmlhelp_basename = "design.plone.contenttypesdoc" # -- Options for LaTeX output --------------------------------------------- latex_elements = { -# The paper size ('letterpaper' or 'a4paper'). -#'papersize': 'letterpaper', - -# The font size ('10pt', '11pt' or '12pt'). -#'pointsize': '10pt', - -# Additional stuff for the LaTeX preamble. -#'preamble': '', - -# Latex figure (float) alignment -#'figure_align': 'htbp', + # The paper size ('letterpaper' or 'a4paper'). + #'papersize': 'letterpaper', + # The font size ('10pt', '11pt' or '12pt'). + #'pointsize': '10pt', + # Additional stuff for the LaTeX preamble. + #'preamble': '', + # Latex figure (float) alignment + #'figure_align': 'htbp', } # The name of an image file (relative to this directory) to place at the top of # the title page. -#latex_logo = None +# latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. -#latex_use_parts = False +# latex_use_parts = False # If true, show page references after internal links. -#latex_show_pagerefs = False +# latex_show_pagerefs = False # If true, show URL addresses after external links. -#latex_show_urls = False +# latex_show_urls = False # Documents to append as an appendix to all manuals. -#latex_appendices = [] +# latex_appendices = [] # If false, no module index is generated. -#latex_domain_indices = True +# latex_domain_indices = True diff --git a/setup.cfg b/setup.cfg index ceaf3244..ad42f735 100644 --- a/setup.cfg +++ b/setup.cfg @@ -21,4 +21,3 @@ max-line-length = 100000 extend-ignore = E203, C901 - diff --git a/setup.py b/setup.py index 98e4bb76..27cebc16 100644 --- a/setup.py +++ b/setup.py @@ -42,7 +42,6 @@ "PyPI": "https://pypi.python.org/pypi/design.plone.contenttypes", "Source": "https://github.com/collective/design.plone.contenttypes", "Tracker": "https://github.com/collective/design.plone.contenttypes/issues", - # 'Documentation': 'https://design.plone.contenttypes.readthedocs.io/en/latest/', }, license="GPL version 2", packages=find_packages("src", exclude=["ez_setup"]), diff --git a/src/design/plone/contenttypes/__init__.py b/src/design/plone/contenttypes/__init__.py index 233bbeca..b752193d 100644 --- a/src/design/plone/contenttypes/__init__.py +++ b/src/design/plone/contenttypes/__init__.py @@ -4,6 +4,7 @@ from plone.app.dexterity.textindexer import utils from zope.i18nmessageid import MessageFactory + _ = MessageFactory("design.plone.contenttypes") diff --git a/src/design/plone/contenttypes/adapters/searchabletext_indexers.py b/src/design/plone/contenttypes/adapters/searchabletext_indexers.py index 193d3df7..d95d2718 100644 --- a/src/design/plone/contenttypes/adapters/searchabletext_indexers.py +++ b/src/design/plone/contenttypes/adapters/searchabletext_indexers.py @@ -1,9 +1,13 @@ # -*- coding: utf-8 -*- +from design.plone.contenttypes.interfaces import IDesignPloneContentType from plone.app.dexterity.textindexer.converters import ( DefaultDexterityTextIndexFieldConverter, ) from plone.app.dexterity.textindexer.interfaces import IDexterityTextIndexFieldConverter from plone.dexterity.interfaces import IDexterityContent +from plone.restapi.indexers import ( + TextBlockSearchableText as BaseTextBlockSearchableText, +) from plone.restapi.interfaces import IBlockSearchableText from z3c.form.interfaces import IWidget from z3c.relationfield.interfaces import IRelationChoice @@ -11,10 +15,6 @@ from zope.component import adapter from zope.interface import implementer from zope.publisher.interfaces.browser import IBrowserRequest -from design.plone.contenttypes.interfaces import IDesignPloneContentType -from plone.restapi.indexers import ( - TextBlockSearchableText as BaseTextBlockSearchableText, -) @implementer(IDexterityTextIndexFieldConverter) diff --git a/src/design/plone/contenttypes/adapters/servizi_correlati.py b/src/design/plone/contenttypes/adapters/servizi_correlati.py index ae9d64f1..ec66b7e0 100644 --- a/src/design/plone/contenttypes/adapters/servizi_correlati.py +++ b/src/design/plone/contenttypes/adapters/servizi_correlati.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- -from .interfaces import ICorrelati, Correlati +from .interfaces import Correlati +from .interfaces import ICorrelati from zope.interface import implementer diff --git a/src/design/plone/contenttypes/behaviors/additional_help_infos.py b/src/design/plone/contenttypes/behaviors/additional_help_infos.py index 143243e4..e5b93c7b 100644 --- a/src/design/plone/contenttypes/behaviors/additional_help_infos.py +++ b/src/design/plone/contenttypes/behaviors/additional_help_infos.py @@ -1,12 +1,13 @@ # -*- coding: utf-8 -*- -from plone.app.dexterity import textindexer -from design.plone.contenttypes import _ from collective.volto.blocksfield.field import BlocksField +from design.plone.contenttypes import _ +from plone.app.dexterity import textindexer from plone.autoform.interfaces import IFormFieldProvider from plone.dexterity.interfaces import IDexterityContent from plone.supermodel import model from zope.component import adapter -from zope.interface import provider, implementer +from zope.interface import implementer +from zope.interface import provider # TODO: valutare se aggiungere 'box_aiuto', in alcuni CT e' obbligatorio diff --git a/src/design/plone/contenttypes/behaviors/address.py b/src/design/plone/contenttypes/behaviors/address.py index cab6c221..c2cd63ed 100644 --- a/src/design/plone/contenttypes/behaviors/address.py +++ b/src/design/plone/contenttypes/behaviors/address.py @@ -1,14 +1,15 @@ # -*- coding: utf-8 -*- -from plone.app.dexterity import textindexer from collective.address.behaviors import IAddress -from plone.dexterity.interfaces import IDexterityContent from design.plone.contenttypes import _ +from design.plone.contenttypes.interfaces.unita_organizzativa import IUnitaOrganizzativa +from plone.app.dexterity import textindexer from plone.autoform.interfaces import IFormFieldProvider +from plone.dexterity.interfaces import IDexterityContent from plone.supermodel import model -from zope.component import adapter from zope import schema -from zope.interface import provider, implementer -from design.plone.contenttypes.interfaces.unita_organizzativa import IUnitaOrganizzativa +from zope.component import adapter +from zope.interface import implementer +from zope.interface import provider class IAddressNomeSede(model.Schema): diff --git a/src/design/plone/contenttypes/behaviors/argomenti.py b/src/design/plone/contenttypes/behaviors/argomenti.py index 22a8fcca..6a1d2ea5 100644 --- a/src/design/plone/contenttypes/behaviors/argomenti.py +++ b/src/design/plone/contenttypes/behaviors/argomenti.py @@ -1,17 +1,19 @@ # -*- coding: utf-8 -*- -from plone.app.dexterity import textindexer from design.plone.contenttypes import _ from design.plone.contenttypes.interfaces.bando import IBandoAgidSchema from design.plone.contenttypes.interfaces.documento import IDocumento from plone.app.contenttypes.interfaces import IDocument +from plone.app.dexterity import textindexer from plone.app.z3cform.widget import RelatedItemsFieldWidget from plone.autoform import directives as form from plone.autoform.interfaces import IFormFieldProvider from plone.dexterity.interfaces import IDexterityContent from plone.supermodel import model -from z3c.relationfield.schema import RelationChoice, RelationList +from z3c.relationfield.schema import RelationChoice +from z3c.relationfield.schema import RelationList from zope.component import adapter -from zope.interface import provider, implementer +from zope.interface import implementer +from zope.interface import provider class IArgomentiSchema(model.Schema): diff --git a/src/design/plone/contenttypes/behaviors/dataset_correlati.py b/src/design/plone/contenttypes/behaviors/dataset_correlati.py index 4047d351..2c402745 100644 --- a/src/design/plone/contenttypes/behaviors/dataset_correlati.py +++ b/src/design/plone/contenttypes/behaviors/dataset_correlati.py @@ -5,9 +5,11 @@ from plone.autoform.interfaces import IFormFieldProvider from plone.dexterity.interfaces import IDexterityContent from plone.supermodel import model -from z3c.relationfield.schema import RelationChoice, RelationList +from z3c.relationfield.schema import RelationChoice +from z3c.relationfield.schema import RelationList from zope.component import adapter -from zope.interface import provider, implementer +from zope.interface import implementer +from zope.interface import provider # TODO: merge with NEWS diff --git a/src/design/plone/contenttypes/behaviors/descrizione_estesa.py b/src/design/plone/contenttypes/behaviors/descrizione_estesa.py index b0d3d789..06c0696f 100644 --- a/src/design/plone/contenttypes/behaviors/descrizione_estesa.py +++ b/src/design/plone/contenttypes/behaviors/descrizione_estesa.py @@ -1,14 +1,15 @@ # -*- coding: utf-8 -*- -from plone.app.dexterity import textindexer +from collective.volto.blocksfield.field import BlocksField from design.plone.contenttypes import _ from design.plone.contenttypes.interfaces.documento import IDocumento -from collective.volto.blocksfield.field import BlocksField +from plone.app.dexterity import textindexer from plone.autoform import directives as form from plone.autoform.interfaces import IFormFieldProvider from plone.dexterity.interfaces import IDexterityContent from plone.supermodel import model from zope.component import adapter -from zope.interface import provider, implementer +from zope.interface import implementer +from zope.interface import provider class IDescrizioneEstesaSchema(model.Schema): diff --git a/src/design/plone/contenttypes/behaviors/evento.py b/src/design/plone/contenttypes/behaviors/evento.py index ebdb93d0..067a1569 100644 --- a/src/design/plone/contenttypes/behaviors/evento.py +++ b/src/design/plone/contenttypes/behaviors/evento.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- -from plone.app.dexterity import textindexer -from design.plone.contenttypes import _ from collective.volto.blocksfield.field import BlocksField +from design.plone.contenttypes import _ +from plone.app.dexterity import textindexer from plone.app.z3cform.widget import RelatedItemsFieldWidget from plone.autoform import directives as form from plone.autoform.interfaces import IFormFieldProvider @@ -11,7 +11,8 @@ from z3c.relationfield.schema import RelationList from zope import schema from zope.component import adapter -from zope.interface import provider, implementer +from zope.interface import implementer +from zope.interface import provider @provider(IFormFieldProvider) @@ -96,7 +97,7 @@ class IEvento(model.Schema): required=False, description=_( "organizzato_da_esterno_help", - default="Se l'evento non è organizzato direttamente dal comune oppure ha anche un organizzatore esterno," + default="Se l'evento non è organizzato direttamente dal comune oppure ha anche un organizzatore esterno," # noqa " indicare il nome del contatto.", ), ) diff --git a/src/design/plone/contenttypes/behaviors/geolocation.py b/src/design/plone/contenttypes/behaviors/geolocation.py index 2b6a79a0..4ca75720 100644 --- a/src/design/plone/contenttypes/behaviors/geolocation.py +++ b/src/design/plone/contenttypes/behaviors/geolocation.py @@ -2,14 +2,13 @@ from collective.geolocationbehavior.geolocation import IGeolocatable from collective.venue.interfaces import IVenue from design.plone.contenttypes import _ +from design.plone.contenttypes.interfaces.unita_organizzativa import IUnitaOrganizzativa from plone.autoform.interfaces import IFormFieldProvider from plone.dexterity.interfaces import IDexterityContent from plone.supermodel import model from zope.component import adapter -from zope.interface import provider, implementer -from design.plone.contenttypes.interfaces.unita_organizzativa import ( - IUnitaOrganizzativa, -) +from zope.interface import implementer +from zope.interface import provider @provider(IFormFieldProvider) diff --git a/src/design/plone/contenttypes/behaviors/luoghi_correlati.py b/src/design/plone/contenttypes/behaviors/luoghi_correlati.py index 6c4cd431..4b0a8531 100644 --- a/src/design/plone/contenttypes/behaviors/luoghi_correlati.py +++ b/src/design/plone/contenttypes/behaviors/luoghi_correlati.py @@ -5,9 +5,11 @@ from plone.autoform.interfaces import IFormFieldProvider from plone.dexterity.interfaces import IDexterityContent from plone.supermodel import model -from z3c.relationfield.schema import RelationChoice, RelationList +from z3c.relationfield.schema import RelationChoice +from z3c.relationfield.schema import RelationList from zope.component import adapter -from zope.interface import provider, implementer +from zope.interface import implementer +from zope.interface import provider # TODO: merge with NEWS diff --git a/src/design/plone/contenttypes/behaviors/luogo.py b/src/design/plone/contenttypes/behaviors/luogo.py index f3ea73f5..65b278f5 100644 --- a/src/design/plone/contenttypes/behaviors/luogo.py +++ b/src/design/plone/contenttypes/behaviors/luogo.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- -from plone.app.dexterity import textindexer -from design.plone.contenttypes import _ from collective.volto.blocksfield.field import BlocksField +from design.plone.contenttypes import _ +from plone.app.dexterity import textindexer from plone.app.z3cform.widget import RelatedItemsFieldWidget from plone.autoform import directives as form from plone.autoform.interfaces import IFormFieldProvider @@ -11,7 +11,8 @@ from z3c.relationfield.schema import RelationList from zope import schema from zope.component import adapter -from zope.interface import provider, implementer +from zope.interface import implementer +from zope.interface import provider @provider(IFormFieldProvider) @@ -90,7 +91,7 @@ class ILuogo(model.Schema): # Decisono con Baio di toglierlo: visto il vocabolario, che in realtà sta - # qui: https://github.com/italia/daf-ontologie-vocabolari-controllati/tree/master/VocabolariControllati/classifications-for-culture/subject-disciplines + # qui: https://github.com/italia/daf-ontologie-vocabolari-controllati/tree/master/VocabolariControllati/classifications-for-culture/subject-disciplines # noqa # riteniamo che possa non fregare nulla a nessuno di questa categorizzazione. # # TODO: aggiungere il vocabolario da https://dataportal.daf.teamdigitale.it/#/vocabularies/subject-disciplines # noqa # # quando ritornano i dati dopo la migrazione, bisognera' vedere dove sono diff --git a/src/design/plone/contenttypes/behaviors/multi_file.py b/src/design/plone/contenttypes/behaviors/multi_file.py index 65f81014..11e306b4 100644 --- a/src/design/plone/contenttypes/behaviors/multi_file.py +++ b/src/design/plone/contenttypes/behaviors/multi_file.py @@ -1,11 +1,12 @@ # -*- coding: utf-8 -*- -from plone.namedfile import field -from plone.dexterity.interfaces import IDexterityContent from design.plone.contenttypes import _ from plone.autoform.interfaces import IFormFieldProvider +from plone.dexterity.interfaces import IDexterityContent +from plone.namedfile import field from plone.supermodel import model from zope.component import adapter -from zope.interface import provider, implementer +from zope.interface import implementer +from zope.interface import provider class IMultiFileSchema(model.Schema): diff --git a/src/design/plone/contenttypes/behaviors/news_additional_fields.py b/src/design/plone/contenttypes/behaviors/news_additional_fields.py index 416afbec..eb8299ec 100644 --- a/src/design/plone/contenttypes/behaviors/news_additional_fields.py +++ b/src/design/plone/contenttypes/behaviors/news_additional_fields.py @@ -1,16 +1,18 @@ # -*- coding: utf-8 -*- -from plone.app.dexterity import textindexer from collective.volto.blocksfield.field import BlocksField from design.plone.contenttypes import _ +from plone.app.contenttypes.interfaces import INewsItem +from plone.app.dexterity import textindexer from plone.app.z3cform.widget import RelatedItemsFieldWidget from plone.autoform import directives as form from plone.autoform.interfaces import IFormFieldProvider -from plone.app.contenttypes.interfaces import INewsItem from plone.supermodel import model -from z3c.relationfield.schema import RelationChoice, RelationList +from z3c.relationfield.schema import RelationChoice +from z3c.relationfield.schema import RelationList from zope import schema from zope.component import adapter -from zope.interface import provider, implementer +from zope.interface import implementer +from zope.interface import provider @provider(IFormFieldProvider) diff --git a/src/design/plone/contenttypes/behaviors/servizi_correlati.py b/src/design/plone/contenttypes/behaviors/servizi_correlati.py index 7579a99a..e8fb2b24 100644 --- a/src/design/plone/contenttypes/behaviors/servizi_correlati.py +++ b/src/design/plone/contenttypes/behaviors/servizi_correlati.py @@ -5,9 +5,11 @@ from plone.autoform.interfaces import IFormFieldProvider from plone.dexterity.interfaces import IDexterityContent from plone.supermodel import model -from z3c.relationfield.schema import RelationChoice, RelationList +from z3c.relationfield.schema import RelationChoice +from z3c.relationfield.schema import RelationList from zope.component import adapter -from zope.interface import provider, implementer +from zope.interface import implementer +from zope.interface import provider # TODO: merge with NEWS diff --git a/src/design/plone/contenttypes/behaviors/show_modified.py b/src/design/plone/contenttypes/behaviors/show_modified.py index e9f6b8c4..691fcde2 100644 --- a/src/design/plone/contenttypes/behaviors/show_modified.py +++ b/src/design/plone/contenttypes/behaviors/show_modified.py @@ -7,7 +7,8 @@ from plone.supermodel import model from zope import schema from zope.component import adapter -from zope.interface import provider, implementer +from zope.interface import implementer +from zope.interface import provider def showModifiedDefaultValue(context=None): diff --git a/src/design/plone/contenttypes/behaviors/strutture_correlate.py b/src/design/plone/contenttypes/behaviors/strutture_correlate.py index 32a2fdbd..c9174a9e 100644 --- a/src/design/plone/contenttypes/behaviors/strutture_correlate.py +++ b/src/design/plone/contenttypes/behaviors/strutture_correlate.py @@ -5,9 +5,11 @@ from plone.autoform.interfaces import IFormFieldProvider from plone.dexterity.interfaces import IDexterityContent from plone.supermodel import model -from z3c.relationfield.schema import RelationChoice, RelationList +from z3c.relationfield.schema import RelationChoice +from z3c.relationfield.schema import RelationList from zope.component import adapter -from zope.interface import provider, implementer +from zope.interface import implementer +from zope.interface import provider @provider(IFormFieldProvider) diff --git a/src/design/plone/contenttypes/behaviors/trasparenza.py b/src/design/plone/contenttypes/behaviors/trasparenza.py index 37b3ef13..90b93fde 100644 --- a/src/design/plone/contenttypes/behaviors/trasparenza.py +++ b/src/design/plone/contenttypes/behaviors/trasparenza.py @@ -1,17 +1,18 @@ # -*- coding: utf-8 -*- -from design.plone.contenttypes import _ from collective.volto.blocksfield.field import BlocksField +from design.plone.contenttypes import _ +from plone.app.z3cform.widget import RelatedItemsFieldWidget +from plone.autoform import directives as form from plone.autoform.interfaces import IFormFieldProvider from plone.dexterity.interfaces import IDexterityContent -from plone.supermodel import model -from zope import schema from plone.namedfile import field -from zope.component import adapter -from zope.interface import provider, implementer +from plone.supermodel import model from z3c.relationfield.schema import RelationChoice from z3c.relationfield.schema import RelationList -from plone.app.z3cform.widget import RelatedItemsFieldWidget -from plone.autoform import directives as form +from zope import schema +from zope.component import adapter +from zope.interface import implementer +from zope.interface import provider @provider(IFormFieldProvider) @@ -36,7 +37,7 @@ class ITrasparenza(model.Schema): required=False, description=_( "descrizione_procedimento_help", - default="Inserisci eventuale testo descrittivo del procedimento.", # noqa + default="Inserisci eventuale testo descrittivo del procedimento.", ), ) file_correlato = field.NamedBlobFile( @@ -51,7 +52,7 @@ class ITrasparenza(model.Schema): soggetti_esterni = BlocksField( title=_( "soggetti_eserni_label", - default="Soggetti esterni, nonché, strutture interne coinvolte nel procedimento", + default="Soggetti esterni, nonché, strutture interne coinvolte nel procedimento", # noqa ), required=False, description=_( diff --git a/src/design/plone/contenttypes/behaviors/update_note.py b/src/design/plone/contenttypes/behaviors/update_note.py index 15f9f7b6..113fe7f1 100644 --- a/src/design/plone/contenttypes/behaviors/update_note.py +++ b/src/design/plone/contenttypes/behaviors/update_note.py @@ -5,7 +5,8 @@ from plone.supermodel import model from zope import schema from zope.component import adapter -from zope.interface import provider, implementer +from zope.interface import implementer +from zope.interface import provider @provider(IFormFieldProvider) @@ -16,8 +17,8 @@ class IUpdateNote(model.Schema): title=_("update_note_label", default="Note di aggiornamento"), description=_( "help_update_note", - default="Inserisci una nota per indicare che il contenuto corrente è stato aggiornato." - "Questo testo può essere visualizzato nei blocchi elenco con determinati layout per informare " + default="Inserisci una nota per indicare che il contenuto corrente è stato aggiornato." # noqa + "Questo testo può essere visualizzato nei blocchi elenco con determinati layout per informare " # noqa "gli utenti che un determinato contenuto è stato aggiornato. " "Ad esempio se in un bando sono stati aggiunti dei documenti.", ), diff --git a/src/design/plone/contenttypes/browser/overrides/plone.app.contenttypes.browser.templates.newsitem.pt b/src/design/plone/contenttypes/browser/overrides/plone.app.contenttypes.browser.templates.newsitem.pt index aec8c90b..53d14271 100644 --- a/src/design/plone/contenttypes/browser/overrides/plone.app.contenttypes.browser.templates.newsitem.pt +++ b/src/design/plone/contenttypes/browser/overrides/plone.app.contenttypes.browser.templates.newsitem.pt @@ -1,22 +1,30 @@ - - + + - - -
- - + + +
+
+
- + diff --git a/src/design/plone/contenttypes/configure.zcml b/src/design/plone/contenttypes/configure.zcml index 0f7d2ef6..5c07e72b 100644 --- a/src/design/plone/contenttypes/configure.zcml +++ b/src/design/plone/contenttypes/configure.zcml @@ -39,9 +39,9 @@ diff --git a/src/design/plone/contenttypes/content/cartella_modulistica.py b/src/design/plone/contenttypes/content/cartella_modulistica.py index 6b52eaf9..e2314d80 100644 --- a/src/design/plone/contenttypes/content/cartella_modulistica.py +++ b/src/design/plone/contenttypes/content/cartella_modulistica.py @@ -1,9 +1,9 @@ # -*- coding: utf-8 -*- -from plone.dexterity.content import Container -from zope.interface import implementer from design.plone.contenttypes.interfaces.cartella_modulistica import ( ICartellaModulistica, ) +from plone.dexterity.content import Container +from zope.interface import implementer @implementer(ICartellaModulistica) diff --git a/src/design/plone/contenttypes/content/dataset.py b/src/design/plone/contenttypes/content/dataset.py index 371233e1..f579b970 100644 --- a/src/design/plone/contenttypes/content/dataset.py +++ b/src/design/plone/contenttypes/content/dataset.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- +from design.plone.contenttypes.interfaces.dataset import IDataset from plone.dexterity.content import Container from zope.interface import implementer -from design.plone.contenttypes.interfaces.dataset import IDataset @implementer(IDataset) diff --git a/src/design/plone/contenttypes/content/documento.py b/src/design/plone/contenttypes/content/documento.py index c246a935..92bc9078 100644 --- a/src/design/plone/contenttypes/content/documento.py +++ b/src/design/plone/contenttypes/content/documento.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- +from design.plone.contenttypes.interfaces.documento import IDocumento from plone.dexterity.content import Container from zope.interface import implementer -from design.plone.contenttypes.interfaces.documento import IDocumento @implementer(IDocumento) diff --git a/src/design/plone/contenttypes/content/documento_personale.py b/src/design/plone/contenttypes/content/documento_personale.py index d6232b95..bbe525aa 100644 --- a/src/design/plone/contenttypes/content/documento_personale.py +++ b/src/design/plone/contenttypes/content/documento_personale.py @@ -1,9 +1,7 @@ # -*- coding: utf-8 -*- +from design.plone.contenttypes.interfaces.documento_personale import IDocumentoPersonale from plone.dexterity.content import Container from zope.interface import implementer -from design.plone.contenttypes.interfaces.documento_personale import ( - IDocumentoPersonale, -) @implementer(IDocumentoPersonale) diff --git a/src/design/plone/contenttypes/content/evento.py b/src/design/plone/contenttypes/content/evento.py index 9f214097..2fe6214b 100644 --- a/src/design/plone/contenttypes/content/evento.py +++ b/src/design/plone/contenttypes/content/evento.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- from plone.dexterity.content import Container -from zope.interface import implementer from plone.event.interfaces import IEvent +from zope.interface import implementer @implementer(IEvent) diff --git a/src/design/plone/contenttypes/content/pagina_argomento.py b/src/design/plone/contenttypes/content/pagina_argomento.py index 38ccc0a0..b8a649e2 100644 --- a/src/design/plone/contenttypes/content/pagina_argomento.py +++ b/src/design/plone/contenttypes/content/pagina_argomento.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- -from design.plone.contenttypes.interfaces.pagina_argomento import ( - IPaginaArgomento, -) +from design.plone.contenttypes.interfaces.pagina_argomento import IPaginaArgomento from plone.dexterity.content import Container from zope.interface import implementer diff --git a/src/design/plone/contenttypes/content/ricevuta_pagamento.py b/src/design/plone/contenttypes/content/ricevuta_pagamento.py index d65ee8a3..28393272 100644 --- a/src/design/plone/contenttypes/content/ricevuta_pagamento.py +++ b/src/design/plone/contenttypes/content/ricevuta_pagamento.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- -from design.plone.contenttypes.interfaces.ricevuta_pagamento import ( - IRicevutaPagamento, -) +from design.plone.contenttypes.interfaces.ricevuta_pagamento import IRicevutaPagamento from plone.dexterity.content import Container from zope.interface import implementer diff --git a/src/design/plone/contenttypes/content/unita_organizzativa.py b/src/design/plone/contenttypes/content/unita_organizzativa.py index 486f0251..180dea88 100644 --- a/src/design/plone/contenttypes/content/unita_organizzativa.py +++ b/src/design/plone/contenttypes/content/unita_organizzativa.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- -from design.plone.contenttypes.interfaces.unita_organizzativa import ( - IUnitaOrganizzativa, -) +from design.plone.contenttypes.interfaces.unita_organizzativa import IUnitaOrganizzativa from plone.dexterity.content import Container from zope.interface import implementer diff --git a/src/design/plone/contenttypes/controlpanels/geolocation_defaults.py b/src/design/plone/contenttypes/controlpanels/geolocation_defaults.py index c8b8ea18..f3deb8c7 100644 --- a/src/design/plone/contenttypes/controlpanels/geolocation_defaults.py +++ b/src/design/plone/contenttypes/controlpanels/geolocation_defaults.py @@ -4,8 +4,8 @@ from plone.app.registry.browser.controlpanel import RegistryEditForm from plone.z3cform import layout from z3c.form import form -from zope.schema import TextLine from zope.interface import Interface +from zope.schema import TextLine class IGeolocationDefaults(Interface): diff --git a/src/design/plone/contenttypes/controlpanels/settings.py b/src/design/plone/contenttypes/controlpanels/settings.py index fd2c53e4..60beed41 100644 --- a/src/design/plone/contenttypes/controlpanels/settings.py +++ b/src/design/plone/contenttypes/controlpanels/settings.py @@ -4,7 +4,10 @@ from plone.app.registry.browser.controlpanel import RegistryEditForm from plone.restapi.controlpanels.interfaces import IControlpanel from zope.interface import Interface -from zope.schema import List, TextLine, SourceText, Bool +from zope.schema import Bool +from zope.schema import List +from zope.schema import SourceText +from zope.schema import TextLine import json diff --git a/src/design/plone/contenttypes/events/documento.py b/src/design/plone/contenttypes/events/documento.py index e3f1e672..e8cc971d 100644 --- a/src/design/plone/contenttypes/events/documento.py +++ b/src/design/plone/contenttypes/events/documento.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- +from design.plone.contenttypes.utils import create_default_blocks from plone import api from Products.CMFPlone.interfaces import ISelectableConstrainTypes -from design.plone.contenttypes.utils import create_default_blocks def documentoCreateHandler(documento, event): diff --git a/src/design/plone/contenttypes/events/evento.py b/src/design/plone/contenttypes/events/evento.py index b7431731..e017f89a 100644 --- a/src/design/plone/contenttypes/events/evento.py +++ b/src/design/plone/contenttypes/events/evento.py @@ -1,8 +1,8 @@ # -*- coding: utf-8 -*- from design.plone.contenttypes.interfaces import IDesignPloneContenttypesLayer from design.plone.contenttypes.utils import create_default_blocks -from Products.CMFPlone.interfaces import ISelectableConstrainTypes from plone import api +from Products.CMFPlone.interfaces import ISelectableConstrainTypes def eventoCreateHandler(evento, event): diff --git a/src/design/plone/contenttypes/events/notizie_e_comunicati_stampa.py b/src/design/plone/contenttypes/events/notizie_e_comunicati_stampa.py index 4ad08877..053928e3 100644 --- a/src/design/plone/contenttypes/events/notizie_e_comunicati_stampa.py +++ b/src/design/plone/contenttypes/events/notizie_e_comunicati_stampa.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- from design.plone.contenttypes.utils import create_default_blocks -from Products.CMFPlone.interfaces import ISelectableConstrainTypes from plone import api +from Products.CMFPlone.interfaces import ISelectableConstrainTypes def notiziaCreateHandler(notizia, event): diff --git a/src/design/plone/contenttypes/events/unita_organizzativa.py b/src/design/plone/contenttypes/events/unita_organizzativa.py index 4edd5603..ec11a746 100644 --- a/src/design/plone/contenttypes/events/unita_organizzativa.py +++ b/src/design/plone/contenttypes/events/unita_organizzativa.py @@ -5,6 +5,7 @@ import logging + logger = logging.getLogger(__name__) diff --git a/src/design/plone/contenttypes/indexers/common.py b/src/design/plone/contenttypes/indexers/common.py index ead0e16d..1e48bbbe 100644 --- a/src/design/plone/contenttypes/indexers/common.py +++ b/src/design/plone/contenttypes/indexers/common.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from plone.indexer.decorator import indexer from plone.dexterity.interfaces import IDexterityContent +from plone.indexer.decorator import indexer @indexer(IDexterityContent) diff --git a/src/design/plone/contenttypes/indexers/events.py b/src/design/plone/contenttypes/indexers/events.py index 16589e2d..1c8a8cd5 100644 --- a/src/design/plone/contenttypes/indexers/events.py +++ b/src/design/plone/contenttypes/indexers/events.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from plone.indexer.decorator import indexer from plone.app.contenttypes.interfaces import IEvent +from plone.indexer.decorator import indexer @indexer(IEvent) diff --git a/src/design/plone/contenttypes/indexers/news.py b/src/design/plone/contenttypes/indexers/news.py index c093c935..d3d8a750 100644 --- a/src/design/plone/contenttypes/indexers/news.py +++ b/src/design/plone/contenttypes/indexers/news.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from plone.indexer.decorator import indexer from plone.app.contenttypes.interfaces import INewsItem +from plone.indexer.decorator import indexer @indexer(INewsItem) diff --git a/src/design/plone/contenttypes/indexers/servizio.py b/src/design/plone/contenttypes/indexers/servizio.py index caf5690d..d7cce4e5 100644 --- a/src/design/plone/contenttypes/indexers/servizio.py +++ b/src/design/plone/contenttypes/indexers/servizio.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from plone.indexer.decorator import indexer from design.plone.contenttypes.interfaces.servizio import IServizio +from plone.indexer.decorator import indexer @indexer(IServizio) diff --git a/src/design/plone/contenttypes/indexers/uo.py b/src/design/plone/contenttypes/indexers/uo.py index 8cca5e3b..842f8f08 100644 --- a/src/design/plone/contenttypes/indexers/uo.py +++ b/src/design/plone/contenttypes/indexers/uo.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from plone.indexer.decorator import indexer from design.plone.contenttypes.interfaces.unita_organizzativa import IUnitaOrganizzativa +from plone.indexer.decorator import indexer @indexer(IUnitaOrganizzativa) diff --git a/src/design/plone/contenttypes/interfaces/bando.py b/src/design/plone/contenttypes/interfaces/bando.py index 94e4c7bd..8100d2b9 100644 --- a/src/design/plone/contenttypes/interfaces/bando.py +++ b/src/design/plone/contenttypes/interfaces/bando.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- -from plone.app.dexterity import textindexer from collective.volto.blocksfield.field import BlocksField from design.plone.contenttypes.interfaces import IDesignPloneContentType +from plone.app.dexterity import textindexer from plone.app.event.base import default_timezone from plone.app.z3cform.widget import AjaxSelectFieldWidget from plone.app.z3cform.widget import DatetimeFieldWidget @@ -11,7 +11,8 @@ from plone.supermodel import model from redturtle.bandi import bandiMessageFactory as _ from redturtle.bandi import bandiMessageFactory as _rtbando -from redturtle.bandi.interfaces.bandoSchema import IBandoSchema, getDefaultEnte +from redturtle.bandi.interfaces.bandoSchema import getDefaultEnte +from redturtle.bandi.interfaces.bandoSchema import IBandoSchema from z3c.form.browser.checkbox import CheckBoxFieldWidget from z3c.form.browser.radio import RadioFieldWidget from z3c.relationfield.schema import RelationChoice diff --git a/src/design/plone/contenttypes/interfaces/dataset.py b/src/design/plone/contenttypes/interfaces/dataset.py index 4fab5b91..a7074f7b 100644 --- a/src/design/plone/contenttypes/interfaces/dataset.py +++ b/src/design/plone/contenttypes/interfaces/dataset.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from design.plone.contenttypes import _ from collective.volto.blocksfield.field import BlocksField +from design.plone.contenttypes import _ from plone.namedfile import field from plone.supermodel import model from zope import schema diff --git a/src/design/plone/contenttypes/interfaces/documento_personale.py b/src/design/plone/contenttypes/interfaces/documento_personale.py index 39091473..00efb253 100644 --- a/src/design/plone/contenttypes/interfaces/documento_personale.py +++ b/src/design/plone/contenttypes/interfaces/documento_personale.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from design.plone.contenttypes import _ from collective.volto.blocksfield.field import BlocksField +from design.plone.contenttypes import _ from plone.namedfile import field from plone.supermodel import model from z3c.relationfield.schema import RelationChoice diff --git a/src/design/plone/contenttypes/interfaces/pagina_argomento.py b/src/design/plone/contenttypes/interfaces/pagina_argomento.py index 3544f800..f2621ea7 100644 --- a/src/design/plone/contenttypes/interfaces/pagina_argomento.py +++ b/src/design/plone/contenttypes/interfaces/pagina_argomento.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- -from plone.app.dexterity import textindexer from design.plone.contenttypes import _ from design.plone.contenttypes.interfaces import IDesignPloneContentType +from plone.app.dexterity import textindexer from plone.app.textfield import RichText from plone.app.z3cform.widget import RelatedItemsFieldWidget from plone.autoform import directives as form diff --git a/src/design/plone/contenttypes/interfaces/persona.py b/src/design/plone/contenttypes/interfaces/persona.py index a87aa992..b6b225af 100644 --- a/src/design/plone/contenttypes/interfaces/persona.py +++ b/src/design/plone/contenttypes/interfaces/persona.py @@ -1,8 +1,8 @@ # -*- coding: utf-8 -*- -from plone.app.dexterity import textindexer from collective.volto.blocksfield.field import BlocksField from design.plone.contenttypes import _ from design.plone.contenttypes.interfaces import IDesignPloneContentType +from plone.app.dexterity import textindexer from plone.app.z3cform.widget import RelatedItemsFieldWidget from plone.autoform import directives as form from plone.namedfile import field @@ -100,7 +100,7 @@ class IPersona(model.Schema, IDesignPloneContentType): "curriculum_vitae_help", default="Allega un file contenente il curriculum vitae della persona. " "Se ha più file da allegare, utilizza questo campo per quello principale " - 'e gli altri mettili dentro alla cartella "Curriculum vitae" che troverai dentro alla Persona.', + 'e gli altri mettili dentro alla cartella "Curriculum vitae" che troverai dentro alla Persona.', # noqa ), ) diff --git a/src/design/plone/contenttypes/interfaces/pratica.py b/src/design/plone/contenttypes/interfaces/pratica.py index 9a872dbf..1d78b6ad 100644 --- a/src/design/plone/contenttypes/interfaces/pratica.py +++ b/src/design/plone/contenttypes/interfaces/pratica.py @@ -1,8 +1,8 @@ # -*- coding: utf-8 -*- -from plone.supermodel import model from collective.volto.blocksfield.field import BlocksField -from zope import schema from design.plone.contenttypes import _ +from plone.supermodel import model +from zope import schema class IPratica(model.Schema): diff --git a/src/design/plone/contenttypes/interfaces/servizio.py b/src/design/plone/contenttypes/interfaces/servizio.py index 0b97721b..81fd2882 100644 --- a/src/design/plone/contenttypes/interfaces/servizio.py +++ b/src/design/plone/contenttypes/interfaces/servizio.py @@ -1,8 +1,8 @@ # -*- coding: utf-8 -*- -from plone.app.dexterity import textindexer from collective.volto.blocksfield.field import BlocksField from design.plone.contenttypes import _ from design.plone.contenttypes.interfaces import IDesignPloneContentType +from plone.app.dexterity import textindexer from plone.app.z3cform.widget import RelatedItemsFieldWidget from plone.autoform import directives as form from plone.supermodel import model diff --git a/src/design/plone/contenttypes/interfaces/unita_organizzativa.py b/src/design/plone/contenttypes/interfaces/unita_organizzativa.py index 81277aeb..3deb043f 100644 --- a/src/design/plone/contenttypes/interfaces/unita_organizzativa.py +++ b/src/design/plone/contenttypes/interfaces/unita_organizzativa.py @@ -1,9 +1,8 @@ # -*- coding: utf-8 -*- -from plone.app.dexterity import textindexer -from collective.taxonomy import generated from collective.volto.blocksfield.field import BlocksField from design.plone.contenttypes import _ from design.plone.contenttypes.interfaces import IDesignPloneContentType +from plone.app.dexterity import textindexer from plone.app.z3cform.widget import RelatedItemsFieldWidget from plone.autoform import directives as form from plone.supermodel import model diff --git a/src/design/plone/contenttypes/locales/it/LC_MESSAGES/collective.geolocationbehavior.po b/src/design/plone/contenttypes/locales/it/LC_MESSAGES/collective.geolocationbehavior.po index 8f248e32..59f296b8 100644 --- a/src/design/plone/contenttypes/locales/it/LC_MESSAGES/collective.geolocationbehavior.po +++ b/src/design/plone/contenttypes/locales/it/LC_MESSAGES/collective.geolocationbehavior.po @@ -28,4 +28,3 @@ msgstr "Coordinate" msgid "help_geolocation" msgstr "Compilare i campi 'Via', 'CAP', 'Città' e 'Nazione' dopo di ché premere 'Cerca nella mappa' per impostare la posizione. Altrimenti è possibile cliccare sul marker e spostarlo sulla mappa" - diff --git a/src/design/plone/contenttypes/locales/it/LC_MESSAGES/plone.po b/src/design/plone/contenttypes/locales/it/LC_MESSAGES/plone.po index d91eb1d1..045d56eb 100644 --- a/src/design/plone/contenttypes/locales/it/LC_MESSAGES/plone.po +++ b/src/design/plone/contenttypes/locales/it/LC_MESSAGES/plone.po @@ -18,4 +18,3 @@ msgstr "" #: CMFPlone/interfaces/controlpanel.py:1432 msgid "To identify things like Twitter Cards. Do not include the \"@\" prefix character." msgstr "Per identificare cose come le Twitter Card. Non includere il carattere \"@\" come prefisso." - diff --git a/src/design/plone/contenttypes/patches/__init__.py b/src/design/plone/contenttypes/patches/__init__.py index 43f89907..ba9acea3 100644 --- a/src/design/plone/contenttypes/patches/__init__.py +++ b/src/design/plone/contenttypes/patches/__init__.py @@ -1,10 +1,12 @@ # -*- coding: utf-8 -*- from design.plone.contenttypes.patches.baseserializer import ( - patch_base_serializer, patch_base_folder_serializer, ) +from design.plone.contenttypes.patches.baseserializer import patch_base_serializer + import logging + logger = logging.getLogger("design.plone.contenttypes.patches") logger.info("Patching plone.restapi.serializer.dxcontent.SerializeToJson._call__") diff --git a/src/design/plone/contenttypes/patches/baseserializer.py b/src/design/plone/contenttypes/patches/baseserializer.py index 1bfc2862..dba20c06 100644 --- a/src/design/plone/contenttypes/patches/baseserializer.py +++ b/src/design/plone/contenttypes/patches/baseserializer.py @@ -11,20 +11,17 @@ """ from collective.taxonomy.vocabulary import Vocabulary -from collective.taxonomy.utility import Taxonomy -from plone.restapi.serializer.dxcontent import ( - SerializeToJson, - SerializeFolderToJson, -) from plone import api from plone.restapi.batching import HypermediaBatch from plone.restapi.deserializer import boolean_value from plone.restapi.interfaces import ISerializeToJson from plone.restapi.interfaces import ISerializeToJsonSummary +from plone.restapi.serializer.dxcontent import SerializeFolderToJson +from plone.restapi.serializer.dxcontent import SerializeToJson from Products.CMFCore.utils import getToolByName from zope.component import getMultiAdapter from zope.i18n import translate -from design.plone.contenttypes import _ + original_serialize_to_json__call__ = SerializeToJson.__call__ diff --git a/src/design/plone/contenttypes/patches/configure.zcml b/src/design/plone/contenttypes/patches/configure.zcml index 6f70898b..2460d6bd 100644 --- a/src/design/plone/contenttypes/patches/configure.zcml +++ b/src/design/plone/contenttypes/patches/configure.zcml @@ -1,14 +1,16 @@ - + - + - + diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/business_events.cfg b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/business_events.cfg index bd970dde..35123908 100644 --- a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/business_events.cfg +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/business_events.cfg @@ -5,4 +5,3 @@ description = Il sistema di gestione contenuti basato su React default_language = it field_title = Eventi della vita delle imprese taxonomy_fieldset = default - diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/business_events.xml b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/business_events.xml index f44fa08e..228b4b55 100644 --- a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/business_events.xml +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/business_events.xml @@ -1,5 +1,11 @@ - - + + Eventi della vita delle imprese @@ -91,8 +97,8 @@ partecipazione_ad_appalti_pubblici_nazionali_e_trasfrontalieri - + Partecipazione ad appalti pubblici nazionali e trasfrontalieri - \ No newline at end of file + diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/person_life_events.cfg b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/person_life_events.cfg index 8ea3a44b..f72dca69 100644 --- a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/person_life_events.cfg +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/person_life_events.cfg @@ -5,4 +5,3 @@ description = Il sistema di gestione contenuti basato su React default_language = it field_title = Eventi della vita delle persone taxonomy_fieldset = default - diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/person_life_events.xml b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/person_life_events.xml index 09a10281..40e60d40 100644 --- a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/person_life_events.xml +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/person_life_events.xml @@ -1,5 +1,11 @@ - - + + Eventi della vita delle persone @@ -109,8 +115,8 @@ possesso_cura_smarrimento_animale_da_compagnia - + Possesso, cura, smarrimento animale da compagnia - \ No newline at end of file + diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/temi_dataset.cfg b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/temi_dataset.cfg index 78934c7e..cf7724f1 100644 --- a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/temi_dataset.cfg +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/temi_dataset.cfg @@ -7,4 +7,3 @@ field_title = Temi di un dataset field_description = Scegli i temi di un dataset taxonomy_fieldset = default is_required = true - diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/temi_dataset.xml b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/temi_dataset.xml index def9bc3b..7cb23b84 100644 --- a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/temi_dataset.xml +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/temi_dataset.xml @@ -1,5 +1,11 @@ - - + + Temi di un dataset @@ -79,8 +85,8 @@ trasporti - + Trasporti - \ No newline at end of file + diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_documenti_albopretorio.cfg b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_documenti_albopretorio.cfg index 7e3e47f2..38d76887 100644 --- a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_documenti_albopretorio.cfg +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_documenti_albopretorio.cfg @@ -6,4 +6,3 @@ default_language = it field_title = Tipologia di Documento albo pretorio taxonomy_fieldset = default is_single_select = true - diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_documenti_albopretorio.xml b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_documenti_albopretorio.xml index 2e426342..944a89eb 100644 --- a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_documenti_albopretorio.xml +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_documenti_albopretorio.xml @@ -1,5 +1,11 @@ - - + + Tipologia di Documento albo pretorio @@ -217,22 +223,22 @@ pubblicazione_esterna - + Pubblicazione esterna atto_terzi - + Atto di terzi atto_terzi_2 - + Atto di terzi - \ No newline at end of file + diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_documento.cfg b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_documento.cfg index 985aa66b..6a337225 100644 --- a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_documento.cfg +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_documento.cfg @@ -7,4 +7,3 @@ field_title = Tipologia del documento field_description = Seleziona la tipologia del documento taxonomy_fieldset = default is_required = true - diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_documento.xml b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_documento.xml index 3205e4ea..990e806e 100644 --- a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_documento.xml +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_documento.xml @@ -1,5 +1,11 @@ - - + + Tipologia del documento @@ -49,8 +55,8 @@ istanza - + Istanza - \ No newline at end of file + diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_evento.cfg b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_evento.cfg index 0f4893ee..7f9be887 100644 --- a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_evento.cfg +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_evento.cfg @@ -7,4 +7,3 @@ field_title = Tipo di evento taxonomy_fieldset = default is_single_select = true is_required = true - diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_evento.xml b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_evento.xml index 1387cbb8..8935654c 100644 --- a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_evento.xml +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_evento.xml @@ -1,5 +1,11 @@ - - + + Tipo di evento @@ -385,13 +391,13 @@ eventi_sportivi - + Eventi sportivi manifestazione_sportiva - + Manifestazione sportiva @@ -427,10 +433,10 @@ raduno_sportivo - + Raduno sportivo - \ No newline at end of file + diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_frequenza_aggiornamento.cfg b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_frequenza_aggiornamento.cfg index c5a194d2..f1bf4e7c 100644 --- a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_frequenza_aggiornamento.cfg +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_frequenza_aggiornamento.cfg @@ -7,4 +7,3 @@ field_title = Tipologia di Frequenza di aggiornamento taxonomy_fieldset = default is_single_select = true is_required = true - diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_frequenza_aggiornamento.xml b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_frequenza_aggiornamento.xml index fa33ad36..2310ccf0 100644 --- a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_frequenza_aggiornamento.xml +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_frequenza_aggiornamento.xml @@ -1,5 +1,11 @@ - - + + Tipologia di Frequenza di aggiornamento @@ -175,8 +181,8 @@ trimestrale - + Trimestrale - \ No newline at end of file + diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_incarico.cfg b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_incarico.cfg index 565f2f96..3c232d7d 100644 --- a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_incarico.cfg +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_incarico.cfg @@ -7,4 +7,3 @@ field_title = Tipo di incarico taxonomy_fieldset = default is_single_select = true is_required = true - diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_incarico.xml b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_incarico.xml index 8a08402f..6d03dfe9 100644 --- a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_incarico.xml +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_incarico.xml @@ -1,5 +1,11 @@ - - + + Tipo di incarico @@ -19,8 +25,8 @@ altro - + Altro - \ No newline at end of file + diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_licenze.cfg b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_licenze.cfg index 9950e92d..343c0bc3 100644 --- a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_licenze.cfg +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_licenze.cfg @@ -7,4 +7,3 @@ field_title = Licenze taxonomy_fieldset = default is_single_select = true is_required = true - diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_licenze.xml b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_licenze.xml index ca265e58..dd8895b9 100644 --- a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_licenze.xml +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_licenze.xml @@ -1,5 +1,11 @@ - - + + Licenze @@ -48,7 +54,7 @@ non_opere_derivate - + Non opere derivate @@ -56,8 +62,8 @@ licenza_sconosciuta - + Licenza sconosciuta - \ No newline at end of file + diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_luogo.cfg b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_luogo.cfg index 17a79526..825096ec 100644 --- a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_luogo.cfg +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_luogo.cfg @@ -5,4 +5,3 @@ description = Il sistema di gestione contenuti basato su React default_language = it field_title = Tipo di luogo taxonomy_fieldset = default - diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_luogo.xml b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_luogo.xml index 4a79b874..1f15ed5e 100644 --- a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_luogo.xml +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_luogo.xml @@ -1,5 +1,11 @@ - - + + Tipo di luogo @@ -511,7 +517,7 @@ struttura_ricettiva - + Struttura ricettiva @@ -535,9 +541,9 @@ rifugio_per_animali - + Rifugio per animali - \ No newline at end of file + diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_notizia.cfg b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_notizia.cfg index b67329db..a94b8435 100644 --- a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_notizia.cfg +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_notizia.cfg @@ -8,4 +8,3 @@ field_description = Seleziona la tipologia della notizia taxonomy_fieldset = default is_single_select = true is_required = true - diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_notizia.xml b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_notizia.xml index ace0d9a6..5af6f429 100644 --- a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_notizia.xml +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_notizia.xml @@ -1,5 +1,11 @@ - - + + Tipologia notizia @@ -19,8 +25,8 @@ avviso - + Avviso - \ No newline at end of file + diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_organizzazione.cfg b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_organizzazione.cfg index 06d0ea2c..c764483c 100644 --- a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_organizzazione.cfg +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_organizzazione.cfg @@ -7,4 +7,3 @@ field_title = Tipologia organizzazione field_description = Selezione la tipologia dell'unità organizzativa taxonomy_fieldset = struttura is_required = true - diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_organizzazione.xml b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_organizzazione.xml index 3936c3bd..00a12a31 100644 --- a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_organizzazione.xml +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_organizzazione.xml @@ -1,5 +1,11 @@ - - + + Tipologia organizzazione @@ -49,7 +55,7 @@ altra_struttura - + Altra struttura @@ -91,9 +97,9 @@ scuola - + Scuola - \ No newline at end of file + diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_pdc.cfg b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_pdc.cfg index 3d0abb96..c75a99eb 100644 --- a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_pdc.cfg +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_pdc.cfg @@ -7,4 +7,3 @@ field_title = Tipo di punto di contatto taxonomy_fieldset = default is_single_select = true is_required = true - diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_pdc.xml b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_pdc.xml index f2c8ffb6..3eac84c2 100644 --- a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_pdc.xml +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_pdc.xml @@ -1,5 +1,11 @@ - - + + Tipo di punto di contatto @@ -31,7 +37,7 @@ account - + Accout @@ -61,9 +67,9 @@ twitter - + Twitter - \ No newline at end of file + diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_stati_pratica.cfg b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_stati_pratica.cfg index c0743186..0961755d 100644 --- a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_stati_pratica.cfg +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_stati_pratica.cfg @@ -7,4 +7,3 @@ field_title = Stati di una Pratica taxonomy_fieldset = default is_single_select = true is_required = true - diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_stati_pratica.xml b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_stati_pratica.xml index 9e6aa514..f6d53dc0 100644 --- a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_stati_pratica.xml +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_stati_pratica.xml @@ -1,5 +1,11 @@ - - + + Stati di una Pratica @@ -43,7 +49,7 @@ processo_concluso - + Processo concluso @@ -55,9 +61,9 @@ esito_negativo - + Esito negativo - \ No newline at end of file + diff --git a/src/design/plone/contenttypes/profiles/default/browserlayer.xml b/src/design/plone/contenttypes/profiles/default/browserlayer.xml index 4e12aec3..a57ffa79 100644 --- a/src/design/plone/contenttypes/profiles/default/browserlayer.xml +++ b/src/design/plone/contenttypes/profiles/default/browserlayer.xml @@ -1,7 +1,6 @@ - + - + diff --git a/src/design/plone/contenttypes/profiles/default/catalog.xml b/src/design/plone/contenttypes/profiles/default/catalog.xml index 5fe69663..adf4fd63 100644 --- a/src/design/plone/contenttypes/profiles/default/catalog.xml +++ b/src/design/plone/contenttypes/profiles/default/catalog.xml @@ -1,68 +1,108 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + - - - - - + + + + + diff --git a/src/design/plone/contenttypes/profiles/default/controlpanel.xml b/src/design/plone/contenttypes/profiles/default/controlpanel.xml index 7702d9c0..8453dfa4 100644 --- a/src/design/plone/contenttypes/profiles/default/controlpanel.xml +++ b/src/design/plone/contenttypes/profiles/default/controlpanel.xml @@ -1,33 +1,32 @@ - - + + - - Manage portal - + + Manage portal + - - Manage portal - + + Manage portal + - diff --git a/src/design/plone/contenttypes/profiles/default/diff_tool.xml b/src/design/plone/contenttypes/profiles/default/diff_tool.xml index 535024f8..b487ad6e 100644 --- a/src/design/plone/contenttypes/profiles/default/diff_tool.xml +++ b/src/design/plone/contenttypes/profiles/default/diff_tool.xml @@ -1,29 +1,45 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/design/plone/contenttypes/profiles/default/metadata.xml b/src/design/plone/contenttypes/profiles/default/metadata.xml index 57c2767b..0fa299ce 100644 --- a/src/design/plone/contenttypes/profiles/default/metadata.xml +++ b/src/design/plone/contenttypes/profiles/default/metadata.xml @@ -1,4 +1,4 @@ - + 6010 diff --git a/src/design/plone/contenttypes/profiles/default/registry/criteria.xml b/src/design/plone/contenttypes/profiles/default/registry/criteria.xml index 48716fc0..5e2f4756 100644 --- a/src/design/plone/contenttypes/profiles/default/registry/criteria.xml +++ b/src/design/plone/contenttypes/profiles/default/registry/criteria.xml @@ -1,287 +1,423 @@ - + + i18n:domain="plone" +> - Tipologia notizia - Tipologia della notizia - True - False - - plone.app.querystring.operation.selection.any - plone.app.querystring.operation.selection.all - - collective.taxonomy.tipologia_notizia - Metadata - + prefix="plone.app.querystring.field.tipologia_notizia" + > + Tipologia notizia + Tipologia della notizia + True + False + + plone.app.querystring.operation.selection.any + plone.app.querystring.operation.selection.all + + collective.taxonomy.tipologia_notizia + Metadata + - Argomenti correlati - Argomenti correlati - True - False - - plone.app.querystring.operation.selection.any - plone.app.querystring.operation.selection.all - - design.plone.vocabularies.argomenti - Metadata - + prefix="plone.app.querystring.field.tassonomia_argomenti" + > + Argomenti correlati + Argomenti correlati + True + False + + plone.app.querystring.operation.selection.any + plone.app.querystring.operation.selection.all + + design.plone.vocabularies.argomenti + Metadata + - Tipologia documento - - True - False - - plone.app.querystring.operation.selection.any - plone.app.querystring.operation.selection.all - - Metadata - collective.taxonomy.tipologia_documento - True + prefix="plone.app.querystring.field.tipologia_documento" + > + Tipologia documento + + True + False + + plone.app.querystring.operation.selection.any + plone.app.querystring.operation.selection.all + + Metadata + collective.taxonomy.tipologia_documento + True - Luogo evento - Luogo correlato legato all'evento - True - False - - plone.app.querystring.operation.selection.any - plone.app.querystring.operation.selection.all - - design.plone.vocabularies.event_location - Metadata - + prefix="plone.app.querystring.field.event_location" + > + Luogo evento + Luogo correlato legato all'evento + True + False + + plone.app.querystring.operation.selection.any + plone.app.querystring.operation.selection.all + + design.plone.vocabularies.event_location + Metadata + - - Ufficio responsabile - Ufficio responsabile documento personale - True - False - - plone.app.querystring.operation.selection.any - plone.app.querystring.operation.selection.all - - design.plone.vocabularies.ufficio_responsabile - Metadata - + + Ufficio responsabile + Ufficio responsabile documento personale + True + False + + plone.app.querystring.operation.selection.any + plone.app.querystring.operation.selection.all + + design.plone.vocabularies.ufficio_responsabile + Metadata + - - Ente bando - Ente bando - True - False - - plone.app.querystring.operation.selection.any - plone.app.querystring.operation.selection.all - - redturtle.bandi.enti.vocabulary - Bando - + + Ente bando + Ente bando + True + False + + plone.app.querystring.operation.selection.any + plone.app.querystring.operation.selection.all + + redturtle.bandi.enti.vocabulary + Bando + - - Data conclusione incarico - Data conclusione incarico - True - False - - plone.app.querystring.operation.date.lessThan - plone.app.querystring.operation.date.largerThan - plone.app.querystring.operation.date.between - plone.app.querystring.operation.date.lessThanRelativeDate - plone.app.querystring.operation.date.largerThanRelativeDate - plone.app.querystring.operation.date.today - plone.app.querystring.operation.date.beforeToday - plone.app.querystring.operation.date.afterToday - plone.app.querystring.operation.date.beforeRelativeDate - plone.app.querystring.operation.date.afterRelativeDate - - Dates - + + Data conclusione incarico + Data conclusione incarico + True + False + + plone.app.querystring.operation.date.lessThan + plone.app.querystring.operation.date.largerThan + plone.app.querystring.operation.date.between + plone.app.querystring.operation.date.lessThanRelativeDate + plone.app.querystring.operation.date.largerThanRelativeDate + plone.app.querystring.operation.date.today + plone.app.querystring.operation.date.beforeToday + plone.app.querystring.operation.date.afterToday + plone.app.querystring.operation.date.beforeRelativeDate + plone.app.querystring.operation.date.afterRelativeDate + + Dates + - Tipologia organizzazione - - True - False - - plone.app.querystring.operation.selection.any - plone.app.querystring.operation.selection.all - - collective.taxonomy.tipologia_organizzazione - Metadata + prefix="plone.app.querystring.field.tipologia_organizzazione" + > + Tipologia organizzazione + + True + False + + plone.app.querystring.operation.selection.any + plone.app.querystring.operation.selection.all + + collective.taxonomy.tipologia_organizzazione + Metadata - Eventi della vita delle imprese - - True - False - - plone.app.querystring.operation.selection.any - plone.app.querystring.operation.selection.all - - collective.taxonomy.business_events - Metadata + prefix="plone.app.querystring.field.business_events" + > + Eventi della vita delle imprese + + True + False + + plone.app.querystring.operation.selection.any + plone.app.querystring.operation.selection.all + + collective.taxonomy.business_events + Metadata - Eventi della vita delle persone - - True - False - - plone.app.querystring.operation.selection.any - plone.app.querystring.operation.selection.all - - collective.taxonomy.person_life_events - Metadata + prefix="plone.app.querystring.field.person_life_events" + > + Eventi della vita delle persone + + True + False + + plone.app.querystring.operation.selection.any + plone.app.querystring.operation.selection.all + + collective.taxonomy.person_life_events + Metadata - Temi del dataset - - True - False - - plone.app.querystring.operation.selection.any - plone.app.querystring.operation.selection.all - - collective.taxonomy.temi_dataset - Metadata + prefix="plone.app.querystring.field.temi_dataset" + > + Temi del dataset + + True + False + + plone.app.querystring.operation.selection.any + plone.app.querystring.operation.selection.all + + collective.taxonomy.temi_dataset + Metadata - Tipologia di incarico - - True - False - - plone.app.querystring.operation.selection.any - plone.app.querystring.operation.selection.all - - collective.taxonomy.tipologia_incarico - Metadata + prefix="plone.app.querystring.field.tipologia_incarico" + > + Tipologia di incarico + + True + False + + plone.app.querystring.operation.selection.any + plone.app.querystring.operation.selection.all + + collective.taxonomy.tipologia_incarico + Metadata - - Tipologia di luogo - - True - False - - plone.app.querystring.operation.selection.any - plone.app.querystring.operation.selection.all - - collective.taxonomy.tipologia_luogo - Metadata + + Tipologia di luogo + + True + False + + plone.app.querystring.operation.selection.any + plone.app.querystring.operation.selection.all + + collective.taxonomy.tipologia_luogo + Metadata - Tipologia di evento - - True - False - - plone.app.querystring.operation.selection.any - plone.app.querystring.operation.selection.all - - collective.taxonomy.tipologia_evento - Metadata + prefix="plone.app.querystring.field.tipologia_evento" + > + Tipologia di evento + + True + False + + plone.app.querystring.operation.selection.any + plone.app.querystring.operation.selection.all + + collective.taxonomy.tipologia_evento + Metadata - Tipologia di punto di contatto - - True - False - - plone.app.querystring.operation.selection.any - plone.app.querystring.operation.selection.all - - collective.taxonomy.tipologia_pdc - Metadata + prefix="plone.app.querystring.field.tipologia_pdc" + > + Tipologia di punto di contatto + + True + False + + plone.app.querystring.operation.selection.any + plone.app.querystring.operation.selection.all + + collective.taxonomy.tipologia_pdc + Metadata - Tipologia di documento albo pretorio - - True - False - - plone.app.querystring.operation.selection.any - plone.app.querystring.operation.selection.all - - collective.taxonomy.tipologia_documenti_albopretorio - Metadata + prefix="plone.app.querystring.field.tipologia_documenti_albopretorio" + > + Tipologia di documento albo pretorio + + True + False + + plone.app.querystring.operation.selection.any + plone.app.querystring.operation.selection.all + + collective.taxonomy.tipologia_documenti_albopretorio + Metadata - Tipologia di frequenza di aggiornamento - - True - False - - plone.app.querystring.operation.selection.any - plone.app.querystring.operation.selection.all - - collective.taxonomy.tipologia_frequenza_aggiornamento - Metadata + prefix="plone.app.querystring.field.tipologia_frequenza_aggiornamento" + > + Tipologia di frequenza di aggiornamento + + True + False + + plone.app.querystring.operation.selection.any + plone.app.querystring.operation.selection.all + + collective.taxonomy.tipologia_frequenza_aggiornamento + Metadata - Tipologia di stati di una pratica - - True - False - - plone.app.querystring.operation.selection.any - plone.app.querystring.operation.selection.all - - collective.taxonomy.tipologia_stati_pratica - Metadata + prefix="plone.app.querystring.field.tipologia_stati_pratica" + > + Tipologia di stati di una pratica + + True + False + + plone.app.querystring.operation.selection.any + plone.app.querystring.operation.selection.all + + collective.taxonomy.tipologia_stati_pratica + Metadata - - Tipologia di licenze - - True - False - - plone.app.querystring.operation.selection.any - plone.app.querystring.operation.selection.all - - collective.taxonomy.tipologia_licenze - Metadata + + Tipologia di licenze + + True + False + + plone.app.querystring.operation.selection.any + plone.app.querystring.operation.selection.all + + collective.taxonomy.tipologia_licenze + Metadata - + prefix="plone.app.querystring.field.argomenti" + remove="True" + > + - + prefix="plone.app.querystring.field.argomenti_correlati" + remove="True" + > + diff --git a/src/design/plone/contenttypes/profiles/default/registry/settings.xml b/src/design/plone/contenttypes/profiles/default/registry/settings.xml index 30c7f7ad..4c03aabd 100644 --- a/src/design/plone/contenttypes/profiles/default/registry/settings.xml +++ b/src/design/plone/contenttypes/profiles/default/registry/settings.xml @@ -1,11 +1,15 @@ - + + i18n:domain="plone" +> - + - + gallery 250:65536 diff --git a/src/design/plone/contenttypes/profiles/default/repositorytool.xml b/src/design/plone/contenttypes/profiles/default/repositorytool.xml index d3457e3e..7c5fef6c 100644 --- a/src/design/plone/contenttypes/profiles/default/repositorytool.xml +++ b/src/design/plone/contenttypes/profiles/default/repositorytool.xml @@ -1,37 +1,37 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/design/plone/contenttypes/profiles/default/rolemap.xml b/src/design/plone/contenttypes/profiles/default/rolemap.xml index 6629737a..f11c831f 100644 --- a/src/design/plone/contenttypes/profiles/default/rolemap.xml +++ b/src/design/plone/contenttypes/profiles/default/rolemap.xml @@ -1,121 +1,151 @@ - + - + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + diff --git a/src/design/plone/contenttypes/profiles/default/types.xml b/src/design/plone/contenttypes/profiles/default/types.xml index 6bfe5e5c..8f0f1622 100644 --- a/src/design/plone/contenttypes/profiles/default/types.xml +++ b/src/design/plone/contenttypes/profiles/default/types.xml @@ -1,5 +1,7 @@ - - + + Controls the available contenttypes in your portal diff --git a/src/design/plone/contenttypes/profiles/default/types/Bando.xml b/src/design/plone/contenttypes/profiles/default/types/Bando.xml index 9971c971..c6e5a8f1 100644 --- a/src/design/plone/contenttypes/profiles/default/types/Bando.xml +++ b/src/design/plone/contenttypes/profiles/default/types/Bando.xml @@ -1,23 +1,34 @@ - - - Bando + + + Bando - - - - - - - - - - + + + + + + + + + + - - design.plone.contenttypes.interfaces.bando.IBandoAgidSchema - view - - - + + design.plone.contenttypes.interfaces.bando.IBandoAgidSchema + view + + + diff --git a/src/design/plone/contenttypes/profiles/default/types/Bando_Folder_Deepening.xml b/src/design/plone/contenttypes/profiles/default/types/Bando_Folder_Deepening.xml index f38b334e..4275a37f 100644 --- a/src/design/plone/contenttypes/profiles/default/types/Bando_Folder_Deepening.xml +++ b/src/design/plone/contenttypes/profiles/default/types/Bando_Folder_Deepening.xml @@ -1,11 +1,16 @@ - - - Cartella Approfondimento - True - - - - - + + + Cartella Approfondimento + True + + + + + diff --git a/src/design/plone/contenttypes/profiles/default/types/CartellaModulistica.xml b/src/design/plone/contenttypes/profiles/default/types/CartellaModulistica.xml index 501b99ba..f09d0367 100644 --- a/src/design/plone/contenttypes/profiles/default/types/CartellaModulistica.xml +++ b/src/design/plone/contenttypes/profiles/default/types/CartellaModulistica.xml @@ -1,21 +1,22 @@ - + + meta_type="Dexterity FTI" + name="CartellaModulistica" + i18n:domain="design.plone.contenttypes" +> - Cartella Modulistica - + Cartella Modulistica + False CartellaModulistica - - + + True @@ -30,30 +31,32 @@ design.plone.contenttypes.AddCartellaModulistica design.plone.contenttypes.content.cartella_modulistica.CartellaModulistica - - + + design.plone.contenttypes.interfaces.cartella_modulistica.ICartellaModulistica - + - - - - - - - - + + + + + + + + - - - + + + @@ -62,48 +65,44 @@ False modulistica_view - - + + - - - - - - + + - - + + diff --git a/src/design/plone/contenttypes/profiles/default/types/Dataset.xml b/src/design/plone/contenttypes/profiles/default/types/Dataset.xml index b1631523..861c195a 100644 --- a/src/design/plone/contenttypes/profiles/default/types/Dataset.xml +++ b/src/design/plone/contenttypes/profiles/default/types/Dataset.xml @@ -1,27 +1,28 @@ - + + meta_type="Dexterity FTI" + name="Dataset" + i18n:domain="design.plone.contenttypes" +> - Dataset - + Dataset + False Dataset - - + + False False - @@ -29,25 +30,27 @@ design.plone.contenttypes.AddDataset design.plone.contenttypes.content.dataset.Dataset - - + + design.plone.contenttypes.interfaces.dataset.IDataset - + - - - - - - - - + + + + + + + + - + @@ -59,47 +62,43 @@ False view - + - - - - - - + + - - + + diff --git a/src/design/plone/contenttypes/profiles/default/types/Document.xml b/src/design/plone/contenttypes/profiles/default/types/Document.xml index b056f099..56036477 100644 --- a/src/design/plone/contenttypes/profiles/default/types/Document.xml +++ b/src/design/plone/contenttypes/profiles/default/types/Document.xml @@ -1,20 +1,25 @@ - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - + + diff --git a/src/design/plone/contenttypes/profiles/default/types/Documento.xml b/src/design/plone/contenttypes/profiles/default/types/Documento.xml index 13d09a41..51f35980 100644 --- a/src/design/plone/contenttypes/profiles/default/types/Documento.xml +++ b/src/design/plone/contenttypes/profiles/default/types/Documento.xml @@ -1,21 +1,22 @@ - + + meta_type="Dexterity FTI" + name="Documento" + i18n:domain="design.plone.contenttypes" +> - Documento - + Documento + False Documento - - + + True @@ -28,12 +29,14 @@ design.plone.contenttypes.AddDocumento design.plone.contenttypes.content.documento.Documento - - + + design.plone.contenttypes.interfaces.documento.IDocumento - + @@ -41,16 +44,16 @@ - + - - - - - + + + + + @@ -64,47 +67,43 @@ False view - + - - - - - - + + - - + + diff --git a/src/design/plone/contenttypes/profiles/default/types/Documento_Personale.xml b/src/design/plone/contenttypes/profiles/default/types/Documento_Personale.xml index 7f3aa76b..a3583d78 100644 --- a/src/design/plone/contenttypes/profiles/default/types/Documento_Personale.xml +++ b/src/design/plone/contenttypes/profiles/default/types/Documento_Personale.xml @@ -1,27 +1,28 @@ - + + meta_type="Dexterity FTI" + name="Documento Personale" + i18n:domain="design.plone.contenttypes" +> - Documento Personale - + Documento Personale + False Documento Personale - - + + False False - @@ -29,25 +30,27 @@ design.plone.contenttypes.AddDocumentoPersonale design.plone.contenttypes.content.documento_personale.DocumentoPersonale - - + + design.plone.contenttypes.interfaces.documento_personale.IDocumentoPersonale - + - - - - - - - - + + + + + + + + - + @@ -57,47 +60,43 @@ False view - + - - - - - - + + - - + + diff --git a/src/design/plone/contenttypes/profiles/default/types/Event.xml b/src/design/plone/contenttypes/profiles/default/types/Event.xml index a691211c..cd3acfc0 100644 --- a/src/design/plone/contenttypes/profiles/default/types/Event.xml +++ b/src/design/plone/contenttypes/profiles/default/types/Event.xml @@ -1,14 +1,22 @@ - - -True - - + + + True + + - - + + @@ -30,16 +38,28 @@ - - - + + + - - - - - - + + + + + + diff --git a/src/design/plone/contenttypes/profiles/default/types/Link.xml b/src/design/plone/contenttypes/profiles/default/types/Link.xml index e63286a1..8aea89da 100644 --- a/src/design/plone/contenttypes/profiles/default/types/Link.xml +++ b/src/design/plone/contenttypes/profiles/default/types/Link.xml @@ -1,14 +1,16 @@ - - + + - - + + - - + + diff --git a/src/design/plone/contenttypes/profiles/default/types/Messaggio.xml b/src/design/plone/contenttypes/profiles/default/types/Messaggio.xml index 68cb1dab..1a73f28a 100644 --- a/src/design/plone/contenttypes/profiles/default/types/Messaggio.xml +++ b/src/design/plone/contenttypes/profiles/default/types/Messaggio.xml @@ -1,27 +1,28 @@ - + + meta_type="Dexterity FTI" + name="Messaggio" + i18n:domain="design.plone.contenttypes" +> - Messaggio - + Messaggio + False Messaggio - - + + False False - @@ -29,26 +30,28 @@ design.plone.contenttypes.AddMessaggio design.plone.contenttypes.content.messaggio.Messaggio - - + + design.plone.contenttypes.interfaces.messaggio.IMessaggio - + - - - - - - - - + + + + + + + + - - + + @@ -57,47 +60,43 @@ False view - + - - - - - - + + - - + + diff --git a/src/design/plone/contenttypes/profiles/default/types/Modulo.xml b/src/design/plone/contenttypes/profiles/default/types/Modulo.xml index 154957de..fe0ea9c1 100644 --- a/src/design/plone/contenttypes/profiles/default/types/Modulo.xml +++ b/src/design/plone/contenttypes/profiles/default/types/Modulo.xml @@ -1,36 +1,39 @@ - + + meta_type="Dexterity FTI" + name="Modulo" + i18n:domain="design.plone.contenttypes" +> - Modulo - Un modulo compilabile. + Modulo + Un modulo compilabile. False Modulo - - + + False False - + design.plone.contenttypes.AddModulo design.plone.contenttypes.content.modulo.Modulo - - + + design.plone.contenttypes.interfaces.modulo.IModulo - + @@ -39,7 +42,7 @@ - + @@ -48,47 +51,43 @@ False view - + - - - - - - + + - - + + diff --git a/src/design/plone/contenttypes/profiles/default/types/News_Item.xml b/src/design/plone/contenttypes/profiles/default/types/News_Item.xml index ac55c50c..d59947b7 100644 --- a/src/design/plone/contenttypes/profiles/default/types/News_Item.xml +++ b/src/design/plone/contenttypes/profiles/default/types/News_Item.xml @@ -1,26 +1,35 @@ - - + + - + Notizie e comunicati stampa - - + + - + - - - - - - - - - - + + + + + + + + + + diff --git a/src/design/plone/contenttypes/profiles/default/types/Pagina_Argomento.xml b/src/design/plone/contenttypes/profiles/default/types/Pagina_Argomento.xml index d3107e86..6adeb800 100644 --- a/src/design/plone/contenttypes/profiles/default/types/Pagina_Argomento.xml +++ b/src/design/plone/contenttypes/profiles/default/types/Pagina_Argomento.xml @@ -1,27 +1,28 @@ - + + meta_type="Dexterity FTI" + name="Pagina Argomento" + i18n:domain="design.plone.contenttypes" +> - Argomento - + Argomento + False Pagina Argomento - - + + True False - @@ -29,32 +30,34 @@ design.plone.contenttypes.AddPaginaArgomento design.plone.contenttypes.content.pagina_argomento.PaginaArgomento - - + + design.plone.contenttypes.interfaces.pagina_argomento.IPaginaArgomento - + - - - - - - + + + + + + - - + + - + - - - + + + @@ -63,47 +66,43 @@ False view - + - - - - - - + + - - + + diff --git a/src/design/plone/contenttypes/profiles/default/types/Persona.xml b/src/design/plone/contenttypes/profiles/default/types/Persona.xml index 1760e335..9578a7df 100644 --- a/src/design/plone/contenttypes/profiles/default/types/Persona.xml +++ b/src/design/plone/contenttypes/profiles/default/types/Persona.xml @@ -1,27 +1,28 @@ - + + meta_type="Dexterity FTI" + name="Persona" + i18n:domain="design.plone.contenttypes" +> - Persona - + Persona + False Persona - - + + True False - @@ -29,24 +30,26 @@ design.plone.contenttypes.AddPersona design.plone.contenttypes.content.persona.Persona - - + + design.plone.contenttypes.interfaces.persona.IPersona - + - - - - - - + + + + + + - - + + @@ -62,47 +65,43 @@ False view - + - - - - - - + + - - + + diff --git a/src/design/plone/contenttypes/profiles/default/types/Pratica.xml b/src/design/plone/contenttypes/profiles/default/types/Pratica.xml index 0bd44799..3faa989a 100644 --- a/src/design/plone/contenttypes/profiles/default/types/Pratica.xml +++ b/src/design/plone/contenttypes/profiles/default/types/Pratica.xml @@ -1,27 +1,28 @@ - + + meta_type="Dexterity FTI" + name="Pratica" + i18n:domain="design.plone.contenttypes" +> - Pratica - + Pratica + False Pratica - - + + False False - @@ -29,25 +30,27 @@ design.plone.contenttypes.AddPratica design.plone.contenttypes.content.pratica.Pratica - - + + design.plone.contenttypes.interfaces.pratica.IPratica - + - - - - - - - - + + + + + + + + - + @@ -57,47 +60,43 @@ False view - + - - - - - - + + - - + + diff --git a/src/design/plone/contenttypes/profiles/default/types/RicevutaPagamento.xml b/src/design/plone/contenttypes/profiles/default/types/RicevutaPagamento.xml index 28ff5fb6..5ed63efc 100644 --- a/src/design/plone/contenttypes/profiles/default/types/RicevutaPagamento.xml +++ b/src/design/plone/contenttypes/profiles/default/types/RicevutaPagamento.xml @@ -1,27 +1,28 @@ - + + meta_type="Dexterity FTI" + name="RicevutaPagamento" + i18n:domain="design.plone.contenttypes" +> - RicevutaPagamento - + RicevutaPagamento + False RicevutaPagamento - - + + False False - @@ -29,23 +30,25 @@ design.plone.contenttypes.AddRicevutaPagamento design.plone.contenttypes.content.ricevuta_pagamento.RicevutaPagamento - - + + design.plone.contenttypes.interfaces.ricevuta_pagamento.IRicevutaPagamento - + - - - - - - - - + + + + + + + + @@ -55,47 +58,43 @@ False view - + - - - - - - + + - - + + diff --git a/src/design/plone/contenttypes/profiles/default/types/Servizio.xml b/src/design/plone/contenttypes/profiles/default/types/Servizio.xml index 7d8fcba9..2fdea882 100644 --- a/src/design/plone/contenttypes/profiles/default/types/Servizio.xml +++ b/src/design/plone/contenttypes/profiles/default/types/Servizio.xml @@ -1,21 +1,22 @@ - + + meta_type="Dexterity FTI" + name="Servizio" + i18n:domain="design.plone.contenttypes" +> - Servizio - + Servizio + False Servizio - - + + True @@ -29,23 +30,25 @@ design.plone.contenttypes.AddServizio design.plone.contenttypes.content.servizio.Servizio - - + + design.plone.contenttypes.interfaces.servizio.IServizio - - - - - - - - - + + + + + + + + + - + @@ -65,47 +68,43 @@ False view - + - - - - - - + + - - + + diff --git a/src/design/plone/contenttypes/profiles/default/types/UnitaOrganizzativa.xml b/src/design/plone/contenttypes/profiles/default/types/UnitaOrganizzativa.xml index bdd243af..f4f705e3 100644 --- a/src/design/plone/contenttypes/profiles/default/types/UnitaOrganizzativa.xml +++ b/src/design/plone/contenttypes/profiles/default/types/UnitaOrganizzativa.xml @@ -1,27 +1,28 @@ - + + meta_type="Dexterity FTI" + name="UnitaOrganizzativa" + i18n:domain="design.plone.contenttypes" +> - Unita Organizzativa - + Unita Organizzativa + False UnitaOrganizzativa - - + + True False - @@ -29,33 +30,35 @@ design.plone.contenttypes.AddUnitaOrganizzativa design.plone.contenttypes.content.unita_organizzativa.UnitaOrganizzativa - - + + design.plone.contenttypes.interfaces.unita_organizzativa.IUnitaOrganizzativa - - - - - - - - - + + + + + + + + + - + - - - - - - - - - - + + + + + + + + + + @@ -65,47 +68,43 @@ False view - + - - - - - - + + - - + + diff --git a/src/design/plone/contenttypes/profiles/default/types/Venue.xml b/src/design/plone/contenttypes/profiles/default/types/Venue.xml index 19982107..a8c07836 100644 --- a/src/design/plone/contenttypes/profiles/default/types/Venue.xml +++ b/src/design/plone/contenttypes/profiles/default/types/Venue.xml @@ -1,38 +1,51 @@ - - -Luogo -design.plone.contenttypes.content.luogo.Venue -collective.venue.interfaces.IVenue - + + + Luogo + design.plone.contenttypes.content.luogo.Venue + collective.venue.interfaces.IVenue + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/design/plone/contenttypes/profiles/to_3000/controlpanel.xml b/src/design/plone/contenttypes/profiles/to_3000/controlpanel.xml index 91effb75..56b28078 100644 --- a/src/design/plone/contenttypes/profiles/to_3000/controlpanel.xml +++ b/src/design/plone/contenttypes/profiles/to_3000/controlpanel.xml @@ -1,14 +1,13 @@ - - + + - - + + - diff --git a/src/design/plone/contenttypes/profiles/to_3000/registry.xml b/src/design/plone/contenttypes/profiles/to_3000/registry.xml index 5ab420c6..431385f0 100644 --- a/src/design/plone/contenttypes/profiles/to_3000/registry.xml +++ b/src/design/plone/contenttypes/profiles/to_3000/registry.xml @@ -1,6 +1,9 @@ - + - - + i18n:domain="plone" +> + + diff --git a/src/design/plone/contenttypes/profiles/uninstall/browserlayer.xml b/src/design/plone/contenttypes/profiles/uninstall/browserlayer.xml index 95e9afba..0b33c404 100644 --- a/src/design/plone/contenttypes/profiles/uninstall/browserlayer.xml +++ b/src/design/plone/contenttypes/profiles/uninstall/browserlayer.xml @@ -1,7 +1,6 @@ - + - + diff --git a/src/design/plone/contenttypes/restapi/deserializers/dxfields.py b/src/design/plone/contenttypes/restapi/deserializers/dxfields.py index 4d220340..7958cad9 100644 --- a/src/design/plone/contenttypes/restapi/deserializers/dxfields.py +++ b/src/design/plone/contenttypes/restapi/deserializers/dxfields.py @@ -15,6 +15,7 @@ import json + KEYS_WITH_URL = ["linkUrl", "navigationRoot", "showMoreLink"] diff --git a/src/design/plone/contenttypes/restapi/deserializers/persona.py b/src/design/plone/contenttypes/restapi/deserializers/persona.py index 762260df..de734fda 100644 --- a/src/design/plone/contenttypes/restapi/deserializers/persona.py +++ b/src/design/plone/contenttypes/restapi/deserializers/persona.py @@ -1,12 +1,12 @@ # -*- coding: utf-8 -*- +from AccessControl import getSecurityManager from design.plone.contenttypes.interfaces.persona import IPersona from plone.restapi.deserializer import json_body +from plone.restapi.deserializer.dxcontent import DeserializeFromJson from plone.restapi.interfaces import IDeserializeFromJson -from zope.interface import implementer from zope.component import adapter +from zope.interface import implementer from zope.interface import Interface -from AccessControl import getSecurityManager -from plone.restapi.deserializer.dxcontent import DeserializeFromJson @implementer(IDeserializeFromJson) diff --git a/src/design/plone/contenttypes/restapi/serializers/bando.py b/src/design/plone/contenttypes/restapi/serializers/bando.py index a0ac5079..9e463ad0 100644 --- a/src/design/plone/contenttypes/restapi/serializers/bando.py +++ b/src/design/plone/contenttypes/restapi/serializers/bando.py @@ -1,10 +1,10 @@ # -*- coding: utf-8 -*- from .dxcontent import SerializeFolderToJson as BaseSerializer +from design.plone.contenttypes.interfaces.bando import IBandoAgidSchema from plone.restapi.interfaces import ISerializeToJson from zope.component import adapter from zope.interface import implementer from zope.interface import Interface -from design.plone.contenttypes.interfaces.bando import IBandoAgidSchema @implementer(ISerializeToJson) diff --git a/src/design/plone/contenttypes/restapi/serializers/cartella_modulistica.py b/src/design/plone/contenttypes/restapi/serializers/cartella_modulistica.py index 0fa01edd..f5ec1879 100644 --- a/src/design/plone/contenttypes/restapi/serializers/cartella_modulistica.py +++ b/src/design/plone/contenttypes/restapi/serializers/cartella_modulistica.py @@ -1,21 +1,20 @@ # -*- coding: utf-8 -*- -from .related_news_serializer import ( - SerializeFolderToJson as RelatedNewsSerializer, -) +from .related_news_serializer import SerializeFolderToJson as RelatedNewsSerializer +from Acquisition import aq_inner from design.plone.contenttypes.interfaces.cartella_modulistica import ( ICartellaModulistica, ) - -from plone.restapi.interfaces import ISerializeToJson, ISerializeToJsonSummary -from zope.component import adapter, getMultiAdapter +from plone.restapi.interfaces import ISerializeToJson +from plone.restapi.interfaces import ISerializeToJsonSummary +from zc.relation.interfaces import ICatalog +from zope.component import adapter +from zope.component import getMultiAdapter +from zope.component import getUtility +from zope.globalrequest import getRequest from zope.interface import implementer from zope.interface import Interface -from Acquisition import aq_inner -from zope.component import getUtility from zope.intid.interfaces import IIntIds from zope.security import checkPermission -from zc.relation.interfaces import ICatalog -from zope.globalrequest import getRequest @implementer(ISerializeToJson) diff --git a/src/design/plone/contenttypes/restapi/serializers/documento.py b/src/design/plone/contenttypes/restapi/serializers/documento.py index 95108d24..5a47cca8 100644 --- a/src/design/plone/contenttypes/restapi/serializers/documento.py +++ b/src/design/plone/contenttypes/restapi/serializers/documento.py @@ -4,9 +4,11 @@ from design.plone.contenttypes.restapi.serializers.dxcontent import ( SerializeFolderToJson, ) -from plone.restapi.interfaces import ISerializeToJson, ISerializeToJsonSummary +from plone.restapi.interfaces import ISerializeToJson +from plone.restapi.interfaces import ISerializeToJsonSummary from zc.relation.interfaces import ICatalog -from zope.component import adapter, getMultiAdapter +from zope.component import adapter +from zope.component import getMultiAdapter from zope.component import getUtility from zope.globalrequest import getRequest from zope.interface import implementer diff --git a/src/design/plone/contenttypes/restapi/serializers/dxcontent.py b/src/design/plone/contenttypes/restapi/serializers/dxcontent.py index 997a5536..f7ae2be1 100644 --- a/src/design/plone/contenttypes/restapi/serializers/dxcontent.py +++ b/src/design/plone/contenttypes/restapi/serializers/dxcontent.py @@ -1,19 +1,16 @@ # -*- coding: utf-8 -*- -from design.plone.contenttypes import _ from design.plone.contenttypes.interfaces import IDesignPloneContenttypesLayer from plone import api from plone.dexterity.interfaces import IDexterityContainer from plone.dexterity.interfaces import IDexterityContent from plone.restapi.interfaces import ISerializeToJson -from zope.component import adapter -from zope.i18n import translate -from zope.interface import implementer -from plone.restapi.serializer.dxcontent import ( - SerializeToJson as BaseSerializer, -) from plone.restapi.serializer.dxcontent import ( SerializeFolderToJson as BaseFolderSerializer, ) +from plone.restapi.serializer.dxcontent import SerializeToJson as BaseSerializer +from zope.component import adapter +from zope.i18n import translate +from zope.interface import implementer @implementer(ISerializeToJson) diff --git a/src/design/plone/contenttypes/restapi/serializers/dxfields.py b/src/design/plone/contenttypes/restapi/serializers/dxfields.py index 08c0ebb9..1b2046d9 100644 --- a/src/design/plone/contenttypes/restapi/serializers/dxfields.py +++ b/src/design/plone/contenttypes/restapi/serializers/dxfields.py @@ -17,6 +17,7 @@ import json + KEYS_WITH_URL = ["linkUrl", "navigationRoot", "showMoreLink"] diff --git a/src/design/plone/contenttypes/restapi/serializers/modulo.py b/src/design/plone/contenttypes/restapi/serializers/modulo.py index 091e1f12..6947da4c 100644 --- a/src/design/plone/contenttypes/restapi/serializers/modulo.py +++ b/src/design/plone/contenttypes/restapi/serializers/modulo.py @@ -1,9 +1,9 @@ # -*- coding: utf-8 -*- +from design.plone.contenttypes.interfaces import IDesignPloneContenttypesLayer from design.plone.contenttypes.interfaces.modulo import IModulo from design.plone.contenttypes.restapi.serializers.summary import ( DefaultJSONSummarySerializer, ) -from design.plone.contenttypes.interfaces import IDesignPloneContenttypesLayer from plone.dexterity.utils import iterSchemata from plone.restapi.interfaces import IFieldSerializer from plone.restapi.interfaces import ISerializeToJsonSummary diff --git a/src/design/plone/contenttypes/restapi/serializers/persona.py b/src/design/plone/contenttypes/restapi/serializers/persona.py index ec370f4d..830606e1 100644 --- a/src/design/plone/contenttypes/restapi/serializers/persona.py +++ b/src/design/plone/contenttypes/restapi/serializers/persona.py @@ -2,9 +2,11 @@ from .related_news_serializer import SerializeFolderToJson from Acquisition import aq_inner from design.plone.contenttypes.interfaces.persona import IPersona -from plone.restapi.interfaces import ISerializeToJson, ISerializeToJsonSummary +from plone.restapi.interfaces import ISerializeToJson +from plone.restapi.interfaces import ISerializeToJsonSummary from zc.relation.interfaces import ICatalog -from zope.component import adapter, getMultiAdapter +from zope.component import adapter +from zope.component import getMultiAdapter from zope.component import getUtility from zope.globalrequest import getRequest from zope.interface import implementer diff --git a/src/design/plone/contenttypes/restapi/serializers/related_news_serializer.py b/src/design/plone/contenttypes/restapi/serializers/related_news_serializer.py index ed876f13..e7cc1e86 100644 --- a/src/design/plone/contenttypes/restapi/serializers/related_news_serializer.py +++ b/src/design/plone/contenttypes/restapi/serializers/related_news_serializer.py @@ -3,12 +3,12 @@ from design.plone.contenttypes.interfaces.servizio import IServizio from plone import api from plone.restapi.interfaces import ISerializeToJson -from zope.component import adapter -from zope.interface import implementer -from zope.interface import Interface from plone.restapi.interfaces import ISerializeToJsonSummary from plone.restapi.serializer.converters import json_compatible +from zope.component import adapter from zope.component import getMultiAdapter +from zope.interface import implementer +from zope.interface import Interface class SerializeFolderToJson(BaseSerializer): diff --git a/src/design/plone/contenttypes/restapi/serializers/summary.py b/src/design/plone/contenttypes/restapi/serializers/summary.py index 471d6765..7d2e7304 100644 --- a/src/design/plone/contenttypes/restapi/serializers/summary.py +++ b/src/design/plone/contenttypes/restapi/serializers/summary.py @@ -8,10 +8,12 @@ from zope.component import adapter from zope.component import getMultiAdapter from zope.i18n import translate -from zope.interface import Interface from zope.interface import implementer +from zope.interface import Interface + import re + RESOLVEUID_RE = re.compile(".*?/resolve[Uu]id/([^/]*)/?(.*)$") @@ -102,7 +104,8 @@ def expand_tassonomia_argomenti(self): def get_bando_state(self): """ - E' il metodo più safe per ottenere lo stato del bando, anche se non il più veloce + È il metodo più safe per ottenere lo stato del bando + anche se non il più veloce """ bando = self.context.getObject() view = api.content.get_view("bando_view", context=bando, request=self.request) diff --git a/src/design/plone/contenttypes/restapi/serializers/unita_organizzativa.py b/src/design/plone/contenttypes/restapi/serializers/unita_organizzativa.py index 82d8388e..6cb03a36 100644 --- a/src/design/plone/contenttypes/restapi/serializers/unita_organizzativa.py +++ b/src/design/plone/contenttypes/restapi/serializers/unita_organizzativa.py @@ -1,25 +1,22 @@ # -*- coding: utf-8 -*- -from .related_news_serializer import ( - SerializeFolderToJson as RelatedNewsSerializer, -) -from design.plone.contenttypes.interfaces.unita_organizzativa import ( - IUnitaOrganizzativa, -) +from .related_news_serializer import SerializeFolderToJson as RelatedNewsSerializer +from Acquisition import aq_inner +from design.plone.contenttypes.interfaces.unita_organizzativa import IUnitaOrganizzativa from design.plone.contenttypes.restapi.serializers.summary import ( DefaultJSONSummarySerializer, ) - from plone import api -from plone.restapi.interfaces import ISerializeToJson, ISerializeToJsonSummary -from zope.component import adapter, getMultiAdapter +from plone.restapi.interfaces import ISerializeToJson +from plone.restapi.interfaces import ISerializeToJsonSummary +from zc.relation.interfaces import ICatalog +from zope.component import adapter +from zope.component import getMultiAdapter +from zope.component import getUtility +from zope.globalrequest import getRequest from zope.interface import implementer from zope.interface import Interface -from Acquisition import aq_inner -from zope.component import getUtility from zope.intid.interfaces import IIntIds from zope.security import checkPermission -from zc.relation.interfaces import ICatalog -from zope.globalrequest import getRequest @implementer(ISerializeToJson) diff --git a/src/design/plone/contenttypes/restapi/serializers/venue.py b/src/design/plone/contenttypes/restapi/serializers/venue.py index 2f8e7ad8..51d98917 100644 --- a/src/design/plone/contenttypes/restapi/serializers/venue.py +++ b/src/design/plone/contenttypes/restapi/serializers/venue.py @@ -1,8 +1,5 @@ # -*- coding: utf-8 -*- -from .related_news_serializer import ( - SerializeFolderToJson as RelatedNewsSerializer, -) - +from .related_news_serializer import SerializeFolderToJson as RelatedNewsSerializer from Acquisition import aq_inner from collective.venue.interfaces import IVenue from design.plone.contenttypes.restapi.serializers.summary import ( @@ -13,7 +10,8 @@ from plone.restapi.interfaces import ISerializeToJsonSummary from plone.restapi.serializer.converters import json_compatible from zc.relation.interfaces import ICatalog -from zope.component import adapter, getMultiAdapter +from zope.component import adapter +from zope.component import getMultiAdapter from zope.component import getUtility from zope.globalrequest import getRequest from zope.interface import implementer diff --git a/src/design/plone/contenttypes/restapi/services/content/add.py b/src/design/plone/contenttypes/restapi/services/content/add.py index 69bd2835..5ef8aa61 100644 --- a/src/design/plone/contenttypes/restapi/services/content/add.py +++ b/src/design/plone/contenttypes/restapi/services/content/add.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from plone.restapi.services.content.add import FolderPost from plone.restapi.deserializer import json_body +from plone.restapi.services.content.add import FolderPost import json diff --git a/src/design/plone/contenttypes/restapi/services/controlpanel.py b/src/design/plone/contenttypes/restapi/services/controlpanel.py index c9b74559..e8bad484 100644 --- a/src/design/plone/contenttypes/restapi/services/controlpanel.py +++ b/src/design/plone/contenttypes/restapi/services/controlpanel.py @@ -1,12 +1,12 @@ # -*- coding: utf-8 -*- +from design.plone.contenttypes.controlpanels.settings import IDesignPloneSettings from design.plone.contenttypes.controlpanels.settings import ( - IDesignPloneSettings, IDesignPloneSettingsControlpanel, ) from plone.restapi.controlpanels import RegistryConfigletPanel from zope.component import adapter -from zope.interface import Interface from zope.interface import implementer +from zope.interface import Interface @adapter(Interface, Interface) diff --git a/src/design/plone/contenttypes/restapi/services/modulistica_items/get.py b/src/design/plone/contenttypes/restapi/services/modulistica_items/get.py index 716cbd75..b1a411a1 100644 --- a/src/design/plone/contenttypes/restapi/services/modulistica_items/get.py +++ b/src/design/plone/contenttypes/restapi/services/modulistica_items/get.py @@ -8,12 +8,12 @@ from plone.restapi.interfaces import ISerializeToJsonSummary from plone.restapi.serializer.converters import json_compatible from plone.restapi.services import Service +from Products.CMFCore.interfaces import IFolderish from zope.component import adapter from zope.component import queryMultiAdapter from zope.interface import implementer from zope.interface import Interface from zope.schema import getFields -from Products.CMFCore.interfaces import IFolderish @implementer(IExpandableElement) diff --git a/src/design/plone/contenttypes/restapi/services/scadenziario/post.py b/src/design/plone/contenttypes/restapi/services/scadenziario/post.py index a310f0a2..6b9e5a4f 100644 --- a/src/design/plone/contenttypes/restapi/services/scadenziario/post.py +++ b/src/design/plone/contenttypes/restapi/services/scadenziario/post.py @@ -17,6 +17,7 @@ from Products.CMFPlone.utils import safe_hasattr from zope.component import getMultiAdapter + zcatalog_version = get_distribution("Products.ZCatalog").version if parse_version(zcatalog_version) >= parse_version("5.1"): SUPPORT_NOT_UUID_QUERIES = True diff --git a/src/design/plone/contenttypes/restapi/services/trasparenza/get.py b/src/design/plone/contenttypes/restapi/services/trasparenza/get.py index e018adae..21ce832c 100644 --- a/src/design/plone/contenttypes/restapi/services/trasparenza/get.py +++ b/src/design/plone/contenttypes/restapi/services/trasparenza/get.py @@ -1,16 +1,16 @@ # -*- coding: utf-8 -*- from plone import api -from plone.restapi.interfaces import ISerializeToJson -from zope.component import getMultiAdapter -from zope.globalrequest import getRequest from plone.restapi.interfaces import IExpandableElement +from plone.restapi.interfaces import ISerializeToJson from plone.restapi.interfaces import ISerializeToJsonSummary from plone.restapi.services import Service +from Products.CMFCore.interfaces import IFolderish from zope.component import adapter +from zope.component import getMultiAdapter from zope.component import queryMultiAdapter +from zope.globalrequest import getRequest from zope.interface import implementer from zope.interface import Interface -from Products.CMFCore.interfaces import IFolderish TRASPARENZA_FIELDS = [ diff --git a/src/design/plone/contenttypes/restapi/services/types/get.py b/src/design/plone/contenttypes/restapi/services/types/get.py index f7ce952e..f02cf16a 100644 --- a/src/design/plone/contenttypes/restapi/services/types/get.py +++ b/src/design/plone/contenttypes/restapi/services/types/get.py @@ -1,13 +1,13 @@ # -*- coding: utf-8 -*- -from plone.restapi.services.types.get import TypesGet as BaseGet -from zope.interface import implementer -from zope.publisher.interfaces import IPublishTraverse +from design.plone.contenttypes import _ from design.plone.contenttypes.controlpanels.geolocation_defaults import ( IGeolocationDefaults, ) -from zope.i18n import translate from plone import api -from design.plone.contenttypes import _ +from plone.restapi.services.types.get import TypesGet as BaseGet +from zope.i18n import translate +from zope.interface import implementer +from zope.publisher.interfaces import IPublishTraverse class FieldsetsMismatchError(Exception): diff --git a/src/design/plone/contenttypes/restapi/types/adapters.py b/src/design/plone/contenttypes/restapi/types/adapters.py index 38d4f3cb..d5f2b931 100644 --- a/src/design/plone/contenttypes/restapi/types/adapters.py +++ b/src/design/plone/contenttypes/restapi/types/adapters.py @@ -1,7 +1,9 @@ # -*- coding: utf-8 -*- +from design.plone.contenttypes import _ from plone.restapi.types.adapters import ObjectJsonSchemaProvider from plone.restapi.types.interfaces import IJsonSchemaProvider -from zope.component import adapter, getUtility +from zope.component import adapter +from zope.component import getUtility from zope.i18n import translate from zope.interface import implementer from zope.interface import Interface diff --git a/src/design/plone/contenttypes/setuphandlers.py b/src/design/plone/contenttypes/setuphandlers.py index d5a08711..188d4471 100644 --- a/src/design/plone/contenttypes/setuphandlers.py +++ b/src/design/plone/contenttypes/setuphandlers.py @@ -1,10 +1,10 @@ # -*- coding: utf-8 -*- +from design.plone.contenttypes.upgrades.upgrades import remove_blocks_behavior +from design.plone.contenttypes.upgrades.upgrades import update_types from plone import api -from redturtle.bandi.interfaces.settings import IBandoSettings from Products.CMFPlone.interfaces import INonInstallable +from redturtle.bandi.interfaces.settings import IBandoSettings from zope.interface import implementer -from design.plone.contenttypes.upgrades.upgrades import remove_blocks_behavior -from design.plone.contenttypes.upgrades.upgrades import update_types @implementer(INonInstallable) @@ -34,16 +34,16 @@ def post_install(context): "plone.leadimage", "volto.preview_image", "plone.tableofcontents", - ] + ], }, } for ct in BEHAVIORS.keys(): ct_behaviors = [ - x for x in portal_types[ct].behaviors if x not in BEHAVIORS[ct]["out"] # noqa + x + for x in portal_types[ct].behaviors + if x not in BEHAVIORS[ct]["out"] # noqa ] - ct_behaviors.extend( - [x for x in BEHAVIORS[ct]["in"] if x not in ct_behaviors] - ) + ct_behaviors.extend([x for x in BEHAVIORS[ct]["in"] if x not in ct_behaviors]) portal_types[ct].behaviors = tuple(ct_behaviors) # remove default ente diff --git a/src/design/plone/contenttypes/testing.py b/src/design/plone/contenttypes/testing.py index 2e5669e9..92432113 100644 --- a/src/design/plone/contenttypes/testing.py +++ b/src/design/plone/contenttypes/testing.py @@ -3,10 +3,9 @@ from plone.app.testing import FunctionalTesting from plone.app.testing import IntegrationTesting from plone.testing import z2 -from zope.configuration import xmlconfig from redturtle.volto.testing import RedturtleVoltoLayer from redturtle.volto.testing import RedturtleVoltoRestApiLayer - +from zope.configuration import xmlconfig import collective.address import collective.folderishtypes diff --git a/src/design/plone/contenttypes/tests/test_argomenti.py b/src/design/plone/contenttypes/tests/test_argomenti.py index 25c55552..bf5ef4df 100644 --- a/src/design/plone/contenttypes/tests/test_argomenti.py +++ b/src/design/plone/contenttypes/tests/test_argomenti.py @@ -3,17 +3,15 @@ DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING, ) from plone import api +from plone.app.testing import setRoles +from plone.app.testing import SITE_OWNER_NAME +from plone.app.testing import SITE_OWNER_PASSWORD +from plone.app.testing import TEST_USER_ID from plone.restapi.testing import RelativeSession from transaction import commit from z3c.relationfield import RelationValue from zope.component import getUtility from zope.intid.interfaces import IIntIds -from plone.app.testing import ( - SITE_OWNER_NAME, - SITE_OWNER_PASSWORD, - TEST_USER_ID, - setRoles, -) import unittest diff --git a/src/design/plone/contenttypes/tests/test_base_serializer.py b/src/design/plone/contenttypes/tests/test_base_serializer.py index 3d56d3fc..048dc102 100644 --- a/src/design/plone/contenttypes/tests/test_base_serializer.py +++ b/src/design/plone/contenttypes/tests/test_base_serializer.py @@ -1,18 +1,17 @@ # -*- coding: utf-8 -*- """Setup tests for this package.""" -from plone import api -from plone.app.testing import ( - SITE_OWNER_NAME, - SITE_OWNER_PASSWORD, - TEST_USER_ID, - setRoles, -) -from plone.restapi.testing import RelativeSession -from transaction import commit from design.plone.contenttypes.testing import ( DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING, ) +from plone import api +from plone.app.testing import setRoles +from plone.app.testing import SITE_OWNER_NAME +from plone.app.testing import SITE_OWNER_PASSWORD +from plone.app.testing import TEST_USER_ID +from plone.restapi.testing import RelativeSession +from transaction import commit + import unittest diff --git a/src/design/plone/contenttypes/tests/test_behavior_descrizione_estesa.py b/src/design/plone/contenttypes/tests/test_behavior_descrizione_estesa.py index b5ac0672..30d71457 100644 --- a/src/design/plone/contenttypes/tests/test_behavior_descrizione_estesa.py +++ b/src/design/plone/contenttypes/tests/test_behavior_descrizione_estesa.py @@ -1,17 +1,15 @@ # -*- coding: utf-8 -*- """Setup tests for this package.""" -from plone import api -from plone.app.testing import ( - SITE_OWNER_NAME, - SITE_OWNER_PASSWORD, - TEST_USER_ID, - setRoles, -) -from plone.restapi.testing import RelativeSession from design.plone.contenttypes.testing import ( DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING, ) +from plone import api +from plone.app.testing import setRoles +from plone.app.testing import SITE_OWNER_NAME +from plone.app.testing import SITE_OWNER_PASSWORD +from plone.app.testing import TEST_USER_ID +from plone.restapi.testing import RelativeSession import unittest diff --git a/src/design/plone/contenttypes/tests/test_behavior_show_modified.py b/src/design/plone/contenttypes/tests/test_behavior_show_modified.py index 6edc1361..edef403d 100644 --- a/src/design/plone/contenttypes/tests/test_behavior_show_modified.py +++ b/src/design/plone/contenttypes/tests/test_behavior_show_modified.py @@ -1,23 +1,19 @@ # -*- coding: utf-8 -*- """Setup tests for this package.""" -from plone import api -from plone.app.testing import ( - SITE_OWNER_NAME, - SITE_OWNER_PASSWORD, - TEST_USER_ID, - setRoles, -) -from plone.restapi.testing import RelativeSession +from design.plone.contenttypes.controlpanels.settings import IDesignPloneSettings from design.plone.contenttypes.testing import ( DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING, ) -from design.plone.contenttypes.controlpanels.settings import ( - IDesignPloneSettings, -) +from plone import api +from plone.app.testing import setRoles +from plone.app.testing import SITE_OWNER_NAME +from plone.app.testing import SITE_OWNER_PASSWORD +from plone.app.testing import TEST_USER_ID +from plone.restapi.testing import RelativeSession -import unittest import transaction +import unittest class TestShowModifiedBehavior(unittest.TestCase): diff --git a/src/design/plone/contenttypes/tests/test_behavior_update_note.py b/src/design/plone/contenttypes/tests/test_behavior_update_note.py index 4624580c..992ffb45 100644 --- a/src/design/plone/contenttypes/tests/test_behavior_update_note.py +++ b/src/design/plone/contenttypes/tests/test_behavior_update_note.py @@ -1,20 +1,18 @@ # -*- coding: utf-8 -*- """Setup tests for this package.""" -from plone import api -from plone.app.testing import ( - SITE_OWNER_NAME, - SITE_OWNER_PASSWORD, - TEST_USER_ID, - setRoles, -) -from plone.restapi.testing import RelativeSession from design.plone.contenttypes.testing import ( DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING, ) +from plone import api +from plone.app.testing import setRoles +from plone.app.testing import SITE_OWNER_NAME +from plone.app.testing import SITE_OWNER_PASSWORD +from plone.app.testing import TEST_USER_ID +from plone.restapi.testing import RelativeSession -import unittest import transaction +import unittest class TestUpdateNoteBehavior(unittest.TestCase): diff --git a/src/design/plone/contenttypes/tests/test_ct_document.py b/src/design/plone/contenttypes/tests/test_ct_document.py index 96f21293..162a3459 100644 --- a/src/design/plone/contenttypes/tests/test_ct_document.py +++ b/src/design/plone/contenttypes/tests/test_ct_document.py @@ -4,6 +4,7 @@ DESIGN_PLONE_CONTENTTYPES_INTEGRATION_TESTING, ) from plone import api + import unittest diff --git a/src/design/plone/contenttypes/tests/test_ct_documento.py b/src/design/plone/contenttypes/tests/test_ct_documento.py index 3d254e71..1fe11213 100644 --- a/src/design/plone/contenttypes/tests/test_ct_documento.py +++ b/src/design/plone/contenttypes/tests/test_ct_documento.py @@ -2,19 +2,21 @@ from design.plone.contenttypes.testing import ( DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING, +) +from design.plone.contenttypes.testing import ( DESIGN_PLONE_CONTENTTYPES_INTEGRATION_TESTING, ) +from plone import api from plone.app.testing import setRoles from plone.app.testing import SITE_OWNER_NAME from plone.app.testing import SITE_OWNER_PASSWORD from plone.app.testing import TEST_USER_ID -from plone.restapi.testing import RelativeSession -from plone import api from plone.namedfile.file import NamedBlobFile +from plone.restapi.testing import RelativeSession -import unittest -import transaction import os +import transaction +import unittest class TestDocument(unittest.TestCase): diff --git a/src/design/plone/contenttypes/tests/test_ct_documento_personale.py b/src/design/plone/contenttypes/tests/test_ct_documento_personale.py index 28021394..75e0fa56 100644 --- a/src/design/plone/contenttypes/tests/test_ct_documento_personale.py +++ b/src/design/plone/contenttypes/tests/test_ct_documento_personale.py @@ -4,6 +4,7 @@ DESIGN_PLONE_CONTENTTYPES_INTEGRATION_TESTING, ) from plone import api + import unittest diff --git a/src/design/plone/contenttypes/tests/test_ct_event.py b/src/design/plone/contenttypes/tests/test_ct_event.py index 57b79ba2..d1f64ca8 100644 --- a/src/design/plone/contenttypes/tests/test_ct_event.py +++ b/src/design/plone/contenttypes/tests/test_ct_event.py @@ -1,17 +1,20 @@ # -*- coding: utf-8 -*- +from design.plone.contenttypes.schema_overrides import SchemaTweaks from design.plone.contenttypes.testing import ( - DESIGN_PLONE_CONTENTTYPES_INTEGRATION_TESTING, DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING, ) +from design.plone.contenttypes.testing import ( + DESIGN_PLONE_CONTENTTYPES_INTEGRATION_TESTING, +) from plone import api from plone.app.testing import setRoles from plone.app.testing import SITE_OWNER_NAME from plone.app.testing import SITE_OWNER_PASSWORD from plone.app.testing import TEST_USER_ID +from plone.autoform.interfaces import IFormFieldProvider from plone.restapi.testing import RelativeSession -from design.plone.contenttypes.schema_overrides import SchemaTweaks from zope.component import provideAdapter -from plone.autoform.interfaces import IFormFieldProvider + import transaction import unittest diff --git a/src/design/plone/contenttypes/tests/test_ct_luogo.py b/src/design/plone/contenttypes/tests/test_ct_luogo.py index 6ebd6725..815ff171 100644 --- a/src/design/plone/contenttypes/tests/test_ct_luogo.py +++ b/src/design/plone/contenttypes/tests/test_ct_luogo.py @@ -1,9 +1,11 @@ # -*- coding: utf-8 -*- from DateTime import DateTime from design.plone.contenttypes.testing import ( - DESIGN_PLONE_CONTENTTYPES_INTEGRATION_TESTING, DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING, ) +from design.plone.contenttypes.testing import ( + DESIGN_PLONE_CONTENTTYPES_INTEGRATION_TESTING, +) from plone import api from plone.app.testing import setRoles from plone.app.testing import SITE_OWNER_NAME diff --git a/src/design/plone/contenttypes/tests/test_ct_modulo.py b/src/design/plone/contenttypes/tests/test_ct_modulo.py index e6a61406..e12bf364 100644 --- a/src/design/plone/contenttypes/tests/test_ct_modulo.py +++ b/src/design/plone/contenttypes/tests/test_ct_modulo.py @@ -4,6 +4,7 @@ DESIGN_PLONE_CONTENTTYPES_INTEGRATION_TESTING, ) from plone import api + import unittest diff --git a/src/design/plone/contenttypes/tests/test_ct_news.py b/src/design/plone/contenttypes/tests/test_ct_news.py index 067fbffc..a72f38a9 100644 --- a/src/design/plone/contenttypes/tests/test_ct_news.py +++ b/src/design/plone/contenttypes/tests/test_ct_news.py @@ -1,17 +1,17 @@ # -*- coding: utf-8 -*- +from design.plone.contenttypes.controlpanels.settings import IDesignPloneSettings from design.plone.contenttypes.testing import ( - DESIGN_PLONE_CONTENTTYPES_INTEGRATION_TESTING, DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING, ) +from design.plone.contenttypes.testing import ( + DESIGN_PLONE_CONTENTTYPES_INTEGRATION_TESTING, +) from plone import api from plone.app.testing import setRoles from plone.app.testing import SITE_OWNER_NAME from plone.app.testing import SITE_OWNER_PASSWORD from plone.app.testing import TEST_USER_ID from plone.restapi.testing import RelativeSession -from design.plone.contenttypes.controlpanels.settings import ( - IDesignPloneSettings, -) import json import transaction diff --git a/src/design/plone/contenttypes/tests/test_ct_pagina_argomento.py b/src/design/plone/contenttypes/tests/test_ct_pagina_argomento.py index 155f4ea5..e598271d 100644 --- a/src/design/plone/contenttypes/tests/test_ct_pagina_argomento.py +++ b/src/design/plone/contenttypes/tests/test_ct_pagina_argomento.py @@ -4,6 +4,7 @@ DESIGN_PLONE_CONTENTTYPES_INTEGRATION_TESTING, ) from plone import api + import unittest diff --git a/src/design/plone/contenttypes/tests/test_ct_persona.py b/src/design/plone/contenttypes/tests/test_ct_persona.py index 88e5fb9d..d9641ec7 100644 --- a/src/design/plone/contenttypes/tests/test_ct_persona.py +++ b/src/design/plone/contenttypes/tests/test_ct_persona.py @@ -1,17 +1,16 @@ # -*- coding: utf-8 -*- from design.plone.contenttypes.testing import ( - DESIGN_PLONE_CONTENTTYPES_INTEGRATION_TESTING, DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING, ) -from plone import api -from plone.app.testing import ( - SITE_OWNER_NAME, - SITE_OWNER_PASSWORD, - TEST_USER_ID, - setRoles, +from design.plone.contenttypes.testing import ( + DESIGN_PLONE_CONTENTTYPES_INTEGRATION_TESTING, ) - +from plone import api +from plone.app.testing import setRoles +from plone.app.testing import SITE_OWNER_NAME +from plone.app.testing import SITE_OWNER_PASSWORD +from plone.app.testing import TEST_USER_ID from plone.restapi.testing import RelativeSession from transaction import commit from z3c.relationfield import RelationValue diff --git a/src/design/plone/contenttypes/tests/test_ct_servizio.py b/src/design/plone/contenttypes/tests/test_ct_servizio.py index e9a31b0f..049c3c0d 100644 --- a/src/design/plone/contenttypes/tests/test_ct_servizio.py +++ b/src/design/plone/contenttypes/tests/test_ct_servizio.py @@ -1,11 +1,11 @@ # -*- coding: utf-8 -*- """Setup tests for this package.""" -from design.plone.contenttypes.testing import ( +from design.plone.contenttypes.testing import ( # noqa DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING, -) # noqa -from design.plone.contenttypes.testing import ( +) +from design.plone.contenttypes.testing import ( # noqa DESIGN_PLONE_CONTENTTYPES_INTEGRATION_TESTING, -) # noqa +) from plone import api from plone.app.testing import setRoles from plone.app.testing import SITE_OWNER_NAME @@ -15,6 +15,7 @@ import unittest + WIDGET_PROPERTY_CHECKS = { "tassonomia_argomenti": { "maximumSelectionSize": 20, diff --git a/src/design/plone/contenttypes/tests/test_ct_unita_organizzativa.py b/src/design/plone/contenttypes/tests/test_ct_unita_organizzativa.py index ded6499f..2d35e2de 100644 --- a/src/design/plone/contenttypes/tests/test_ct_unita_organizzativa.py +++ b/src/design/plone/contenttypes/tests/test_ct_unita_organizzativa.py @@ -5,12 +5,10 @@ DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING, ) from plone import api -from plone.app.testing import ( - SITE_OWNER_NAME, - SITE_OWNER_PASSWORD, - TEST_USER_ID, - setRoles, -) +from plone.app.testing import setRoles +from plone.app.testing import SITE_OWNER_NAME +from plone.app.testing import SITE_OWNER_PASSWORD +from plone.app.testing import TEST_USER_ID from plone.restapi.testing import RelativeSession from Products.CMFPlone.utils import getToolByName from transaction import commit diff --git a/src/design/plone/contenttypes/tests/test_relateditems_with_dates.py b/src/design/plone/contenttypes/tests/test_relateditems_with_dates.py index 0ea0b3fd..0e24dc77 100644 --- a/src/design/plone/contenttypes/tests/test_relateditems_with_dates.py +++ b/src/design/plone/contenttypes/tests/test_relateditems_with_dates.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from DateTime import DateTime from datetime import datetime +from DateTime import DateTime from design.plone.contenttypes.testing import ( DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING, ) @@ -15,7 +15,6 @@ from zope.component import getUtility from zope.intid.interfaces import IIntIds - import unittest @@ -142,7 +141,7 @@ def test_api_do_not_return_related_items_with_effective_date_in_future_for_anon( res_anon = self.api_session_anon.get(page.absolute_url()).json() self.assertEqual(len(res_anon["relatedItems"]), 1) - def test_api_do_not_return_related_items_with_effective_date_in_future_for_users_that_cant_edit_context( + def test_api_do_not_return_related_items_with_effective_date_in_future_for_users_that_cant_edit_context( # noqa self, ): api.user.create( diff --git a/src/design/plone/contenttypes/tests/test_setup.py b/src/design/plone/contenttypes/tests/test_setup.py index f65c5847..6664220c 100644 --- a/src/design/plone/contenttypes/tests/test_setup.py +++ b/src/design/plone/contenttypes/tests/test_setup.py @@ -1,9 +1,9 @@ # -*- coding: utf-8 -*- """Setup tests for this package.""" +from design.plone.contenttypes.controlpanels.settings import IDesignPloneSettings from design.plone.contenttypes.testing import ( DESIGN_PLONE_CONTENTTYPES_INTEGRATION_TESTING, ) -from design.plone.contenttypes.controlpanels.settings import IDesignPloneSettings from plone import api from plone.app.testing import setRoles from plone.app.testing import TEST_USER_ID diff --git a/src/design/plone/contenttypes/tests/test_summary_serializer.py b/src/design/plone/contenttypes/tests/test_summary_serializer.py index bf18f1e3..f3b20443 100644 --- a/src/design/plone/contenttypes/tests/test_summary_serializer.py +++ b/src/design/plone/contenttypes/tests/test_summary_serializer.py @@ -11,8 +11,8 @@ from plone.restapi.interfaces import ISerializeToJsonSummary from plone.restapi.testing import RelativeSession from transaction import commit -from zope.component import getMultiAdapter from z3c.relationfield import RelationValue +from zope.component import getMultiAdapter from zope.component import getUtility from zope.intid.interfaces import IIntIds diff --git a/src/design/plone/contenttypes/tests/test_vocabularies.py b/src/design/plone/contenttypes/tests/test_vocabularies.py index 9026f853..d5ed2106 100644 --- a/src/design/plone/contenttypes/tests/test_vocabularies.py +++ b/src/design/plone/contenttypes/tests/test_vocabularies.py @@ -1,19 +1,17 @@ # -*- coding: utf-8 -*- +from design.plone.contenttypes.controlpanels.settings import IDesignPloneSettings from design.plone.contenttypes.testing import ( DESIGN_PLONE_CONTENTTYPES_INTEGRATION_TESTING, ) from plone import api from plone.app.testing import setRoles from plone.app.testing import TEST_USER_ID +from transaction import commit from zope.component import getUtility from zope.schema.interfaces import IVocabularyFactory -from transaction import commit -from design.plone.contenttypes.controlpanels.settings import ( - IDesignPloneSettings, -) -import unittest import json +import unittest class TestControlpanelVocabularies(unittest.TestCase): diff --git a/src/design/plone/contenttypes/upgrades/draftjs_converter.py b/src/design/plone/contenttypes/upgrades/draftjs_converter.py index 0e7cdf85..b203b8c9 100644 --- a/src/design/plone/contenttypes/upgrades/draftjs_converter.py +++ b/src/design/plone/contenttypes/upgrades/draftjs_converter.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*-s +from plone import api from Products.CMFPlone.utils import safe_unicode from uuid import uuid4 -from plone import api import logging import lxml @@ -9,6 +9,7 @@ import re import requests + logger = logging.getLogger(__name__) draftjs_converter = os.environ.get("DRAFTJS_CONVERTER_URL") @@ -132,7 +133,7 @@ def _fix_blocks(block): def _conversion_tool(html): if not draftjs_converter: raise Exception( - "DRAFTJS_CONVERTER_URL environment varialbe not set. Unable to convert html to draftjs." + "DRAFTJS_CONVERTER_URL environment varialbe not set. Unable to convert html to draftjs." # noqa ) resp = requests.post(draftjs_converter, data={"html": html}) if resp.status_code != 200: diff --git a/src/design/plone/contenttypes/upgrades/upgrades.py b/src/design/plone/contenttypes/upgrades/upgrades.py index 268b66e1..a28bd47c 100644 --- a/src/design/plone/contenttypes/upgrades/upgrades.py +++ b/src/design/plone/contenttypes/upgrades/upgrades.py @@ -20,10 +20,11 @@ from zope.intid.interfaces import IIntIds from z3c.relationfield import RelationValue -import logging import json +import logging import six + logger = logging.getLogger(__name__) DEFAULT_PROFILE = "profile-design.plone.contenttypes:default" @@ -62,6 +63,7 @@ def remove_blocks_behavior(context): [x for x in portal_types[ptype].behaviors if x != "volto.blocks"] ) + def remap_fields(mapping): pc = api.portal.get_tool(name="portal_catalog") brains = pc() @@ -419,7 +421,10 @@ def to_2002(context): fixed_total = 0 for brain in api.content.find(portal_type="Persona"): item = brain.getObject() - if hasattr(item, "tipologia_persona") and item.tipologia_persona in type_mapping: # noqa + if ( + hasattr(item, "tipologia_persona") + and item.tipologia_persona in type_mapping + ): # noqa item.tipologia_persona = type_mapping[item.tipologia_persona] fixed_total += 1 commit() @@ -761,9 +766,7 @@ def to_4000(context): ruoli[lang].append(ruolo) if api.portal.get_registry_record( - "ruoli_persona", - interface=IDesignPloneSettings, - default=None + "ruoli_persona", interface=IDesignPloneSettings, default=None ): api.portal.set_registry_record( "ruoli_persona", json.dumps(ruoli), interface=IDesignPloneSettings diff --git a/src/design/plone/contenttypes/utils.py b/src/design/plone/contenttypes/utils.py index 0a9d795b..734e19b8 100644 --- a/src/design/plone/contenttypes/utils.py +++ b/src/design/plone/contenttypes/utils.py @@ -1,12 +1,10 @@ # -*- coding: utf-8 -*- -from design.plone.contenttypes.controlpanels.settings import ( - IDesignPloneSettings, -) +from design.plone.contenttypes.controlpanels.settings import IDesignPloneSettings from plone import api from uuid import uuid4 -import logging import json +import logging import six diff --git a/src/design/plone/contenttypes/vocabularies/tags_vocabulary.py b/src/design/plone/contenttypes/vocabularies/tags_vocabulary.py index a4be0110..4df59b1a 100644 --- a/src/design/plone/contenttypes/vocabularies/tags_vocabulary.py +++ b/src/design/plone/contenttypes/vocabularies/tags_vocabulary.py @@ -22,27 +22,19 @@ def __call__(self, context): # Just an example list of content for our vocabulary, # this can be any static or dynamic data, a catalog result for example. items = [ - VocabItem( - "accesso_all_informazione", - _("Accesso all'informazione") - ), + VocabItem("accesso_all_informazione", _("Accesso all'informazione")), VocabItem("acqua", _("Acqua")), VocabItem("agricoltura", _("Agricoltura")), VocabItem("animale_domestico", _("Animale domestico")), VocabItem("aria", _("Aria")), - VocabItem( - "assistenza_agli_anziani", _("Assistenza agli invalidi") - ), + VocabItem("assistenza_agli_anziani", _("Assistenza agli invalidi")), VocabItem("assistenza_sociale", _("Assistenza sociale")), VocabItem("associazioni", _("Associazioni")), VocabItem("bilancio", _("Bilancio")), VocabItem("commercio_all_ingresso", _("Commercio all'ingrosso")), VocabItem("commercio_al_minuto", _("Commercio al minuto")), VocabItem("commercio_ambulante", _("Commercio ambulante")), - VocabItem( - "comunicazione_istituzionale", - _("Comunicazione istituzionale") - ), + VocabItem("comunicazione_istituzionale", _("Comunicazione istituzionale")), VocabItem("comunicazione_politica", _("Comunicazione politica")), VocabItem("concordi", _("Concorsi")), VocabItem("covid_19", _("Covid - 19")), @@ -50,9 +42,7 @@ def __call__(self, context): VocabItem("energie_rinnovabili", _("Energie rinnovabili")), VocabItem("estero", _("Estero")), VocabItem("foreste", _("Foreste")), - VocabItem( - "formazione_professionale", _("Formazione professionale") - ), + VocabItem("formazione_professionale", _("Formazione professionale")), VocabItem("gemellaggi", _("Gemellaggi")), VocabItem("gestione_rifiuti", _("Gestione rifiuti")), VocabItem("giustizia", _("Giustizia")), @@ -87,9 +77,7 @@ def __call__(self, context): VocabItem("sviluppo_sostenibile", _("Sviluppo sostenibile")), VocabItem("tassa_sui_servizi", _("Tassa sui servizi")), VocabItem("tempo_libero", _("Tempo libero")), - VocabItem( - "trasparenza_amministrativa", _("Trasparenza amministrativa") - ), + VocabItem("trasparenza_amministrativa", _("Trasparenza amministrativa")), VocabItem("trasporto_pubblico", _("Trasporto pubblico")), VocabItem("turismo", _("Turismo")), VocabItem("urbanizzazione", _("Urbanizzazione")), From 88b512828564974df89bd6a92469926d1e44896c Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Fri, 30 Dec 2022 15:05:43 +0100 Subject: [PATCH 024/487] [doc] updated versions --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 27cebc16..a5e6869a 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="5.0.4.dev0", + version="6.0.0.dev0", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 5955dfba082a70814c786fed2ea17e9a5d95c388 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Fri, 30 Dec 2022 15:27:27 +0100 Subject: [PATCH 025/487] [dev] add pyroma to pre-commit --- .pre-commit-config.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 2d36b143..f2ff3233 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -49,3 +49,7 @@ repos: hooks: - id: zpretty name: zpretty + - repo: https://github.com/regebro/pyroma + rev: "3.2" + hooks: + - id: pyroma From 7db0eaead9a881347ddf6d304bc8be7b8f298ac1 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Fri, 30 Dec 2022 15:32:51 +0100 Subject: [PATCH 026/487] [doc] updated README --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 9bf12b85..051edb95 100644 --- a/README.md +++ b/README.md @@ -417,6 +417,11 @@ Per aggiornare le traduzioni, basta usare lo script `update_locales` dentro alla # Contribuisci +Questo pacchetto usa pre-commit per cui prima di iniziare a sviluppare: +- installa pre-commit come dipendenza del tuo ambiente di lavoro +- fai *pre-commit install* per installare gli hook + + - Issue Tracker: https://github.com/redturtle/design.plone.contenttypes/issues - Codice sorgente: https://github.com/redturtle/design.plone.contenttypes From 8c95a55c2e314a4695d440220ac750c244ca2df3 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Wed, 4 Jan 2023 11:10:56 +0100 Subject: [PATCH 027/487] merge with pnrr --- .gitignore | 1 + .../behaviors/contatti_20230104105939.py | 220 ++++ .../behaviors/contatti_20230104110153.py | 222 ++++ .../behaviors/contatti_20230104110322.py | 212 ++++ .../unita_organizzativa_20230104105939.py | 220 ++++ .../unita_organizzativa_20230104110033.py | 213 ++++ .../unita_organizzativa_20230104110045.py | 212 ++++ .../unita_organizzativa_20230104110116.py | 211 +++ .../default/types/Persona_20230104105939.xml | 115 ++ .../default/types/Persona_20230104110533.xml | 107 ++ .../default/types/Servizio_20230104105939.xml | 120 ++ .../default/types/Servizio_20230104110559.xml | 110 ++ .../profiles/default/types_20230104105939.xml | 59 + .../profiles/default/types_20230104110435.xml | 51 + .../profiles/default/types_20230104110443.xml | 51 + .../profiles/default/types_20230104110501.xml | 49 + .../restapi/types/adapters_20230104105939.py | 109 ++ .../restapi/types/adapters_20230104110615.py | 104 ++ .../restapi/types/adapters_20230104110625.py | 102 ++ .../restapi/types/adapters_20230104110639.py | 100 ++ .../upgrades/upgrades_20230104105158.py | 1124 ++++++++++++++++ .../upgrades/upgrades_20230104110844.py | 1130 +++++++++++++++++ .../upgrades/upgrades_20230104110851.py | 1129 ++++++++++++++++ .../upgrades/upgrades_20230104110901.py | 1127 ++++++++++++++++ .../upgrades/upgrades_20230104110903.py | 1126 ++++++++++++++++ .../contenttypes/restapi/types/adapters.py | 4 - .../plone/contenttypes/upgrades/upgrades.py | 12 +- 27 files changed, 8225 insertions(+), 15 deletions(-) create mode 100644 .history/src/design/plone/contenttypes/behaviors/contatti_20230104105939.py create mode 100644 .history/src/design/plone/contenttypes/behaviors/contatti_20230104110153.py create mode 100644 .history/src/design/plone/contenttypes/behaviors/contatti_20230104110322.py create mode 100644 .history/src/design/plone/contenttypes/interfaces/unita_organizzativa_20230104105939.py create mode 100644 .history/src/design/plone/contenttypes/interfaces/unita_organizzativa_20230104110033.py create mode 100644 .history/src/design/plone/contenttypes/interfaces/unita_organizzativa_20230104110045.py create mode 100644 .history/src/design/plone/contenttypes/interfaces/unita_organizzativa_20230104110116.py create mode 100644 .history/src/design/plone/contenttypes/profiles/default/types/Persona_20230104105939.xml create mode 100644 .history/src/design/plone/contenttypes/profiles/default/types/Persona_20230104110533.xml create mode 100644 .history/src/design/plone/contenttypes/profiles/default/types/Servizio_20230104105939.xml create mode 100644 .history/src/design/plone/contenttypes/profiles/default/types/Servizio_20230104110559.xml create mode 100644 .history/src/design/plone/contenttypes/profiles/default/types_20230104105939.xml create mode 100644 .history/src/design/plone/contenttypes/profiles/default/types_20230104110435.xml create mode 100644 .history/src/design/plone/contenttypes/profiles/default/types_20230104110443.xml create mode 100644 .history/src/design/plone/contenttypes/profiles/default/types_20230104110501.xml create mode 100644 .history/src/design/plone/contenttypes/restapi/types/adapters_20230104105939.py create mode 100644 .history/src/design/plone/contenttypes/restapi/types/adapters_20230104110615.py create mode 100644 .history/src/design/plone/contenttypes/restapi/types/adapters_20230104110625.py create mode 100644 .history/src/design/plone/contenttypes/restapi/types/adapters_20230104110639.py create mode 100644 .history/src/design/plone/contenttypes/upgrades/upgrades_20230104105158.py create mode 100644 .history/src/design/plone/contenttypes/upgrades/upgrades_20230104110844.py create mode 100644 .history/src/design/plone/contenttypes/upgrades/upgrades_20230104110851.py create mode 100644 .history/src/design/plone/contenttypes/upgrades/upgrades_20230104110901.py create mode 100644 .history/src/design/plone/contenttypes/upgrades/upgrades_20230104110903.py diff --git a/.gitignore b/.gitignore index 15f86be8..1772f39c 100644 --- a/.gitignore +++ b/.gitignore @@ -44,3 +44,4 @@ reports/ !src/design pyvenv.cfg .Python +.history \ No newline at end of file diff --git a/.history/src/design/plone/contenttypes/behaviors/contatti_20230104105939.py b/.history/src/design/plone/contenttypes/behaviors/contatti_20230104105939.py new file mode 100644 index 00000000..475c051b --- /dev/null +++ b/.history/src/design/plone/contenttypes/behaviors/contatti_20230104105939.py @@ -0,0 +1,220 @@ +# -*- coding: utf-8 -*- +from collective.venue.interfaces import IVenue +<<<<<<< HEAD +from collective.volto.blocksfield.field import BlocksField +from design.plone.contenttypes import _ +from design.plone.contenttypes.interfaces.unita_organizzativa import IUnitaOrganizzativa +from plone.app.dexterity import textindexer +======= +from design.plone.contenttypes import _ +>>>>>>> pnrr +from plone.autoform.interfaces import IFormFieldProvider +from plone.supermodel import model +from z3c.relationfield.schema import RelationChoice +from z3c.relationfield.schema import RelationList +from zope.component import adapter +<<<<<<< HEAD +from zope.interface import implementer +from zope.interface import provider +======= +from plone.app.z3cform.widget import RelatedItemsFieldWidget +from plone.autoform import directives as form +from zope.interface import provider, implementer +from design.plone.contenttypes.interfaces.unita_organizzativa import IUnitaOrganizzativa +from design.plone.contenttypes.interfaces.persona import IPersona +from design.plone.contenttypes.interfaces.servizio import IServizio +>>>>>>> pnrr + + +@provider(IFormFieldProvider) +class IContattiUnitaOrganizzativa(model.Schema): + contact_info = RelationList( + title=_( + "contact_info_label", + default="Informazioni di contatto", + ), + description=_( + "contact_info_help", + default="Contatti dell'unità organizzativa.", + ), + required=True, + default=[], + value_type=RelationChoice( + title=_("Informazioni di contatto"), + vocabulary="plone.app.vocabularies.Catalog", + ), + ) + form.widget( + "contact_info", + RelatedItemsFieldWidget, + vocabulary="plone.app.vocabularies.Catalog", + pattern_options={"maximumSelectionSize": 10, "selectableTypes": ["PuntoDiContatto"]}, + ) + + +@provider(IFormFieldProvider) +class IContattiPersona(model.Schema): + contact_info = RelationList( + title=_( + "contact_info_label", + default="Punti di contatto", + ), + description=_( + "contact_info_help", + default="Punti di contatto della persona.", + ), + required=True, + default=[], + value_type=RelationChoice( + title=_("Punti di contatto"), + vocabulary="plone.app.vocabularies.Catalog", + ), + ) + + form.widget( + "contact_info", + RelatedItemsFieldWidget, + vocabulary="plone.app.vocabularies.Catalog", + pattern_options={"maximumSelectionSize": 10, "selectableTypes": ["PuntoDiContatto"]}, + ) + model.fieldset( + "contatti", + label=_("contatti_label", default="Contatti"), + fields=["contact_info"], + ) + + +@provider(IFormFieldProvider) +class IContattiServizio(model.Schema): + contact_info = RelationList( + title=_( + "contact_info_label", + default="Contatti", + ), + description=_( + "contact_info_help", + default="I contatti per il servizio.", + ), + required=True, + default=[], + value_type=RelationChoice( + title=_("Contatti"), + vocabulary="plone.app.vocabularies.Catalog", + ), + ) + form.widget( + "contact_info", + RelatedItemsFieldWidget, + vocabulary="plone.app.vocabularies.Catalog", + pattern_options={"maximumSelectionSize": 10, "selectableTypes": ["PuntoDiContatto"]}, + ) + model.fieldset( + "contatti", + label=_("contatti_label", default="Contatti"), + fields=["contact_info"], + ) + + +@provider(IFormFieldProvider) +class IContattiVenue(model.Schema): + contact_info = RelationList( + title=_( + "contact_info_label", + default="Punti di contatto", + ), + description=_( + "contact_info_help", + default="Telefono, mail o altri punti di contatto.", + ), + required=True, + default=[], + value_type=RelationChoice( + title=_("Punti di contatto"), + vocabulary="plone.app.vocabularies.Catalog", + ), + ) + form.widget( + "contact_info", + RelatedItemsFieldWidget, + vocabulary="plone.app.vocabularies.Catalog", + pattern_options={"maximumSelectionSize": 10, "selectableTypes": ["PuntoDiContatto"]}, + ) + model.fieldset( + "contatti", + label=_("contatti_label", default="Contatti"), + fields=["contact_info"], + ) + + +@provider(IFormFieldProvider) +class IContattiEvent(model.Schema): + contact_info = RelationList( + title=_( + "contact_info_label", + default="Punti di contatto", + ), + description=_( + "contact_info_help", + default="Relazione con i punti di contatto dell'evento.", + ), + required=True, + default=[], + value_type=RelationChoice( + title=_("Punti di contatto"), + vocabulary="plone.app.vocabularies.Catalog", + ), + ) + form.widget( + "contact_info", + RelatedItemsFieldWidget, + vocabulary="plone.app.vocabularies.Catalog", + pattern_options={"maximumSelectionSize": 10, "selectableTypes": ["PuntoDiContatto"]}, + ) + model.fieldset( + "contatti", + label=_("contatti_label", default="Contatti"), + fields=["contact_info"], + ) + +@implementer(IContattiEvent) +@adapter(IContattiEvent) +class ContattiEvent(object): + """ """ + + def __init__(self, context): + self.context = context + + +@implementer(IContattiPersona) +@adapter(IPersona) +class ContattiPersona(object): + """ """ + + def __init__(self, context): + self.context = context + +@implementer(IContattiServizio) +@adapter(IServizio) +class ContattiServizio(object): + """ """ + + def __init__(self, context): + self.context = context + + +@implementer(IContattiUnitaOrganizzativa) +@adapter(IUnitaOrganizzativa) +class ContattiUnitaOrganizzativa(object): + """ """ + + def __init__(self, context): + self.context = context + + +@implementer(IContattiVenue) +@adapter(IVenue) +class ContattiVenue(object): + """ """ + + def __init__(self, context): + self.context = context diff --git a/.history/src/design/plone/contenttypes/behaviors/contatti_20230104110153.py b/.history/src/design/plone/contenttypes/behaviors/contatti_20230104110153.py new file mode 100644 index 00000000..dc59d18d --- /dev/null +++ b/.history/src/design/plone/contenttypes/behaviors/contatti_20230104110153.py @@ -0,0 +1,222 @@ +# -*- coding: utf-8 -*- +from collective.venue.interfaces import IVenue +<<<<<<< HEAD +from collective.volto.blocksfield.field import BlocksField +from design.plone.contenttypes import _ +from design.plone.contenttypes.interfaces.unita_organizzativa import IUnitaOrganizzativa +from plone.app.dexterity import textindexer +======= +from design.plone.contenttypes import _ +>>>>>>> pnrr +from plone.autoform.interfaces import IFormFieldProvider +from plone.supermodel import model +from z3c.relationfield.schema import RelationChoice +from z3c.relationfield.schema import RelationList +from zope.component import adapter +<<<<<<< HEAD +from zope.interface import implementer +from zope.interface import provider +======= +from plone.app.z3cform.widget import RelatedItemsFieldWidget +from plone.autoform import directives as form +from zope.interface import provider, implementer +from design.plone.contenttypes.interfaces.unita_organizzativa import IUnitaOrganizzativa +from design.plone.contenttypes.interfaces.persona import IPersona +from design.plone.contenttypes.interfaces.servizio import IServizio +>>>>>>> pnrr + + +@provider(IFormFieldProvider) +class IContattiUnitaOrganizzativa(model.Schema): + contact_info = RelationList( + title=_( + "contact_info_label", + default="Informazioni di contatto", + ), + description=_( + "contact_info_help", + default="Contatti dell'unità organizzativa.", + ), + required=True, + default=[], + value_type=RelationChoice( + title=_("Informazioni di contatto"), + vocabulary="plone.app.vocabularies.Catalog", + ), + ) + form.widget( + "contact_info", + RelatedItemsFieldWidget, + vocabulary="plone.app.vocabularies.Catalog", + pattern_options={"maximumSelectionSize": 10, "selectableTypes": ["PuntoDiContatto"]}, + ) + + +@provider(IFormFieldProvider) +class IContattiPersona(model.Schema): + contact_info = RelationList( + title=_( + "contact_info_label", + default="Punti di contatto", + ), + description=_( + "contact_info_help", + default="Punti di contatto della persona.", + ), + required=True, + default=[], + value_type=RelationChoice( + title=_("Punti di contatto"), + vocabulary="plone.app.vocabularies.Catalog", + ), + ) + + form.widget( + "contact_info", + RelatedItemsFieldWidget, + vocabulary="plone.app.vocabularies.Catalog", + pattern_options={"maximumSelectionSize": 10, "selectableTypes": ["PuntoDiContatto"]}, + ) + model.fieldset( + "contatti", + label=_("contatti_label", default="Contatti"), + fields=["contact_info"], + ) + + +@provider(IFormFieldProvider) +class IContattiServizio(model.Schema): + contact_info = RelationList( + title=_( + "contact_info_label", + default="Contatti", + ), + description=_( + "contact_info_help", + default="I contatti per il servizio.", + ), + required=True, + default=[], + value_type=RelationChoice( + title=_("Contatti"), + vocabulary="plone.app.vocabularies.Catalog", + ), + ) + form.widget( + "contact_info", + RelatedItemsFieldWidget, + vocabulary="plone.app.vocabularies.Catalog", + pattern_options={"maximumSelectionSize": 10, "selectableTypes": ["PuntoDiContatto"]}, + ) + model.fieldset( + "contatti", + label=_("contatti_label", default="Contatti"), + fields=["contact_info"], + ) + + +@provider(IFormFieldProvider) +class IContattiVenue(model.Schema): + contact_info = RelationList( + title=_( + "contact_info_label", + default="Punti di contatto", + ), + description=_( + "contact_info_help", + default="Telefono, mail o altri punti di contatto.", + ), + required=True, + default=[], + value_type=RelationChoice( + title=_("Punti di contatto"), + vocabulary="plone.app.vocabularies.Catalog", + ), + ) + form.widget( + "contact_info", + RelatedItemsFieldWidget, + vocabulary="plone.app.vocabularies.Catalog", + pattern_options={"maximumSelectionSize": 10, "selectableTypes": ["PuntoDiContatto"]}, + ) + model.fieldset( + "contatti", + label=_("contatti_label", default="Contatti"), + fields=["contact_info"], + ) + + +@provider(IFormFieldProvider) +class IContattiEvent(model.Schema): + contact_info = RelationList( + title=_( + "contact_info_label", + default="Punti di contatto", + ), + description=_( + "contact_info_help", + default="Relazione con i punti di contatto dell'evento.", + ), + required=True, + default=[], + value_type=RelationChoice( + title=_("Punti di contatto"), + vocabulary="plone.app.vocabularies.Catalog", + ), + ) + form.widget( + "contact_info", + RelatedItemsFieldWidget, + vocabulary="plone.app.vocabularies.Catalog", + pattern_options={"maximumSelectionSize": 10, "selectableTypes": ["PuntoDiContatto"]}, + ) + model.fieldset( + "contatti", + label=_("contatti_label", default="Contatti"), + fields=["contact_info"], + ) + + +@implementer(IContattiEvent) +@adapter(IContattiEvent) +class ContattiEvent(object): + """ """ + + def __init__(self, context): + self.context = context + + +@implementer(IContattiPersona) +@adapter(IPersona) +class ContattiPersona(object): + """ """ + + def __init__(self, context): + self.context = context + + +@implementer(IContattiServizio) +@adapter(IServizio) +class ContattiServizio(object): + """ """ + + def __init__(self, context): + self.context = context + + +@implementer(IContattiUnitaOrganizzativa) +@adapter(IUnitaOrganizzativa) +class ContattiUnitaOrganizzativa(object): + """ """ + + def __init__(self, context): + self.context = context + + +@implementer(IContattiVenue) +@adapter(IVenue) +class ContattiVenue(object): + """ """ + + def __init__(self, context): + self.context = context diff --git a/.history/src/design/plone/contenttypes/behaviors/contatti_20230104110322.py b/.history/src/design/plone/contenttypes/behaviors/contatti_20230104110322.py new file mode 100644 index 00000000..0879aeed --- /dev/null +++ b/.history/src/design/plone/contenttypes/behaviors/contatti_20230104110322.py @@ -0,0 +1,212 @@ +# -*- coding: utf-8 -*- +from collective.venue.interfaces import IVenue +from collective.volto.blocksfield.field import BlocksField +from design.plone.contenttypes import _ +from plone.app.dexterity import textindexer +from plone.autoform.interfaces import IFormFieldProvider +from plone.supermodel import model +from z3c.relationfield.schema import RelationChoice +from z3c.relationfield.schema import RelationList +from zope.component import adapter +from plone.app.z3cform.widget import RelatedItemsFieldWidget +from plone.autoform import directives as form +from zope.interface import provider, implementer +from design.plone.contenttypes.interfaces.unita_organizzativa import IUnitaOrganizzativa +from design.plone.contenttypes.interfaces.persona import IPersona +from design.plone.contenttypes.interfaces.servizio import IServizio + + +@provider(IFormFieldProvider) +class IContattiUnitaOrganizzativa(model.Schema): + contact_info = RelationList( + title=_( + "contact_info_label", + default="Informazioni di contatto", + ), + description=_( + "contact_info_help", + default="Contatti dell'unità organizzativa.", + ), + required=True, + default=[], + value_type=RelationChoice( + title=_("Informazioni di contatto"), + vocabulary="plone.app.vocabularies.Catalog", + ), + ) + form.widget( + "contact_info", + RelatedItemsFieldWidget, + vocabulary="plone.app.vocabularies.Catalog", + pattern_options={"maximumSelectionSize": 10, "selectableTypes": ["PuntoDiContatto"]}, + ) + + +@provider(IFormFieldProvider) +class IContattiPersona(model.Schema): + contact_info = RelationList( + title=_( + "contact_info_label", + default="Punti di contatto", + ), + description=_( + "contact_info_help", + default="Punti di contatto della persona.", + ), + required=True, + default=[], + value_type=RelationChoice( + title=_("Punti di contatto"), + vocabulary="plone.app.vocabularies.Catalog", + ), + ) + + form.widget( + "contact_info", + RelatedItemsFieldWidget, + vocabulary="plone.app.vocabularies.Catalog", + pattern_options={"maximumSelectionSize": 10, "selectableTypes": ["PuntoDiContatto"]}, + ) + model.fieldset( + "contatti", + label=_("contatti_label", default="Contatti"), + fields=["contact_info"], + ) + + +@provider(IFormFieldProvider) +class IContattiServizio(model.Schema): + contact_info = RelationList( + title=_( + "contact_info_label", + default="Contatti", + ), + description=_( + "contact_info_help", + default="I contatti per il servizio.", + ), + required=True, + default=[], + value_type=RelationChoice( + title=_("Contatti"), + vocabulary="plone.app.vocabularies.Catalog", + ), + ) + form.widget( + "contact_info", + RelatedItemsFieldWidget, + vocabulary="plone.app.vocabularies.Catalog", + pattern_options={"maximumSelectionSize": 10, "selectableTypes": ["PuntoDiContatto"]}, + ) + model.fieldset( + "contatti", + label=_("contatti_label", default="Contatti"), + fields=["contact_info"], + ) + + +@provider(IFormFieldProvider) +class IContattiVenue(model.Schema): + contact_info = RelationList( + title=_( + "contact_info_label", + default="Punti di contatto", + ), + description=_( + "contact_info_help", + default="Telefono, mail o altri punti di contatto.", + ), + required=True, + default=[], + value_type=RelationChoice( + title=_("Punti di contatto"), + vocabulary="plone.app.vocabularies.Catalog", + ), + ) + form.widget( + "contact_info", + RelatedItemsFieldWidget, + vocabulary="plone.app.vocabularies.Catalog", + pattern_options={"maximumSelectionSize": 10, "selectableTypes": ["PuntoDiContatto"]}, + ) + model.fieldset( + "contatti", + label=_("contatti_label", default="Contatti"), + fields=["contact_info"], + ) + + +@provider(IFormFieldProvider) +class IContattiEvent(model.Schema): + contact_info = RelationList( + title=_( + "contact_info_label", + default="Punti di contatto", + ), + description=_( + "contact_info_help", + default="Relazione con i punti di contatto dell'evento.", + ), + required=True, + default=[], + value_type=RelationChoice( + title=_("Punti di contatto"), + vocabulary="plone.app.vocabularies.Catalog", + ), + ) + form.widget( + "contact_info", + RelatedItemsFieldWidget, + vocabulary="plone.app.vocabularies.Catalog", + pattern_options={"maximumSelectionSize": 10, "selectableTypes": ["PuntoDiContatto"]}, + ) + model.fieldset( + "contatti", + label=_("contatti_label", default="Contatti"), + fields=["contact_info"], + ) + + +@implementer(IContattiEvent) +@adapter(IContattiEvent) +class ContattiEvent(object): + """ """ + + def __init__(self, context): + self.context = context + + +@implementer(IContattiPersona) +@adapter(IPersona) +class ContattiPersona(object): + """ """ + + def __init__(self, context): + self.context = context + + +@implementer(IContattiServizio) +@adapter(IServizio) +class ContattiServizio(object): + """ """ + + def __init__(self, context): + self.context = context + + +@implementer(IContattiUnitaOrganizzativa) +@adapter(IUnitaOrganizzativa) +class ContattiUnitaOrganizzativa(object): + """ """ + + def __init__(self, context): + self.context = context + + +@implementer(IContattiVenue) +@adapter(IVenue) +class ContattiVenue(object): + """ """ + + def __init__(self, context): + self.context = context diff --git a/.history/src/design/plone/contenttypes/interfaces/unita_organizzativa_20230104105939.py b/.history/src/design/plone/contenttypes/interfaces/unita_organizzativa_20230104105939.py new file mode 100644 index 00000000..92166416 --- /dev/null +++ b/.history/src/design/plone/contenttypes/interfaces/unita_organizzativa_20230104105939.py @@ -0,0 +1,220 @@ +# -*- coding: utf-8 -*- +from collective.volto.blocksfield.field import BlocksField +from design.plone.contenttypes import _ +from design.plone.contenttypes.interfaces import IDesignPloneContentType +from plone.app.dexterity import textindexer +from plone.app.z3cform.widget import RelatedItemsFieldWidget +from plone.autoform import directives as form +from plone.supermodel import model +from z3c.relationfield.schema import RelationChoice +from z3c.relationfield.schema import RelationList + + +# TODO: migration script for these commented fields towards PDC +# contact_info +# Probabilmente non possibile trattandosi di un campo a blocchi +# preferirei si arrangiassero le redazioni. Altrimenti si defaulta +# ad un tipo a caso + tutto il testo e poi si arrangiano comunque +class IUnitaOrganizzativa(model.Schema, IDesignPloneContentType): + """Marker interface for content type UnitaOrganizzativa""" + + competenze = BlocksField( + title=_("uo_competenze_label", default="Competenze"), + description=_( + "uo_competenze_help", + default="Descrizione dei compiti assegnati alla struttura.", + ), + required=False, + ) + + legami_con_altre_strutture = RelationList( + title=_( + "legami_altre_strutture_label", default="Servizi o uffici di riferimento" + ), + default=[], + description=_( + "legami_con_altre_strutture_help", + default="Selezionare la lista di strutture e/o uffici collegati" + " a questa unità organizzativa.", + ), + value_type=RelationChoice( + title=_("Struttura"), vocabulary="plone.app.vocabularies.Catalog" + ), + required=False, + ) + + responsabile = RelationList( + title=_("responsabile_label", default="Responsabile"), + value_type=RelationChoice( + title=_("Responsabile"), + vocabulary="plone.app.vocabularies.Catalog", + ), + description=_( + "responsabile_help", + default="Selezionare il/i responsabile/i della struttura.", + ), + default=[], + required=False, + ) + + assessore_riferimento = RelationList( + title="Assessore di riferimento", + # vocabolario di riferimento sara' dinamico con i content type + # persona presenti all'interno della macro Amministrazione" + value_type=RelationChoice( + title=_("Assessore di riferimento"), + vocabulary="plone.app.vocabularies.Catalog", + ), + description=_( + "assessore_riferimento_help", + default="Inserire l'assessore di riferimento della struttura," + " se esiste.", + ), + required=False, + default=[], + ) + + # vocabolario di riferimento sara' dinamico con i content type persona + persone_struttura = RelationList( + title=_( + "persone_struttura_label", default="Persone che compongono la struttura" + ), + default=[], + value_type=RelationChoice( + title=_("Persone della struttura"), + vocabulary="plone.app.vocabularies.Catalog", + ), + description=_( + "persone_struttura_help", + default="Seleziona la lista delle persone che compongono" " la struttura.", + ), + required=False, + ) + + sede = RelationList( + title=_("sede_label", default="Sede principale"), + default=[], + description=_( + "sede_help", + default="Seleziona il Luogo in cui questa struttura ha sede. " + "Se non è presente un contenuto di tipo Luogo a cui far " + "riferimento, puoi compilare i campi seguenti. Se selezioni un " + "Luogo, puoi usare comunque i campi seguenti per sovrascrivere " + "alcune informazioni.", + ), + value_type=RelationChoice( + title=_("Sede"), vocabulary="plone.app.vocabularies.Catalog" + ), + required=False, + ) + + sedi_secondarie = RelationList( + title=_("sedi_secondarie_label", default="Sedi secondarie"), + default=[], + description=_( + "sedi_secondarie_help", + default="Seleziona una lista di eventuali contenuti di tipo Luogo" + " che sono sedi secondarie di questa struttura. " + "Per queste sedi non sarà possibile sovrascrivere i dati. " + "Nel caso servano informazioni diverse, è possibile usare il campo" + " sottostante.", + ), + value_type=RelationChoice( + title=_("Sede"), vocabulary="plone.app.vocabularies.Catalog" + ), + required=False, + ) + + + #  custom widgets + form.widget( + "persone_struttura", + RelatedItemsFieldWidget, + vocabulary="plone.app.vocabularies.Catalog", + pattern_options={"selectableTypes": ["Persona"], "maximumSelectionSize": 50}, + ) + form.widget( + "legami_con_altre_strutture", + RelatedItemsFieldWidget, + vocabulary="plone.app.vocabularies.Catalog", + pattern_options={ + "maximumSelectionSize": 10, + "selectableTypes": ["UnitaOrganizzativa"], + }, + ) + form.widget( + "responsabile", + RelatedItemsFieldWidget, + vocabulary="plone.app.vocabularies.Catalog", + pattern_options={ + "maximumSelectionSize": 1, + "selectableTypes": ["Persona"], + # "basePath": "/amministrazione", + }, + ) + form.widget( + "assessore_riferimento", + RelatedItemsFieldWidget, + vocabulary="plone.app.vocabularies.Catalog", + pattern_options={ + "maximumSelectionSize": 1, + "selectableTypes": ["Persona"], + # "basePath": "/amministrazione", + }, + ) + form.widget( + "sede", + RelatedItemsFieldWidget, + vocabulary="plone.app.vocabularies.Catalog", + pattern_options={"maximumSelectionSize": 1, "selectableTypes": ["Venue"]}, + ) + form.widget( + "sedi_secondarie", + RelatedItemsFieldWidget, + vocabulary="plone.app.vocabularies.Catalog", + pattern_options={ + "maximumSelectionSize": 10, + "selectableTypes": ["Venue"], + # "basePath": "/servizi", + }, + ) + + # custom fieldsets and order + model.fieldset( + "cosa_fa", + label=_("cosa_fa_label", default="Cosa fa"), + fields=["competenze"], + ) + model.fieldset( + "struttura", + label=_("struttura_label", default="Struttura"), + fields=[ + "legami_con_altre_strutture", + "responsabile", + "assessore_riferimento", + ], + ) + model.fieldset( + "persone", + label=_("persone_label", default="Persone"), + fields=["persone_struttura"], + ) + model.fieldset( + "contatti", + label=_("contatti_label", default="Contatti"), + fields=["sede", "sedi_secondarie"], + ) +<<<<<<< HEAD + form.order_after( + sedi_secondarie="IContattiUnitaOrganizzativa.orario_pubblico" + ) # noqa + form.order_after(contact_info="sedi_secondarie") +======= + form.order_after(sedi_secondarie="IContattiUnitaOrganizzativa.orario_pubblico") + # form.order_after(contact_info="sedi_secondarie") +>>>>>>> pnrr + + # SearchableText indexers + textindexer.searchable("competenze") + textindexer.searchable("assessore_riferimento") + textindexer.searchable("responsabile") diff --git a/.history/src/design/plone/contenttypes/interfaces/unita_organizzativa_20230104110033.py b/.history/src/design/plone/contenttypes/interfaces/unita_organizzativa_20230104110033.py new file mode 100644 index 00000000..99b47c74 --- /dev/null +++ b/.history/src/design/plone/contenttypes/interfaces/unita_organizzativa_20230104110033.py @@ -0,0 +1,213 @@ +# -*- coding: utf-8 -*- +from collective.volto.blocksfield.field import BlocksField +from design.plone.contenttypes import _ +from design.plone.contenttypes.interfaces import IDesignPloneContentType +from plone.app.dexterity import textindexer +from plone.app.z3cform.widget import RelatedItemsFieldWidget +from plone.autoform import directives as form +from plone.supermodel import model +from z3c.relationfield.schema import RelationChoice +from z3c.relationfield.schema import RelationList + + +# TODO: migration script for these commented fields towards PDC +# contact_info +# Probabilmente non possibile trattandosi di un campo a blocchi +# preferirei si arrangiassero le redazioni. Altrimenti si defaulta +# ad un tipo a caso + tutto il testo e poi si arrangiano comunque +class IUnitaOrganizzativa(model.Schema, IDesignPloneContentType): + """Marker interface for content type UnitaOrganizzativa""" + + competenze = BlocksField( + title=_("uo_competenze_label", default="Competenze"), + description=_( + "uo_competenze_help", + default="Descrizione dei compiti assegnati alla struttura.", + ), + required=False, + ) + + legami_con_altre_strutture = RelationList( + title=_( + "legami_altre_strutture_label", default="Servizi o uffici di riferimento" + ), + default=[], + description=_( + "legami_con_altre_strutture_help", + default="Selezionare la lista di strutture e/o uffici collegati" + " a questa unità organizzativa.", + ), + value_type=RelationChoice( + title=_("Struttura"), vocabulary="plone.app.vocabularies.Catalog" + ), + required=False, + ) + + responsabile = RelationList( + title=_("responsabile_label", default="Responsabile"), + value_type=RelationChoice( + title=_("Responsabile"), + vocabulary="plone.app.vocabularies.Catalog", + ), + description=_( + "responsabile_help", + default="Selezionare il/i responsabile/i della struttura.", + ), + default=[], + required=False, + ) + + assessore_riferimento = RelationList( + title="Assessore di riferimento", + # vocabolario di riferimento sara' dinamico con i content type + # persona presenti all'interno della macro Amministrazione" + value_type=RelationChoice( + title=_("Assessore di riferimento"), + vocabulary="plone.app.vocabularies.Catalog", + ), + description=_( + "assessore_riferimento_help", + default="Inserire l'assessore di riferimento della struttura," + " se esiste.", + ), + required=False, + default=[], + ) + + # vocabolario di riferimento sara' dinamico con i content type persona + persone_struttura = RelationList( + title=_( + "persone_struttura_label", default="Persone che compongono la struttura" + ), + default=[], + value_type=RelationChoice( + title=_("Persone della struttura"), + vocabulary="plone.app.vocabularies.Catalog", + ), + description=_( + "persone_struttura_help", + default="Seleziona la lista delle persone che compongono" " la struttura.", + ), + required=False, + ) + + sede = RelationList( + title=_("sede_label", default="Sede principale"), + default=[], + description=_( + "sede_help", + default="Seleziona il Luogo in cui questa struttura ha sede. " + "Se non è presente un contenuto di tipo Luogo a cui far " + "riferimento, puoi compilare i campi seguenti. Se selezioni un " + "Luogo, puoi usare comunque i campi seguenti per sovrascrivere " + "alcune informazioni.", + ), + value_type=RelationChoice( + title=_("Sede"), vocabulary="plone.app.vocabularies.Catalog" + ), + required=False, + ) + + sedi_secondarie = RelationList( + title=_("sedi_secondarie_label", default="Sedi secondarie"), + default=[], + description=_( + "sedi_secondarie_help", + default="Seleziona una lista di eventuali contenuti di tipo Luogo" + " che sono sedi secondarie di questa struttura. " + "Per queste sedi non sarà possibile sovrascrivere i dati. " + "Nel caso servano informazioni diverse, è possibile usare il campo" + " sottostante.", + ), + value_type=RelationChoice( + title=_("Sede"), vocabulary="plone.app.vocabularies.Catalog" + ), + required=False, + ) + + + # custom widgets + form.widget( + "persone_struttura", + RelatedItemsFieldWidget, + vocabulary="plone.app.vocabularies.Catalog", + pattern_options={"selectableTypes": ["Persona"], "maximumSelectionSize": 50}, + ) + form.widget( + "legami_con_altre_strutture", + RelatedItemsFieldWidget, + vocabulary="plone.app.vocabularies.Catalog", + pattern_options={ + "maximumSelectionSize": 10, + "selectableTypes": ["UnitaOrganizzativa"], + }, + ) + form.widget( + "responsabile", + RelatedItemsFieldWidget, + vocabulary="plone.app.vocabularies.Catalog", + pattern_options={ + "maximumSelectionSize": 1, + "selectableTypes": ["Persona"], + # "basePath": "/amministrazione", + }, + ) + form.widget( + "assessore_riferimento", + RelatedItemsFieldWidget, + vocabulary="plone.app.vocabularies.Catalog", + pattern_options={ + "maximumSelectionSize": 1, + "selectableTypes": ["Persona"], + # "basePath": "/amministrazione", + }, + ) + form.widget( + "sede", + RelatedItemsFieldWidget, + vocabulary="plone.app.vocabularies.Catalog", + pattern_options={"maximumSelectionSize": 1, "selectableTypes": ["Venue"]}, + ) + form.widget( + "sedi_secondarie", + RelatedItemsFieldWidget, + vocabulary="plone.app.vocabularies.Catalog", + pattern_options={ + "maximumSelectionSize": 10, + "selectableTypes": ["Venue"], + # "basePath": "/servizi", + }, + ) + + # custom fieldsets and order + model.fieldset( + "cosa_fa", + label=_("cosa_fa_label", default="Cosa fa"), + fields=["competenze"], + ) + model.fieldset( + "struttura", + label=_("struttura_label", default="Struttura"), + fields=[ + "legami_con_altre_strutture", + "responsabile", + "assessore_riferimento", + ], + ) + model.fieldset( + "persone", + label=_("persone_label", default="Persone"), + fields=["persone_struttura"], + ) + model.fieldset( + "contatti", + label=_("contatti_label", default="Contatti"), + fields=["sede", "sedi_secondarie"], + ) + form.order_after(sedi_secondarie="IContattiUnitaOrganizzativa.orario_pubblico") + # form.order_after(contact_info="sedi_secondarie") + + # SearchableText indexers + textindexer.searchable("competenze") + textindexer.searchable("assessore_riferimento") + textindexer.searchable("responsabile") diff --git a/.history/src/design/plone/contenttypes/interfaces/unita_organizzativa_20230104110045.py b/.history/src/design/plone/contenttypes/interfaces/unita_organizzativa_20230104110045.py new file mode 100644 index 00000000..d0439a93 --- /dev/null +++ b/.history/src/design/plone/contenttypes/interfaces/unita_organizzativa_20230104110045.py @@ -0,0 +1,212 @@ +# -*- coding: utf-8 -*- +from collective.volto.blocksfield.field import BlocksField +from design.plone.contenttypes import _ +from design.plone.contenttypes.interfaces import IDesignPloneContentType +from plone.app.dexterity import textindexer +from plone.app.z3cform.widget import RelatedItemsFieldWidget +from plone.autoform import directives as form +from plone.supermodel import model +from z3c.relationfield.schema import RelationChoice +from z3c.relationfield.schema import RelationList + + +# TODO: migration script for these commented fields towards PDC +# contact_info +# Probabilmente non possibile trattandosi di un campo a blocchi +# preferirei si arrangiassero le redazioni. Altrimenti si defaulta +# ad un tipo a caso + tutto il testo e poi si arrangiano comunque +class IUnitaOrganizzativa(model.Schema, IDesignPloneContentType): + """Marker interface for content type UnitaOrganizzativa""" + + competenze = BlocksField( + title=_("uo_competenze_label", default="Competenze"), + description=_( + "uo_competenze_help", + default="Descrizione dei compiti assegnati alla struttura.", + ), + required=False, + ) + + legami_con_altre_strutture = RelationList( + title=_( + "legami_altre_strutture_label", default="Servizi o uffici di riferimento" + ), + default=[], + description=_( + "legami_con_altre_strutture_help", + default="Selezionare la lista di strutture e/o uffici collegati" + " a questa unità organizzativa.", + ), + value_type=RelationChoice( + title=_("Struttura"), vocabulary="plone.app.vocabularies.Catalog" + ), + required=False, + ) + + responsabile = RelationList( + title=_("responsabile_label", default="Responsabile"), + value_type=RelationChoice( + title=_("Responsabile"), + vocabulary="plone.app.vocabularies.Catalog", + ), + description=_( + "responsabile_help", + default="Selezionare il/i responsabile/i della struttura.", + ), + default=[], + required=False, + ) + + assessore_riferimento = RelationList( + title="Assessore di riferimento", + # vocabolario di riferimento sara' dinamico con i content type + # persona presenti all'interno della macro Amministrazione" + value_type=RelationChoice( + title=_("Assessore di riferimento"), + vocabulary="plone.app.vocabularies.Catalog", + ), + description=_( + "assessore_riferimento_help", + default="Inserire l'assessore di riferimento della struttura," + " se esiste.", + ), + required=False, + default=[], + ) + + # vocabolario di riferimento sara' dinamico con i content type persona + persone_struttura = RelationList( + title=_( + "persone_struttura_label", default="Persone che compongono la struttura" + ), + default=[], + value_type=RelationChoice( + title=_("Persone della struttura"), + vocabulary="plone.app.vocabularies.Catalog", + ), + description=_( + "persone_struttura_help", + default="Seleziona la lista delle persone che compongono" " la struttura.", + ), + required=False, + ) + + sede = RelationList( + title=_("sede_label", default="Sede principale"), + default=[], + description=_( + "sede_help", + default="Seleziona il Luogo in cui questa struttura ha sede. " + "Se non è presente un contenuto di tipo Luogo a cui far " + "riferimento, puoi compilare i campi seguenti. Se selezioni un " + "Luogo, puoi usare comunque i campi seguenti per sovrascrivere " + "alcune informazioni.", + ), + value_type=RelationChoice( + title=_("Sede"), vocabulary="plone.app.vocabularies.Catalog" + ), + required=False, + ) + + sedi_secondarie = RelationList( + title=_("sedi_secondarie_label", default="Sedi secondarie"), + default=[], + description=_( + "sedi_secondarie_help", + default="Seleziona una lista di eventuali contenuti di tipo Luogo" + " che sono sedi secondarie di questa struttura. " + "Per queste sedi non sarà possibile sovrascrivere i dati. " + "Nel caso servano informazioni diverse, è possibile usare il campo" + " sottostante.", + ), + value_type=RelationChoice( + title=_("Sede"), vocabulary="plone.app.vocabularies.Catalog" + ), + required=False, + ) + + # custom widgets + form.widget( + "persone_struttura", + RelatedItemsFieldWidget, + vocabulary="plone.app.vocabularies.Catalog", + pattern_options={"selectableTypes": ["Persona"], "maximumSelectionSize": 50}, + ) + form.widget( + "legami_con_altre_strutture", + RelatedItemsFieldWidget, + vocabulary="plone.app.vocabularies.Catalog", + pattern_options={ + "maximumSelectionSize": 10, + "selectableTypes": ["UnitaOrganizzativa"], + }, + ) + form.widget( + "responsabile", + RelatedItemsFieldWidget, + vocabulary="plone.app.vocabularies.Catalog", + pattern_options={ + "maximumSelectionSize": 1, + "selectableTypes": ["Persona"], + # "basePath": "/amministrazione", + }, + ) + form.widget( + "assessore_riferimento", + RelatedItemsFieldWidget, + vocabulary="plone.app.vocabularies.Catalog", + pattern_options={ + "maximumSelectionSize": 1, + "selectableTypes": ["Persona"], + # "basePath": "/amministrazione", + }, + ) + form.widget( + "sede", + RelatedItemsFieldWidget, + vocabulary="plone.app.vocabularies.Catalog", + pattern_options={"maximumSelectionSize": 1, "selectableTypes": ["Venue"]}, + ) + form.widget( + "sedi_secondarie", + RelatedItemsFieldWidget, + vocabulary="plone.app.vocabularies.Catalog", + pattern_options={ + "maximumSelectionSize": 10, + "selectableTypes": ["Venue"], + # "basePath": "/servizi", + }, + ) + + # custom fieldsets and order + model.fieldset( + "cosa_fa", + label=_("cosa_fa_label", default="Cosa fa"), + fields=["competenze"], + ) + model.fieldset( + "struttura", + label=_("struttura_label", default="Struttura"), + fields=[ + "legami_con_altre_strutture", + "responsabile", + "assessore_riferimento", + ], + ) + model.fieldset( + "persone", + label=_("persone_label", default="Persone"), + fields=["persone_struttura"], + ) + model.fieldset( + "contatti", + label=_("contatti_label", default="Contatti"), + fields=["sede", "sedi_secondarie"], + ) + form.order_after(sedi_secondarie="IContattiUnitaOrganizzativa.orario_pubblico") + # form.order_after(contact_info="sedi_secondarie") + + # SearchableText indexers + textindexer.searchable("competenze") + textindexer.searchable("assessore_riferimento") + textindexer.searchable("responsabile") diff --git a/.history/src/design/plone/contenttypes/interfaces/unita_organizzativa_20230104110116.py b/.history/src/design/plone/contenttypes/interfaces/unita_organizzativa_20230104110116.py new file mode 100644 index 00000000..e4fd69f0 --- /dev/null +++ b/.history/src/design/plone/contenttypes/interfaces/unita_organizzativa_20230104110116.py @@ -0,0 +1,211 @@ +# -*- coding: utf-8 -*- +from collective.volto.blocksfield.field import BlocksField +from design.plone.contenttypes import _ +from design.plone.contenttypes.interfaces import IDesignPloneContentType +from plone.app.dexterity import textindexer +from plone.app.z3cform.widget import RelatedItemsFieldWidget +from plone.autoform import directives as form +from plone.supermodel import model +from z3c.relationfield.schema import RelationChoice +from z3c.relationfield.schema import RelationList + + +# TODO: migration script for these commented fields towards PDC +# contact_info +# Probabilmente non possibile trattandosi di un campo a blocchi +# preferirei si arrangiassero le redazioni. Altrimenti si defaulta +# ad un tipo a caso + tutto il testo e poi si arrangiano comunque +class IUnitaOrganizzativa(model.Schema, IDesignPloneContentType): + """Marker interface for content type UnitaOrganizzativa""" + + competenze = BlocksField( + title=_("uo_competenze_label", default="Competenze"), + description=_( + "uo_competenze_help", + default="Descrizione dei compiti assegnati alla struttura.", + ), + required=False, + ) + + legami_con_altre_strutture = RelationList( + title=_( + "legami_altre_strutture_label", default="Servizi o uffici di riferimento" + ), + default=[], + description=_( + "legami_con_altre_strutture_help", + default="Selezionare la lista di strutture e/o uffici collegati" + " a questa unità organizzativa.", + ), + value_type=RelationChoice( + title=_("Struttura"), vocabulary="plone.app.vocabularies.Catalog" + ), + required=False, + ) + + responsabile = RelationList( + title=_("responsabile_label", default="Responsabile"), + value_type=RelationChoice( + title=_("Responsabile"), + vocabulary="plone.app.vocabularies.Catalog", + ), + description=_( + "responsabile_help", + default="Selezionare il/i responsabile/i della struttura.", + ), + default=[], + required=False, + ) + + assessore_riferimento = RelationList( + title="Assessore di riferimento", + # vocabolario di riferimento sara' dinamico con i content type + # persona presenti all'interno della macro Amministrazione" + value_type=RelationChoice( + title=_("Assessore di riferimento"), + vocabulary="plone.app.vocabularies.Catalog", + ), + description=_( + "assessore_riferimento_help", + default="Inserire l'assessore di riferimento della struttura," + " se esiste.", + ), + required=False, + default=[], + ) + + # vocabolario di riferimento sara' dinamico con i content type persona + persone_struttura = RelationList( + title=_( + "persone_struttura_label", default="Persone che compongono la struttura" + ), + default=[], + value_type=RelationChoice( + title=_("Persone della struttura"), + vocabulary="plone.app.vocabularies.Catalog", + ), + description=_( + "persone_struttura_help", + default="Seleziona la lista delle persone che compongono" " la struttura.", + ), + required=False, + ) + + sede = RelationList( + title=_("sede_label", default="Sede principale"), + default=[], + description=_( + "sede_help", + default="Seleziona il Luogo in cui questa struttura ha sede. " + "Se non è presente un contenuto di tipo Luogo a cui far " + "riferimento, puoi compilare i campi seguenti. Se selezioni un " + "Luogo, puoi usare comunque i campi seguenti per sovrascrivere " + "alcune informazioni.", + ), + value_type=RelationChoice( + title=_("Sede"), vocabulary="plone.app.vocabularies.Catalog" + ), + required=False, + ) + + sedi_secondarie = RelationList( + title=_("sedi_secondarie_label", default="Sedi secondarie"), + default=[], + description=_( + "sedi_secondarie_help", + default="Seleziona una lista di eventuali contenuti di tipo Luogo" + " che sono sedi secondarie di questa struttura. " + "Per queste sedi non sarà possibile sovrascrivere i dati. " + "Nel caso servano informazioni diverse, è possibile usare il campo" + " sottostante.", + ), + value_type=RelationChoice( + title=_("Sede"), vocabulary="plone.app.vocabularies.Catalog" + ), + required=False, + ) + + # custom widgets + form.widget( + "persone_struttura", + RelatedItemsFieldWidget, + vocabulary="plone.app.vocabularies.Catalog", + pattern_options={"selectableTypes": ["Persona"], "maximumSelectionSize": 50}, + ) + form.widget( + "legami_con_altre_strutture", + RelatedItemsFieldWidget, + vocabulary="plone.app.vocabularies.Catalog", + pattern_options={ + "maximumSelectionSize": 10, + "selectableTypes": ["UnitaOrganizzativa"], + }, + ) + form.widget( + "responsabile", + RelatedItemsFieldWidget, + vocabulary="plone.app.vocabularies.Catalog", + pattern_options={ + "maximumSelectionSize": 1, + "selectableTypes": ["Persona"], + # "basePath": "/amministrazione", + }, + ) + form.widget( + "assessore_riferimento", + RelatedItemsFieldWidget, + vocabulary="plone.app.vocabularies.Catalog", + pattern_options={ + "maximumSelectionSize": 1, + "selectableTypes": ["Persona"], + # "basePath": "/amministrazione", + }, + ) + form.widget( + "sede", + RelatedItemsFieldWidget, + vocabulary="plone.app.vocabularies.Catalog", + pattern_options={"maximumSelectionSize": 1, "selectableTypes": ["Venue"]}, + ) + form.widget( + "sedi_secondarie", + RelatedItemsFieldWidget, + vocabulary="plone.app.vocabularies.Catalog", + pattern_options={ + "maximumSelectionSize": 10, + "selectableTypes": ["Venue"], + # "basePath": "/servizi", + }, + ) + + # custom fieldsets and order + model.fieldset( + "cosa_fa", + label=_("cosa_fa_label", default="Cosa fa"), + fields=["competenze"], + ) + model.fieldset( + "struttura", + label=_("struttura_label", default="Struttura"), + fields=[ + "legami_con_altre_strutture", + "responsabile", + "assessore_riferimento", + ], + ) + model.fieldset( + "persone", + label=_("persone_label", default="Persone"), + fields=["persone_struttura"], + ) + model.fieldset( + "contatti", + label=_("contatti_label", default="Contatti"), + fields=["sede", "sedi_secondarie"], + ) + form.order_after(sedi_secondarie="IContattiUnitaOrganizzativa.orario_pubblico") + + # SearchableText indexers + textindexer.searchable("competenze") + textindexer.searchable("assessore_riferimento") + textindexer.searchable("responsabile") diff --git a/.history/src/design/plone/contenttypes/profiles/default/types/Persona_20230104105939.xml b/.history/src/design/plone/contenttypes/profiles/default/types/Persona_20230104105939.xml new file mode 100644 index 00000000..6a0cf185 --- /dev/null +++ b/.history/src/design/plone/contenttypes/profiles/default/types/Persona_20230104105939.xml @@ -0,0 +1,115 @@ + + + + + Persona + + + False + Persona + + + + + True + False + + + + + design.plone.contenttypes.AddPersona + design.plone.contenttypes.content.persona.Persona + + + design.plone.contenttypes.interfaces.persona.IPersona + + + + + + + + + + + + + + +<<<<<<< HEAD + + + + + +======= + + + + + + +>>>>>>> pnrr + + + + string:${folder_url}/++add++Persona + view + False + view + + + + + + + + + + + + + + + + + + + diff --git a/.history/src/design/plone/contenttypes/profiles/default/types/Persona_20230104110533.xml b/.history/src/design/plone/contenttypes/profiles/default/types/Persona_20230104110533.xml new file mode 100644 index 00000000..9578a7df --- /dev/null +++ b/.history/src/design/plone/contenttypes/profiles/default/types/Persona_20230104110533.xml @@ -0,0 +1,107 @@ + + + + + Persona + + + False + Persona + + + + + True + False + + + + + design.plone.contenttypes.AddPersona + design.plone.contenttypes.content.persona.Persona + + + design.plone.contenttypes.interfaces.persona.IPersona + + + + + + + + + + + + + + + + + + + + + + + + string:${folder_url}/++add++Persona + view + False + view + + + + + + + + + + + + + + + + + + + diff --git a/.history/src/design/plone/contenttypes/profiles/default/types/Servizio_20230104105939.xml b/.history/src/design/plone/contenttypes/profiles/default/types/Servizio_20230104105939.xml new file mode 100644 index 00000000..2c82dc6f --- /dev/null +++ b/.history/src/design/plone/contenttypes/profiles/default/types/Servizio_20230104105939.xml @@ -0,0 +1,120 @@ + + + + + Servizio + + + False + Servizio + + + + + True + True + + + + + + + + design.plone.contenttypes.AddServizio + design.plone.contenttypes.content.servizio.Servizio + + + design.plone.contenttypes.interfaces.servizio.IServizio + + + + + + + + + + + + + + + +<<<<<<< HEAD + + + + + + + + + +======= + + + + + + + + +>>>>>>> pnrr + + + + string:${folder_url}/++add++Servizio + view + False + view + + + + + + + + + + + + + + + + + + + diff --git a/.history/src/design/plone/contenttypes/profiles/default/types/Servizio_20230104110559.xml b/.history/src/design/plone/contenttypes/profiles/default/types/Servizio_20230104110559.xml new file mode 100644 index 00000000..241dbc58 --- /dev/null +++ b/.history/src/design/plone/contenttypes/profiles/default/types/Servizio_20230104110559.xml @@ -0,0 +1,110 @@ + + + + + Servizio + + + False + Servizio + + + + + True + True + + + + + + + + design.plone.contenttypes.AddServizio + design.plone.contenttypes.content.servizio.Servizio + + + design.plone.contenttypes.interfaces.servizio.IServizio + + + + + + + + + + + + + + + + + + + + + + + + + + + + + string:${folder_url}/++add++Servizio + view + False + view + + + + + + + + + + + + + + + + + + + diff --git a/.history/src/design/plone/contenttypes/profiles/default/types_20230104105939.xml b/.history/src/design/plone/contenttypes/profiles/default/types_20230104105939.xml new file mode 100644 index 00000000..a045886e --- /dev/null +++ b/.history/src/design/plone/contenttypes/profiles/default/types_20230104105939.xml @@ -0,0 +1,59 @@ + + + Controls the available contenttypes in your portal +<<<<<<< HEAD + + + + + + + + + + + + +======= + + + + + + + + + + + + + + +>>>>>>> pnrr + diff --git a/.history/src/design/plone/contenttypes/profiles/default/types_20230104110435.xml b/.history/src/design/plone/contenttypes/profiles/default/types_20230104110435.xml new file mode 100644 index 00000000..63795015 --- /dev/null +++ b/.history/src/design/plone/contenttypes/profiles/default/types_20230104110435.xml @@ -0,0 +1,51 @@ + + + Controls the available contenttypes in your portal +<<<<<<< HEAD + + + + + + + + + + + + + + + + + diff --git a/.history/src/design/plone/contenttypes/profiles/default/types_20230104110443.xml b/.history/src/design/plone/contenttypes/profiles/default/types_20230104110443.xml new file mode 100644 index 00000000..63795015 --- /dev/null +++ b/.history/src/design/plone/contenttypes/profiles/default/types_20230104110443.xml @@ -0,0 +1,51 @@ + + + Controls the available contenttypes in your portal +<<<<<<< HEAD + + + + + + + + + + + + + + + + + diff --git a/.history/src/design/plone/contenttypes/profiles/default/types_20230104110501.xml b/.history/src/design/plone/contenttypes/profiles/default/types_20230104110501.xml new file mode 100644 index 00000000..cd0ac12b --- /dev/null +++ b/.history/src/design/plone/contenttypes/profiles/default/types_20230104110501.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + diff --git a/.history/src/design/plone/contenttypes/restapi/types/adapters_20230104105939.py b/.history/src/design/plone/contenttypes/restapi/types/adapters_20230104105939.py new file mode 100644 index 00000000..6b5f73f5 --- /dev/null +++ b/.history/src/design/plone/contenttypes/restapi/types/adapters_20230104105939.py @@ -0,0 +1,109 @@ +# -*- coding: utf-8 -*- +from design.plone.contenttypes import _ +from plone.restapi.types.adapters import ObjectJsonSchemaProvider +from plone.restapi.types.interfaces import IJsonSchemaProvider +from zope.component import adapter +from zope.component import getUtility +from zope.i18n import translate +from zope.interface import implementer +from zope.interface import Interface +<<<<<<< HEAD +from zope.schema.interfaces import IField +from zope.schema.interfaces import IVocabularyFactory +======= +from zope.schema.interfaces import IField, IVocabularyFactory +from collective.z3cform.datagridfield.interfaces import IRow +from plone import api +from plone.restapi.types.adapters import ListJsonSchemaProvider +from plone.restapi.types.utils import get_fieldsets +from plone.restapi.types.utils import get_jsonschema_properties +from plone.restapi.types.utils import iter_fields +from zope.schema.interfaces import IList +from design.plone.contenttypes.interfaces import IDesignPloneContenttypesLayer + + +from design.plone.contenttypes import _ +>>>>>>> pnrr + + +@adapter(IField, Interface, Interface) +@implementer(IJsonSchemaProvider) +class LeadImageJsonSchemaProvider(ObjectJsonSchemaProvider): + def get_size_vocabulary(self): + + factory = getUtility( + IVocabularyFactory, "design.plone.vocabularies.leadimage_dimension" + ) + + vocabulary = factory(self.context)._terms + return {term.token: term.title for term in vocabulary if term.token} + + def get_schema(self): + schema = super(LeadImageJsonSchemaProvider, self).get_schema() + sizes = self.get_size_vocabulary() + portal_type = getattr(self.request, "steps")[-1] + portal_type_size = sizes.get(portal_type, None) + if portal_type_size: + msgid = _( + "image_size_help", + default="La dimensione dell'immagine dovrebbe essere di ${size} px", # noqa + mapping={"size": portal_type_size}, + ) + schema["description"] = translate(msgid, context=self.request) + + return schema + + +@adapter(IList, Interface, IDesignPloneContenttypesLayer) +@implementer(IJsonSchemaProvider) +class DataGridFieldJsonSchemaProvider(ListJsonSchemaProvider): + def get_widget(self): + if self.field.getName() == "value_punto_contatto": + return "data_grid" + return super().get_widget() + + +@adapter(IRow, Interface, Interface) +@implementer(IJsonSchemaProvider) +class DataGridRowJsonSchemaProvider(ObjectJsonSchemaProvider): + def __init__(self, field, context, request): + super().__init__(field, context, request) + self.fieldsets = get_fieldsets(context, request, self.field.schema) + + def get_factory(self): + return "DataGridField Row" + + def get_properties(self): + if self.prefix: + prefix = ".".join([self.prefix, self.field.__name__]) + else: + prefix = self.field.__name__ + return get_jsonschema_properties( + self.context, self.request, self.fieldsets, prefix + ) + + def additional(self): + info = super().additional() + properties = self.get_properties() + required = [] + for field in iter_fields(self.fieldsets): + name = field.field.getName() + + # Determine required fields + if field.field.required: + required.append(name) + + # Include field modes + if field.mode: + properties[name]["mode"] = field.mode + + info["fieldsets"] = [ + { + "id": "default", + "title": "Default", + "fields": [x for x in properties.keys()], + }, + ] + info["required"] = required + info["properties"] = properties + return info diff --git a/.history/src/design/plone/contenttypes/restapi/types/adapters_20230104110615.py b/.history/src/design/plone/contenttypes/restapi/types/adapters_20230104110615.py new file mode 100644 index 00000000..d5f2b931 --- /dev/null +++ b/.history/src/design/plone/contenttypes/restapi/types/adapters_20230104110615.py @@ -0,0 +1,104 @@ +# -*- coding: utf-8 -*- +from design.plone.contenttypes import _ +from plone.restapi.types.adapters import ObjectJsonSchemaProvider +from plone.restapi.types.interfaces import IJsonSchemaProvider +from zope.component import adapter +from zope.component import getUtility +from zope.i18n import translate +from zope.interface import implementer +from zope.interface import Interface +from zope.schema.interfaces import IField, IVocabularyFactory +from collective.z3cform.datagridfield.interfaces import IRow +from plone import api +from plone.restapi.types.adapters import ListJsonSchemaProvider +from plone.restapi.types.utils import get_fieldsets +from plone.restapi.types.utils import get_jsonschema_properties +from plone.restapi.types.utils import iter_fields +from zope.schema.interfaces import IList +from design.plone.contenttypes.interfaces import IDesignPloneContenttypesLayer + + +from design.plone.contenttypes import _ + + +@adapter(IField, Interface, Interface) +@implementer(IJsonSchemaProvider) +class LeadImageJsonSchemaProvider(ObjectJsonSchemaProvider): + def get_size_vocabulary(self): + + factory = getUtility( + IVocabularyFactory, "design.plone.vocabularies.leadimage_dimension" + ) + + vocabulary = factory(self.context)._terms + return {term.token: term.title for term in vocabulary if term.token} + + def get_schema(self): + schema = super(LeadImageJsonSchemaProvider, self).get_schema() + sizes = self.get_size_vocabulary() + portal_type = getattr(self.request, "steps")[-1] + portal_type_size = sizes.get(portal_type, None) + if portal_type_size: + msgid = _( + "image_size_help", + default="La dimensione dell'immagine dovrebbe essere di ${size} px", # noqa + mapping={"size": portal_type_size}, + ) + schema["description"] = translate(msgid, context=self.request) + + return schema + + +@adapter(IList, Interface, IDesignPloneContenttypesLayer) +@implementer(IJsonSchemaProvider) +class DataGridFieldJsonSchemaProvider(ListJsonSchemaProvider): + def get_widget(self): + if self.field.getName() == "value_punto_contatto": + return "data_grid" + return super().get_widget() + + +@adapter(IRow, Interface, Interface) +@implementer(IJsonSchemaProvider) +class DataGridRowJsonSchemaProvider(ObjectJsonSchemaProvider): + def __init__(self, field, context, request): + super().__init__(field, context, request) + self.fieldsets = get_fieldsets(context, request, self.field.schema) + + def get_factory(self): + return "DataGridField Row" + + def get_properties(self): + if self.prefix: + prefix = ".".join([self.prefix, self.field.__name__]) + else: + prefix = self.field.__name__ + return get_jsonschema_properties( + self.context, self.request, self.fieldsets, prefix + ) + + def additional(self): + info = super().additional() + properties = self.get_properties() + required = [] + for field in iter_fields(self.fieldsets): + name = field.field.getName() + + # Determine required fields + if field.field.required: + required.append(name) + + # Include field modes + if field.mode: + properties[name]["mode"] = field.mode + + info["fieldsets"] = [ + { + "id": "default", + "title": "Default", + "fields": [x for x in properties.keys()], + }, + ] + info["required"] = required + info["properties"] = properties + return info diff --git a/.history/src/design/plone/contenttypes/restapi/types/adapters_20230104110625.py b/.history/src/design/plone/contenttypes/restapi/types/adapters_20230104110625.py new file mode 100644 index 00000000..b3617553 --- /dev/null +++ b/.history/src/design/plone/contenttypes/restapi/types/adapters_20230104110625.py @@ -0,0 +1,102 @@ +# -*- coding: utf-8 -*- +from design.plone.contenttypes import _ +from plone.restapi.types.adapters import ObjectJsonSchemaProvider +from plone.restapi.types.interfaces import IJsonSchemaProvider +from zope.component import adapter +from zope.component import getUtility +from zope.i18n import translate +from zope.interface import implementer +from zope.interface import Interface +from zope.schema.interfaces import IField, IVocabularyFactory +from collective.z3cform.datagridfield.interfaces import IRow +from plone import api +from plone.restapi.types.adapters import ListJsonSchemaProvider +from plone.restapi.types.utils import get_fieldsets +from plone.restapi.types.utils import get_jsonschema_properties +from plone.restapi.types.utils import iter_fields +from zope.schema.interfaces import IList +from design.plone.contenttypes.interfaces import IDesignPloneContenttypesLayer +from design.plone.contenttypes import _ + + +@adapter(IField, Interface, Interface) +@implementer(IJsonSchemaProvider) +class LeadImageJsonSchemaProvider(ObjectJsonSchemaProvider): + def get_size_vocabulary(self): + + factory = getUtility( + IVocabularyFactory, "design.plone.vocabularies.leadimage_dimension" + ) + + vocabulary = factory(self.context)._terms + return {term.token: term.title for term in vocabulary if term.token} + + def get_schema(self): + schema = super(LeadImageJsonSchemaProvider, self).get_schema() + sizes = self.get_size_vocabulary() + portal_type = getattr(self.request, "steps")[-1] + portal_type_size = sizes.get(portal_type, None) + if portal_type_size: + msgid = _( + "image_size_help", + default="La dimensione dell'immagine dovrebbe essere di ${size} px", # noqa + mapping={"size": portal_type_size}, + ) + schema["description"] = translate(msgid, context=self.request) + + return schema + + +@adapter(IList, Interface, IDesignPloneContenttypesLayer) +@implementer(IJsonSchemaProvider) +class DataGridFieldJsonSchemaProvider(ListJsonSchemaProvider): + def get_widget(self): + if self.field.getName() == "value_punto_contatto": + return "data_grid" + return super().get_widget() + + +@adapter(IRow, Interface, Interface) +@implementer(IJsonSchemaProvider) +class DataGridRowJsonSchemaProvider(ObjectJsonSchemaProvider): + def __init__(self, field, context, request): + super().__init__(field, context, request) + self.fieldsets = get_fieldsets(context, request, self.field.schema) + + def get_factory(self): + return "DataGridField Row" + + def get_properties(self): + if self.prefix: + prefix = ".".join([self.prefix, self.field.__name__]) + else: + prefix = self.field.__name__ + return get_jsonschema_properties( + self.context, self.request, self.fieldsets, prefix + ) + + def additional(self): + info = super().additional() + properties = self.get_properties() + required = [] + for field in iter_fields(self.fieldsets): + name = field.field.getName() + + # Determine required fields + if field.field.required: + required.append(name) + + # Include field modes + if field.mode: + properties[name]["mode"] = field.mode + + info["fieldsets"] = [ + { + "id": "default", + "title": "Default", + "fields": [x for x in properties.keys()], + }, + ] + info["required"] = required + info["properties"] = properties + return info diff --git a/.history/src/design/plone/contenttypes/restapi/types/adapters_20230104110639.py b/.history/src/design/plone/contenttypes/restapi/types/adapters_20230104110639.py new file mode 100644 index 00000000..11c712d2 --- /dev/null +++ b/.history/src/design/plone/contenttypes/restapi/types/adapters_20230104110639.py @@ -0,0 +1,100 @@ +# -*- coding: utf-8 -*- +from design.plone.contenttypes import _ +from plone.restapi.types.adapters import ObjectJsonSchemaProvider +from plone.restapi.types.interfaces import IJsonSchemaProvider +from zope.component import adapter +from zope.component import getUtility +from zope.i18n import translate +from zope.interface import implementer +from zope.interface import Interface +from zope.schema.interfaces import IField, IVocabularyFactory +from collective.z3cform.datagridfield.interfaces import IRow +from plone.restapi.types.adapters import ListJsonSchemaProvider +from plone.restapi.types.utils import get_fieldsets +from plone.restapi.types.utils import get_jsonschema_properties +from plone.restapi.types.utils import iter_fields +from zope.schema.interfaces import IList +from design.plone.contenttypes.interfaces import IDesignPloneContenttypesLayer + + +@adapter(IField, Interface, Interface) +@implementer(IJsonSchemaProvider) +class LeadImageJsonSchemaProvider(ObjectJsonSchemaProvider): + def get_size_vocabulary(self): + + factory = getUtility( + IVocabularyFactory, "design.plone.vocabularies.leadimage_dimension" + ) + + vocabulary = factory(self.context)._terms + return {term.token: term.title for term in vocabulary if term.token} + + def get_schema(self): + schema = super(LeadImageJsonSchemaProvider, self).get_schema() + sizes = self.get_size_vocabulary() + portal_type = getattr(self.request, "steps")[-1] + portal_type_size = sizes.get(portal_type, None) + if portal_type_size: + msgid = _( + "image_size_help", + default="La dimensione dell'immagine dovrebbe essere di ${size} px", # noqa + mapping={"size": portal_type_size}, + ) + schema["description"] = translate(msgid, context=self.request) + + return schema + + +@adapter(IList, Interface, IDesignPloneContenttypesLayer) +@implementer(IJsonSchemaProvider) +class DataGridFieldJsonSchemaProvider(ListJsonSchemaProvider): + def get_widget(self): + if self.field.getName() == "value_punto_contatto": + return "data_grid" + return super().get_widget() + + +@adapter(IRow, Interface, Interface) +@implementer(IJsonSchemaProvider) +class DataGridRowJsonSchemaProvider(ObjectJsonSchemaProvider): + def __init__(self, field, context, request): + super().__init__(field, context, request) + self.fieldsets = get_fieldsets(context, request, self.field.schema) + + def get_factory(self): + return "DataGridField Row" + + def get_properties(self): + if self.prefix: + prefix = ".".join([self.prefix, self.field.__name__]) + else: + prefix = self.field.__name__ + return get_jsonschema_properties( + self.context, self.request, self.fieldsets, prefix + ) + + def additional(self): + info = super().additional() + properties = self.get_properties() + required = [] + for field in iter_fields(self.fieldsets): + name = field.field.getName() + + # Determine required fields + if field.field.required: + required.append(name) + + # Include field modes + if field.mode: + properties[name]["mode"] = field.mode + + info["fieldsets"] = [ + { + "id": "default", + "title": "Default", + "fields": [x for x in properties.keys()], + }, + ] + info["required"] = required + info["properties"] = properties + return info diff --git a/.history/src/design/plone/contenttypes/upgrades/upgrades_20230104105158.py b/.history/src/design/plone/contenttypes/upgrades/upgrades_20230104105158.py new file mode 100644 index 00000000..1456f582 --- /dev/null +++ b/.history/src/design/plone/contenttypes/upgrades/upgrades_20230104105158.py @@ -0,0 +1,1124 @@ +# -*- coding: utf-8 -*- +from Acquisition import aq_base +from collective.volto.blocksfield.field import BlocksField +from copy import deepcopy +from design.plone.contenttypes.controlpanels.settings import IDesignPloneSettings +from design.plone.contenttypes.upgrades.draftjs_converter import to_draftjs +from design.plone.contenttypes.setuphandlers import remove_blocks_behavior +from plone import api +from plone.app.textfield.value import RichTextValue +from plone.app.upgrade.utils import installOrReinstallProduct +from plone.dexterity.utils import iterSchemata +from redturtle.bandi.interfaces.settings import IBandoSettings +from transaction import commit +from z3c.relationfield import RelationValue +from zope.component import getUtility +from zope.event import notify +from zope.intid.interfaces import IIntIds +from zope.lifecycleevent import ObjectModifiedEvent +from zope.schema import getFields + +import logging +import json +import six + +logger = logging.getLogger(__name__) + +DEFAULT_PROFILE = "profile-design.plone.contenttypes:default" + +# standard upgrades # + + +def update_profile(context, profile, run_dependencies=True): + context.runImportStepFromProfile(DEFAULT_PROFILE, profile, run_dependencies) + + +def update_types(context): + update_profile(context, "typeinfo") + + +def update_rolemap(context): + update_profile(context, "rolemap") + + +def update_registry(context): + update_profile(context, "plone.app.registry", run_dependencies=False) + + +def update_catalog(context): + update_profile(context, "catalog") + + +def update_controlpanel(context): + update_profile(context, "controlpanel") + + +def remap_fields(mapping): + pc = api.portal.get_tool(name="portal_catalog") + brains = pc() + tot = len(brains) + logger.info("Trovati {} elementi da sistemare.".format(tot)) + # remap fields + for brain in brains: + item = brain.getObject() + for old, new in mapping.items(): + value = getattr(item, old, None) + if value: + setattr(item, new, value) + setattr(item, old, None) + logger.info( + "- {url}: {old} -> {new}".format( + url=brain.getURL(), old=old, new=new + ) + ) + delattr(item, old) + + +# custom ones # + + +def to_1001(context): + + update_types(context) + + # cleanup event behaviors + portal_types = api.portal.get_tool(name="portal_types") + behaviors = portal_types["Event"].behaviors + to_remove = [ + "design.plone.contenttypes.behavior.luoghi_correlati", + "design.plone.contenttypes.behavior.argomenti_evento", + "design.plone.contenttypes.behavior.additional_help_infos_evento", + ] + portal_types["Event"].behaviors = tuple( + [x for x in behaviors if x not in to_remove] + ) + + mapping = { + # "descrizione_destinatari": "a_chi_si_rivolge", + "canale_fisico": "dove_rivolgersi_extra", + "canale_fisico_prenotazione": "prenota_appuntamento", + "fasi_scadenze": "tempi_e_scadenze", + "sedi_e_luoghi": "dove_rivolgersi", + "box_aiuto": "ulteriori_informazioni", + "riferimento_telefonico_luogo": "telefono", + "riferimento_mail_luogo": "email", + } + remap_fields(mapping=mapping) + + +def to_1003(context): + + update_types(context) + + mapping = { + "unita_amministrativa_responsabile": "unita_amministrative_responsabili", # noqa + "sedi": "sede", + "contatto_reperibilita": "reperibilita", + "evento_supportato_da": "supportato_da", + } + remap_fields(mapping=mapping) + + +def to_1005(context): + def fix_index(blocks): + for block in blocks.values(): + if block.get("@type", "") == "listing": + for query in block.get("query", []): + if ( + query["i"] == "argomenti_correlati" + or query["i"] == "tassonomia_argomenti" + ): # noqa + query["i"] = "argomenti" + logger.info(" - {}".format(brain.getURL())) + + # fix root + portal = api.portal.get() + portal_blocks = json.loads(portal.blocks) + fix_index(portal_blocks) + portal.blocks = json.dumps(portal_blocks) + + logger.info("Fixing listing blocks.") + for brain in api.content.find(object_provides="plone.restapi.behaviors.IBlocks"): + item = brain.getObject() + blocks = deepcopy(getattr(item, "blocks", {})) + if blocks: + fix_index(blocks) + item.blocks = blocks + logger.info("** Reindexing items that refers to an argument **") + for brain in api.portal.get_tool("portal_catalog")(): + item = brain.getObject() + if getattr(item.aq_base, "tassonomia_argomenti", []): + logger.info(" - {}".format(brain.getURL())) + item.reindexObject(idxs=["argomenti"]) + + +def to_1006(context): + def fix_index(blocks): + for block in blocks.values(): + if block.get("@type", "") == "listing": + for query in block.get("query", []): + if ( + query["i"] == "argomenti_correlati" + or query["i"] == "tassonomia_argomenti" + or query["i"] == "argomenti" + ): # noqa + query["i"] = "argomenti" + query["v"] = [x.Title for x in api.content.find(UID=query["v"])] + logger.info(" - {}".format(brain.getURL())) + + # fix root + portal = api.portal.get() + portal_blocks = json.loads(portal.blocks) + fix_index(portal_blocks) + portal.blocks = json.dumps(portal_blocks) + + logger.info("Fixing listing blocks.") + for brain in api.content.find(object_provides="plone.restapi.behaviors.IBlocks"): + item = brain.getObject() + blocks = deepcopy(getattr(item, "blocks", {})) + if blocks: + fix_index(blocks) + item.blocks = blocks + + +def to_1007(context): + for brain in api.content.find(portal_type="Persona"): + item = brain.getObject() + if item.email: + item.email = [item.email] + if item.telefono: + item.telefono = [item.telefono] + + +def to_1008(context): + installOrReinstallProduct(api.portal.get(), "redturtle.bandi") + + +def to_1009(context): + def fix_index(blocks): + """ + revert to tassonomia_argomenti + """ + for block in blocks.values(): + if block.get("@type", "") == "listing": + for query in block.get("query", []): + if query["i"] == "argomenti": + query["i"] = "tassonomia_argomenti" + logger.info(" - {}".format(brain.getURL())) + + # fix root + portal = api.portal.get() + portal_blocks = json.loads(portal.blocks) + fix_index(portal_blocks) + portal.blocks = json.dumps(portal_blocks) + + logger.info("Fixing listing blocks.") + for brain in api.content.find(object_provides="plone.restapi.behaviors.IBlocks"): + item = brain.getObject() + blocks = deepcopy(getattr(item, "blocks", {})) + if blocks: + fix_index(blocks) + item.blocks = blocks + logger.info("** Reindexing items that refers to an argument **") + for brain in api.portal.get_tool("portal_catalog")(): + item = brain.getObject() + if getattr(item.aq_base, "tassonomia_argomenti", []): + logger.info(" - {}".format(brain.getURL())) + item.reindexObject(idxs=["tassonomia_argomenti"]) + + +def to_1010(context): + pc = api.portal.get_tool(name="portal_catalog") + pc.manage_reindexIndex(ids=["event_location"]) + + +def to_1013(context): + def fix_template_name(blocks): + """ + revert to tassonomia_argomenti + """ + found = False + for block in blocks.values(): + if ( + block.get("@type", "") == "listing" + and block.get("template", "") == "imageGallery" + ): + block["template"] = "photogallery" + found = True + return found + + # fix root + logger.info('Changing listing block template from "imageGallery" to "photogallery') + portal = api.portal.get() + portal_blocks = json.loads(portal.blocks) + to_update = fix_template_name(portal_blocks) + fixed_items = [] + if to_update: + portal.blocks = json.dumps(portal_blocks) + fixed_items.append("Root") + i = 0 + brains = api.content.find(object_provides="plone.restapi.behaviors.IBlocks") + tot = len(brains) + for brain in brains: + i += 1 + if i % 1000 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + item = brain.getObject() + blocks = deepcopy(getattr(item, "blocks", {})) + if blocks: + to_update = fix_template_name(blocks) + if to_update: + item.blocks = blocks + fixed_items.append(brain.getPath()) + + logger.info("Finish") + if fixed_items: + logger.info("Updated items:") + for fixed in fixed_items: + logger.info("- {}".format(fixed)) + else: + logger.info("No items affected.") + + +def to_1014(context): + update_types(context) + portal_types = api.portal.get_tool(name="portal_types") + portal_types["Bando"].behaviors = tuple( + [ + x + for x in portal_types["Bando"].behaviors + if x != "design.plone.contenttypes.behavior.argomenti" + ] + ) + + +def to_1015(context): + update_types(context) + + # cleanup trasparenza behavior from CTs + portal_types = api.portal.get_tool(name="portal_types") + service_behaviors = portal_types["Servizio"].behaviors + to_remove = [ + "design.plone.contenttypes.behavior.trasparenza", + ] + portal_types["Servizio"].behaviors = tuple( + [x for x in service_behaviors if x not in to_remove] + ) + persona_behaviors = portal_types["Persona"].behaviors + portal_types["Persona"].behaviors = tuple( + [x for x in persona_behaviors if x not in to_remove] + ) + + +def to_1016(context): + section_ids = ["amministrazione", "servizi", "novita", "documenti-e-dati"] + sections = [] + portal = api.portal.get() + for id in section_ids: + item = portal.get(id, None) + if item: + sections.append({"title": item.title, "linkUrl": [item.UID()]}) + settings = [{"rootPath": "/", "items": sections}] + api.portal.set_registry_record( + "search_sections", + json.dumps(settings), + interface=IDesignPloneSettings, + ) + + +def to_2000(context): # noqa: C901 + # remove volto.blocks behavior from news and events and add new one + update_types(context) + portal_types = api.portal.get_tool(name="portal_types") + for ptype in ["News Item", "Event"]: + portal_types[ptype].behaviors = tuple( + [x for x in portal_types[ptype].behaviors if x != "volto.blocks"] + ) + portal_types["Pagina Argomento"].behaviors = tuple( + [ + x + for x in portal_types["Pagina Argomento"].behaviors + if x != "design.plone.contenttypes.behavior.additional_help_infos" + ] + ) + # now copy values in new fields + pc = api.portal.get_tool(name="portal_catalog") + brains = pc() + tot = len(brains) + i = 0 + logger.info("### START CONVERSION FIELDS RICHTEXT -> DRAFTJS ###") + for brain in brains: + i += 1 + if i % 1000 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + item = brain.getObject() + if brain.portal_type in ["Event", "News Item"]: + blocks = getattr(item, "blocks", {}) + blocks_layout = getattr(item, "blocks_layout", {"items": []})["items"] + if not blocks: + continue + title_uid = "" + new_blocks = {} + for uid, block in blocks.items(): + if block.get("@type", "") == "title": + title_uid = uid + else: + new_blocks[uid] = block + item.descrizione_estesa = { + "blocks": new_blocks, + "blocks_layout": { + "items": [x for x in blocks_layout if x != title_uid] + }, + } + item.blocks = None + item.blocks_layout = None + for schema in iterSchemata(item): + for name, field in getFields(schema).items(): + if not isinstance(field, BlocksField): + continue + value = field.get(item) + if not value: + continue + if isinstance(value, six.string_types): + value = "

{}

".format(value) + elif isinstance(value, RichTextValue): + value = value.raw + else: + continue + if value == "


": + value = "" + try: + new_value = to_draftjs(value) + except Exception as e: + logger.error( + "[NOT MIGRATED] - {}: {}".format(brain.getPath(), name) + ) + raise e + setattr(item, name, new_value) + + +def to_2002(context): + """Per l'aggiornamento del vocabolario tipologie_persona, sistemiamo + tutti quelli già presenti. + """ + type_mapping = { + "altro": "Altro tipo", + "politica": "Politica", + "amministrativa": "Amministrativa", + } + logger.info("Fixing 'Tipologia Persona'...") + fixed_total = 0 + for brain in api.content.find(portal_type="Persona"): + item = brain.getObject() + if hasattr(item, "tipologia_persona") and item.tipologia_persona in type_mapping: # noqa + item.tipologia_persona = type_mapping[item.tipologia_persona] + fixed_total += 1 + commit() + logger.info("Fixing 'Tipologia Persona': DONE") + logger.info("Updated {} objects".format(fixed_total)) + + +def to_3000(context): + """ """ + update_registry(context) + update_controlpanel(context) + multilanguage = [ + "tipologie_notizia", + "tipologie_unita_organizzativa", + # "tipologie_documento", + "tipologie_persona", + ] + simple = ["lead_image_dimension", "search_sections"] + old_entry = "design.plone.contenttypes.controlpanels.vocabularies.IVocabulariesControlPanel.{}" # noqa + for field in simple: + value = api.portal.get_registry_record(old_entry.format(field)) + api.portal.set_registry_record(field, value, interface=IDesignPloneSettings) + + for field in multilanguage: + try: + value = api.portal.get_registry_record(old_entry.format(field)) + api.portal.set_registry_record( + field, + json.dumps({"it": value}), + interface=IDesignPloneSettings, + ) + except Exception: + continue + + context.runAllImportStepsFromProfile("profile-design.plone.contenttypes:to_3000") + + +def to_3101(context): + intids = getUtility(IIntIds) + logger.info("Fixing Documento references...") + fixed_total = 0 + for brain in api.content.find(portal_type="Documento"): + item = brain.getObject() + for rel in getattr(item, "servizi_collegati", []): + service = rel.to_object + if service: + service.altri_documenti.append(RelationValue(intids.getId(item))) + notify(ObjectModifiedEvent(service)) + logger.info("Fixed item {}".format("/".join(service.getPhysicalPath()))) + + if getattr(item, "servizi_collegati", []): + delattr(item, "servizi_collegati") + notify(ObjectModifiedEvent(item)) + fixed_total += 1 + logger.info("Fixed item {}".format("/".join(item.getPhysicalPath()))) + + logger.info("Fixing 'Documento': DONE") + logger.info("Updated {} objects Documento".format(fixed_total)) + + +def to_3102(context): + update_types(context) + + # cleanup trasparenza behavior from CTs + portal_types = api.portal.get_tool(name="portal_types") + to_remove = [ + "design.plone.contenttypes.behavior.trasparenza", + ] + for key, value in portal_types.items(): + ct_behaviors = getattr(value, "behaviors", None) + if ct_behaviors is not None: + portal_types[key].behaviors = tuple( + [x for x in ct_behaviors if x not in to_remove] + ) + + +def to_volto13(context): # noqa: C901 + # convert listing blocks with new standard + + logger.info("### START CONVERSION TO VOLTO 13: default => simpleCard ###") + + def fix_listing(blocks, url): + for block in blocks.values(): + if block.get("@type", "") == "listing": + if block.get("template", False) and not block.get("variation", False): + # import pdb + + # pdb.set_trace() + logger.error("- {}".format(url)) + if block.get("template", False) and block.get("variation", False): + logger.error("- {}".format(url)) + if block.get("variation", "") == "default": + block["variation"] = "simpleCard" + logger.info("- {}".format(url)) + + # fix root + portal = api.portal.get() + portal_blocks = json.loads(portal.blocks) + fix_listing(portal_blocks, portal.absolute_url()) + portal.blocks = json.dumps(portal_blocks) + + # fix blocks in contents + pc = api.portal.get_tool(name="portal_catalog") + brains = pc() + tot = len(brains) + i = 0 + for brain in brains: + i += 1 + if i % 1000 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + item = aq_base(brain.getObject()) + if getattr(item, "blocks", {}): + blocks = deepcopy(item.blocks) + if blocks: + fix_listing(blocks, brain.getURL()) + item.blocks = blocks + for schema in iterSchemata(item): + # fix blocks in blocksfields + for name, field in getFields(schema).items(): + if name == "blocks": + blocks = deepcopy(item.blocks) + if blocks: + fix_listing(blocks, brain.getURL()) + item.blocks = blocks + elif isinstance(field, BlocksField): + value = deepcopy(field.get(item)) + if not value: + continue + if isinstance(value, str): + if value == "": + setattr( + item, + name, + {"blocks": {}, "blocks_layout": {"items": []}}, + ) + continue + try: + blocks = value.get("blocks", {}) + except AttributeError: + logger.warning( + "[RICHTEXT] - {} (not converted)".format(brain.getURL()) + ) + if blocks: + fix_listing(blocks, brain.getURL()) + setattr(item, name, value) + + +def to_3400(context): # noqa: C901 + logger.info("### START CONVERSION BLOCKS: newsHome -> highlitedContent ###") + + def fix_block(blocks, url): + for block in blocks.values(): + if block.get("@type", "") == "newsHome": + block["@type"] = "highlitedContent" + + # fix root + portal = api.portal.get() + portal_blocks = json.loads(portal.blocks) + fix_block(portal_blocks, portal.absolute_url()) + portal.blocks = json.dumps(portal_blocks) + + # fix blocks in contents + pc = api.portal.get_tool(name="portal_catalog") + brains = pc() + tot = len(brains) + i = 0 + for brain in brains: + i += 1 + if i % 1000 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + item = aq_base(brain.getObject()) + if getattr(item, "blocks", {}): + blocks = deepcopy(item.blocks) + if blocks: + fix_block(blocks, brain.getURL()) + item.blocks = blocks + for schema in iterSchemata(item): + # fix blocks in blocksfields + for name, field in getFields(schema).items(): + if name == "blocks": + blocks = deepcopy(item.blocks) + if blocks: + fix_block(blocks, brain.getURL()) + item.blocks = blocks + elif isinstance(field, BlocksField): + value = deepcopy(field.get(item)) + if not value: + continue + if isinstance(value, str): + if value == "": + setattr( + item, + name, + {"blocks": {}, "blocks_layout": {"items": []}}, + ) + continue + try: + blocks = value.get("blocks", {}) + except AttributeError: + logger.warning( + "[RICHTEXT] - {} (not converted)".format(brain.getURL()) + ) + if blocks: + fix_block(blocks, brain.getURL()) + setattr(item, name, value) + + +def to_3401(context): # noqa: C901 + logger.info("File type can now be added inside a CartellaModulistica") + update_types(context) + + +def to_3500(context): + logger.info("Add new index and reindex UO") + update_catalog(context) + + # remove unused index + catalog = api.portal.get_tool(name="portal_catalog") + if "office_venue" in catalog.indexes(): + catalog.manage_delIndex("office_venue") + + # reindex + brains = api.content.find(portal_type="UnitaOrganizzativa") + tot = len(brains) + logger.info("Found {} UO.".format(tot)) + i = 0 + for brain in brains: + i += 1 + if i % 1000 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + uo = brain.getObject() + uo.reindexObject(idxs=["uo_location", "tipologia_organizzazione"]) + + +def to_3501(context): + logger.info("Reindex UO for new SearchableText fields") + + brains = api.content.find(portal_type="UnitaOrganizzativa") + tot = len(brains) + logger.info("Found {} UO.".format(tot)) + i = 0 + for brain in brains: + i += 1 + if i % 1000 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + uo = brain.getObject() + uo.reindexObject(idxs=["SearchableText"]) + + +def to_3600(context): + logger.info("Enable kitconcept.seo behavior") + types_list = [ + "UnitaOrganizzativa", + "Bando", + "Subsite", + "Venue", + "Persona", + "Event", + "News Item", + "Document", + "Documento", + "Servizio", + "CartellaModulistica", + "Pagina Argomento", + ] + portal_types = api.portal.get_tool(name="portal_types") + for ct_type in types_list: + if "kitconcept.seo" not in portal_types[ct_type].behaviors: + portal_types[ct_type].behaviors += ("kitconcept.seo",) + logger.info("Enabled kitconcept.seo on: {}".format(ct_type)) + + logger.info("Bandi customizations") + update_catalog(context) + api.portal.set_registry_record("default_ente", (), interface=IBandoSettings) + + portal_types = api.portal.get_tool(name="portal_types") + portal_types["Bando Folder Deepening"].allowed_content_types = ( + "Modulo", + "File", + "Link", + ) + portal_types["Bando"].default_view = "view" + portal_types["Bando"].view_methods = ("view",) + + logger.info("Reindex SearchableText") + pc = api.portal.get_tool(name="portal_catalog") + pc.reindexIndex("SearchableText", context.REQUEST) + + logger.info("Reindex Bandi") + i = 0 + brains = api.content.find(portal_type="Bando") + tot = len(brains) + for brain in brains: + i += 1 + if i % 1000 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + bando = brain.getObject() + bando.reindexObject(idxs=["ufficio_responsabile_bando", "Subject_bando"]) + + +def to_3700(context): + logger.info("Set show_modified_default as True") + + api.portal.set_registry_record( + "show_modified_default", True, interface=IDesignPloneSettings + ) + + +def to_3800(context): + logger.info("Fix Venue addable types") + + portal_types = api.portal.get_tool(name="portal_types") + portal_types["Venue"].allowed_content_types = ( + "Folder", + "Image", + "File", + "Link", + ) + + +def to_3900(context): + logger.info("Add new metadata: ruolo") + + brains = api.content.find(portal_type="Persona") + for brain in brains: + persona = brain.getObject() + persona.reindexObject() + + +def to_4000(context): + logger.info("Move ruolo to a choice field") + ruoli = {"it": [], "en": []} + brains = api.content.find(portal_type="Persona") + for brain in brains: + persona = brain.getObject() + ruolo = getattr(persona, "ruolo", "") + lang = brain.language + if ruolo not in ruoli[lang]: + ruoli[lang].append(ruolo) + + if api.portal.get_registry_record( + "ruoli_persona", + interface=IDesignPloneSettings, + default=None + ): + api.portal.set_registry_record( + "ruoli_persona", json.dumps(ruoli), interface=IDesignPloneSettings + ) + + +def to_4100(context): + logger.info("Add constrainttypes behavior to Document") + + portal_types = api.portal.get_tool(name="portal_types") + document_behaviors = list(portal_types["Document"].behaviors) + [ + "plone.constraintypes" + ] + portal_types["Document"].behaviors = tuple(document_behaviors) + + +def to_4200(context): + logger.info("Add criteria and indexes to Persona") + + update_catalog(context) + update_registry(context) + + brains = api.content.find(portal_type="Persona") + for brain in brains: + persona = brain.getObject() + persona.reindexObject(idxs=["data_conclusione_incarico"]) + + +def to_5000(context): + logger.info("Enable preview_image behavior in all content types") + + portal_types = api.portal.get_tool(name="portal_types") + + for portal_type, fti in portal_types.items(): + behaviors = list(getattr(fti, "behaviors", ())) + if not behaviors: + continue + if portal_type == "Document": + behaviors = [ + x + for x in behaviors + if x not in ["plone.leadimage", "volto.preview_image"] + ] + behaviors.extend(["plone.leadimage", "volto.preview_image"]) + else: + if "plone.leadimage" not in behaviors or "volto.preview_image" in behaviors: + continue + behaviors.insert(behaviors.index("plone.leadimage") + 1, "volto.preview_image") + fti.behaviors = tuple(behaviors) + + logger.info("Move immagine_testata to image") + catalog = api.portal.get_tool("portal_catalog") + i = 0 + brains = catalog() + tot = len(brains) + for brain in brains: + i += 1 + if i % 500 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + obj = brain.getObject() + if "image" in obj.keys(): + api.content.rename(obj=obj["image"], new_id="image-1") + if brain.portal_type == "Document": + immagine_testata = getattr(obj, "immagine_testata", None) + if immagine_testata: + obj.image = immagine_testata + obj.immagine_testata = None + catalog.catalog_object(obj) + + +def to_5001(context): + catalog = api.portal.get_tool("portal_catalog") + i = 0 + brains = catalog(portal_type="Pagina Argomento") + tot = len(brains) + logger.info("Add icona metadata to {}".format(tot)) + for brain in brains: + i += 1 + if i % 500 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + obj = brain.getObject() + catalog.catalog_object(obj) + + +def to_5002(context): + """ + Reindex non-folderish items because there were some metadata not updated + """ + catalog = api.portal.get_tool("portal_catalog") + i = 0 + brains = catalog(is_folderish=False) + tot = len(brains) + for brain in brains: + i += 1 + if i % 500 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + obj = brain.getObject() + catalog.catalog_object(obj) + + +def to_5200(context): + """ + add new behavior for Bando + """ + portal_types = api.portal.get_tool(name="portal_types") + fti = portal_types["Bando"] + behaviors = list(getattr(fti, "behaviors", ())) + if "design.plone.contenttypes.behavior.update_note" not in behaviors: + behaviors.append("design.plone.contenttypes.behavior.update_note") + fti.behaviors = tuple(behaviors) + + +def to_5210(context): + logger.info("Enable preview_image behavior in Bandi content types") + + portal_types = api.portal.get_tool(name="portal_types") + fti = portal_types["Bando"] + behaviors = list(getattr(fti, "behaviors", ())) + if "volto.preview_image" not in behaviors: + behaviors.append("volto.preview_image") + fti.behaviors = tuple(behaviors) + + +def to_5220(context): + """ + Reindex Venues + """ + logger.info("Reindex SearchableText for Venue items.") + catalog = api.portal.get_tool("portal_catalog") + i = 0 + brains = catalog(portal_type="Venue") + tot = len(brains) + for brain in brains: + i += 1 + if i % 500 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + obj = brain.getObject() + obj.reindexObject(idxs=["SearchableText", "object_provides"]) + + +def to_5300(context): + update_profile(context, "plone-difftool") + update_profile(context, "repositorytool") + + portal_types = api.portal.get_tool(name="portal_types") + for portal_type, fti in portal_types.items(): + if portal_type in [ + "CartellaModulistica", + "Documento", + "Link", + "Pagina Argomento", + "Persona", + "Servizio", + "UnitaOrganizzativa", + "Venue", + ]: + behaviors = list(getattr(fti, "behaviors", ())) + if "plone.versioning" not in behaviors: + behaviors.append("plone.versioning") + fti.behaviors = tuple(behaviors) + + +def to_5310(context): + """ + Reindex Bandi + """ + logger.info("Reindex SearchableText for Bandi items.") + catalog = api.portal.get_tool("portal_catalog") + i = 0 + brains = catalog(portal_type="Bando") + tot = len(brains) + for brain in brains: + i += 1 + if i % 500 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + brain.getObject().reindexObject(idxs=["SearchableText"]) + + +def to_5400(context): + logger.info('Remove "volto.blocks" behavior from News Item and Event.') + remove_blocks_behavior(context) + + +def to_5410(context): + + # cleanup Document behaviors + portal_types = api.portal.get_tool(name="portal_types") + behaviors = portal_types["Document"].behaviors + to_remove = [ + "plone.tableofcontents", + ] + portal_types["Document"].behaviors = tuple( + [x for x in behaviors if x not in to_remove] + ) + + +def to_6000(context): + """ """ + logger.info( + "Convert behavior: collective.dexteritytextindexer => plone.textindexer" # noqa + ) + portal_types = api.portal.get_tool(name="portal_types") + for fti in portal_types.values(): + behaviors = [] + for behavior in getattr(fti, "behaviors", ()): + if behavior == "collective.dexteritytextindexer": + behavior = "plone.textindexer" + behaviors.append(behavior) + + fti.behaviors = tuple(behaviors) + + +def to_6010(context): + """ """ + update_types(context) + update_registry(context) + update_catalog(context) + update_rolemap(context) + + +def migrate_pdc_and_incarico(context): + # Cannot test rn, blind coding + update_types(context) + update_registry(context) + update_catalog(context) + update_rolemap(context) + # "field name in original ct": "field name in new ct" + type_mapping = { + "Persona": { + 'PDC': { + "telefono": "phone", + "fax": "fax", + "email": "email", + "pec": "pec", + }, + "Incarico": { + # HOW? Need taxonomies also + # We could do: + # persona.ruolo.title = incarico.title + # persona.items.compensi = incarico.items.compensi? + "ruolo?": "incarico?", + # BlobFile to relation with Documento + "atto_nomina": "atto_nomina", + "data_conclusione_incarico": "data_conclusione_incarico", + "data_insediamento": "data_insediamento", + } + }, + "UnitaOrganizzativa": { + 'PDC': { + "telefono": "phone", + "fax": "fax", + "email": "email", + "pec": "pec", + }, + }, + # TODO: tbc + "Event": { + 'PDC': { + "telefono": "phone", + "fax": "fax", + "email": "email", + "pec": "pec", + }, + }, + # TODO: tbc + "Venue": { + 'PDC': { + "riferimento_telefonico_struttura": "phone", + "riferimento_fax_struttura": "fax", + "riferimento_mail_struttura": "email", + "riferimento_pec_struttura": "pec", + }, + }, + # TODO: tbc + "Servizio": { + # questi non sono presenti sul ct originale + 'PDC': { + "telefono": "phone", + "fax": "fax", + "email": "email", + "pec": "pec", + }, + }, + } + + def createIncaricoAndMigratePersona(portal_type): + # Taxonomies work needs to be completed before, blind coding ahead + if portal_type == 'Persona': + fixed_total = 0 + for brain in api.content.find(portal_type=portal_type): + item = brain.getObject() + atto_nomina = item.atto_nomina + logger.info(f"Fixing Punto di Contatto for '{item.title}'...") # noqa + file_bog = api.content.find(context=item, depth=1, id='atti-nomina') + if not file_bog: + try: + file_bog = api.content.create( + type="Document", id="atti-nomina", title="Atti Nomina", container=item + ) + except Exception: + logger.error("Error", Exception) + + try: + new_atto_nomina = api.content.create( + type="File", + id=atto_nomina.id, + title=atto_nomina.title, + container=item, + **{'file': atto_nomina} + ) + intids = getUtility(IIntIds) + relation = [RelationValue(intids.getId(new_atto_nomina))] + incarico = api.content.create( + type="Incarico", title=item.ruolo.title, container=item + ) + incarico.atto_nomina = relation + item.atto_nomina = None + fixed_total += 1 + logger.info(f"Fixing Punto di Contatto for '{item.title}'...:DONE") # noqa + except Exception: + logger.error("Error", Exception) + logger.info("Updated {} objects".format(fixed_total)) + + pass + + def createPDCandMigrateOldCTs(portal_type): + logger.info(f"Fixing Punto di Contatto for '{portal_type}'...") # noqa + fixed_total = 0 + mapping = None + # mapping = type_mapping[portal_type]["PDC"] + # Reenable mapping to use + if not mapping: + logger.info(f"No need to fix Punto di Contatto for '{portal_type}: DONE") + return + for brain in api.content.find(portal_type=portal_type): + item = brain.getObject() + kwargs = { + "value_punto_contatto": [], + "persona": [] + } + for key, value in mapping.items(): + import pdb; pdb.set_trace() + + if hasattr(item, key): + kwargs["value_punto_contatto"].append({ + 'pdc_type': value, + 'pdc_value': item[key] + }) + + new_pdc = api.content.create( + type='PuntoDiContatto', + title=f"Punto di Contatto {item.id}", + container=item, + **kwargs, + ) + intids = getUtility(IIntIds) + import pdb; pdb.set_trace() + item.contact_info = [RelationValue(intids.getId(new_pdc))] + fixed_total += 1 + + logger.info(f"Fixing Punto di Contatto for '{portal_type}: DONE") + logger.info("Updated {} objects".format(fixed_total)) + + for pt in type_mapping: + logger.info("Migrating existing CTs for use with new Incarico and PDC Content Types") + createPDCandMigrateOldCTs(pt) + createIncaricoAndMigratePersona(pt) diff --git a/.history/src/design/plone/contenttypes/upgrades/upgrades_20230104110844.py b/.history/src/design/plone/contenttypes/upgrades/upgrades_20230104110844.py new file mode 100644 index 00000000..74acdebb --- /dev/null +++ b/.history/src/design/plone/contenttypes/upgrades/upgrades_20230104110844.py @@ -0,0 +1,1130 @@ +# -*- coding: utf-8 -*- +from Acquisition import aq_base +from collective.volto.blocksfield.field import BlocksField +from copy import deepcopy +from design.plone.contenttypes.controlpanels.settings import IDesignPloneSettings +from design.plone.contenttypes.upgrades.draftjs_converter import to_draftjs +from design.plone.contenttypes.setuphandlers import remove_blocks_behavior +from plone import api +from plone.app.textfield.value import RichTextValue +from plone.app.upgrade.utils import installOrReinstallProduct +from plone.dexterity.utils import iterSchemata +from redturtle.bandi.interfaces.settings import IBandoSettings +from transaction import commit +from z3c.relationfield import RelationValue +from zope.component import getUtility +from zope.event import notify +from zope.intid.interfaces import IIntIds +from zope.lifecycleevent import ObjectModifiedEvent +from zope.schema import getFields +from zope.component import getUtility +from zope.intid.interfaces import IIntIds +from z3c.relationfield import RelationValue + +import json +import logging +import json +import six + + +logger = logging.getLogger(__name__) + +DEFAULT_PROFILE = "profile-design.plone.contenttypes:default" + +# standard upgrades # + + +def update_profile(context, profile, run_dependencies=True): + context.runImportStepFromProfile(DEFAULT_PROFILE, profile, run_dependencies) + + +def update_types(context): + update_profile(context, "typeinfo") + + +def update_rolemap(context): + update_profile(context, "rolemap") + + +def update_registry(context): + update_profile(context, "plone.app.registry", run_dependencies=False) + + +def update_catalog(context): + update_profile(context, "catalog") + + +def update_controlpanel(context): + update_profile(context, "controlpanel") + + +def remap_fields(mapping): + pc = api.portal.get_tool(name="portal_catalog") + brains = pc() + tot = len(brains) + logger.info("Trovati {} elementi da sistemare.".format(tot)) + # remap fields + for brain in brains: + item = brain.getObject() + for old, new in mapping.items(): + value = getattr(item, old, None) + if value: + setattr(item, new, value) + setattr(item, old, None) + logger.info( + "- {url}: {old} -> {new}".format( + url=brain.getURL(), old=old, new=new + ) + ) + delattr(item, old) + + +# custom ones # + + +def to_1001(context): + + update_types(context) + + # cleanup event behaviors + portal_types = api.portal.get_tool(name="portal_types") + behaviors = portal_types["Event"].behaviors + to_remove = [ + "design.plone.contenttypes.behavior.luoghi_correlati", + "design.plone.contenttypes.behavior.argomenti_evento", + "design.plone.contenttypes.behavior.additional_help_infos_evento", + ] + portal_types["Event"].behaviors = tuple( + [x for x in behaviors if x not in to_remove] + ) + + mapping = { + # "descrizione_destinatari": "a_chi_si_rivolge", + "canale_fisico": "dove_rivolgersi_extra", + "canale_fisico_prenotazione": "prenota_appuntamento", + "fasi_scadenze": "tempi_e_scadenze", + "sedi_e_luoghi": "dove_rivolgersi", + "box_aiuto": "ulteriori_informazioni", + "riferimento_telefonico_luogo": "telefono", + "riferimento_mail_luogo": "email", + } + remap_fields(mapping=mapping) + + +def to_1003(context): + + update_types(context) + + mapping = { + "unita_amministrativa_responsabile": "unita_amministrative_responsabili", # noqa + "sedi": "sede", + "contatto_reperibilita": "reperibilita", + "evento_supportato_da": "supportato_da", + } + remap_fields(mapping=mapping) + + +def to_1005(context): + def fix_index(blocks): + for block in blocks.values(): + if block.get("@type", "") == "listing": + for query in block.get("query", []): + if ( + query["i"] == "argomenti_correlati" + or query["i"] == "tassonomia_argomenti" + ): # noqa + query["i"] = "argomenti" + logger.info(" - {}".format(brain.getURL())) + + # fix root + portal = api.portal.get() + portal_blocks = json.loads(portal.blocks) + fix_index(portal_blocks) + portal.blocks = json.dumps(portal_blocks) + + logger.info("Fixing listing blocks.") + for brain in api.content.find(object_provides="plone.restapi.behaviors.IBlocks"): + item = brain.getObject() + blocks = deepcopy(getattr(item, "blocks", {})) + if blocks: + fix_index(blocks) + item.blocks = blocks + logger.info("** Reindexing items that refers to an argument **") + for brain in api.portal.get_tool("portal_catalog")(): + item = brain.getObject() + if getattr(item.aq_base, "tassonomia_argomenti", []): + logger.info(" - {}".format(brain.getURL())) + item.reindexObject(idxs=["argomenti"]) + + +def to_1006(context): + def fix_index(blocks): + for block in blocks.values(): + if block.get("@type", "") == "listing": + for query in block.get("query", []): + if ( + query["i"] == "argomenti_correlati" + or query["i"] == "tassonomia_argomenti" + or query["i"] == "argomenti" + ): # noqa + query["i"] = "argomenti" + query["v"] = [x.Title for x in api.content.find(UID=query["v"])] + logger.info(" - {}".format(brain.getURL())) + + # fix root + portal = api.portal.get() + portal_blocks = json.loads(portal.blocks) + fix_index(portal_blocks) + portal.blocks = json.dumps(portal_blocks) + + logger.info("Fixing listing blocks.") + for brain in api.content.find(object_provides="plone.restapi.behaviors.IBlocks"): + item = brain.getObject() + blocks = deepcopy(getattr(item, "blocks", {})) + if blocks: + fix_index(blocks) + item.blocks = blocks + + +def to_1007(context): + for brain in api.content.find(portal_type="Persona"): + item = brain.getObject() + if item.email: + item.email = [item.email] + if item.telefono: + item.telefono = [item.telefono] + + +def to_1008(context): + installOrReinstallProduct(api.portal.get(), "redturtle.bandi") + + +def to_1009(context): + def fix_index(blocks): + """ + revert to tassonomia_argomenti + """ + for block in blocks.values(): + if block.get("@type", "") == "listing": + for query in block.get("query", []): + if query["i"] == "argomenti": + query["i"] = "tassonomia_argomenti" + logger.info(" - {}".format(brain.getURL())) + + # fix root + portal = api.portal.get() + portal_blocks = json.loads(portal.blocks) + fix_index(portal_blocks) + portal.blocks = json.dumps(portal_blocks) + + logger.info("Fixing listing blocks.") + for brain in api.content.find(object_provides="plone.restapi.behaviors.IBlocks"): + item = brain.getObject() + blocks = deepcopy(getattr(item, "blocks", {})) + if blocks: + fix_index(blocks) + item.blocks = blocks + logger.info("** Reindexing items that refers to an argument **") + for brain in api.portal.get_tool("portal_catalog")(): + item = brain.getObject() + if getattr(item.aq_base, "tassonomia_argomenti", []): + logger.info(" - {}".format(brain.getURL())) + item.reindexObject(idxs=["tassonomia_argomenti"]) + + +def to_1010(context): + pc = api.portal.get_tool(name="portal_catalog") + pc.manage_reindexIndex(ids=["event_location"]) + + +def to_1013(context): + def fix_template_name(blocks): + """ + revert to tassonomia_argomenti + """ + found = False + for block in blocks.values(): + if ( + block.get("@type", "") == "listing" + and block.get("template", "") == "imageGallery" + ): + block["template"] = "photogallery" + found = True + return found + + # fix root + logger.info('Changing listing block template from "imageGallery" to "photogallery') + portal = api.portal.get() + portal_blocks = json.loads(portal.blocks) + to_update = fix_template_name(portal_blocks) + fixed_items = [] + if to_update: + portal.blocks = json.dumps(portal_blocks) + fixed_items.append("Root") + i = 0 + brains = api.content.find(object_provides="plone.restapi.behaviors.IBlocks") + tot = len(brains) + for brain in brains: + i += 1 + if i % 1000 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + item = brain.getObject() + blocks = deepcopy(getattr(item, "blocks", {})) + if blocks: + to_update = fix_template_name(blocks) + if to_update: + item.blocks = blocks + fixed_items.append(brain.getPath()) + + logger.info("Finish") + if fixed_items: + logger.info("Updated items:") + for fixed in fixed_items: + logger.info("- {}".format(fixed)) + else: + logger.info("No items affected.") + + +def to_1014(context): + update_types(context) + portal_types = api.portal.get_tool(name="portal_types") + portal_types["Bando"].behaviors = tuple( + [ + x + for x in portal_types["Bando"].behaviors + if x != "design.plone.contenttypes.behavior.argomenti" + ] + ) + + +def to_1015(context): + update_types(context) + + # cleanup trasparenza behavior from CTs + portal_types = api.portal.get_tool(name="portal_types") + service_behaviors = portal_types["Servizio"].behaviors + to_remove = [ + "design.plone.contenttypes.behavior.trasparenza", + ] + portal_types["Servizio"].behaviors = tuple( + [x for x in service_behaviors if x not in to_remove] + ) + persona_behaviors = portal_types["Persona"].behaviors + portal_types["Persona"].behaviors = tuple( + [x for x in persona_behaviors if x not in to_remove] + ) + + +def to_1016(context): + section_ids = ["amministrazione", "servizi", "novita", "documenti-e-dati"] + sections = [] + portal = api.portal.get() + for id in section_ids: + item = portal.get(id, None) + if item: + sections.append({"title": item.title, "linkUrl": [item.UID()]}) + settings = [{"rootPath": "/", "items": sections}] + api.portal.set_registry_record( + "search_sections", + json.dumps(settings), + interface=IDesignPloneSettings, + ) + + +def to_2000(context): # noqa: C901 + # remove volto.blocks behavior from news and events and add new one + update_types(context) + portal_types = api.portal.get_tool(name="portal_types") + for ptype in ["News Item", "Event"]: + portal_types[ptype].behaviors = tuple( + [x for x in portal_types[ptype].behaviors if x != "volto.blocks"] + ) + portal_types["Pagina Argomento"].behaviors = tuple( + [ + x + for x in portal_types["Pagina Argomento"].behaviors + if x != "design.plone.contenttypes.behavior.additional_help_infos" + ] + ) + # now copy values in new fields + pc = api.portal.get_tool(name="portal_catalog") + brains = pc() + tot = len(brains) + i = 0 + logger.info("### START CONVERSION FIELDS RICHTEXT -> DRAFTJS ###") + for brain in brains: + i += 1 + if i % 1000 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + item = brain.getObject() + if brain.portal_type in ["Event", "News Item"]: + blocks = getattr(item, "blocks", {}) + blocks_layout = getattr(item, "blocks_layout", {"items": []})["items"] + if not blocks: + continue + title_uid = "" + new_blocks = {} + for uid, block in blocks.items(): + if block.get("@type", "") == "title": + title_uid = uid + else: + new_blocks[uid] = block + item.descrizione_estesa = { + "blocks": new_blocks, + "blocks_layout": { + "items": [x for x in blocks_layout if x != title_uid] + }, + } + item.blocks = None + item.blocks_layout = None + for schema in iterSchemata(item): + for name, field in getFields(schema).items(): + if not isinstance(field, BlocksField): + continue + value = field.get(item) + if not value: + continue + if isinstance(value, six.string_types): + value = "

{}

".format(value) + elif isinstance(value, RichTextValue): + value = value.raw + else: + continue + if value == "


": + value = "" + try: + new_value = to_draftjs(value) + except Exception as e: + logger.error( + "[NOT MIGRATED] - {}: {}".format(brain.getPath(), name) + ) + raise e + setattr(item, name, new_value) + + +def to_2002(context): + """Per l'aggiornamento del vocabolario tipologie_persona, sistemiamo + tutti quelli già presenti. + """ + type_mapping = { + "altro": "Altro tipo", + "politica": "Politica", + "amministrativa": "Amministrativa", + } + logger.info("Fixing 'Tipologia Persona'...") + fixed_total = 0 + for brain in api.content.find(portal_type="Persona"): + item = brain.getObject() + if ( + hasattr(item, "tipologia_persona") + and item.tipologia_persona in type_mapping + ): # noqa + item.tipologia_persona = type_mapping[item.tipologia_persona] + fixed_total += 1 + commit() + logger.info("Fixing 'Tipologia Persona': DONE") + logger.info("Updated {} objects".format(fixed_total)) + + +def to_3000(context): + """ """ + update_registry(context) + update_controlpanel(context) + multilanguage = [ + "tipologie_notizia", + "tipologie_unita_organizzativa", + # "tipologie_documento", + "tipologie_persona", + ] + simple = ["lead_image_dimension", "search_sections"] + old_entry = "design.plone.contenttypes.controlpanels.vocabularies.IVocabulariesControlPanel.{}" # noqa + for field in simple: + value = api.portal.get_registry_record(old_entry.format(field)) + api.portal.set_registry_record(field, value, interface=IDesignPloneSettings) + + for field in multilanguage: + try: + value = api.portal.get_registry_record(old_entry.format(field)) + api.portal.set_registry_record( + field, + json.dumps({"it": value}), + interface=IDesignPloneSettings, + ) + except Exception: + continue + + context.runAllImportStepsFromProfile("profile-design.plone.contenttypes:to_3000") + + +def to_3101(context): + intids = getUtility(IIntIds) + logger.info("Fixing Documento references...") + fixed_total = 0 + for brain in api.content.find(portal_type="Documento"): + item = brain.getObject() + for rel in getattr(item, "servizi_collegati", []): + service = rel.to_object + if service: + service.altri_documenti.append(RelationValue(intids.getId(item))) + notify(ObjectModifiedEvent(service)) + logger.info("Fixed item {}".format("/".join(service.getPhysicalPath()))) + + if getattr(item, "servizi_collegati", []): + delattr(item, "servizi_collegati") + notify(ObjectModifiedEvent(item)) + fixed_total += 1 + logger.info("Fixed item {}".format("/".join(item.getPhysicalPath()))) + + logger.info("Fixing 'Documento': DONE") + logger.info("Updated {} objects Documento".format(fixed_total)) + + +def to_3102(context): + update_types(context) + + # cleanup trasparenza behavior from CTs + portal_types = api.portal.get_tool(name="portal_types") + to_remove = [ + "design.plone.contenttypes.behavior.trasparenza", + ] + for key, value in portal_types.items(): + ct_behaviors = getattr(value, "behaviors", None) + if ct_behaviors is not None: + portal_types[key].behaviors = tuple( + [x for x in ct_behaviors if x not in to_remove] + ) + + +def to_volto13(context): # noqa: C901 + # convert listing blocks with new standard + + logger.info("### START CONVERSION TO VOLTO 13: default => simpleCard ###") + + def fix_listing(blocks, url): + for block in blocks.values(): + if block.get("@type", "") == "listing": + if block.get("template", False) and not block.get("variation", False): + # import pdb + + # pdb.set_trace() + logger.error("- {}".format(url)) + if block.get("template", False) and block.get("variation", False): + logger.error("- {}".format(url)) + if block.get("variation", "") == "default": + block["variation"] = "simpleCard" + logger.info("- {}".format(url)) + + # fix root + portal = api.portal.get() + portal_blocks = json.loads(portal.blocks) + fix_listing(portal_blocks, portal.absolute_url()) + portal.blocks = json.dumps(portal_blocks) + + # fix blocks in contents + pc = api.portal.get_tool(name="portal_catalog") + brains = pc() + tot = len(brains) + i = 0 + for brain in brains: + i += 1 + if i % 1000 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + item = aq_base(brain.getObject()) + if getattr(item, "blocks", {}): + blocks = deepcopy(item.blocks) + if blocks: + fix_listing(blocks, brain.getURL()) + item.blocks = blocks + for schema in iterSchemata(item): + # fix blocks in blocksfields + for name, field in getFields(schema).items(): + if name == "blocks": + blocks = deepcopy(item.blocks) + if blocks: + fix_listing(blocks, brain.getURL()) + item.blocks = blocks + elif isinstance(field, BlocksField): + value = deepcopy(field.get(item)) + if not value: + continue + if isinstance(value, str): + if value == "": + setattr( + item, + name, + {"blocks": {}, "blocks_layout": {"items": []}}, + ) + continue + try: + blocks = value.get("blocks", {}) + except AttributeError: + logger.warning( + "[RICHTEXT] - {} (not converted)".format(brain.getURL()) + ) + if blocks: + fix_listing(blocks, brain.getURL()) + setattr(item, name, value) + + +def to_3400(context): # noqa: C901 + logger.info("### START CONVERSION BLOCKS: newsHome -> highlitedContent ###") + + def fix_block(blocks, url): + for block in blocks.values(): + if block.get("@type", "") == "newsHome": + block["@type"] = "highlitedContent" + + # fix root + portal = api.portal.get() + portal_blocks = json.loads(portal.blocks) + fix_block(portal_blocks, portal.absolute_url()) + portal.blocks = json.dumps(portal_blocks) + + # fix blocks in contents + pc = api.portal.get_tool(name="portal_catalog") + brains = pc() + tot = len(brains) + i = 0 + for brain in brains: + i += 1 + if i % 1000 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + item = aq_base(brain.getObject()) + if getattr(item, "blocks", {}): + blocks = deepcopy(item.blocks) + if blocks: + fix_block(blocks, brain.getURL()) + item.blocks = blocks + for schema in iterSchemata(item): + # fix blocks in blocksfields + for name, field in getFields(schema).items(): + if name == "blocks": + blocks = deepcopy(item.blocks) + if blocks: + fix_block(blocks, brain.getURL()) + item.blocks = blocks + elif isinstance(field, BlocksField): + value = deepcopy(field.get(item)) + if not value: + continue + if isinstance(value, str): + if value == "": + setattr( + item, + name, + {"blocks": {}, "blocks_layout": {"items": []}}, + ) + continue + try: + blocks = value.get("blocks", {}) + except AttributeError: + logger.warning( + "[RICHTEXT] - {} (not converted)".format(brain.getURL()) + ) + if blocks: + fix_block(blocks, brain.getURL()) + setattr(item, name, value) + + +def to_3401(context): # noqa: C901 + logger.info("File type can now be added inside a CartellaModulistica") + update_types(context) + + +def to_3500(context): + logger.info("Add new index and reindex UO") + update_catalog(context) + + # remove unused index + catalog = api.portal.get_tool(name="portal_catalog") + if "office_venue" in catalog.indexes(): + catalog.manage_delIndex("office_venue") + + # reindex + brains = api.content.find(portal_type="UnitaOrganizzativa") + tot = len(brains) + logger.info("Found {} UO.".format(tot)) + i = 0 + for brain in brains: + i += 1 + if i % 1000 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + uo = brain.getObject() + uo.reindexObject(idxs=["uo_location", "tipologia_organizzazione"]) + + +def to_3501(context): + logger.info("Reindex UO for new SearchableText fields") + + brains = api.content.find(portal_type="UnitaOrganizzativa") + tot = len(brains) + logger.info("Found {} UO.".format(tot)) + i = 0 + for brain in brains: + i += 1 + if i % 1000 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + uo = brain.getObject() + uo.reindexObject(idxs=["SearchableText"]) + + +def to_3600(context): + logger.info("Enable kitconcept.seo behavior") + types_list = [ + "UnitaOrganizzativa", + "Bando", + "Subsite", + "Venue", + "Persona", + "Event", + "News Item", + "Document", + "Documento", + "Servizio", + "CartellaModulistica", + "Pagina Argomento", + ] + portal_types = api.portal.get_tool(name="portal_types") + for ct_type in types_list: + if "kitconcept.seo" not in portal_types[ct_type].behaviors: + portal_types[ct_type].behaviors += ("kitconcept.seo",) + logger.info("Enabled kitconcept.seo on: {}".format(ct_type)) + + logger.info("Bandi customizations") + update_catalog(context) + api.portal.set_registry_record("default_ente", (), interface=IBandoSettings) + + portal_types = api.portal.get_tool(name="portal_types") + portal_types["Bando Folder Deepening"].allowed_content_types = ( + "Modulo", + "File", + "Link", + ) + portal_types["Bando"].default_view = "view" + portal_types["Bando"].view_methods = ("view",) + + logger.info("Reindex SearchableText") + pc = api.portal.get_tool(name="portal_catalog") + pc.reindexIndex("SearchableText", context.REQUEST) + + logger.info("Reindex Bandi") + i = 0 + brains = api.content.find(portal_type="Bando") + tot = len(brains) + for brain in brains: + i += 1 + if i % 1000 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + bando = brain.getObject() + bando.reindexObject(idxs=["ufficio_responsabile_bando", "Subject_bando"]) + + +def to_3700(context): + logger.info("Set show_modified_default as True") + + api.portal.set_registry_record( + "show_modified_default", True, interface=IDesignPloneSettings + ) + + +def to_3800(context): + logger.info("Fix Venue addable types") + + portal_types = api.portal.get_tool(name="portal_types") + portal_types["Venue"].allowed_content_types = ( + "Folder", + "Image", + "File", + "Link", + ) + + +def to_3900(context): + logger.info("Add new metadata: ruolo") + + brains = api.content.find(portal_type="Persona") + for brain in brains: + persona = brain.getObject() + persona.reindexObject() + + +def to_4000(context): + logger.info("Move ruolo to a choice field") + ruoli = {"it": [], "en": []} + brains = api.content.find(portal_type="Persona") + for brain in brains: + persona = brain.getObject() + ruolo = getattr(persona, "ruolo", "") + lang = brain.language + if ruolo not in ruoli[lang]: + ruoli[lang].append(ruolo) + + if api.portal.get_registry_record( + "ruoli_persona", interface=IDesignPloneSettings, default=None + ): + api.portal.set_registry_record( + "ruoli_persona", json.dumps(ruoli), interface=IDesignPloneSettings + ) + + +def to_4100(context): + logger.info("Add constrainttypes behavior to Document") + + portal_types = api.portal.get_tool(name="portal_types") + document_behaviors = list(portal_types["Document"].behaviors) + [ + "plone.constraintypes" + ] + portal_types["Document"].behaviors = tuple(document_behaviors) + + +def to_4200(context): + logger.info("Add criteria and indexes to Persona") + + update_catalog(context) + update_registry(context) + + brains = api.content.find(portal_type="Persona") + for brain in brains: + persona = brain.getObject() + persona.reindexObject(idxs=["data_conclusione_incarico"]) + + +def to_5000(context): + logger.info("Enable preview_image behavior in all content types") + + portal_types = api.portal.get_tool(name="portal_types") + + for portal_type, fti in portal_types.items(): + behaviors = list(getattr(fti, "behaviors", ())) + if not behaviors: + continue + if portal_type == "Document": + behaviors = [ + x + for x in behaviors + if x not in ["plone.leadimage", "volto.preview_image"] + ] + behaviors.extend(["plone.leadimage", "volto.preview_image"]) + else: + if "plone.leadimage" not in behaviors or "volto.preview_image" in behaviors: + continue + behaviors.insert(behaviors.index("plone.leadimage") + 1, "volto.preview_image") + fti.behaviors = tuple(behaviors) + + logger.info("Move immagine_testata to image") + catalog = api.portal.get_tool("portal_catalog") + i = 0 + brains = catalog() + tot = len(brains) + for brain in brains: + i += 1 + if i % 500 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + obj = brain.getObject() + if "image" in obj.keys(): + api.content.rename(obj=obj["image"], new_id="image-1") + if brain.portal_type == "Document": + immagine_testata = getattr(obj, "immagine_testata", None) + if immagine_testata: + obj.image = immagine_testata + obj.immagine_testata = None + catalog.catalog_object(obj) + + +def to_5001(context): + catalog = api.portal.get_tool("portal_catalog") + i = 0 + brains = catalog(portal_type="Pagina Argomento") + tot = len(brains) + logger.info("Add icona metadata to {}".format(tot)) + for brain in brains: + i += 1 + if i % 500 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + obj = brain.getObject() + catalog.catalog_object(obj) + + +def to_5002(context): + """ + Reindex non-folderish items because there were some metadata not updated + """ + catalog = api.portal.get_tool("portal_catalog") + i = 0 + brains = catalog(is_folderish=False) + tot = len(brains) + for brain in brains: + i += 1 + if i % 500 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + obj = brain.getObject() + catalog.catalog_object(obj) + + +def to_5200(context): + """ + add new behavior for Bando + """ + portal_types = api.portal.get_tool(name="portal_types") + fti = portal_types["Bando"] + behaviors = list(getattr(fti, "behaviors", ())) + if "design.plone.contenttypes.behavior.update_note" not in behaviors: + behaviors.append("design.plone.contenttypes.behavior.update_note") + fti.behaviors = tuple(behaviors) + + +def to_5210(context): + logger.info("Enable preview_image behavior in Bandi content types") + + portal_types = api.portal.get_tool(name="portal_types") + fti = portal_types["Bando"] + behaviors = list(getattr(fti, "behaviors", ())) + if "volto.preview_image" not in behaviors: + behaviors.append("volto.preview_image") + fti.behaviors = tuple(behaviors) + + +def to_5220(context): + """ + Reindex Venues + """ + logger.info("Reindex SearchableText for Venue items.") + catalog = api.portal.get_tool("portal_catalog") + i = 0 + brains = catalog(portal_type="Venue") + tot = len(brains) + for brain in brains: + i += 1 + if i % 500 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + obj = brain.getObject() + obj.reindexObject(idxs=["SearchableText", "object_provides"]) + + +def to_5300(context): + update_profile(context, "plone-difftool") + update_profile(context, "repositorytool") + + portal_types = api.portal.get_tool(name="portal_types") + for portal_type, fti in portal_types.items(): + if portal_type in [ + "CartellaModulistica", + "Documento", + "Link", + "Pagina Argomento", + "Persona", + "Servizio", + "UnitaOrganizzativa", + "Venue", + ]: + behaviors = list(getattr(fti, "behaviors", ())) + if "plone.versioning" not in behaviors: + behaviors.append("plone.versioning") + fti.behaviors = tuple(behaviors) + + +def to_5310(context): + """ + Reindex Bandi + """ + logger.info("Reindex SearchableText for Bandi items.") + catalog = api.portal.get_tool("portal_catalog") + i = 0 + brains = catalog(portal_type="Bando") + tot = len(brains) + for brain in brains: + i += 1 + if i % 500 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + brain.getObject().reindexObject(idxs=["SearchableText"]) + + +def to_5400(context): + logger.info('Remove "volto.blocks" behavior from News Item and Event.') + remove_blocks_behavior(context) + + +def to_5410(context): + + # cleanup Document behaviors + portal_types = api.portal.get_tool(name="portal_types") + behaviors = portal_types["Document"].behaviors + to_remove = [ + "plone.tableofcontents", + ] + portal_types["Document"].behaviors = tuple( + [x for x in behaviors if x not in to_remove] + ) + + +def to_6000(context): + """ """ + logger.info( + "Convert behavior: collective.dexteritytextindexer => plone.textindexer" # noqa + ) + portal_types = api.portal.get_tool(name="portal_types") + for fti in portal_types.values(): + behaviors = [] + for behavior in getattr(fti, "behaviors", ()): + if behavior == "collective.dexteritytextindexer": + behavior = "plone.textindexer" + behaviors.append(behavior) + + fti.behaviors = tuple(behaviors) + + +def to_6010(context): + """ """ + update_types(context) + update_registry(context) + update_catalog(context) + update_rolemap(context) + + +def migrate_pdc_and_incarico(context): + # Cannot test rn, blind coding + update_types(context) + update_registry(context) + update_catalog(context) + update_rolemap(context) + # "field name in original ct": "field name in new ct" + type_mapping = { + "Persona": { + 'PDC': { + "telefono": "phone", + "fax": "fax", + "email": "email", + "pec": "pec", + }, + "Incarico": { + # HOW? Need taxonomies also + # We could do: + # persona.ruolo.title = incarico.title + # persona.items.compensi = incarico.items.compensi? + "ruolo?": "incarico?", + # BlobFile to relation with Documento + "atto_nomina": "atto_nomina", + "data_conclusione_incarico": "data_conclusione_incarico", + "data_insediamento": "data_insediamento", + } + }, + "UnitaOrganizzativa": { + 'PDC': { + "telefono": "phone", + "fax": "fax", + "email": "email", + "pec": "pec", + }, + }, + # TODO: tbc + "Event": { + 'PDC': { + "telefono": "phone", + "fax": "fax", + "email": "email", + "pec": "pec", + }, + }, + # TODO: tbc + "Venue": { + 'PDC': { + "riferimento_telefonico_struttura": "phone", + "riferimento_fax_struttura": "fax", + "riferimento_mail_struttura": "email", + "riferimento_pec_struttura": "pec", + }, + }, + # TODO: tbc + "Servizio": { + # questi non sono presenti sul ct originale + 'PDC': { + "telefono": "phone", + "fax": "fax", + "email": "email", + "pec": "pec", + }, + }, + } + + def createIncaricoAndMigratePersona(portal_type): + # Taxonomies work needs to be completed before, blind coding ahead + if portal_type == 'Persona': + fixed_total = 0 + for brain in api.content.find(portal_type=portal_type): + item = brain.getObject() + atto_nomina = item.atto_nomina + logger.info(f"Fixing Punto di Contatto for '{item.title}'...") # noqa + file_bog = api.content.find(context=item, depth=1, id='atti-nomina') + if not file_bog: + try: + file_bog = api.content.create( + type="Document", id="atti-nomina", title="Atti Nomina", container=item + ) + except Exception: + logger.error("Error", Exception) + + try: + new_atto_nomina = api.content.create( + type="File", + id=atto_nomina.id, + title=atto_nomina.title, + container=item, + **{'file': atto_nomina} + ) + intids = getUtility(IIntIds) + relation = [RelationValue(intids.getId(new_atto_nomina))] + incarico = api.content.create( + type="Incarico", title=item.ruolo.title, container=item + ) + incarico.atto_nomina = relation + item.atto_nomina = None + fixed_total += 1 + logger.info(f"Fixing Punto di Contatto for '{item.title}'...:DONE") # noqa + except Exception: + logger.error("Error", Exception) + logger.info("Updated {} objects".format(fixed_total)) + + pass + + def createPDCandMigrateOldCTs(portal_type): + logger.info(f"Fixing Punto di Contatto for '{portal_type}'...") # noqa + fixed_total = 0 + mapping = None + # mapping = type_mapping[portal_type]["PDC"] + # Reenable mapping to use + if not mapping: + logger.info(f"No need to fix Punto di Contatto for '{portal_type}: DONE") + return + for brain in api.content.find(portal_type=portal_type): + item = brain.getObject() + kwargs = { + "value_punto_contatto": [], + "persona": [] + } + for key, value in mapping.items(): + import pdb; pdb.set_trace() + + if hasattr(item, key): + kwargs["value_punto_contatto"].append({ + 'pdc_type': value, + 'pdc_value': item[key] + }) + + new_pdc = api.content.create( + type='PuntoDiContatto', + title=f"Punto di Contatto {item.id}", + container=item, + **kwargs, + ) + intids = getUtility(IIntIds) + import pdb; pdb.set_trace() + item.contact_info = [RelationValue(intids.getId(new_pdc))] + fixed_total += 1 + + logger.info(f"Fixing Punto di Contatto for '{portal_type}: DONE") + logger.info("Updated {} objects".format(fixed_total)) + + for pt in type_mapping: + logger.info("Migrating existing CTs for use with new Incarico and PDC Content Types") + createPDCandMigrateOldCTs(pt) + createIncaricoAndMigratePersona(pt) diff --git a/.history/src/design/plone/contenttypes/upgrades/upgrades_20230104110851.py b/.history/src/design/plone/contenttypes/upgrades/upgrades_20230104110851.py new file mode 100644 index 00000000..68fcecb5 --- /dev/null +++ b/.history/src/design/plone/contenttypes/upgrades/upgrades_20230104110851.py @@ -0,0 +1,1129 @@ +# -*- coding: utf-8 -*- +from Acquisition import aq_base +from collective.volto.blocksfield.field import BlocksField +from copy import deepcopy +from design.plone.contenttypes.controlpanels.settings import IDesignPloneSettings +from design.plone.contenttypes.upgrades.draftjs_converter import to_draftjs +from design.plone.contenttypes.setuphandlers import remove_blocks_behavior +from plone import api +from plone.app.textfield.value import RichTextValue +from plone.app.upgrade.utils import installOrReinstallProduct +from plone.dexterity.utils import iterSchemata +from redturtle.bandi.interfaces.settings import IBandoSettings +from transaction import commit +from z3c.relationfield import RelationValue +from zope.component import getUtility +from zope.event import notify +from zope.intid.interfaces import IIntIds +from zope.lifecycleevent import ObjectModifiedEvent +from zope.schema import getFields +from zope.component import getUtility +from zope.intid.interfaces import IIntIds +from z3c.relationfield import RelationValue + +import json +import logging +import six + + +logger = logging.getLogger(__name__) + +DEFAULT_PROFILE = "profile-design.plone.contenttypes:default" + +# standard upgrades # + + +def update_profile(context, profile, run_dependencies=True): + context.runImportStepFromProfile(DEFAULT_PROFILE, profile, run_dependencies) + + +def update_types(context): + update_profile(context, "typeinfo") + + +def update_rolemap(context): + update_profile(context, "rolemap") + + +def update_registry(context): + update_profile(context, "plone.app.registry", run_dependencies=False) + + +def update_catalog(context): + update_profile(context, "catalog") + + +def update_controlpanel(context): + update_profile(context, "controlpanel") + + +def remap_fields(mapping): + pc = api.portal.get_tool(name="portal_catalog") + brains = pc() + tot = len(brains) + logger.info("Trovati {} elementi da sistemare.".format(tot)) + # remap fields + for brain in brains: + item = brain.getObject() + for old, new in mapping.items(): + value = getattr(item, old, None) + if value: + setattr(item, new, value) + setattr(item, old, None) + logger.info( + "- {url}: {old} -> {new}".format( + url=brain.getURL(), old=old, new=new + ) + ) + delattr(item, old) + + +# custom ones # + + +def to_1001(context): + + update_types(context) + + # cleanup event behaviors + portal_types = api.portal.get_tool(name="portal_types") + behaviors = portal_types["Event"].behaviors + to_remove = [ + "design.plone.contenttypes.behavior.luoghi_correlati", + "design.plone.contenttypes.behavior.argomenti_evento", + "design.plone.contenttypes.behavior.additional_help_infos_evento", + ] + portal_types["Event"].behaviors = tuple( + [x for x in behaviors if x not in to_remove] + ) + + mapping = { + # "descrizione_destinatari": "a_chi_si_rivolge", + "canale_fisico": "dove_rivolgersi_extra", + "canale_fisico_prenotazione": "prenota_appuntamento", + "fasi_scadenze": "tempi_e_scadenze", + "sedi_e_luoghi": "dove_rivolgersi", + "box_aiuto": "ulteriori_informazioni", + "riferimento_telefonico_luogo": "telefono", + "riferimento_mail_luogo": "email", + } + remap_fields(mapping=mapping) + + +def to_1003(context): + + update_types(context) + + mapping = { + "unita_amministrativa_responsabile": "unita_amministrative_responsabili", # noqa + "sedi": "sede", + "contatto_reperibilita": "reperibilita", + "evento_supportato_da": "supportato_da", + } + remap_fields(mapping=mapping) + + +def to_1005(context): + def fix_index(blocks): + for block in blocks.values(): + if block.get("@type", "") == "listing": + for query in block.get("query", []): + if ( + query["i"] == "argomenti_correlati" + or query["i"] == "tassonomia_argomenti" + ): # noqa + query["i"] = "argomenti" + logger.info(" - {}".format(brain.getURL())) + + # fix root + portal = api.portal.get() + portal_blocks = json.loads(portal.blocks) + fix_index(portal_blocks) + portal.blocks = json.dumps(portal_blocks) + + logger.info("Fixing listing blocks.") + for brain in api.content.find(object_provides="plone.restapi.behaviors.IBlocks"): + item = brain.getObject() + blocks = deepcopy(getattr(item, "blocks", {})) + if blocks: + fix_index(blocks) + item.blocks = blocks + logger.info("** Reindexing items that refers to an argument **") + for brain in api.portal.get_tool("portal_catalog")(): + item = brain.getObject() + if getattr(item.aq_base, "tassonomia_argomenti", []): + logger.info(" - {}".format(brain.getURL())) + item.reindexObject(idxs=["argomenti"]) + + +def to_1006(context): + def fix_index(blocks): + for block in blocks.values(): + if block.get("@type", "") == "listing": + for query in block.get("query", []): + if ( + query["i"] == "argomenti_correlati" + or query["i"] == "tassonomia_argomenti" + or query["i"] == "argomenti" + ): # noqa + query["i"] = "argomenti" + query["v"] = [x.Title for x in api.content.find(UID=query["v"])] + logger.info(" - {}".format(brain.getURL())) + + # fix root + portal = api.portal.get() + portal_blocks = json.loads(portal.blocks) + fix_index(portal_blocks) + portal.blocks = json.dumps(portal_blocks) + + logger.info("Fixing listing blocks.") + for brain in api.content.find(object_provides="plone.restapi.behaviors.IBlocks"): + item = brain.getObject() + blocks = deepcopy(getattr(item, "blocks", {})) + if blocks: + fix_index(blocks) + item.blocks = blocks + + +def to_1007(context): + for brain in api.content.find(portal_type="Persona"): + item = brain.getObject() + if item.email: + item.email = [item.email] + if item.telefono: + item.telefono = [item.telefono] + + +def to_1008(context): + installOrReinstallProduct(api.portal.get(), "redturtle.bandi") + + +def to_1009(context): + def fix_index(blocks): + """ + revert to tassonomia_argomenti + """ + for block in blocks.values(): + if block.get("@type", "") == "listing": + for query in block.get("query", []): + if query["i"] == "argomenti": + query["i"] = "tassonomia_argomenti" + logger.info(" - {}".format(brain.getURL())) + + # fix root + portal = api.portal.get() + portal_blocks = json.loads(portal.blocks) + fix_index(portal_blocks) + portal.blocks = json.dumps(portal_blocks) + + logger.info("Fixing listing blocks.") + for brain in api.content.find(object_provides="plone.restapi.behaviors.IBlocks"): + item = brain.getObject() + blocks = deepcopy(getattr(item, "blocks", {})) + if blocks: + fix_index(blocks) + item.blocks = blocks + logger.info("** Reindexing items that refers to an argument **") + for brain in api.portal.get_tool("portal_catalog")(): + item = brain.getObject() + if getattr(item.aq_base, "tassonomia_argomenti", []): + logger.info(" - {}".format(brain.getURL())) + item.reindexObject(idxs=["tassonomia_argomenti"]) + + +def to_1010(context): + pc = api.portal.get_tool(name="portal_catalog") + pc.manage_reindexIndex(ids=["event_location"]) + + +def to_1013(context): + def fix_template_name(blocks): + """ + revert to tassonomia_argomenti + """ + found = False + for block in blocks.values(): + if ( + block.get("@type", "") == "listing" + and block.get("template", "") == "imageGallery" + ): + block["template"] = "photogallery" + found = True + return found + + # fix root + logger.info('Changing listing block template from "imageGallery" to "photogallery') + portal = api.portal.get() + portal_blocks = json.loads(portal.blocks) + to_update = fix_template_name(portal_blocks) + fixed_items = [] + if to_update: + portal.blocks = json.dumps(portal_blocks) + fixed_items.append("Root") + i = 0 + brains = api.content.find(object_provides="plone.restapi.behaviors.IBlocks") + tot = len(brains) + for brain in brains: + i += 1 + if i % 1000 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + item = brain.getObject() + blocks = deepcopy(getattr(item, "blocks", {})) + if blocks: + to_update = fix_template_name(blocks) + if to_update: + item.blocks = blocks + fixed_items.append(brain.getPath()) + + logger.info("Finish") + if fixed_items: + logger.info("Updated items:") + for fixed in fixed_items: + logger.info("- {}".format(fixed)) + else: + logger.info("No items affected.") + + +def to_1014(context): + update_types(context) + portal_types = api.portal.get_tool(name="portal_types") + portal_types["Bando"].behaviors = tuple( + [ + x + for x in portal_types["Bando"].behaviors + if x != "design.plone.contenttypes.behavior.argomenti" + ] + ) + + +def to_1015(context): + update_types(context) + + # cleanup trasparenza behavior from CTs + portal_types = api.portal.get_tool(name="portal_types") + service_behaviors = portal_types["Servizio"].behaviors + to_remove = [ + "design.plone.contenttypes.behavior.trasparenza", + ] + portal_types["Servizio"].behaviors = tuple( + [x for x in service_behaviors if x not in to_remove] + ) + persona_behaviors = portal_types["Persona"].behaviors + portal_types["Persona"].behaviors = tuple( + [x for x in persona_behaviors if x not in to_remove] + ) + + +def to_1016(context): + section_ids = ["amministrazione", "servizi", "novita", "documenti-e-dati"] + sections = [] + portal = api.portal.get() + for id in section_ids: + item = portal.get(id, None) + if item: + sections.append({"title": item.title, "linkUrl": [item.UID()]}) + settings = [{"rootPath": "/", "items": sections}] + api.portal.set_registry_record( + "search_sections", + json.dumps(settings), + interface=IDesignPloneSettings, + ) + + +def to_2000(context): # noqa: C901 + # remove volto.blocks behavior from news and events and add new one + update_types(context) + portal_types = api.portal.get_tool(name="portal_types") + for ptype in ["News Item", "Event"]: + portal_types[ptype].behaviors = tuple( + [x for x in portal_types[ptype].behaviors if x != "volto.blocks"] + ) + portal_types["Pagina Argomento"].behaviors = tuple( + [ + x + for x in portal_types["Pagina Argomento"].behaviors + if x != "design.plone.contenttypes.behavior.additional_help_infos" + ] + ) + # now copy values in new fields + pc = api.portal.get_tool(name="portal_catalog") + brains = pc() + tot = len(brains) + i = 0 + logger.info("### START CONVERSION FIELDS RICHTEXT -> DRAFTJS ###") + for brain in brains: + i += 1 + if i % 1000 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + item = brain.getObject() + if brain.portal_type in ["Event", "News Item"]: + blocks = getattr(item, "blocks", {}) + blocks_layout = getattr(item, "blocks_layout", {"items": []})["items"] + if not blocks: + continue + title_uid = "" + new_blocks = {} + for uid, block in blocks.items(): + if block.get("@type", "") == "title": + title_uid = uid + else: + new_blocks[uid] = block + item.descrizione_estesa = { + "blocks": new_blocks, + "blocks_layout": { + "items": [x for x in blocks_layout if x != title_uid] + }, + } + item.blocks = None + item.blocks_layout = None + for schema in iterSchemata(item): + for name, field in getFields(schema).items(): + if not isinstance(field, BlocksField): + continue + value = field.get(item) + if not value: + continue + if isinstance(value, six.string_types): + value = "

{}

".format(value) + elif isinstance(value, RichTextValue): + value = value.raw + else: + continue + if value == "


": + value = "" + try: + new_value = to_draftjs(value) + except Exception as e: + logger.error( + "[NOT MIGRATED] - {}: {}".format(brain.getPath(), name) + ) + raise e + setattr(item, name, new_value) + + +def to_2002(context): + """Per l'aggiornamento del vocabolario tipologie_persona, sistemiamo + tutti quelli già presenti. + """ + type_mapping = { + "altro": "Altro tipo", + "politica": "Politica", + "amministrativa": "Amministrativa", + } + logger.info("Fixing 'Tipologia Persona'...") + fixed_total = 0 + for brain in api.content.find(portal_type="Persona"): + item = brain.getObject() + if ( + hasattr(item, "tipologia_persona") + and item.tipologia_persona in type_mapping + ): # noqa + item.tipologia_persona = type_mapping[item.tipologia_persona] + fixed_total += 1 + commit() + logger.info("Fixing 'Tipologia Persona': DONE") + logger.info("Updated {} objects".format(fixed_total)) + + +def to_3000(context): + """ """ + update_registry(context) + update_controlpanel(context) + multilanguage = [ + "tipologie_notizia", + "tipologie_unita_organizzativa", + # "tipologie_documento", + "tipologie_persona", + ] + simple = ["lead_image_dimension", "search_sections"] + old_entry = "design.plone.contenttypes.controlpanels.vocabularies.IVocabulariesControlPanel.{}" # noqa + for field in simple: + value = api.portal.get_registry_record(old_entry.format(field)) + api.portal.set_registry_record(field, value, interface=IDesignPloneSettings) + + for field in multilanguage: + try: + value = api.portal.get_registry_record(old_entry.format(field)) + api.portal.set_registry_record( + field, + json.dumps({"it": value}), + interface=IDesignPloneSettings, + ) + except Exception: + continue + + context.runAllImportStepsFromProfile("profile-design.plone.contenttypes:to_3000") + + +def to_3101(context): + intids = getUtility(IIntIds) + logger.info("Fixing Documento references...") + fixed_total = 0 + for brain in api.content.find(portal_type="Documento"): + item = brain.getObject() + for rel in getattr(item, "servizi_collegati", []): + service = rel.to_object + if service: + service.altri_documenti.append(RelationValue(intids.getId(item))) + notify(ObjectModifiedEvent(service)) + logger.info("Fixed item {}".format("/".join(service.getPhysicalPath()))) + + if getattr(item, "servizi_collegati", []): + delattr(item, "servizi_collegati") + notify(ObjectModifiedEvent(item)) + fixed_total += 1 + logger.info("Fixed item {}".format("/".join(item.getPhysicalPath()))) + + logger.info("Fixing 'Documento': DONE") + logger.info("Updated {} objects Documento".format(fixed_total)) + + +def to_3102(context): + update_types(context) + + # cleanup trasparenza behavior from CTs + portal_types = api.portal.get_tool(name="portal_types") + to_remove = [ + "design.plone.contenttypes.behavior.trasparenza", + ] + for key, value in portal_types.items(): + ct_behaviors = getattr(value, "behaviors", None) + if ct_behaviors is not None: + portal_types[key].behaviors = tuple( + [x for x in ct_behaviors if x not in to_remove] + ) + + +def to_volto13(context): # noqa: C901 + # convert listing blocks with new standard + + logger.info("### START CONVERSION TO VOLTO 13: default => simpleCard ###") + + def fix_listing(blocks, url): + for block in blocks.values(): + if block.get("@type", "") == "listing": + if block.get("template", False) and not block.get("variation", False): + # import pdb + + # pdb.set_trace() + logger.error("- {}".format(url)) + if block.get("template", False) and block.get("variation", False): + logger.error("- {}".format(url)) + if block.get("variation", "") == "default": + block["variation"] = "simpleCard" + logger.info("- {}".format(url)) + + # fix root + portal = api.portal.get() + portal_blocks = json.loads(portal.blocks) + fix_listing(portal_blocks, portal.absolute_url()) + portal.blocks = json.dumps(portal_blocks) + + # fix blocks in contents + pc = api.portal.get_tool(name="portal_catalog") + brains = pc() + tot = len(brains) + i = 0 + for brain in brains: + i += 1 + if i % 1000 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + item = aq_base(brain.getObject()) + if getattr(item, "blocks", {}): + blocks = deepcopy(item.blocks) + if blocks: + fix_listing(blocks, brain.getURL()) + item.blocks = blocks + for schema in iterSchemata(item): + # fix blocks in blocksfields + for name, field in getFields(schema).items(): + if name == "blocks": + blocks = deepcopy(item.blocks) + if blocks: + fix_listing(blocks, brain.getURL()) + item.blocks = blocks + elif isinstance(field, BlocksField): + value = deepcopy(field.get(item)) + if not value: + continue + if isinstance(value, str): + if value == "": + setattr( + item, + name, + {"blocks": {}, "blocks_layout": {"items": []}}, + ) + continue + try: + blocks = value.get("blocks", {}) + except AttributeError: + logger.warning( + "[RICHTEXT] - {} (not converted)".format(brain.getURL()) + ) + if blocks: + fix_listing(blocks, brain.getURL()) + setattr(item, name, value) + + +def to_3400(context): # noqa: C901 + logger.info("### START CONVERSION BLOCKS: newsHome -> highlitedContent ###") + + def fix_block(blocks, url): + for block in blocks.values(): + if block.get("@type", "") == "newsHome": + block["@type"] = "highlitedContent" + + # fix root + portal = api.portal.get() + portal_blocks = json.loads(portal.blocks) + fix_block(portal_blocks, portal.absolute_url()) + portal.blocks = json.dumps(portal_blocks) + + # fix blocks in contents + pc = api.portal.get_tool(name="portal_catalog") + brains = pc() + tot = len(brains) + i = 0 + for brain in brains: + i += 1 + if i % 1000 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + item = aq_base(brain.getObject()) + if getattr(item, "blocks", {}): + blocks = deepcopy(item.blocks) + if blocks: + fix_block(blocks, brain.getURL()) + item.blocks = blocks + for schema in iterSchemata(item): + # fix blocks in blocksfields + for name, field in getFields(schema).items(): + if name == "blocks": + blocks = deepcopy(item.blocks) + if blocks: + fix_block(blocks, brain.getURL()) + item.blocks = blocks + elif isinstance(field, BlocksField): + value = deepcopy(field.get(item)) + if not value: + continue + if isinstance(value, str): + if value == "": + setattr( + item, + name, + {"blocks": {}, "blocks_layout": {"items": []}}, + ) + continue + try: + blocks = value.get("blocks", {}) + except AttributeError: + logger.warning( + "[RICHTEXT] - {} (not converted)".format(brain.getURL()) + ) + if blocks: + fix_block(blocks, brain.getURL()) + setattr(item, name, value) + + +def to_3401(context): # noqa: C901 + logger.info("File type can now be added inside a CartellaModulistica") + update_types(context) + + +def to_3500(context): + logger.info("Add new index and reindex UO") + update_catalog(context) + + # remove unused index + catalog = api.portal.get_tool(name="portal_catalog") + if "office_venue" in catalog.indexes(): + catalog.manage_delIndex("office_venue") + + # reindex + brains = api.content.find(portal_type="UnitaOrganizzativa") + tot = len(brains) + logger.info("Found {} UO.".format(tot)) + i = 0 + for brain in brains: + i += 1 + if i % 1000 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + uo = brain.getObject() + uo.reindexObject(idxs=["uo_location", "tipologia_organizzazione"]) + + +def to_3501(context): + logger.info("Reindex UO for new SearchableText fields") + + brains = api.content.find(portal_type="UnitaOrganizzativa") + tot = len(brains) + logger.info("Found {} UO.".format(tot)) + i = 0 + for brain in brains: + i += 1 + if i % 1000 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + uo = brain.getObject() + uo.reindexObject(idxs=["SearchableText"]) + + +def to_3600(context): + logger.info("Enable kitconcept.seo behavior") + types_list = [ + "UnitaOrganizzativa", + "Bando", + "Subsite", + "Venue", + "Persona", + "Event", + "News Item", + "Document", + "Documento", + "Servizio", + "CartellaModulistica", + "Pagina Argomento", + ] + portal_types = api.portal.get_tool(name="portal_types") + for ct_type in types_list: + if "kitconcept.seo" not in portal_types[ct_type].behaviors: + portal_types[ct_type].behaviors += ("kitconcept.seo",) + logger.info("Enabled kitconcept.seo on: {}".format(ct_type)) + + logger.info("Bandi customizations") + update_catalog(context) + api.portal.set_registry_record("default_ente", (), interface=IBandoSettings) + + portal_types = api.portal.get_tool(name="portal_types") + portal_types["Bando Folder Deepening"].allowed_content_types = ( + "Modulo", + "File", + "Link", + ) + portal_types["Bando"].default_view = "view" + portal_types["Bando"].view_methods = ("view",) + + logger.info("Reindex SearchableText") + pc = api.portal.get_tool(name="portal_catalog") + pc.reindexIndex("SearchableText", context.REQUEST) + + logger.info("Reindex Bandi") + i = 0 + brains = api.content.find(portal_type="Bando") + tot = len(brains) + for brain in brains: + i += 1 + if i % 1000 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + bando = brain.getObject() + bando.reindexObject(idxs=["ufficio_responsabile_bando", "Subject_bando"]) + + +def to_3700(context): + logger.info("Set show_modified_default as True") + + api.portal.set_registry_record( + "show_modified_default", True, interface=IDesignPloneSettings + ) + + +def to_3800(context): + logger.info("Fix Venue addable types") + + portal_types = api.portal.get_tool(name="portal_types") + portal_types["Venue"].allowed_content_types = ( + "Folder", + "Image", + "File", + "Link", + ) + + +def to_3900(context): + logger.info("Add new metadata: ruolo") + + brains = api.content.find(portal_type="Persona") + for brain in brains: + persona = brain.getObject() + persona.reindexObject() + + +def to_4000(context): + logger.info("Move ruolo to a choice field") + ruoli = {"it": [], "en": []} + brains = api.content.find(portal_type="Persona") + for brain in brains: + persona = brain.getObject() + ruolo = getattr(persona, "ruolo", "") + lang = brain.language + if ruolo not in ruoli[lang]: + ruoli[lang].append(ruolo) + + if api.portal.get_registry_record( + "ruoli_persona", interface=IDesignPloneSettings, default=None + ): + api.portal.set_registry_record( + "ruoli_persona", json.dumps(ruoli), interface=IDesignPloneSettings + ) + + +def to_4100(context): + logger.info("Add constrainttypes behavior to Document") + + portal_types = api.portal.get_tool(name="portal_types") + document_behaviors = list(portal_types["Document"].behaviors) + [ + "plone.constraintypes" + ] + portal_types["Document"].behaviors = tuple(document_behaviors) + + +def to_4200(context): + logger.info("Add criteria and indexes to Persona") + + update_catalog(context) + update_registry(context) + + brains = api.content.find(portal_type="Persona") + for brain in brains: + persona = brain.getObject() + persona.reindexObject(idxs=["data_conclusione_incarico"]) + + +def to_5000(context): + logger.info("Enable preview_image behavior in all content types") + + portal_types = api.portal.get_tool(name="portal_types") + + for portal_type, fti in portal_types.items(): + behaviors = list(getattr(fti, "behaviors", ())) + if not behaviors: + continue + if portal_type == "Document": + behaviors = [ + x + for x in behaviors + if x not in ["plone.leadimage", "volto.preview_image"] + ] + behaviors.extend(["plone.leadimage", "volto.preview_image"]) + else: + if "plone.leadimage" not in behaviors or "volto.preview_image" in behaviors: + continue + behaviors.insert(behaviors.index("plone.leadimage") + 1, "volto.preview_image") + fti.behaviors = tuple(behaviors) + + logger.info("Move immagine_testata to image") + catalog = api.portal.get_tool("portal_catalog") + i = 0 + brains = catalog() + tot = len(brains) + for brain in brains: + i += 1 + if i % 500 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + obj = brain.getObject() + if "image" in obj.keys(): + api.content.rename(obj=obj["image"], new_id="image-1") + if brain.portal_type == "Document": + immagine_testata = getattr(obj, "immagine_testata", None) + if immagine_testata: + obj.image = immagine_testata + obj.immagine_testata = None + catalog.catalog_object(obj) + + +def to_5001(context): + catalog = api.portal.get_tool("portal_catalog") + i = 0 + brains = catalog(portal_type="Pagina Argomento") + tot = len(brains) + logger.info("Add icona metadata to {}".format(tot)) + for brain in brains: + i += 1 + if i % 500 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + obj = brain.getObject() + catalog.catalog_object(obj) + + +def to_5002(context): + """ + Reindex non-folderish items because there were some metadata not updated + """ + catalog = api.portal.get_tool("portal_catalog") + i = 0 + brains = catalog(is_folderish=False) + tot = len(brains) + for brain in brains: + i += 1 + if i % 500 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + obj = brain.getObject() + catalog.catalog_object(obj) + + +def to_5200(context): + """ + add new behavior for Bando + """ + portal_types = api.portal.get_tool(name="portal_types") + fti = portal_types["Bando"] + behaviors = list(getattr(fti, "behaviors", ())) + if "design.plone.contenttypes.behavior.update_note" not in behaviors: + behaviors.append("design.plone.contenttypes.behavior.update_note") + fti.behaviors = tuple(behaviors) + + +def to_5210(context): + logger.info("Enable preview_image behavior in Bandi content types") + + portal_types = api.portal.get_tool(name="portal_types") + fti = portal_types["Bando"] + behaviors = list(getattr(fti, "behaviors", ())) + if "volto.preview_image" not in behaviors: + behaviors.append("volto.preview_image") + fti.behaviors = tuple(behaviors) + + +def to_5220(context): + """ + Reindex Venues + """ + logger.info("Reindex SearchableText for Venue items.") + catalog = api.portal.get_tool("portal_catalog") + i = 0 + brains = catalog(portal_type="Venue") + tot = len(brains) + for brain in brains: + i += 1 + if i % 500 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + obj = brain.getObject() + obj.reindexObject(idxs=["SearchableText", "object_provides"]) + + +def to_5300(context): + update_profile(context, "plone-difftool") + update_profile(context, "repositorytool") + + portal_types = api.portal.get_tool(name="portal_types") + for portal_type, fti in portal_types.items(): + if portal_type in [ + "CartellaModulistica", + "Documento", + "Link", + "Pagina Argomento", + "Persona", + "Servizio", + "UnitaOrganizzativa", + "Venue", + ]: + behaviors = list(getattr(fti, "behaviors", ())) + if "plone.versioning" not in behaviors: + behaviors.append("plone.versioning") + fti.behaviors = tuple(behaviors) + + +def to_5310(context): + """ + Reindex Bandi + """ + logger.info("Reindex SearchableText for Bandi items.") + catalog = api.portal.get_tool("portal_catalog") + i = 0 + brains = catalog(portal_type="Bando") + tot = len(brains) + for brain in brains: + i += 1 + if i % 500 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + brain.getObject().reindexObject(idxs=["SearchableText"]) + + +def to_5400(context): + logger.info('Remove "volto.blocks" behavior from News Item and Event.') + remove_blocks_behavior(context) + + +def to_5410(context): + + # cleanup Document behaviors + portal_types = api.portal.get_tool(name="portal_types") + behaviors = portal_types["Document"].behaviors + to_remove = [ + "plone.tableofcontents", + ] + portal_types["Document"].behaviors = tuple( + [x for x in behaviors if x not in to_remove] + ) + + +def to_6000(context): + """ """ + logger.info( + "Convert behavior: collective.dexteritytextindexer => plone.textindexer" # noqa + ) + portal_types = api.portal.get_tool(name="portal_types") + for fti in portal_types.values(): + behaviors = [] + for behavior in getattr(fti, "behaviors", ()): + if behavior == "collective.dexteritytextindexer": + behavior = "plone.textindexer" + behaviors.append(behavior) + + fti.behaviors = tuple(behaviors) + + +def to_6010(context): + """ """ + update_types(context) + update_registry(context) + update_catalog(context) + update_rolemap(context) + + +def migrate_pdc_and_incarico(context): + # Cannot test rn, blind coding + update_types(context) + update_registry(context) + update_catalog(context) + update_rolemap(context) + # "field name in original ct": "field name in new ct" + type_mapping = { + "Persona": { + 'PDC': { + "telefono": "phone", + "fax": "fax", + "email": "email", + "pec": "pec", + }, + "Incarico": { + # HOW? Need taxonomies also + # We could do: + # persona.ruolo.title = incarico.title + # persona.items.compensi = incarico.items.compensi? + "ruolo?": "incarico?", + # BlobFile to relation with Documento + "atto_nomina": "atto_nomina", + "data_conclusione_incarico": "data_conclusione_incarico", + "data_insediamento": "data_insediamento", + } + }, + "UnitaOrganizzativa": { + 'PDC': { + "telefono": "phone", + "fax": "fax", + "email": "email", + "pec": "pec", + }, + }, + # TODO: tbc + "Event": { + 'PDC': { + "telefono": "phone", + "fax": "fax", + "email": "email", + "pec": "pec", + }, + }, + # TODO: tbc + "Venue": { + 'PDC': { + "riferimento_telefonico_struttura": "phone", + "riferimento_fax_struttura": "fax", + "riferimento_mail_struttura": "email", + "riferimento_pec_struttura": "pec", + }, + }, + # TODO: tbc + "Servizio": { + # questi non sono presenti sul ct originale + 'PDC': { + "telefono": "phone", + "fax": "fax", + "email": "email", + "pec": "pec", + }, + }, + } + + def createIncaricoAndMigratePersona(portal_type): + # Taxonomies work needs to be completed before, blind coding ahead + if portal_type == 'Persona': + fixed_total = 0 + for brain in api.content.find(portal_type=portal_type): + item = brain.getObject() + atto_nomina = item.atto_nomina + logger.info(f"Fixing Punto di Contatto for '{item.title}'...") # noqa + file_bog = api.content.find(context=item, depth=1, id='atti-nomina') + if not file_bog: + try: + file_bog = api.content.create( + type="Document", id="atti-nomina", title="Atti Nomina", container=item + ) + except Exception: + logger.error("Error", Exception) + + try: + new_atto_nomina = api.content.create( + type="File", + id=atto_nomina.id, + title=atto_nomina.title, + container=item, + **{'file': atto_nomina} + ) + intids = getUtility(IIntIds) + relation = [RelationValue(intids.getId(new_atto_nomina))] + incarico = api.content.create( + type="Incarico", title=item.ruolo.title, container=item + ) + incarico.atto_nomina = relation + item.atto_nomina = None + fixed_total += 1 + logger.info(f"Fixing Punto di Contatto for '{item.title}'...:DONE") # noqa + except Exception: + logger.error("Error", Exception) + logger.info("Updated {} objects".format(fixed_total)) + + pass + + def createPDCandMigrateOldCTs(portal_type): + logger.info(f"Fixing Punto di Contatto for '{portal_type}'...") # noqa + fixed_total = 0 + mapping = None + # mapping = type_mapping[portal_type]["PDC"] + # Reenable mapping to use + if not mapping: + logger.info(f"No need to fix Punto di Contatto for '{portal_type}: DONE") + return + for brain in api.content.find(portal_type=portal_type): + item = brain.getObject() + kwargs = { + "value_punto_contatto": [], + "persona": [] + } + for key, value in mapping.items(): + import pdb; pdb.set_trace() + + if hasattr(item, key): + kwargs["value_punto_contatto"].append({ + 'pdc_type': value, + 'pdc_value': item[key] + }) + + new_pdc = api.content.create( + type='PuntoDiContatto', + title=f"Punto di Contatto {item.id}", + container=item, + **kwargs, + ) + intids = getUtility(IIntIds) + import pdb; pdb.set_trace() + item.contact_info = [RelationValue(intids.getId(new_pdc))] + fixed_total += 1 + + logger.info(f"Fixing Punto di Contatto for '{portal_type}: DONE") + logger.info("Updated {} objects".format(fixed_total)) + + for pt in type_mapping: + logger.info("Migrating existing CTs for use with new Incarico and PDC Content Types") + createPDCandMigrateOldCTs(pt) + createIncaricoAndMigratePersona(pt) diff --git a/.history/src/design/plone/contenttypes/upgrades/upgrades_20230104110901.py b/.history/src/design/plone/contenttypes/upgrades/upgrades_20230104110901.py new file mode 100644 index 00000000..e90dedb6 --- /dev/null +++ b/.history/src/design/plone/contenttypes/upgrades/upgrades_20230104110901.py @@ -0,0 +1,1127 @@ +# -*- coding: utf-8 -*- +from Acquisition import aq_base +from collective.volto.blocksfield.field import BlocksField +from copy import deepcopy +from design.plone.contenttypes.controlpanels.settings import IDesignPloneSettings +from design.plone.contenttypes.upgrades.draftjs_converter import to_draftjs +from design.plone.contenttypes.setuphandlers import remove_blocks_behavior +from plone import api +from plone.app.textfield.value import RichTextValue +from plone.app.upgrade.utils import installOrReinstallProduct +from plone.dexterity.utils import iterSchemata +from redturtle.bandi.interfaces.settings import IBandoSettings +from transaction import commit +from z3c.relationfield import RelationValue +from zope.component import getUtility +from zope.event import notify +from zope.intid.interfaces import IIntIds +from zope.lifecycleevent import ObjectModifiedEvent +from zope.schema import getFields + + +import json +import logging +import six + + +logger = logging.getLogger(__name__) + +DEFAULT_PROFILE = "profile-design.plone.contenttypes:default" + +# standard upgrades # + + +def update_profile(context, profile, run_dependencies=True): + context.runImportStepFromProfile(DEFAULT_PROFILE, profile, run_dependencies) + + +def update_types(context): + update_profile(context, "typeinfo") + + +def update_rolemap(context): + update_profile(context, "rolemap") + + +def update_registry(context): + update_profile(context, "plone.app.registry", run_dependencies=False) + + +def update_catalog(context): + update_profile(context, "catalog") + + +def update_controlpanel(context): + update_profile(context, "controlpanel") + + +def remap_fields(mapping): + pc = api.portal.get_tool(name="portal_catalog") + brains = pc() + tot = len(brains) + logger.info("Trovati {} elementi da sistemare.".format(tot)) + # remap fields + for brain in brains: + item = brain.getObject() + for old, new in mapping.items(): + value = getattr(item, old, None) + if value: + setattr(item, new, value) + setattr(item, old, None) + logger.info( + "- {url}: {old} -> {new}".format( + url=brain.getURL(), old=old, new=new + ) + ) + delattr(item, old) + + +# custom ones # + + +def to_1001(context): + + update_types(context) + + # cleanup event behaviors + portal_types = api.portal.get_tool(name="portal_types") + behaviors = portal_types["Event"].behaviors + to_remove = [ + "design.plone.contenttypes.behavior.luoghi_correlati", + "design.plone.contenttypes.behavior.argomenti_evento", + "design.plone.contenttypes.behavior.additional_help_infos_evento", + ] + portal_types["Event"].behaviors = tuple( + [x for x in behaviors if x not in to_remove] + ) + + mapping = { + # "descrizione_destinatari": "a_chi_si_rivolge", + "canale_fisico": "dove_rivolgersi_extra", + "canale_fisico_prenotazione": "prenota_appuntamento", + "fasi_scadenze": "tempi_e_scadenze", + "sedi_e_luoghi": "dove_rivolgersi", + "box_aiuto": "ulteriori_informazioni", + "riferimento_telefonico_luogo": "telefono", + "riferimento_mail_luogo": "email", + } + remap_fields(mapping=mapping) + + +def to_1003(context): + + update_types(context) + + mapping = { + "unita_amministrativa_responsabile": "unita_amministrative_responsabili", # noqa + "sedi": "sede", + "contatto_reperibilita": "reperibilita", + "evento_supportato_da": "supportato_da", + } + remap_fields(mapping=mapping) + + +def to_1005(context): + def fix_index(blocks): + for block in blocks.values(): + if block.get("@type", "") == "listing": + for query in block.get("query", []): + if ( + query["i"] == "argomenti_correlati" + or query["i"] == "tassonomia_argomenti" + ): # noqa + query["i"] = "argomenti" + logger.info(" - {}".format(brain.getURL())) + + # fix root + portal = api.portal.get() + portal_blocks = json.loads(portal.blocks) + fix_index(portal_blocks) + portal.blocks = json.dumps(portal_blocks) + + logger.info("Fixing listing blocks.") + for brain in api.content.find(object_provides="plone.restapi.behaviors.IBlocks"): + item = brain.getObject() + blocks = deepcopy(getattr(item, "blocks", {})) + if blocks: + fix_index(blocks) + item.blocks = blocks + logger.info("** Reindexing items that refers to an argument **") + for brain in api.portal.get_tool("portal_catalog")(): + item = brain.getObject() + if getattr(item.aq_base, "tassonomia_argomenti", []): + logger.info(" - {}".format(brain.getURL())) + item.reindexObject(idxs=["argomenti"]) + + +def to_1006(context): + def fix_index(blocks): + for block in blocks.values(): + if block.get("@type", "") == "listing": + for query in block.get("query", []): + if ( + query["i"] == "argomenti_correlati" + or query["i"] == "tassonomia_argomenti" + or query["i"] == "argomenti" + ): # noqa + query["i"] = "argomenti" + query["v"] = [x.Title for x in api.content.find(UID=query["v"])] + logger.info(" - {}".format(brain.getURL())) + + # fix root + portal = api.portal.get() + portal_blocks = json.loads(portal.blocks) + fix_index(portal_blocks) + portal.blocks = json.dumps(portal_blocks) + + logger.info("Fixing listing blocks.") + for brain in api.content.find(object_provides="plone.restapi.behaviors.IBlocks"): + item = brain.getObject() + blocks = deepcopy(getattr(item, "blocks", {})) + if blocks: + fix_index(blocks) + item.blocks = blocks + + +def to_1007(context): + for brain in api.content.find(portal_type="Persona"): + item = brain.getObject() + if item.email: + item.email = [item.email] + if item.telefono: + item.telefono = [item.telefono] + + +def to_1008(context): + installOrReinstallProduct(api.portal.get(), "redturtle.bandi") + + +def to_1009(context): + def fix_index(blocks): + """ + revert to tassonomia_argomenti + """ + for block in blocks.values(): + if block.get("@type", "") == "listing": + for query in block.get("query", []): + if query["i"] == "argomenti": + query["i"] = "tassonomia_argomenti" + logger.info(" - {}".format(brain.getURL())) + + # fix root + portal = api.portal.get() + portal_blocks = json.loads(portal.blocks) + fix_index(portal_blocks) + portal.blocks = json.dumps(portal_blocks) + + logger.info("Fixing listing blocks.") + for brain in api.content.find(object_provides="plone.restapi.behaviors.IBlocks"): + item = brain.getObject() + blocks = deepcopy(getattr(item, "blocks", {})) + if blocks: + fix_index(blocks) + item.blocks = blocks + logger.info("** Reindexing items that refers to an argument **") + for brain in api.portal.get_tool("portal_catalog")(): + item = brain.getObject() + if getattr(item.aq_base, "tassonomia_argomenti", []): + logger.info(" - {}".format(brain.getURL())) + item.reindexObject(idxs=["tassonomia_argomenti"]) + + +def to_1010(context): + pc = api.portal.get_tool(name="portal_catalog") + pc.manage_reindexIndex(ids=["event_location"]) + + +def to_1013(context): + def fix_template_name(blocks): + """ + revert to tassonomia_argomenti + """ + found = False + for block in blocks.values(): + if ( + block.get("@type", "") == "listing" + and block.get("template", "") == "imageGallery" + ): + block["template"] = "photogallery" + found = True + return found + + # fix root + logger.info('Changing listing block template from "imageGallery" to "photogallery') + portal = api.portal.get() + portal_blocks = json.loads(portal.blocks) + to_update = fix_template_name(portal_blocks) + fixed_items = [] + if to_update: + portal.blocks = json.dumps(portal_blocks) + fixed_items.append("Root") + i = 0 + brains = api.content.find(object_provides="plone.restapi.behaviors.IBlocks") + tot = len(brains) + for brain in brains: + i += 1 + if i % 1000 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + item = brain.getObject() + blocks = deepcopy(getattr(item, "blocks", {})) + if blocks: + to_update = fix_template_name(blocks) + if to_update: + item.blocks = blocks + fixed_items.append(brain.getPath()) + + logger.info("Finish") + if fixed_items: + logger.info("Updated items:") + for fixed in fixed_items: + logger.info("- {}".format(fixed)) + else: + logger.info("No items affected.") + + +def to_1014(context): + update_types(context) + portal_types = api.portal.get_tool(name="portal_types") + portal_types["Bando"].behaviors = tuple( + [ + x + for x in portal_types["Bando"].behaviors + if x != "design.plone.contenttypes.behavior.argomenti" + ] + ) + + +def to_1015(context): + update_types(context) + + # cleanup trasparenza behavior from CTs + portal_types = api.portal.get_tool(name="portal_types") + service_behaviors = portal_types["Servizio"].behaviors + to_remove = [ + "design.plone.contenttypes.behavior.trasparenza", + ] + portal_types["Servizio"].behaviors = tuple( + [x for x in service_behaviors if x not in to_remove] + ) + persona_behaviors = portal_types["Persona"].behaviors + portal_types["Persona"].behaviors = tuple( + [x for x in persona_behaviors if x not in to_remove] + ) + + +def to_1016(context): + section_ids = ["amministrazione", "servizi", "novita", "documenti-e-dati"] + sections = [] + portal = api.portal.get() + for id in section_ids: + item = portal.get(id, None) + if item: + sections.append({"title": item.title, "linkUrl": [item.UID()]}) + settings = [{"rootPath": "/", "items": sections}] + api.portal.set_registry_record( + "search_sections", + json.dumps(settings), + interface=IDesignPloneSettings, + ) + + +def to_2000(context): # noqa: C901 + # remove volto.blocks behavior from news and events and add new one + update_types(context) + portal_types = api.portal.get_tool(name="portal_types") + for ptype in ["News Item", "Event"]: + portal_types[ptype].behaviors = tuple( + [x for x in portal_types[ptype].behaviors if x != "volto.blocks"] + ) + portal_types["Pagina Argomento"].behaviors = tuple( + [ + x + for x in portal_types["Pagina Argomento"].behaviors + if x != "design.plone.contenttypes.behavior.additional_help_infos" + ] + ) + # now copy values in new fields + pc = api.portal.get_tool(name="portal_catalog") + brains = pc() + tot = len(brains) + i = 0 + logger.info("### START CONVERSION FIELDS RICHTEXT -> DRAFTJS ###") + for brain in brains: + i += 1 + if i % 1000 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + item = brain.getObject() + if brain.portal_type in ["Event", "News Item"]: + blocks = getattr(item, "blocks", {}) + blocks_layout = getattr(item, "blocks_layout", {"items": []})["items"] + if not blocks: + continue + title_uid = "" + new_blocks = {} + for uid, block in blocks.items(): + if block.get("@type", "") == "title": + title_uid = uid + else: + new_blocks[uid] = block + item.descrizione_estesa = { + "blocks": new_blocks, + "blocks_layout": { + "items": [x for x in blocks_layout if x != title_uid] + }, + } + item.blocks = None + item.blocks_layout = None + for schema in iterSchemata(item): + for name, field in getFields(schema).items(): + if not isinstance(field, BlocksField): + continue + value = field.get(item) + if not value: + continue + if isinstance(value, six.string_types): + value = "

{}

".format(value) + elif isinstance(value, RichTextValue): + value = value.raw + else: + continue + if value == "


": + value = "" + try: + new_value = to_draftjs(value) + except Exception as e: + logger.error( + "[NOT MIGRATED] - {}: {}".format(brain.getPath(), name) + ) + raise e + setattr(item, name, new_value) + + +def to_2002(context): + """Per l'aggiornamento del vocabolario tipologie_persona, sistemiamo + tutti quelli già presenti. + """ + type_mapping = { + "altro": "Altro tipo", + "politica": "Politica", + "amministrativa": "Amministrativa", + } + logger.info("Fixing 'Tipologia Persona'...") + fixed_total = 0 + for brain in api.content.find(portal_type="Persona"): + item = brain.getObject() + if ( + hasattr(item, "tipologia_persona") + and item.tipologia_persona in type_mapping + ): # noqa + item.tipologia_persona = type_mapping[item.tipologia_persona] + fixed_total += 1 + commit() + logger.info("Fixing 'Tipologia Persona': DONE") + logger.info("Updated {} objects".format(fixed_total)) + + +def to_3000(context): + """ """ + update_registry(context) + update_controlpanel(context) + multilanguage = [ + "tipologie_notizia", + "tipologie_unita_organizzativa", + # "tipologie_documento", + "tipologie_persona", + ] + simple = ["lead_image_dimension", "search_sections"] + old_entry = "design.plone.contenttypes.controlpanels.vocabularies.IVocabulariesControlPanel.{}" # noqa + for field in simple: + value = api.portal.get_registry_record(old_entry.format(field)) + api.portal.set_registry_record(field, value, interface=IDesignPloneSettings) + + for field in multilanguage: + try: + value = api.portal.get_registry_record(old_entry.format(field)) + api.portal.set_registry_record( + field, + json.dumps({"it": value}), + interface=IDesignPloneSettings, + ) + except Exception: + continue + + context.runAllImportStepsFromProfile("profile-design.plone.contenttypes:to_3000") + + +def to_3101(context): + intids = getUtility(IIntIds) + logger.info("Fixing Documento references...") + fixed_total = 0 + for brain in api.content.find(portal_type="Documento"): + item = brain.getObject() + for rel in getattr(item, "servizi_collegati", []): + service = rel.to_object + if service: + service.altri_documenti.append(RelationValue(intids.getId(item))) + notify(ObjectModifiedEvent(service)) + logger.info("Fixed item {}".format("/".join(service.getPhysicalPath()))) + + if getattr(item, "servizi_collegati", []): + delattr(item, "servizi_collegati") + notify(ObjectModifiedEvent(item)) + fixed_total += 1 + logger.info("Fixed item {}".format("/".join(item.getPhysicalPath()))) + + logger.info("Fixing 'Documento': DONE") + logger.info("Updated {} objects Documento".format(fixed_total)) + + +def to_3102(context): + update_types(context) + + # cleanup trasparenza behavior from CTs + portal_types = api.portal.get_tool(name="portal_types") + to_remove = [ + "design.plone.contenttypes.behavior.trasparenza", + ] + for key, value in portal_types.items(): + ct_behaviors = getattr(value, "behaviors", None) + if ct_behaviors is not None: + portal_types[key].behaviors = tuple( + [x for x in ct_behaviors if x not in to_remove] + ) + + +def to_volto13(context): # noqa: C901 + # convert listing blocks with new standard + + logger.info("### START CONVERSION TO VOLTO 13: default => simpleCard ###") + + def fix_listing(blocks, url): + for block in blocks.values(): + if block.get("@type", "") == "listing": + if block.get("template", False) and not block.get("variation", False): + # import pdb + + # pdb.set_trace() + logger.error("- {}".format(url)) + if block.get("template", False) and block.get("variation", False): + logger.error("- {}".format(url)) + if block.get("variation", "") == "default": + block["variation"] = "simpleCard" + logger.info("- {}".format(url)) + + # fix root + portal = api.portal.get() + portal_blocks = json.loads(portal.blocks) + fix_listing(portal_blocks, portal.absolute_url()) + portal.blocks = json.dumps(portal_blocks) + + # fix blocks in contents + pc = api.portal.get_tool(name="portal_catalog") + brains = pc() + tot = len(brains) + i = 0 + for brain in brains: + i += 1 + if i % 1000 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + item = aq_base(brain.getObject()) + if getattr(item, "blocks", {}): + blocks = deepcopy(item.blocks) + if blocks: + fix_listing(blocks, brain.getURL()) + item.blocks = blocks + for schema in iterSchemata(item): + # fix blocks in blocksfields + for name, field in getFields(schema).items(): + if name == "blocks": + blocks = deepcopy(item.blocks) + if blocks: + fix_listing(blocks, brain.getURL()) + item.blocks = blocks + elif isinstance(field, BlocksField): + value = deepcopy(field.get(item)) + if not value: + continue + if isinstance(value, str): + if value == "": + setattr( + item, + name, + {"blocks": {}, "blocks_layout": {"items": []}}, + ) + continue + try: + blocks = value.get("blocks", {}) + except AttributeError: + logger.warning( + "[RICHTEXT] - {} (not converted)".format(brain.getURL()) + ) + if blocks: + fix_listing(blocks, brain.getURL()) + setattr(item, name, value) + + +def to_3400(context): # noqa: C901 + logger.info("### START CONVERSION BLOCKS: newsHome -> highlitedContent ###") + + def fix_block(blocks, url): + for block in blocks.values(): + if block.get("@type", "") == "newsHome": + block["@type"] = "highlitedContent" + + # fix root + portal = api.portal.get() + portal_blocks = json.loads(portal.blocks) + fix_block(portal_blocks, portal.absolute_url()) + portal.blocks = json.dumps(portal_blocks) + + # fix blocks in contents + pc = api.portal.get_tool(name="portal_catalog") + brains = pc() + tot = len(brains) + i = 0 + for brain in brains: + i += 1 + if i % 1000 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + item = aq_base(brain.getObject()) + if getattr(item, "blocks", {}): + blocks = deepcopy(item.blocks) + if blocks: + fix_block(blocks, brain.getURL()) + item.blocks = blocks + for schema in iterSchemata(item): + # fix blocks in blocksfields + for name, field in getFields(schema).items(): + if name == "blocks": + blocks = deepcopy(item.blocks) + if blocks: + fix_block(blocks, brain.getURL()) + item.blocks = blocks + elif isinstance(field, BlocksField): + value = deepcopy(field.get(item)) + if not value: + continue + if isinstance(value, str): + if value == "": + setattr( + item, + name, + {"blocks": {}, "blocks_layout": {"items": []}}, + ) + continue + try: + blocks = value.get("blocks", {}) + except AttributeError: + logger.warning( + "[RICHTEXT] - {} (not converted)".format(brain.getURL()) + ) + if blocks: + fix_block(blocks, brain.getURL()) + setattr(item, name, value) + + +def to_3401(context): # noqa: C901 + logger.info("File type can now be added inside a CartellaModulistica") + update_types(context) + + +def to_3500(context): + logger.info("Add new index and reindex UO") + update_catalog(context) + + # remove unused index + catalog = api.portal.get_tool(name="portal_catalog") + if "office_venue" in catalog.indexes(): + catalog.manage_delIndex("office_venue") + + # reindex + brains = api.content.find(portal_type="UnitaOrganizzativa") + tot = len(brains) + logger.info("Found {} UO.".format(tot)) + i = 0 + for brain in brains: + i += 1 + if i % 1000 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + uo = brain.getObject() + uo.reindexObject(idxs=["uo_location", "tipologia_organizzazione"]) + + +def to_3501(context): + logger.info("Reindex UO for new SearchableText fields") + + brains = api.content.find(portal_type="UnitaOrganizzativa") + tot = len(brains) + logger.info("Found {} UO.".format(tot)) + i = 0 + for brain in brains: + i += 1 + if i % 1000 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + uo = brain.getObject() + uo.reindexObject(idxs=["SearchableText"]) + + +def to_3600(context): + logger.info("Enable kitconcept.seo behavior") + types_list = [ + "UnitaOrganizzativa", + "Bando", + "Subsite", + "Venue", + "Persona", + "Event", + "News Item", + "Document", + "Documento", + "Servizio", + "CartellaModulistica", + "Pagina Argomento", + ] + portal_types = api.portal.get_tool(name="portal_types") + for ct_type in types_list: + if "kitconcept.seo" not in portal_types[ct_type].behaviors: + portal_types[ct_type].behaviors += ("kitconcept.seo",) + logger.info("Enabled kitconcept.seo on: {}".format(ct_type)) + + logger.info("Bandi customizations") + update_catalog(context) + api.portal.set_registry_record("default_ente", (), interface=IBandoSettings) + + portal_types = api.portal.get_tool(name="portal_types") + portal_types["Bando Folder Deepening"].allowed_content_types = ( + "Modulo", + "File", + "Link", + ) + portal_types["Bando"].default_view = "view" + portal_types["Bando"].view_methods = ("view",) + + logger.info("Reindex SearchableText") + pc = api.portal.get_tool(name="portal_catalog") + pc.reindexIndex("SearchableText", context.REQUEST) + + logger.info("Reindex Bandi") + i = 0 + brains = api.content.find(portal_type="Bando") + tot = len(brains) + for brain in brains: + i += 1 + if i % 1000 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + bando = brain.getObject() + bando.reindexObject(idxs=["ufficio_responsabile_bando", "Subject_bando"]) + + +def to_3700(context): + logger.info("Set show_modified_default as True") + + api.portal.set_registry_record( + "show_modified_default", True, interface=IDesignPloneSettings + ) + + +def to_3800(context): + logger.info("Fix Venue addable types") + + portal_types = api.portal.get_tool(name="portal_types") + portal_types["Venue"].allowed_content_types = ( + "Folder", + "Image", + "File", + "Link", + ) + + +def to_3900(context): + logger.info("Add new metadata: ruolo") + + brains = api.content.find(portal_type="Persona") + for brain in brains: + persona = brain.getObject() + persona.reindexObject() + + +def to_4000(context): + logger.info("Move ruolo to a choice field") + ruoli = {"it": [], "en": []} + brains = api.content.find(portal_type="Persona") + for brain in brains: + persona = brain.getObject() + ruolo = getattr(persona, "ruolo", "") + lang = brain.language + if ruolo not in ruoli[lang]: + ruoli[lang].append(ruolo) + + if api.portal.get_registry_record( + "ruoli_persona", interface=IDesignPloneSettings, default=None + ): + api.portal.set_registry_record( + "ruoli_persona", json.dumps(ruoli), interface=IDesignPloneSettings + ) + + +def to_4100(context): + logger.info("Add constrainttypes behavior to Document") + + portal_types = api.portal.get_tool(name="portal_types") + document_behaviors = list(portal_types["Document"].behaviors) + [ + "plone.constraintypes" + ] + portal_types["Document"].behaviors = tuple(document_behaviors) + + +def to_4200(context): + logger.info("Add criteria and indexes to Persona") + + update_catalog(context) + update_registry(context) + + brains = api.content.find(portal_type="Persona") + for brain in brains: + persona = brain.getObject() + persona.reindexObject(idxs=["data_conclusione_incarico"]) + + +def to_5000(context): + logger.info("Enable preview_image behavior in all content types") + + portal_types = api.portal.get_tool(name="portal_types") + + for portal_type, fti in portal_types.items(): + behaviors = list(getattr(fti, "behaviors", ())) + if not behaviors: + continue + if portal_type == "Document": + behaviors = [ + x + for x in behaviors + if x not in ["plone.leadimage", "volto.preview_image"] + ] + behaviors.extend(["plone.leadimage", "volto.preview_image"]) + else: + if "plone.leadimage" not in behaviors or "volto.preview_image" in behaviors: + continue + behaviors.insert(behaviors.index("plone.leadimage") + 1, "volto.preview_image") + fti.behaviors = tuple(behaviors) + + logger.info("Move immagine_testata to image") + catalog = api.portal.get_tool("portal_catalog") + i = 0 + brains = catalog() + tot = len(brains) + for brain in brains: + i += 1 + if i % 500 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + obj = brain.getObject() + if "image" in obj.keys(): + api.content.rename(obj=obj["image"], new_id="image-1") + if brain.portal_type == "Document": + immagine_testata = getattr(obj, "immagine_testata", None) + if immagine_testata: + obj.image = immagine_testata + obj.immagine_testata = None + catalog.catalog_object(obj) + + +def to_5001(context): + catalog = api.portal.get_tool("portal_catalog") + i = 0 + brains = catalog(portal_type="Pagina Argomento") + tot = len(brains) + logger.info("Add icona metadata to {}".format(tot)) + for brain in brains: + i += 1 + if i % 500 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + obj = brain.getObject() + catalog.catalog_object(obj) + + +def to_5002(context): + """ + Reindex non-folderish items because there were some metadata not updated + """ + catalog = api.portal.get_tool("portal_catalog") + i = 0 + brains = catalog(is_folderish=False) + tot = len(brains) + for brain in brains: + i += 1 + if i % 500 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + obj = brain.getObject() + catalog.catalog_object(obj) + + +def to_5200(context): + """ + add new behavior for Bando + """ + portal_types = api.portal.get_tool(name="portal_types") + fti = portal_types["Bando"] + behaviors = list(getattr(fti, "behaviors", ())) + if "design.plone.contenttypes.behavior.update_note" not in behaviors: + behaviors.append("design.plone.contenttypes.behavior.update_note") + fti.behaviors = tuple(behaviors) + + +def to_5210(context): + logger.info("Enable preview_image behavior in Bandi content types") + + portal_types = api.portal.get_tool(name="portal_types") + fti = portal_types["Bando"] + behaviors = list(getattr(fti, "behaviors", ())) + if "volto.preview_image" not in behaviors: + behaviors.append("volto.preview_image") + fti.behaviors = tuple(behaviors) + + +def to_5220(context): + """ + Reindex Venues + """ + logger.info("Reindex SearchableText for Venue items.") + catalog = api.portal.get_tool("portal_catalog") + i = 0 + brains = catalog(portal_type="Venue") + tot = len(brains) + for brain in brains: + i += 1 + if i % 500 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + obj = brain.getObject() + obj.reindexObject(idxs=["SearchableText", "object_provides"]) + + +def to_5300(context): + update_profile(context, "plone-difftool") + update_profile(context, "repositorytool") + + portal_types = api.portal.get_tool(name="portal_types") + for portal_type, fti in portal_types.items(): + if portal_type in [ + "CartellaModulistica", + "Documento", + "Link", + "Pagina Argomento", + "Persona", + "Servizio", + "UnitaOrganizzativa", + "Venue", + ]: + behaviors = list(getattr(fti, "behaviors", ())) + if "plone.versioning" not in behaviors: + behaviors.append("plone.versioning") + fti.behaviors = tuple(behaviors) + + +def to_5310(context): + """ + Reindex Bandi + """ + logger.info("Reindex SearchableText for Bandi items.") + catalog = api.portal.get_tool("portal_catalog") + i = 0 + brains = catalog(portal_type="Bando") + tot = len(brains) + for brain in brains: + i += 1 + if i % 500 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + brain.getObject().reindexObject(idxs=["SearchableText"]) + + +def to_5400(context): + logger.info('Remove "volto.blocks" behavior from News Item and Event.') + remove_blocks_behavior(context) + + +def to_5410(context): + + # cleanup Document behaviors + portal_types = api.portal.get_tool(name="portal_types") + behaviors = portal_types["Document"].behaviors + to_remove = [ + "plone.tableofcontents", + ] + portal_types["Document"].behaviors = tuple( + [x for x in behaviors if x not in to_remove] + ) + + +def to_6000(context): + """ """ + logger.info( + "Convert behavior: collective.dexteritytextindexer => plone.textindexer" # noqa + ) + portal_types = api.portal.get_tool(name="portal_types") + for fti in portal_types.values(): + behaviors = [] + for behavior in getattr(fti, "behaviors", ()): + if behavior == "collective.dexteritytextindexer": + behavior = "plone.textindexer" + behaviors.append(behavior) + + fti.behaviors = tuple(behaviors) + + +def to_6010(context): + """ """ + update_types(context) + update_registry(context) + update_catalog(context) + update_rolemap(context) + + +def migrate_pdc_and_incarico(context): + # Cannot test rn, blind coding + update_types(context) + update_registry(context) + update_catalog(context) + update_rolemap(context) + # "field name in original ct": "field name in new ct" + type_mapping = { + "Persona": { + 'PDC': { + "telefono": "phone", + "fax": "fax", + "email": "email", + "pec": "pec", + }, + "Incarico": { + # HOW? Need taxonomies also + # We could do: + # persona.ruolo.title = incarico.title + # persona.items.compensi = incarico.items.compensi? + "ruolo?": "incarico?", + # BlobFile to relation with Documento + "atto_nomina": "atto_nomina", + "data_conclusione_incarico": "data_conclusione_incarico", + "data_insediamento": "data_insediamento", + } + }, + "UnitaOrganizzativa": { + 'PDC': { + "telefono": "phone", + "fax": "fax", + "email": "email", + "pec": "pec", + }, + }, + # TODO: tbc + "Event": { + 'PDC': { + "telefono": "phone", + "fax": "fax", + "email": "email", + "pec": "pec", + }, + }, + # TODO: tbc + "Venue": { + 'PDC': { + "riferimento_telefonico_struttura": "phone", + "riferimento_fax_struttura": "fax", + "riferimento_mail_struttura": "email", + "riferimento_pec_struttura": "pec", + }, + }, + # TODO: tbc + "Servizio": { + # questi non sono presenti sul ct originale + 'PDC': { + "telefono": "phone", + "fax": "fax", + "email": "email", + "pec": "pec", + }, + }, + } + + def createIncaricoAndMigratePersona(portal_type): + # Taxonomies work needs to be completed before, blind coding ahead + if portal_type == 'Persona': + fixed_total = 0 + for brain in api.content.find(portal_type=portal_type): + item = brain.getObject() + atto_nomina = item.atto_nomina + logger.info(f"Fixing Punto di Contatto for '{item.title}'...") # noqa + file_bog = api.content.find(context=item, depth=1, id='atti-nomina') + if not file_bog: + try: + file_bog = api.content.create( + type="Document", id="atti-nomina", title="Atti Nomina", container=item + ) + except Exception: + logger.error("Error", Exception) + + try: + new_atto_nomina = api.content.create( + type="File", + id=atto_nomina.id, + title=atto_nomina.title, + container=item, + **{'file': atto_nomina} + ) + intids = getUtility(IIntIds) + relation = [RelationValue(intids.getId(new_atto_nomina))] + incarico = api.content.create( + type="Incarico", title=item.ruolo.title, container=item + ) + incarico.atto_nomina = relation + item.atto_nomina = None + fixed_total += 1 + logger.info(f"Fixing Punto di Contatto for '{item.title}'...:DONE") # noqa + except Exception: + logger.error("Error", Exception) + logger.info("Updated {} objects".format(fixed_total)) + + pass + + def createPDCandMigrateOldCTs(portal_type): + logger.info(f"Fixing Punto di Contatto for '{portal_type}'...") # noqa + fixed_total = 0 + mapping = None + # mapping = type_mapping[portal_type]["PDC"] + # Reenable mapping to use + if not mapping: + logger.info(f"No need to fix Punto di Contatto for '{portal_type}: DONE") + return + for brain in api.content.find(portal_type=portal_type): + item = brain.getObject() + kwargs = { + "value_punto_contatto": [], + "persona": [] + } + for key, value in mapping.items(): + import pdb; pdb.set_trace() + + if hasattr(item, key): + kwargs["value_punto_contatto"].append({ + 'pdc_type': value, + 'pdc_value': item[key] + }) + + new_pdc = api.content.create( + type='PuntoDiContatto', + title=f"Punto di Contatto {item.id}", + container=item, + **kwargs, + ) + intids = getUtility(IIntIds) + import pdb; pdb.set_trace() + item.contact_info = [RelationValue(intids.getId(new_pdc))] + fixed_total += 1 + + logger.info(f"Fixing Punto di Contatto for '{portal_type}: DONE") + logger.info("Updated {} objects".format(fixed_total)) + + for pt in type_mapping: + logger.info("Migrating existing CTs for use with new Incarico and PDC Content Types") + createPDCandMigrateOldCTs(pt) + createIncaricoAndMigratePersona(pt) diff --git a/.history/src/design/plone/contenttypes/upgrades/upgrades_20230104110903.py b/.history/src/design/plone/contenttypes/upgrades/upgrades_20230104110903.py new file mode 100644 index 00000000..5db2695d --- /dev/null +++ b/.history/src/design/plone/contenttypes/upgrades/upgrades_20230104110903.py @@ -0,0 +1,1126 @@ +# -*- coding: utf-8 -*- +from Acquisition import aq_base +from collective.volto.blocksfield.field import BlocksField +from copy import deepcopy +from design.plone.contenttypes.controlpanels.settings import IDesignPloneSettings +from design.plone.contenttypes.upgrades.draftjs_converter import to_draftjs +from design.plone.contenttypes.setuphandlers import remove_blocks_behavior +from plone import api +from plone.app.textfield.value import RichTextValue +from plone.app.upgrade.utils import installOrReinstallProduct +from plone.dexterity.utils import iterSchemata +from redturtle.bandi.interfaces.settings import IBandoSettings +from transaction import commit +from z3c.relationfield import RelationValue +from zope.component import getUtility +from zope.event import notify +from zope.intid.interfaces import IIntIds +from zope.lifecycleevent import ObjectModifiedEvent +from zope.schema import getFields + +import json +import logging +import six + + +logger = logging.getLogger(__name__) + +DEFAULT_PROFILE = "profile-design.plone.contenttypes:default" + +# standard upgrades # + + +def update_profile(context, profile, run_dependencies=True): + context.runImportStepFromProfile(DEFAULT_PROFILE, profile, run_dependencies) + + +def update_types(context): + update_profile(context, "typeinfo") + + +def update_rolemap(context): + update_profile(context, "rolemap") + + +def update_registry(context): + update_profile(context, "plone.app.registry", run_dependencies=False) + + +def update_catalog(context): + update_profile(context, "catalog") + + +def update_controlpanel(context): + update_profile(context, "controlpanel") + + +def remap_fields(mapping): + pc = api.portal.get_tool(name="portal_catalog") + brains = pc() + tot = len(brains) + logger.info("Trovati {} elementi da sistemare.".format(tot)) + # remap fields + for brain in brains: + item = brain.getObject() + for old, new in mapping.items(): + value = getattr(item, old, None) + if value: + setattr(item, new, value) + setattr(item, old, None) + logger.info( + "- {url}: {old} -> {new}".format( + url=brain.getURL(), old=old, new=new + ) + ) + delattr(item, old) + + +# custom ones # + + +def to_1001(context): + + update_types(context) + + # cleanup event behaviors + portal_types = api.portal.get_tool(name="portal_types") + behaviors = portal_types["Event"].behaviors + to_remove = [ + "design.plone.contenttypes.behavior.luoghi_correlati", + "design.plone.contenttypes.behavior.argomenti_evento", + "design.plone.contenttypes.behavior.additional_help_infos_evento", + ] + portal_types["Event"].behaviors = tuple( + [x for x in behaviors if x not in to_remove] + ) + + mapping = { + # "descrizione_destinatari": "a_chi_si_rivolge", + "canale_fisico": "dove_rivolgersi_extra", + "canale_fisico_prenotazione": "prenota_appuntamento", + "fasi_scadenze": "tempi_e_scadenze", + "sedi_e_luoghi": "dove_rivolgersi", + "box_aiuto": "ulteriori_informazioni", + "riferimento_telefonico_luogo": "telefono", + "riferimento_mail_luogo": "email", + } + remap_fields(mapping=mapping) + + +def to_1003(context): + + update_types(context) + + mapping = { + "unita_amministrativa_responsabile": "unita_amministrative_responsabili", # noqa + "sedi": "sede", + "contatto_reperibilita": "reperibilita", + "evento_supportato_da": "supportato_da", + } + remap_fields(mapping=mapping) + + +def to_1005(context): + def fix_index(blocks): + for block in blocks.values(): + if block.get("@type", "") == "listing": + for query in block.get("query", []): + if ( + query["i"] == "argomenti_correlati" + or query["i"] == "tassonomia_argomenti" + ): # noqa + query["i"] = "argomenti" + logger.info(" - {}".format(brain.getURL())) + + # fix root + portal = api.portal.get() + portal_blocks = json.loads(portal.blocks) + fix_index(portal_blocks) + portal.blocks = json.dumps(portal_blocks) + + logger.info("Fixing listing blocks.") + for brain in api.content.find(object_provides="plone.restapi.behaviors.IBlocks"): + item = brain.getObject() + blocks = deepcopy(getattr(item, "blocks", {})) + if blocks: + fix_index(blocks) + item.blocks = blocks + logger.info("** Reindexing items that refers to an argument **") + for brain in api.portal.get_tool("portal_catalog")(): + item = brain.getObject() + if getattr(item.aq_base, "tassonomia_argomenti", []): + logger.info(" - {}".format(brain.getURL())) + item.reindexObject(idxs=["argomenti"]) + + +def to_1006(context): + def fix_index(blocks): + for block in blocks.values(): + if block.get("@type", "") == "listing": + for query in block.get("query", []): + if ( + query["i"] == "argomenti_correlati" + or query["i"] == "tassonomia_argomenti" + or query["i"] == "argomenti" + ): # noqa + query["i"] = "argomenti" + query["v"] = [x.Title for x in api.content.find(UID=query["v"])] + logger.info(" - {}".format(brain.getURL())) + + # fix root + portal = api.portal.get() + portal_blocks = json.loads(portal.blocks) + fix_index(portal_blocks) + portal.blocks = json.dumps(portal_blocks) + + logger.info("Fixing listing blocks.") + for brain in api.content.find(object_provides="plone.restapi.behaviors.IBlocks"): + item = brain.getObject() + blocks = deepcopy(getattr(item, "blocks", {})) + if blocks: + fix_index(blocks) + item.blocks = blocks + + +def to_1007(context): + for brain in api.content.find(portal_type="Persona"): + item = brain.getObject() + if item.email: + item.email = [item.email] + if item.telefono: + item.telefono = [item.telefono] + + +def to_1008(context): + installOrReinstallProduct(api.portal.get(), "redturtle.bandi") + + +def to_1009(context): + def fix_index(blocks): + """ + revert to tassonomia_argomenti + """ + for block in blocks.values(): + if block.get("@type", "") == "listing": + for query in block.get("query", []): + if query["i"] == "argomenti": + query["i"] = "tassonomia_argomenti" + logger.info(" - {}".format(brain.getURL())) + + # fix root + portal = api.portal.get() + portal_blocks = json.loads(portal.blocks) + fix_index(portal_blocks) + portal.blocks = json.dumps(portal_blocks) + + logger.info("Fixing listing blocks.") + for brain in api.content.find(object_provides="plone.restapi.behaviors.IBlocks"): + item = brain.getObject() + blocks = deepcopy(getattr(item, "blocks", {})) + if blocks: + fix_index(blocks) + item.blocks = blocks + logger.info("** Reindexing items that refers to an argument **") + for brain in api.portal.get_tool("portal_catalog")(): + item = brain.getObject() + if getattr(item.aq_base, "tassonomia_argomenti", []): + logger.info(" - {}".format(brain.getURL())) + item.reindexObject(idxs=["tassonomia_argomenti"]) + + +def to_1010(context): + pc = api.portal.get_tool(name="portal_catalog") + pc.manage_reindexIndex(ids=["event_location"]) + + +def to_1013(context): + def fix_template_name(blocks): + """ + revert to tassonomia_argomenti + """ + found = False + for block in blocks.values(): + if ( + block.get("@type", "") == "listing" + and block.get("template", "") == "imageGallery" + ): + block["template"] = "photogallery" + found = True + return found + + # fix root + logger.info('Changing listing block template from "imageGallery" to "photogallery') + portal = api.portal.get() + portal_blocks = json.loads(portal.blocks) + to_update = fix_template_name(portal_blocks) + fixed_items = [] + if to_update: + portal.blocks = json.dumps(portal_blocks) + fixed_items.append("Root") + i = 0 + brains = api.content.find(object_provides="plone.restapi.behaviors.IBlocks") + tot = len(brains) + for brain in brains: + i += 1 + if i % 1000 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + item = brain.getObject() + blocks = deepcopy(getattr(item, "blocks", {})) + if blocks: + to_update = fix_template_name(blocks) + if to_update: + item.blocks = blocks + fixed_items.append(brain.getPath()) + + logger.info("Finish") + if fixed_items: + logger.info("Updated items:") + for fixed in fixed_items: + logger.info("- {}".format(fixed)) + else: + logger.info("No items affected.") + + +def to_1014(context): + update_types(context) + portal_types = api.portal.get_tool(name="portal_types") + portal_types["Bando"].behaviors = tuple( + [ + x + for x in portal_types["Bando"].behaviors + if x != "design.plone.contenttypes.behavior.argomenti" + ] + ) + + +def to_1015(context): + update_types(context) + + # cleanup trasparenza behavior from CTs + portal_types = api.portal.get_tool(name="portal_types") + service_behaviors = portal_types["Servizio"].behaviors + to_remove = [ + "design.plone.contenttypes.behavior.trasparenza", + ] + portal_types["Servizio"].behaviors = tuple( + [x for x in service_behaviors if x not in to_remove] + ) + persona_behaviors = portal_types["Persona"].behaviors + portal_types["Persona"].behaviors = tuple( + [x for x in persona_behaviors if x not in to_remove] + ) + + +def to_1016(context): + section_ids = ["amministrazione", "servizi", "novita", "documenti-e-dati"] + sections = [] + portal = api.portal.get() + for id in section_ids: + item = portal.get(id, None) + if item: + sections.append({"title": item.title, "linkUrl": [item.UID()]}) + settings = [{"rootPath": "/", "items": sections}] + api.portal.set_registry_record( + "search_sections", + json.dumps(settings), + interface=IDesignPloneSettings, + ) + + +def to_2000(context): # noqa: C901 + # remove volto.blocks behavior from news and events and add new one + update_types(context) + portal_types = api.portal.get_tool(name="portal_types") + for ptype in ["News Item", "Event"]: + portal_types[ptype].behaviors = tuple( + [x for x in portal_types[ptype].behaviors if x != "volto.blocks"] + ) + portal_types["Pagina Argomento"].behaviors = tuple( + [ + x + for x in portal_types["Pagina Argomento"].behaviors + if x != "design.plone.contenttypes.behavior.additional_help_infos" + ] + ) + # now copy values in new fields + pc = api.portal.get_tool(name="portal_catalog") + brains = pc() + tot = len(brains) + i = 0 + logger.info("### START CONVERSION FIELDS RICHTEXT -> DRAFTJS ###") + for brain in brains: + i += 1 + if i % 1000 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + item = brain.getObject() + if brain.portal_type in ["Event", "News Item"]: + blocks = getattr(item, "blocks", {}) + blocks_layout = getattr(item, "blocks_layout", {"items": []})["items"] + if not blocks: + continue + title_uid = "" + new_blocks = {} + for uid, block in blocks.items(): + if block.get("@type", "") == "title": + title_uid = uid + else: + new_blocks[uid] = block + item.descrizione_estesa = { + "blocks": new_blocks, + "blocks_layout": { + "items": [x for x in blocks_layout if x != title_uid] + }, + } + item.blocks = None + item.blocks_layout = None + for schema in iterSchemata(item): + for name, field in getFields(schema).items(): + if not isinstance(field, BlocksField): + continue + value = field.get(item) + if not value: + continue + if isinstance(value, six.string_types): + value = "

{}

".format(value) + elif isinstance(value, RichTextValue): + value = value.raw + else: + continue + if value == "


": + value = "" + try: + new_value = to_draftjs(value) + except Exception as e: + logger.error( + "[NOT MIGRATED] - {}: {}".format(brain.getPath(), name) + ) + raise e + setattr(item, name, new_value) + + +def to_2002(context): + """Per l'aggiornamento del vocabolario tipologie_persona, sistemiamo + tutti quelli già presenti. + """ + type_mapping = { + "altro": "Altro tipo", + "politica": "Politica", + "amministrativa": "Amministrativa", + } + logger.info("Fixing 'Tipologia Persona'...") + fixed_total = 0 + for brain in api.content.find(portal_type="Persona"): + item = brain.getObject() + if ( + hasattr(item, "tipologia_persona") + and item.tipologia_persona in type_mapping + ): # noqa + item.tipologia_persona = type_mapping[item.tipologia_persona] + fixed_total += 1 + commit() + logger.info("Fixing 'Tipologia Persona': DONE") + logger.info("Updated {} objects".format(fixed_total)) + + +def to_3000(context): + """ """ + update_registry(context) + update_controlpanel(context) + multilanguage = [ + "tipologie_notizia", + "tipologie_unita_organizzativa", + # "tipologie_documento", + "tipologie_persona", + ] + simple = ["lead_image_dimension", "search_sections"] + old_entry = "design.plone.contenttypes.controlpanels.vocabularies.IVocabulariesControlPanel.{}" # noqa + for field in simple: + value = api.portal.get_registry_record(old_entry.format(field)) + api.portal.set_registry_record(field, value, interface=IDesignPloneSettings) + + for field in multilanguage: + try: + value = api.portal.get_registry_record(old_entry.format(field)) + api.portal.set_registry_record( + field, + json.dumps({"it": value}), + interface=IDesignPloneSettings, + ) + except Exception: + continue + + context.runAllImportStepsFromProfile("profile-design.plone.contenttypes:to_3000") + + +def to_3101(context): + intids = getUtility(IIntIds) + logger.info("Fixing Documento references...") + fixed_total = 0 + for brain in api.content.find(portal_type="Documento"): + item = brain.getObject() + for rel in getattr(item, "servizi_collegati", []): + service = rel.to_object + if service: + service.altri_documenti.append(RelationValue(intids.getId(item))) + notify(ObjectModifiedEvent(service)) + logger.info("Fixed item {}".format("/".join(service.getPhysicalPath()))) + + if getattr(item, "servizi_collegati", []): + delattr(item, "servizi_collegati") + notify(ObjectModifiedEvent(item)) + fixed_total += 1 + logger.info("Fixed item {}".format("/".join(item.getPhysicalPath()))) + + logger.info("Fixing 'Documento': DONE") + logger.info("Updated {} objects Documento".format(fixed_total)) + + +def to_3102(context): + update_types(context) + + # cleanup trasparenza behavior from CTs + portal_types = api.portal.get_tool(name="portal_types") + to_remove = [ + "design.plone.contenttypes.behavior.trasparenza", + ] + for key, value in portal_types.items(): + ct_behaviors = getattr(value, "behaviors", None) + if ct_behaviors is not None: + portal_types[key].behaviors = tuple( + [x for x in ct_behaviors if x not in to_remove] + ) + + +def to_volto13(context): # noqa: C901 + # convert listing blocks with new standard + + logger.info("### START CONVERSION TO VOLTO 13: default => simpleCard ###") + + def fix_listing(blocks, url): + for block in blocks.values(): + if block.get("@type", "") == "listing": + if block.get("template", False) and not block.get("variation", False): + # import pdb + + # pdb.set_trace() + logger.error("- {}".format(url)) + if block.get("template", False) and block.get("variation", False): + logger.error("- {}".format(url)) + if block.get("variation", "") == "default": + block["variation"] = "simpleCard" + logger.info("- {}".format(url)) + + # fix root + portal = api.portal.get() + portal_blocks = json.loads(portal.blocks) + fix_listing(portal_blocks, portal.absolute_url()) + portal.blocks = json.dumps(portal_blocks) + + # fix blocks in contents + pc = api.portal.get_tool(name="portal_catalog") + brains = pc() + tot = len(brains) + i = 0 + for brain in brains: + i += 1 + if i % 1000 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + item = aq_base(brain.getObject()) + if getattr(item, "blocks", {}): + blocks = deepcopy(item.blocks) + if blocks: + fix_listing(blocks, brain.getURL()) + item.blocks = blocks + for schema in iterSchemata(item): + # fix blocks in blocksfields + for name, field in getFields(schema).items(): + if name == "blocks": + blocks = deepcopy(item.blocks) + if blocks: + fix_listing(blocks, brain.getURL()) + item.blocks = blocks + elif isinstance(field, BlocksField): + value = deepcopy(field.get(item)) + if not value: + continue + if isinstance(value, str): + if value == "": + setattr( + item, + name, + {"blocks": {}, "blocks_layout": {"items": []}}, + ) + continue + try: + blocks = value.get("blocks", {}) + except AttributeError: + logger.warning( + "[RICHTEXT] - {} (not converted)".format(brain.getURL()) + ) + if blocks: + fix_listing(blocks, brain.getURL()) + setattr(item, name, value) + + +def to_3400(context): # noqa: C901 + logger.info("### START CONVERSION BLOCKS: newsHome -> highlitedContent ###") + + def fix_block(blocks, url): + for block in blocks.values(): + if block.get("@type", "") == "newsHome": + block["@type"] = "highlitedContent" + + # fix root + portal = api.portal.get() + portal_blocks = json.loads(portal.blocks) + fix_block(portal_blocks, portal.absolute_url()) + portal.blocks = json.dumps(portal_blocks) + + # fix blocks in contents + pc = api.portal.get_tool(name="portal_catalog") + brains = pc() + tot = len(brains) + i = 0 + for brain in brains: + i += 1 + if i % 1000 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + item = aq_base(brain.getObject()) + if getattr(item, "blocks", {}): + blocks = deepcopy(item.blocks) + if blocks: + fix_block(blocks, brain.getURL()) + item.blocks = blocks + for schema in iterSchemata(item): + # fix blocks in blocksfields + for name, field in getFields(schema).items(): + if name == "blocks": + blocks = deepcopy(item.blocks) + if blocks: + fix_block(blocks, brain.getURL()) + item.blocks = blocks + elif isinstance(field, BlocksField): + value = deepcopy(field.get(item)) + if not value: + continue + if isinstance(value, str): + if value == "": + setattr( + item, + name, + {"blocks": {}, "blocks_layout": {"items": []}}, + ) + continue + try: + blocks = value.get("blocks", {}) + except AttributeError: + logger.warning( + "[RICHTEXT] - {} (not converted)".format(brain.getURL()) + ) + if blocks: + fix_block(blocks, brain.getURL()) + setattr(item, name, value) + + +def to_3401(context): # noqa: C901 + logger.info("File type can now be added inside a CartellaModulistica") + update_types(context) + + +def to_3500(context): + logger.info("Add new index and reindex UO") + update_catalog(context) + + # remove unused index + catalog = api.portal.get_tool(name="portal_catalog") + if "office_venue" in catalog.indexes(): + catalog.manage_delIndex("office_venue") + + # reindex + brains = api.content.find(portal_type="UnitaOrganizzativa") + tot = len(brains) + logger.info("Found {} UO.".format(tot)) + i = 0 + for brain in brains: + i += 1 + if i % 1000 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + uo = brain.getObject() + uo.reindexObject(idxs=["uo_location", "tipologia_organizzazione"]) + + +def to_3501(context): + logger.info("Reindex UO for new SearchableText fields") + + brains = api.content.find(portal_type="UnitaOrganizzativa") + tot = len(brains) + logger.info("Found {} UO.".format(tot)) + i = 0 + for brain in brains: + i += 1 + if i % 1000 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + uo = brain.getObject() + uo.reindexObject(idxs=["SearchableText"]) + + +def to_3600(context): + logger.info("Enable kitconcept.seo behavior") + types_list = [ + "UnitaOrganizzativa", + "Bando", + "Subsite", + "Venue", + "Persona", + "Event", + "News Item", + "Document", + "Documento", + "Servizio", + "CartellaModulistica", + "Pagina Argomento", + ] + portal_types = api.portal.get_tool(name="portal_types") + for ct_type in types_list: + if "kitconcept.seo" not in portal_types[ct_type].behaviors: + portal_types[ct_type].behaviors += ("kitconcept.seo",) + logger.info("Enabled kitconcept.seo on: {}".format(ct_type)) + + logger.info("Bandi customizations") + update_catalog(context) + api.portal.set_registry_record("default_ente", (), interface=IBandoSettings) + + portal_types = api.portal.get_tool(name="portal_types") + portal_types["Bando Folder Deepening"].allowed_content_types = ( + "Modulo", + "File", + "Link", + ) + portal_types["Bando"].default_view = "view" + portal_types["Bando"].view_methods = ("view",) + + logger.info("Reindex SearchableText") + pc = api.portal.get_tool(name="portal_catalog") + pc.reindexIndex("SearchableText", context.REQUEST) + + logger.info("Reindex Bandi") + i = 0 + brains = api.content.find(portal_type="Bando") + tot = len(brains) + for brain in brains: + i += 1 + if i % 1000 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + bando = brain.getObject() + bando.reindexObject(idxs=["ufficio_responsabile_bando", "Subject_bando"]) + + +def to_3700(context): + logger.info("Set show_modified_default as True") + + api.portal.set_registry_record( + "show_modified_default", True, interface=IDesignPloneSettings + ) + + +def to_3800(context): + logger.info("Fix Venue addable types") + + portal_types = api.portal.get_tool(name="portal_types") + portal_types["Venue"].allowed_content_types = ( + "Folder", + "Image", + "File", + "Link", + ) + + +def to_3900(context): + logger.info("Add new metadata: ruolo") + + brains = api.content.find(portal_type="Persona") + for brain in brains: + persona = brain.getObject() + persona.reindexObject() + + +def to_4000(context): + logger.info("Move ruolo to a choice field") + ruoli = {"it": [], "en": []} + brains = api.content.find(portal_type="Persona") + for brain in brains: + persona = brain.getObject() + ruolo = getattr(persona, "ruolo", "") + lang = brain.language + if ruolo not in ruoli[lang]: + ruoli[lang].append(ruolo) + + if api.portal.get_registry_record( + "ruoli_persona", interface=IDesignPloneSettings, default=None + ): + api.portal.set_registry_record( + "ruoli_persona", json.dumps(ruoli), interface=IDesignPloneSettings + ) + + +def to_4100(context): + logger.info("Add constrainttypes behavior to Document") + + portal_types = api.portal.get_tool(name="portal_types") + document_behaviors = list(portal_types["Document"].behaviors) + [ + "plone.constraintypes" + ] + portal_types["Document"].behaviors = tuple(document_behaviors) + + +def to_4200(context): + logger.info("Add criteria and indexes to Persona") + + update_catalog(context) + update_registry(context) + + brains = api.content.find(portal_type="Persona") + for brain in brains: + persona = brain.getObject() + persona.reindexObject(idxs=["data_conclusione_incarico"]) + + +def to_5000(context): + logger.info("Enable preview_image behavior in all content types") + + portal_types = api.portal.get_tool(name="portal_types") + + for portal_type, fti in portal_types.items(): + behaviors = list(getattr(fti, "behaviors", ())) + if not behaviors: + continue + if portal_type == "Document": + behaviors = [ + x + for x in behaviors + if x not in ["plone.leadimage", "volto.preview_image"] + ] + behaviors.extend(["plone.leadimage", "volto.preview_image"]) + else: + if "plone.leadimage" not in behaviors or "volto.preview_image" in behaviors: + continue + behaviors.insert(behaviors.index("plone.leadimage") + 1, "volto.preview_image") + fti.behaviors = tuple(behaviors) + + logger.info("Move immagine_testata to image") + catalog = api.portal.get_tool("portal_catalog") + i = 0 + brains = catalog() + tot = len(brains) + for brain in brains: + i += 1 + if i % 500 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + obj = brain.getObject() + if "image" in obj.keys(): + api.content.rename(obj=obj["image"], new_id="image-1") + if brain.portal_type == "Document": + immagine_testata = getattr(obj, "immagine_testata", None) + if immagine_testata: + obj.image = immagine_testata + obj.immagine_testata = None + catalog.catalog_object(obj) + + +def to_5001(context): + catalog = api.portal.get_tool("portal_catalog") + i = 0 + brains = catalog(portal_type="Pagina Argomento") + tot = len(brains) + logger.info("Add icona metadata to {}".format(tot)) + for brain in brains: + i += 1 + if i % 500 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + obj = brain.getObject() + catalog.catalog_object(obj) + + +def to_5002(context): + """ + Reindex non-folderish items because there were some metadata not updated + """ + catalog = api.portal.get_tool("portal_catalog") + i = 0 + brains = catalog(is_folderish=False) + tot = len(brains) + for brain in brains: + i += 1 + if i % 500 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + obj = brain.getObject() + catalog.catalog_object(obj) + + +def to_5200(context): + """ + add new behavior for Bando + """ + portal_types = api.portal.get_tool(name="portal_types") + fti = portal_types["Bando"] + behaviors = list(getattr(fti, "behaviors", ())) + if "design.plone.contenttypes.behavior.update_note" not in behaviors: + behaviors.append("design.plone.contenttypes.behavior.update_note") + fti.behaviors = tuple(behaviors) + + +def to_5210(context): + logger.info("Enable preview_image behavior in Bandi content types") + + portal_types = api.portal.get_tool(name="portal_types") + fti = portal_types["Bando"] + behaviors = list(getattr(fti, "behaviors", ())) + if "volto.preview_image" not in behaviors: + behaviors.append("volto.preview_image") + fti.behaviors = tuple(behaviors) + + +def to_5220(context): + """ + Reindex Venues + """ + logger.info("Reindex SearchableText for Venue items.") + catalog = api.portal.get_tool("portal_catalog") + i = 0 + brains = catalog(portal_type="Venue") + tot = len(brains) + for brain in brains: + i += 1 + if i % 500 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + obj = brain.getObject() + obj.reindexObject(idxs=["SearchableText", "object_provides"]) + + +def to_5300(context): + update_profile(context, "plone-difftool") + update_profile(context, "repositorytool") + + portal_types = api.portal.get_tool(name="portal_types") + for portal_type, fti in portal_types.items(): + if portal_type in [ + "CartellaModulistica", + "Documento", + "Link", + "Pagina Argomento", + "Persona", + "Servizio", + "UnitaOrganizzativa", + "Venue", + ]: + behaviors = list(getattr(fti, "behaviors", ())) + if "plone.versioning" not in behaviors: + behaviors.append("plone.versioning") + fti.behaviors = tuple(behaviors) + + +def to_5310(context): + """ + Reindex Bandi + """ + logger.info("Reindex SearchableText for Bandi items.") + catalog = api.portal.get_tool("portal_catalog") + i = 0 + brains = catalog(portal_type="Bando") + tot = len(brains) + for brain in brains: + i += 1 + if i % 500 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + brain.getObject().reindexObject(idxs=["SearchableText"]) + + +def to_5400(context): + logger.info('Remove "volto.blocks" behavior from News Item and Event.') + remove_blocks_behavior(context) + + +def to_5410(context): + + # cleanup Document behaviors + portal_types = api.portal.get_tool(name="portal_types") + behaviors = portal_types["Document"].behaviors + to_remove = [ + "plone.tableofcontents", + ] + portal_types["Document"].behaviors = tuple( + [x for x in behaviors if x not in to_remove] + ) + + +def to_6000(context): + """ """ + logger.info( + "Convert behavior: collective.dexteritytextindexer => plone.textindexer" # noqa + ) + portal_types = api.portal.get_tool(name="portal_types") + for fti in portal_types.values(): + behaviors = [] + for behavior in getattr(fti, "behaviors", ()): + if behavior == "collective.dexteritytextindexer": + behavior = "plone.textindexer" + behaviors.append(behavior) + + fti.behaviors = tuple(behaviors) + + +def to_6010(context): + """ """ + update_types(context) + update_registry(context) + update_catalog(context) + update_rolemap(context) + + +def migrate_pdc_and_incarico(context): + # Cannot test rn, blind coding + update_types(context) + update_registry(context) + update_catalog(context) + update_rolemap(context) + # "field name in original ct": "field name in new ct" + type_mapping = { + "Persona": { + 'PDC': { + "telefono": "phone", + "fax": "fax", + "email": "email", + "pec": "pec", + }, + "Incarico": { + # HOW? Need taxonomies also + # We could do: + # persona.ruolo.title = incarico.title + # persona.items.compensi = incarico.items.compensi? + "ruolo?": "incarico?", + # BlobFile to relation with Documento + "atto_nomina": "atto_nomina", + "data_conclusione_incarico": "data_conclusione_incarico", + "data_insediamento": "data_insediamento", + } + }, + "UnitaOrganizzativa": { + 'PDC': { + "telefono": "phone", + "fax": "fax", + "email": "email", + "pec": "pec", + }, + }, + # TODO: tbc + "Event": { + 'PDC': { + "telefono": "phone", + "fax": "fax", + "email": "email", + "pec": "pec", + }, + }, + # TODO: tbc + "Venue": { + 'PDC': { + "riferimento_telefonico_struttura": "phone", + "riferimento_fax_struttura": "fax", + "riferimento_mail_struttura": "email", + "riferimento_pec_struttura": "pec", + }, + }, + # TODO: tbc + "Servizio": { + # questi non sono presenti sul ct originale + 'PDC': { + "telefono": "phone", + "fax": "fax", + "email": "email", + "pec": "pec", + }, + }, + } + + def createIncaricoAndMigratePersona(portal_type): + # Taxonomies work needs to be completed before, blind coding ahead + if portal_type == 'Persona': + fixed_total = 0 + for brain in api.content.find(portal_type=portal_type): + item = brain.getObject() + atto_nomina = item.atto_nomina + logger.info(f"Fixing Punto di Contatto for '{item.title}'...") # noqa + file_bog = api.content.find(context=item, depth=1, id='atti-nomina') + if not file_bog: + try: + file_bog = api.content.create( + type="Document", id="atti-nomina", title="Atti Nomina", container=item + ) + except Exception: + logger.error("Error", Exception) + + try: + new_atto_nomina = api.content.create( + type="File", + id=atto_nomina.id, + title=atto_nomina.title, + container=item, + **{'file': atto_nomina} + ) + intids = getUtility(IIntIds) + relation = [RelationValue(intids.getId(new_atto_nomina))] + incarico = api.content.create( + type="Incarico", title=item.ruolo.title, container=item + ) + incarico.atto_nomina = relation + item.atto_nomina = None + fixed_total += 1 + logger.info(f"Fixing Punto di Contatto for '{item.title}'...:DONE") # noqa + except Exception: + logger.error("Error", Exception) + logger.info("Updated {} objects".format(fixed_total)) + + pass + + def createPDCandMigrateOldCTs(portal_type): + logger.info(f"Fixing Punto di Contatto for '{portal_type}'...") # noqa + fixed_total = 0 + mapping = None + # mapping = type_mapping[portal_type]["PDC"] + # Reenable mapping to use + if not mapping: + logger.info(f"No need to fix Punto di Contatto for '{portal_type}: DONE") + return + for brain in api.content.find(portal_type=portal_type): + item = brain.getObject() + kwargs = { + "value_punto_contatto": [], + "persona": [] + } + for key, value in mapping.items(): + import pdb; pdb.set_trace() + + if hasattr(item, key): + kwargs["value_punto_contatto"].append({ + 'pdc_type': value, + 'pdc_value': item[key] + }) + + new_pdc = api.content.create( + type='PuntoDiContatto', + title=f"Punto di Contatto {item.id}", + container=item, + **kwargs, + ) + intids = getUtility(IIntIds) + import pdb; pdb.set_trace() + item.contact_info = [RelationValue(intids.getId(new_pdc))] + fixed_total += 1 + + logger.info(f"Fixing Punto di Contatto for '{portal_type}: DONE") + logger.info("Updated {} objects".format(fixed_total)) + + for pt in type_mapping: + logger.info("Migrating existing CTs for use with new Incarico and PDC Content Types") + createPDCandMigrateOldCTs(pt) + createIncaricoAndMigratePersona(pt) diff --git a/src/design/plone/contenttypes/restapi/types/adapters.py b/src/design/plone/contenttypes/restapi/types/adapters.py index d5f2b931..11c712d2 100644 --- a/src/design/plone/contenttypes/restapi/types/adapters.py +++ b/src/design/plone/contenttypes/restapi/types/adapters.py @@ -9,7 +9,6 @@ from zope.interface import Interface from zope.schema.interfaces import IField, IVocabularyFactory from collective.z3cform.datagridfield.interfaces import IRow -from plone import api from plone.restapi.types.adapters import ListJsonSchemaProvider from plone.restapi.types.utils import get_fieldsets from plone.restapi.types.utils import get_jsonschema_properties @@ -18,9 +17,6 @@ from design.plone.contenttypes.interfaces import IDesignPloneContenttypesLayer -from design.plone.contenttypes import _ - - @adapter(IField, Interface, Interface) @implementer(IJsonSchemaProvider) class LeadImageJsonSchemaProvider(ObjectJsonSchemaProvider): diff --git a/src/design/plone/contenttypes/upgrades/upgrades.py b/src/design/plone/contenttypes/upgrades/upgrades.py index a28bd47c..5db2695d 100644 --- a/src/design/plone/contenttypes/upgrades/upgrades.py +++ b/src/design/plone/contenttypes/upgrades/upgrades.py @@ -4,6 +4,7 @@ from copy import deepcopy from design.plone.contenttypes.controlpanels.settings import IDesignPloneSettings from design.plone.contenttypes.upgrades.draftjs_converter import to_draftjs +from design.plone.contenttypes.setuphandlers import remove_blocks_behavior from plone import api from plone.app.textfield.value import RichTextValue from plone.app.upgrade.utils import installOrReinstallProduct @@ -16,9 +17,6 @@ from zope.intid.interfaces import IIntIds from zope.lifecycleevent import ObjectModifiedEvent from zope.schema import getFields -from zope.component import getUtility -from zope.intid.interfaces import IIntIds -from z3c.relationfield import RelationValue import json import logging @@ -56,14 +54,6 @@ def update_controlpanel(context): update_profile(context, "controlpanel") -def remove_blocks_behavior(context): - portal_types = api.portal.get_tool(name="portal_types") - for ptype in ["News Item", "Event"]: - portal_types[ptype].behaviors = tuple( - [x for x in portal_types[ptype].behaviors if x != "volto.blocks"] - ) - - def remap_fields(mapping): pc = api.portal.get_tool(name="portal_catalog") brains = pc() From cbf6d9d06279ed02538497f953488a5057e837b5 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Wed, 4 Jan 2023 11:11:37 +0100 Subject: [PATCH 028/487] update gitignore --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 1772f39c..fbc2fb1d 100644 --- a/.gitignore +++ b/.gitignore @@ -44,4 +44,4 @@ reports/ !src/design pyvenv.cfg .Python -.history \ No newline at end of file +.history/* From d851341057de1c36a85c8f527f9b42779decaf64 Mon Sep 17 00:00:00 2001 From: Martina Bustacchini Date: Wed, 4 Jan 2023 12:05:00 +0100 Subject: [PATCH 029/487] fix circular import --- src/design/plone/contenttypes/setuphandlers.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/design/plone/contenttypes/setuphandlers.py b/src/design/plone/contenttypes/setuphandlers.py index 188d4471..7f97ea44 100644 --- a/src/design/plone/contenttypes/setuphandlers.py +++ b/src/design/plone/contenttypes/setuphandlers.py @@ -1,6 +1,4 @@ # -*- coding: utf-8 -*- -from design.plone.contenttypes.upgrades.upgrades import remove_blocks_behavior -from design.plone.contenttypes.upgrades.upgrades import update_types from plone import api from Products.CMFPlone.interfaces import INonInstallable from redturtle.bandi.interfaces.settings import IBandoSettings @@ -51,9 +49,17 @@ def post_install(context): def post_install_taxonomy(context): - update_types(context) + context.runImportStepFromProfile("profile-design.plone.contenttypes:default", "typeinfo", True) def uninstall(context): """Uninstall script""" # Do something at the end of the uninstallation of this package. + + +def remove_blocks_behavior(context): + portal_types = api.portal.get_tool(name="portal_types") + for ptype in ["News Item", "Event"]: + portal_types[ptype].behaviors = tuple( + [x for x in portal_types[ptype].behaviors if x != "volto.blocks"] + ) From 05b05d0468be3ff474ef74e6742f27f57460bd64 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Wed, 4 Jan 2023 12:47:23 +0100 Subject: [PATCH 030/487] decouple help text and link for canale digitale --- src/design/plone/contenttypes/interfaces/servizio.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/design/plone/contenttypes/interfaces/servizio.py b/src/design/plone/contenttypes/interfaces/servizio.py index 81fd2882..aa26a188 100644 --- a/src/design/plone/contenttypes/interfaces/servizio.py +++ b/src/design/plone/contenttypes/interfaces/servizio.py @@ -111,6 +111,15 @@ class IServizio(model.Schema, IDesignPloneContentType): title=_("canale_digitale", default="Canale digitale"), description=_( "canale_digitale_help", + default="Testo di introduzione del canale digitale", + ), + required=False, + ) + + canale_digitale_link = schema.URI( + title=_("canale_digitale_link", default="Link al canale digitale"), + description=_( + "canale_digitale_link_help", default="Collegamento con l'eventuale canale digitale di" " attivazione del servizio.", ), @@ -374,6 +383,7 @@ class IServizio(model.Schema, IDesignPloneContentType): "cosa_si_ottiene", "procedure_collegate", "canale_digitale", + "canale_digitale_link", "autenticazione", "dove_rivolgersi", "dove_rivolgersi_extra", From 07604c2fb92abe0f61ca5d44d16118b9e55f33cb Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Wed, 4 Jan 2023 16:40:03 +0100 Subject: [PATCH 031/487] update campi unita organizzativa --- .../plone/contenttypes/behaviors/contatti.py | 5 + .../interfaces/unita_organizzativa.py | 8 +- .../taxonomies/tipologia_organizzazione.cfg | 2 +- .../restapi/deserializers/configure.zcml | 1 + .../restapi/deserializers/servizio.py | 7 + .../deserializers/unitaorganizzativa.py | 141 ++++++++++++++++++ .../restapi/services/types/get.py | 12 ++ 7 files changed, 171 insertions(+), 5 deletions(-) create mode 100644 src/design/plone/contenttypes/restapi/deserializers/unitaorganizzativa.py diff --git a/src/design/plone/contenttypes/behaviors/contatti.py b/src/design/plone/contenttypes/behaviors/contatti.py index 2666bb32..adb79174 100644 --- a/src/design/plone/contenttypes/behaviors/contatti.py +++ b/src/design/plone/contenttypes/behaviors/contatti.py @@ -41,6 +41,11 @@ class IContattiUnitaOrganizzativa(model.Schema): "selectableTypes": ["PuntoDiContatto"], }, ) + model.fieldset( + "contatti", + label=_("contatti_label", default="Contatti"), + fields=["contact_info"], + ) @provider(IFormFieldProvider) diff --git a/src/design/plone/contenttypes/interfaces/unita_organizzativa.py b/src/design/plone/contenttypes/interfaces/unita_organizzativa.py index 1c08e60d..33dfea62 100644 --- a/src/design/plone/contenttypes/interfaces/unita_organizzativa.py +++ b/src/design/plone/contenttypes/interfaces/unita_organizzativa.py @@ -24,7 +24,7 @@ class IUnitaOrganizzativa(model.Schema, IDesignPloneContentType): "uo_competenze_help", default="Descrizione dei compiti assegnati alla struttura.", ), - required=False, + required=True, ) legami_con_altre_strutture = RelationList( @@ -88,7 +88,7 @@ class IUnitaOrganizzativa(model.Schema, IDesignPloneContentType): "persone_struttura_help", default="Seleziona la lista delle persone che compongono" " la struttura.", ), - required=False, + required=True, ) sede = RelationList( @@ -105,11 +105,11 @@ class IUnitaOrganizzativa(model.Schema, IDesignPloneContentType): value_type=RelationChoice( title=_("Sede"), vocabulary="plone.app.vocabularies.Catalog" ), - required=False, + required=True, ) sedi_secondarie = RelationList( - title=_("sedi_secondarie_label", default="Sedi secondarie"), + title=_("sedi_secondarie_label", default="Altre sedi"), default=[], description=_( "sedi_secondarie_help", diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_organizzazione.cfg b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_organizzazione.cfg index c764483c..a81020c6 100644 --- a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_organizzazione.cfg +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_organizzazione.cfg @@ -1,6 +1,6 @@ [taxonomy] name = tipologia_organizzazione -title = Tipologia organizzazione +title = Tipo di organizzazione description = Selezione la tipologia dell'unità organizzativa default_language = it field_title = Tipologia organizzazione diff --git a/src/design/plone/contenttypes/restapi/deserializers/configure.zcml b/src/design/plone/contenttypes/restapi/deserializers/configure.zcml index a859e49e..3274d9ed 100644 --- a/src/design/plone/contenttypes/restapi/deserializers/configure.zcml +++ b/src/design/plone/contenttypes/restapi/deserializers/configure.zcml @@ -5,6 +5,7 @@ + diff --git a/src/design/plone/contenttypes/restapi/deserializers/servizio.py b/src/design/plone/contenttypes/restapi/deserializers/servizio.py index d316af07..729515b8 100644 --- a/src/design/plone/contenttypes/restapi/deserializers/servizio.py +++ b/src/design/plone/contenttypes/restapi/deserializers/servizio.py @@ -123,10 +123,17 @@ def __call__( ) ) ) + if "description" not in data and not self.context.description: + errors.append(new_error("La descrizione del servizio è obbligatorio")) for field in MANDATORY_RICH_TEXT_FIELDS: if field in data and not text_in_block(data.get(field)): errors.append(new_error("Il campo {} è obbligatorio".format(field))) + # Se siamo nella patch siamo in modifica. Se siamo in modifica e siamo su un + # sito che ha avuto upgrade alla versione pnrr può essere che dei campi obbligatori + # un tempo non lo fossero e quindi arriviamo fino a qui + if field not in data and not text_in_block(getattr(self.context, field)): + errors.append(new_error("Il campo {} è obbligatorio".format(field))) if errors: raise BadRequest(errors) diff --git a/src/design/plone/contenttypes/restapi/deserializers/unitaorganizzativa.py b/src/design/plone/contenttypes/restapi/deserializers/unitaorganizzativa.py new file mode 100644 index 00000000..afbed5a7 --- /dev/null +++ b/src/design/plone/contenttypes/restapi/deserializers/unitaorganizzativa.py @@ -0,0 +1,141 @@ +# -*- coding: utf-8 -*- +from design.plone.contenttypes.interfaces.unita_organizzativa import IUnitaOrganizzativa +from plone.restapi.deserializer import json_body +from plone.restapi.interfaces import IDeserializeFromJson +from zope.interface import implementer +from zope.component import adapter +from zope.interface import Interface +from plone.restapi.deserializer.dxcontent import DeserializeFromJson +from zExceptions import BadRequest +from plone.restapi.behaviors import IBlocks +from plone.restapi.indexers import SearchableText_blocks + + +TITLE_MAX_LEN = 160 +DESCRIPTION_MAX_LEN = 255 +EMPTY_BLOCK_MARKER = {"@type": "text"} +MANDATORY_RICH_TEXT_FIELDS = [ + "competenze" +] + + +def new_error(message): + return {"error": "ValidationError", "message": message} + + +def text_in_block(blocks): + @implementer(IBlocks) + class FakeObject(object): + """ + We use a fake object to use SearchableText Indexer + """ + + def Subject(self): + return "" + + def __init__(self, blocks, blocks_layout): + self.blocks = blocks + self.blocks_layout = blocks_layout + self.id = "" + self.title = "" + self.description = "" + + if not blocks: + return None + + fakeObj = FakeObject(blocks.get("blocks", ""), blocks.get("blocks_layout", "")) + return SearchableText_blocks(fakeObj)() + + +@implementer(IDeserializeFromJson) +@adapter(IUnitaOrganizzativa, Interface) +class DeserializeUnitaOrganizzativaFromJson(DeserializeFromJson): + def __call__( + self, validate_all=False, data=None, create=False + ): # noqa: ignore=C901 + + if data is None: + data = json_body(self.request) + + method = self.request.get("method") + is_post = method == "POST" + is_patch = method == "PATCH" + errors = [] + + title = data.get("title") + description = data.get("description") + + if is_post: + # Title validation + if not title: + errors.append(new_error("Il titolo dell'unità organizzativa è obbligatorio")) + elif len(title) > TITLE_MAX_LEN: + errors.append( + new_error( + "Il titolo può avere una lunghezza di massimo {} caratteri".format( + TITLE_MAX_LEN + ) + ) + ) + + # description validation + if not description: + errors.append(new_error("La descrizione dell'unità organizzativa è obbligatorio")) + elif len(description) > DESCRIPTION_MAX_LEN: + errors.append( + new_error( + "La descrizione deve avere una lunghezza di massimo {} caratteri".format( + DESCRIPTION_MAX_LEN + ) + ) + ) + + for field in MANDATORY_RICH_TEXT_FIELDS: + if field not in data: + errors.append(new_error("Il campo {} è obbligatorio".format(field))) + elif field in data and not text_in_block(data.get(field)): + errors.append(new_error("Il campo {} è obbligatorio".format(field))) + + if is_patch: + # Title validation + if "title" in data and not title: + errors.append(new_error("Il titolo del servizio è obbligatorio")) + + if title and len(title) > TITLE_MAX_LEN: + errors.append( + new_error( + "Il titolo può avere una lunghezza di massimo {} caratteri".format( + TITLE_MAX_LEN + ) + ) + ) + # description validation + if "description" in data and not description: + errors.append(new_error("La descrizione del servizio è obbligatorio")) + if description and len(description) > DESCRIPTION_MAX_LEN: + errors.append( + new_error( + "La descrizione del servizio deve avere una lunghezza di massimo {} caratteri".format( + DESCRIPTION_MAX_LEN + ) + ) + ) + + if "description" not in data and not self.context.description: + errors.append(new_error("La descrizione del servizio è obbligatorio")) + + for field in MANDATORY_RICH_TEXT_FIELDS: + if field in data and not text_in_block(data.get(field)): + errors.append(new_error("Il campo {} è obbligatorio".format(field))) + + # Se siamo nella patch siamo in modifica. Se siamo in modifica e siamo su un + # sito che ha avuto upgrade alla versione pnrr può essere che dei campi obbligatori + # un tempo non lo fossero e quindi arriviamo fino a qui + if field not in data and not text_in_block(getattr(self.context, field)): + errors.append(new_error("Il campo {} è obbligatorio".format(field))) + + if errors: + raise BadRequest(errors) + return super(DeserializeUnitaOrganizzativaFromJson, self).__call__( + validate_all=False, data=data, create=False + ) diff --git a/src/design/plone/contenttypes/restapi/services/types/get.py b/src/design/plone/contenttypes/restapi/services/types/get.py index cfa89976..570af1c7 100644 --- a/src/design/plone/contenttypes/restapi/services/types/get.py +++ b/src/design/plone/contenttypes/restapi/services/types/get.py @@ -234,6 +234,16 @@ def customize_servizio_schema(self, result): result.get("required").append("description") return result + def customize_uo_schema(self, result): + result.get("required").append("description") + versioning_fields = ["contact_info"] + for field in versioning_fields: + for fieldset in result["fieldsets"]: + if fieldset.get("id") == "contatti" and field in fieldset["fields"]: + fieldset["fields"].remove(field) + fieldset["fields"].insert(0, field) + return result + def reply(self): result = super(TypesGet, self).reply() @@ -254,6 +264,8 @@ def reply(self): result = self.customize_document_schema(result) if pt == "Servizio": result = self.customize_servizio_schema(result) + if pt == "UnitaOrganizzativa": + result = self.customize_uo_schema(result) result = self.customize_versioning_fields_fieldset(result) return result From bb1e39d9b724d55b652dcbbeb46258acda70a5bf Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Wed, 4 Jan 2023 17:11:28 +0100 Subject: [PATCH 032/487] black --- .../plone/contenttypes/events/incarico.py | 2 -- .../plone/contenttypes/interfaces/incarico.py | 33 +++++-------------- .../interfaces/punto_di_contatto.py | 13 ++------ .../restapi/deserializers/servizio.py | 4 ++- .../deserializers/unitaorganizzativa.py | 16 +++++---- .../restapi/serializers/summary.py | 2 +- .../plone/contenttypes/setuphandlers.py | 15 +++------ 7 files changed, 30 insertions(+), 55 deletions(-) diff --git a/src/design/plone/contenttypes/events/incarico.py b/src/design/plone/contenttypes/events/incarico.py index 4e52ae22..08269022 100644 --- a/src/design/plone/contenttypes/events/incarico.py +++ b/src/design/plone/contenttypes/events/incarico.py @@ -15,14 +15,12 @@ def incaricoCreateHandler(incarico, event): """ FOLDERS = [ - {"id": "compensi-file", "title": "Compensi", "contains": ("File",)}, { "id": "importi-di-viaggio-e-o-servizi", "title": "Importi di viaggio e/o servizi", "contains": ("File",), }, - ] for folder in FOLDERS: if folder["id"] in incarico: diff --git a/src/design/plone/contenttypes/interfaces/incarico.py b/src/design/plone/contenttypes/interfaces/incarico.py index dbf3d3ea..ec19587f 100644 --- a/src/design/plone/contenttypes/interfaces/incarico.py +++ b/src/design/plone/contenttypes/interfaces/incarico.py @@ -14,10 +14,7 @@ class IIncarico(model.Schema, IDesignPloneContentType): """Marker interface for content type Incarico""" compensi = BlocksField( - title=_( - "compensi_incarico_label", - default="Compensi", - ), + title=_("compensi_incarico_label", default="Compensi",), description=_( "compensi_incarico_help", default="Solo per incarico politico: compensi di qualsiasi natura" @@ -39,12 +36,8 @@ class IIncarico(model.Schema, IDesignPloneContentType): required=False, ) - unita_organizzativa = RelationList( - title=_( - "unita_organizzativa_incarico_label", - default="Unità organizzativa", - ), + title=_("unita_organizzativa_incarico_label", default="Unità organizzativa",), description=_( "unita_organizzativa_incarico_help", default="Seleziona l'organizzazione presso la quale svolge l'incarico.", @@ -52,8 +45,7 @@ class IIncarico(model.Schema, IDesignPloneContentType): required=False, default=[], value_type=RelationChoice( - title=_("Unità organizzativa"), - vocabulary="plone.app.vocabularies.Catalog", + title=_("Unità organizzativa"), vocabulary="plone.app.vocabularies.Catalog", ), ) @@ -76,8 +68,7 @@ class IIncarico(model.Schema, IDesignPloneContentType): ) data_inizio_incarico = schema.Date( - title=_("data_inizio_incarico", default="Data inizio incarico"), - required=True, + title=_("data_inizio_incarico", default="Data inizio incarico"), required=True, ) data_conclusione_incarico = schema.Date( @@ -86,15 +77,11 @@ class IIncarico(model.Schema, IDesignPloneContentType): ) data_insediamento = schema.Date( - title=_("data_insediamento", default="Data insediamento"), - required=False, + title=_("data_insediamento", default="Data insediamento"), required=False, ) atto_nomina = RelationList( - title=_( - "atto_nomina_incarico_label", - default="Atto di nomina", - ), + title=_("atto_nomina_incarico_label", default="Atto di nomina",), description=_( "atto_nomina_incarico_help", default="Inserire riferimento all'atto di nomina della persona", @@ -102,8 +89,7 @@ class IIncarico(model.Schema, IDesignPloneContentType): required=False, default=[], value_type=RelationChoice( - title=_("Atto di nomina"), - vocabulary="plone.app.vocabularies.Catalog", + title=_("Atto di nomina"), vocabulary="plone.app.vocabularies.Catalog", ), ) @@ -132,10 +118,7 @@ class IIncarico(model.Schema, IDesignPloneContentType): "atto_nomina", RelatedItemsFieldWidget, vocabulary="plone.app.vocabularies.Catalog", - pattern_options={ - "maximumSelectionSize": 1, - "selectableTypes": ["Documento"], - }, + pattern_options={"maximumSelectionSize": 1, "selectableTypes": ["Documento"],}, ) #  custom fieldsets diff --git a/src/design/plone/contenttypes/interfaces/punto_di_contatto.py b/src/design/plone/contenttypes/interfaces/punto_di_contatto.py index deb10582..ecc5647f 100644 --- a/src/design/plone/contenttypes/interfaces/punto_di_contatto.py +++ b/src/design/plone/contenttypes/interfaces/punto_di_contatto.py @@ -14,20 +14,14 @@ class IPDCValueSchema(model.Schema): pdc_type = schema.Choice( title=_("pdc_type_label", default="Tipo"), - description=_( - "type_help", - default="Tipo", - ), + description=_("type_help", default="Tipo",), vocabulary="design.plone.contenttypes.pdc_value_type", required=True, default="", ) pdc_value = schema.TextLine( title=_("pdc_value_label", default="Contatto"), - description=_( - "pdc_value_help", - default="Contatto", - ), + description=_("pdc_value_help", default="Contatto",), required=True, default="", ) @@ -49,7 +43,6 @@ class IPuntoDiContatto(model.Schema, IDesignPloneContentType): ) form.widget( - "value_punto_contatto", - DataGridFieldFactory, + "value_punto_contatto", DataGridFieldFactory, ) diff --git a/src/design/plone/contenttypes/restapi/deserializers/servizio.py b/src/design/plone/contenttypes/restapi/deserializers/servizio.py index 729515b8..ddce3f63 100644 --- a/src/design/plone/contenttypes/restapi/deserializers/servizio.py +++ b/src/design/plone/contenttypes/restapi/deserializers/servizio.py @@ -132,7 +132,9 @@ def __call__( # Se siamo nella patch siamo in modifica. Se siamo in modifica e siamo su un # sito che ha avuto upgrade alla versione pnrr può essere che dei campi obbligatori # un tempo non lo fossero e quindi arriviamo fino a qui - if field not in data and not text_in_block(getattr(self.context, field)): + if field not in data and not text_in_block( + getattr(self.context, field) + ): errors.append(new_error("Il campo {} è obbligatorio".format(field))) if errors: diff --git a/src/design/plone/contenttypes/restapi/deserializers/unitaorganizzativa.py b/src/design/plone/contenttypes/restapi/deserializers/unitaorganizzativa.py index afbed5a7..8adc5adc 100644 --- a/src/design/plone/contenttypes/restapi/deserializers/unitaorganizzativa.py +++ b/src/design/plone/contenttypes/restapi/deserializers/unitaorganizzativa.py @@ -14,9 +14,7 @@ TITLE_MAX_LEN = 160 DESCRIPTION_MAX_LEN = 255 EMPTY_BLOCK_MARKER = {"@type": "text"} -MANDATORY_RICH_TEXT_FIELDS = [ - "competenze" -] +MANDATORY_RICH_TEXT_FIELDS = ["competenze"] def new_error(message): @@ -68,7 +66,9 @@ def __call__( if is_post: # Title validation if not title: - errors.append(new_error("Il titolo dell'unità organizzativa è obbligatorio")) + errors.append( + new_error("Il titolo dell'unità organizzativa è obbligatorio") + ) elif len(title) > TITLE_MAX_LEN: errors.append( new_error( @@ -80,7 +80,9 @@ def __call__( # description validation if not description: - errors.append(new_error("La descrizione dell'unità organizzativa è obbligatorio")) + errors.append( + new_error("La descrizione dell'unità organizzativa è obbligatorio") + ) elif len(description) > DESCRIPTION_MAX_LEN: errors.append( new_error( @@ -131,7 +133,9 @@ def __call__( # Se siamo nella patch siamo in modifica. Se siamo in modifica e siamo su un # sito che ha avuto upgrade alla versione pnrr può essere che dei campi obbligatori # un tempo non lo fossero e quindi arriviamo fino a qui - if field not in data and not text_in_block(getattr(self.context, field)): + if field not in data and not text_in_block( + getattr(self.context, field) + ): errors.append(new_error("Il campo {} è obbligatorio".format(field))) if errors: diff --git a/src/design/plone/contenttypes/restapi/serializers/summary.py b/src/design/plone/contenttypes/restapi/serializers/summary.py index 7d2e7304..18873aad 100644 --- a/src/design/plone/contenttypes/restapi/serializers/summary.py +++ b/src/design/plone/contenttypes/restapi/serializers/summary.py @@ -119,4 +119,4 @@ def get_incarichi(self): except AttributeError: obj = self.context - return ', '.join([x.to_object.title for x in obj.incarichi]) + return ", ".join([x.to_object.title for x in obj.incarichi]) diff --git a/src/design/plone/contenttypes/setuphandlers.py b/src/design/plone/contenttypes/setuphandlers.py index 7f97ea44..58436406 100644 --- a/src/design/plone/contenttypes/setuphandlers.py +++ b/src/design/plone/contenttypes/setuphandlers.py @@ -24,15 +24,8 @@ def post_install(context): portal_types = api.portal.get_tool(name="portal_types") BEHAVIORS = { "Document": { - "in": [ - "plone.leadimage", - "volto.preview_image", - ], - "out": [ - "plone.leadimage", - "volto.preview_image", - "plone.tableofcontents", - ], + "in": ["plone.leadimage", "volto.preview_image",], + "out": ["plone.leadimage", "volto.preview_image", "plone.tableofcontents",], }, } for ct in BEHAVIORS.keys(): @@ -49,7 +42,9 @@ def post_install(context): def post_install_taxonomy(context): - context.runImportStepFromProfile("profile-design.plone.contenttypes:default", "typeinfo", True) + context.runImportStepFromProfile( + "profile-design.plone.contenttypes:default", "typeinfo", True + ) def uninstall(context): From f13610cb872e0e4803f717ff2e7a486edac850ba Mon Sep 17 00:00:00 2001 From: Martina Bustacchini Date: Thu, 5 Jan 2023 13:02:46 +0100 Subject: [PATCH 033/487] feat; added SearchableText to PDC and custom serializer, add taxonomy and fix schema --- .../contenttypes/adapters/configure.zcml | 2 + .../adapters/searchabletext_indexers.py | 28 +++++++++ .../plone/contenttypes/behaviors/contatti.py | 7 +++ .../contenttypes/indexers/configure.zcml | 5 ++ .../indexers/punto_di_contatto.py | 20 ++++++ .../interfaces/punto_di_contatto.py | 26 +++++++- .../behaviors/taxonomies/tipologia_pdc.xml | 2 +- .../restapi/serializers/configure.zcml | 1 + .../restapi/serializers/punto_di_contatto.py | 62 +++++++++++++++++++ 9 files changed, 151 insertions(+), 2 deletions(-) create mode 100644 src/design/plone/contenttypes/indexers/punto_di_contatto.py create mode 100644 src/design/plone/contenttypes/restapi/serializers/punto_di_contatto.py diff --git a/src/design/plone/contenttypes/adapters/configure.zcml b/src/design/plone/contenttypes/adapters/configure.zcml index 21fa4dac..8f7a3224 100644 --- a/src/design/plone/contenttypes/adapters/configure.zcml +++ b/src/design/plone/contenttypes/adapters/configure.zcml @@ -13,6 +13,8 @@ + + + + diff --git a/src/design/plone/contenttypes/indexers/punto_di_contatto.py b/src/design/plone/contenttypes/indexers/punto_di_contatto.py new file mode 100644 index 00000000..bda84a91 --- /dev/null +++ b/src/design/plone/contenttypes/indexers/punto_di_contatto.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +from design.plone.contenttypes.interfaces.punto_di_contatto import IPuntoDiContatto +from plone.app.dexterity.textindexer.interfaces import IDynamicTextIndexExtender +from zope.interface import implementer +from zope.component import adapter + + +@implementer(IDynamicTextIndexExtender) +@adapter(IPuntoDiContatto) +class PuntoDiContattoMoreTextToIndex(object): + def __init__(self, context): + self.context = context + + def __call__(self): + """Extend the searchable text with a custom string""" + result = [] + field_value = getattr(self.context, "value_punto_contatto", []) + for value in field_value: + result.append(value.get("pdc_value", "")) + return " ".join(result) diff --git a/src/design/plone/contenttypes/interfaces/punto_di_contatto.py b/src/design/plone/contenttypes/interfaces/punto_di_contatto.py index deb10582..c1e9f291 100644 --- a/src/design/plone/contenttypes/interfaces/punto_di_contatto.py +++ b/src/design/plone/contenttypes/interfaces/punto_di_contatto.py @@ -11,6 +11,7 @@ from collective.z3cform.datagridfield.row import DictRow + class IPDCValueSchema(model.Schema): pdc_type = schema.Choice( title=_("pdc_type_label", default="Tipo"), @@ -18,7 +19,7 @@ class IPDCValueSchema(model.Schema): "type_help", default="Tipo", ), - vocabulary="design.plone.contenttypes.pdc_value_type", + vocabulary="collective.taxonomy.tipologia_pdc", required=True, default="", ) @@ -47,9 +48,32 @@ class IPuntoDiContatto(model.Schema, IDesignPloneContentType): ), required=True, ) + persona = RelationList( + title=_( + "persona_incarico_label", + default="Persona", + ), + description=_( + "persona_incarico_help", + default="Seleziona la/e persona/e che ha/hanno la carica e l'incarico.", + ), + value_type=RelationChoice(vocabulary="plone.app.vocabularies.Catalog"), + required=False, + default=[], + ) form.widget( "value_punto_contatto", DataGridFieldFactory, ) + form.widget( + "persona", + RelatedItemsFieldWidget, + vocabulary="plone.app.vocabularies.Catalog", + pattern_options={ + "maximumSelectionSize": 10, + "selectableTypes": ["Persona"], + }, + ) + diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_pdc.xml b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_pdc.xml index 3eac84c2..6b723795 100644 --- a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_pdc.xml +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_pdc.xml @@ -38,7 +38,7 @@ account - Accout + Account whatsapp diff --git a/src/design/plone/contenttypes/restapi/serializers/configure.zcml b/src/design/plone/contenttypes/restapi/serializers/configure.zcml index 69d79f8d..fc404aea 100644 --- a/src/design/plone/contenttypes/restapi/serializers/configure.zcml +++ b/src/design/plone/contenttypes/restapi/serializers/configure.zcml @@ -21,4 +21,5 @@ + diff --git a/src/design/plone/contenttypes/restapi/serializers/punto_di_contatto.py b/src/design/plone/contenttypes/restapi/serializers/punto_di_contatto.py new file mode 100644 index 00000000..799f1388 --- /dev/null +++ b/src/design/plone/contenttypes/restapi/serializers/punto_di_contatto.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- +from .related_news_serializer import SerializeFolderToJson +from Acquisition import aq_inner +from design.plone.contenttypes.interfaces.punto_di_contatto import IPuntoDiContatto +from plone.restapi.interfaces import ISerializeToJson +from plone.restapi.interfaces import ISerializeToJsonSummary +from zc.relation.interfaces import ICatalog +from zope.component import adapter +from zope.component import getMultiAdapter +from zope.component import getUtility +from zope.globalrequest import getRequest +from zope.interface import implementer +from zope.interface import Interface +from zope.intid.interfaces import IIntIds +from zope.security import checkPermission + + +@implementer(ISerializeToJson) +@adapter(IPuntoDiContatto, Interface) +class PuntoDiContattoSerializer(SerializeFolderToJson): + index = "" + + def related_contents(self, field, portal_type): + """ """ + catalog = getUtility(ICatalog) + intids = getUtility(IIntIds) + items = [] + relations = catalog.findRelations( + dict( + to_id=intids.getId(aq_inner(self.context)), + from_attribute=field, + ) + ) + + for rel in relations: + obj = intids.queryObject(rel.from_id) + if obj is not None and checkPermission("zope2.View", obj) and getattr(obj, 'portal_type', None) == portal_type: + summary = getMultiAdapter( + (obj, getRequest()), ISerializeToJsonSummary + )() + items.append(summary) + return sorted(items, key=lambda k: k["title"]) + + def __call__(self, version=None, include_items=True): + result = super(PuntoDiContattoSerializer, self).__call__( + version=version, include_items=include_items + ) + strutture_correlate = self.related_contents(field="contact_info", portal_type="UnitaOrganizzativa") + servizi_correlati = self.related_contents(field="contact_info", portal_type="Servizio") + luoghi_correlati = self.related_contents(field="contact_info", portal_type="Venue") + persone_correlate = self.related_contents(field="contact_info", portal_type="Persona") + + if strutture_correlate: + result["strutture_correlate"] = strutture_correlate + if servizi_correlati: + result["servizi_correlati"] = servizi_correlati + if luoghi_correlati: + result["luoghi_correlati"] = luoghi_correlati + if persone_correlate: + result["persone_correlate"] = persone_correlate + + return result From 0b0e2f18ec925fa252d2e9c2cd296b9ad567f814 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Thu, 5 Jan 2023 14:03:28 +0100 Subject: [PATCH 034/487] fix persona content type --- .../plone/contenttypes/interfaces/persona.py | 23 ++++----------- .../interfaces/punto_di_contatto.py | 14 ++------- .../taxonomies/tipologia_incarico.cfg | 2 +- .../profiles/default/types/Persona.xml | 2 +- .../restapi/serializers/configure.zcml | 1 + .../restapi/serializers/persona.py | 5 +--- .../restapi/serializers/summary.py | 29 +++++++++++++++++-- .../restapi/services/types/get.py | 1 + 8 files changed, 40 insertions(+), 37 deletions(-) diff --git a/src/design/plone/contenttypes/interfaces/persona.py b/src/design/plone/contenttypes/interfaces/persona.py index b6b225af..e6b67ff5 100644 --- a/src/design/plone/contenttypes/interfaces/persona.py +++ b/src/design/plone/contenttypes/interfaces/persona.py @@ -10,7 +10,6 @@ from z3c.relationfield.schema import RelationChoice from z3c.relationfield.schema import RelationList - # TODO: migration script for these commented fields towards PDC # telefono # fax @@ -34,8 +33,7 @@ class IPersona(model.Schema, IDesignPloneContentType): organizzazione_riferimento = RelationList( title=_( - "organizzazione_riferimento_label", - default="Organizzazione di riferimento", + "organizzazione_riferimento_label", default="Organizzazione di riferimento", ), description=_( "organizzazione_riferimento_help", @@ -50,17 +48,12 @@ class IPersona(model.Schema, IDesignPloneContentType): required=False, ) incarichi = RelationList( - title=_( - "incarichi_label", - default="Incarichi", - ), + title=_("incarichi_label", default="Incarichi",), description=_( - "incarichi_help", - default="Seleziona la lista di incarichi della persona.", + "incarichi_help", default="Seleziona la lista di incarichi della persona.", ), value_type=RelationChoice( - title=_("Incarichi"), - vocabulary="plone.app.vocabularies.Catalog", + title=_("Incarichi"), vocabulary="plone.app.vocabularies.Catalog", ), default=[], required=False, @@ -77,8 +70,7 @@ class IPersona(model.Schema, IDesignPloneContentType): deleghe = BlocksField( title=_("deleghe_label", default="Deleghe"), description=_( - "deleghe_help", - default="Elenco delle deleghe a capo della persona.", + "deleghe_help", default="Elenco delle deleghe a capo della persona.", ), required=False, ) @@ -119,10 +111,7 @@ class IPersona(model.Schema, IDesignPloneContentType): "incarichi", RelatedItemsFieldWidget, vocabulary="plone.app.vocabularies.Catalog", - pattern_options={ - "maximumSelectionSize": 10, - "selectableTypes": ["Incarico"], - }, + pattern_options={"maximumSelectionSize": 10, "selectableTypes": ["Incarico"],}, ) # custom fieldsets diff --git a/src/design/plone/contenttypes/interfaces/punto_di_contatto.py b/src/design/plone/contenttypes/interfaces/punto_di_contatto.py index deb10582..102e9d20 100644 --- a/src/design/plone/contenttypes/interfaces/punto_di_contatto.py +++ b/src/design/plone/contenttypes/interfaces/punto_di_contatto.py @@ -14,20 +14,14 @@ class IPDCValueSchema(model.Schema): pdc_type = schema.Choice( title=_("pdc_type_label", default="Tipo"), - description=_( - "type_help", - default="Tipo", - ), + description=_("type_help", default="Tipo",), vocabulary="design.plone.contenttypes.pdc_value_type", required=True, default="", ) pdc_value = schema.TextLine( title=_("pdc_value_label", default="Contatto"), - description=_( - "pdc_value_help", - default="Contatto", - ), + description=_("pdc_value_help", default="Contatto",), required=True, default="", ) @@ -49,7 +43,5 @@ class IPuntoDiContatto(model.Schema, IDesignPloneContentType): ) form.widget( - "value_punto_contatto", - DataGridFieldFactory, + "value_punto_contatto", DataGridFieldFactory, ) - diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_incarico.cfg b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_incarico.cfg index 3c232d7d..24a0aab1 100644 --- a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_incarico.cfg +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_incarico.cfg @@ -1,7 +1,7 @@ [taxonomy] name = tipologia_incarico title = Tipo di incarico -description = Il sistema di gestione contenuti basato su React +description = Tipologie di incarico default_language = it field_title = Tipo di incarico taxonomy_fieldset = default diff --git a/src/design/plone/contenttypes/profiles/default/types/Persona.xml b/src/design/plone/contenttypes/profiles/default/types/Persona.xml index 9578a7df..2acdccf2 100644 --- a/src/design/plone/contenttypes/profiles/default/types/Persona.xml +++ b/src/design/plone/contenttypes/profiles/default/types/Persona.xml @@ -8,7 +8,7 @@ Persona + >Persona pubblica diff --git a/src/design/plone/contenttypes/restapi/serializers/configure.zcml b/src/design/plone/contenttypes/restapi/serializers/configure.zcml index 69d79f8d..9ce01e87 100644 --- a/src/design/plone/contenttypes/restapi/serializers/configure.zcml +++ b/src/design/plone/contenttypes/restapi/serializers/configure.zcml @@ -5,6 +5,7 @@ + diff --git a/src/design/plone/contenttypes/restapi/serializers/persona.py b/src/design/plone/contenttypes/restapi/serializers/persona.py index 830606e1..ea3a38a8 100644 --- a/src/design/plone/contenttypes/restapi/serializers/persona.py +++ b/src/design/plone/contenttypes/restapi/serializers/persona.py @@ -26,10 +26,7 @@ def related_contents(self, field): intids = getUtility(IIntIds) items = [] relations = catalog.findRelations( - dict( - to_id=intids.getId(aq_inner(self.context)), - from_attribute=field, - ) + dict(to_id=intids.getId(aq_inner(self.context)), from_attribute=field,) ) for rel in relations: diff --git a/src/design/plone/contenttypes/restapi/serializers/summary.py b/src/design/plone/contenttypes/restapi/serializers/summary.py index 7d2e7304..35ab2522 100644 --- a/src/design/plone/contenttypes/restapi/serializers/summary.py +++ b/src/design/plone/contenttypes/restapi/serializers/summary.py @@ -5,12 +5,15 @@ from redturtle.volto.restapi.serializer.summary import ( DefaultJSONSummarySerializer as BaseSerializer, ) +from design.plone.contenttypes.interfaces.incarico import IIncarico from zope.component import adapter -from zope.component import getMultiAdapter +from zope.component import getMultiAdapter, getUtility from zope.i18n import translate from zope.interface import implementer from zope.interface import Interface - +from collective.taxonomy.interfaces import ITaxonomy +from collective.taxonomy import PATH_SEPARATOR +from plone.restapi.serializer.converters import json_compatible import re @@ -119,4 +122,24 @@ def get_incarichi(self): except AttributeError: obj = self.context - return ', '.join([x.to_object.title for x in obj.incarichi]) + return ", ".join([x.to_object.title for x in obj.incarichi]) + + +@implementer(ISerializeToJsonSummary) +@adapter(IIncarico, IDesignPloneContenttypesLayer) +class IncaricoDefaultJSONSummarySerializer(DefaultJSONSummarySerializer): + def __call__(self, force_all_metadata=False): + res = super().__call__(force_all_metadata=force_all_metadata) + taxonomy = getUtility(ITaxonomy, name="collective.taxonomy.tipologia_incarico") + taxonomy_voc = taxonomy.makeVocabulary(self.request.get("LANGUAGE")) + if "taxonomy_tipologia_incarico" not in res: + res["taxonomy_tipologia_incarico"] = taxonomy_voc.inv_data.get( + self.context.taxonomy_tipologia_incarico + ).replace(PATH_SEPARATOR, "") + if "data_inizio_incarico" not in res: + res["data_inizio_incarico"] = json_compatible( + self.context.data_inizio_incarico + ) + if "compensi" not in res: + res["compensi"] = json_compatible(self.context.compensi) + return res diff --git a/src/design/plone/contenttypes/restapi/services/types/get.py b/src/design/plone/contenttypes/restapi/services/types/get.py index cfa89976..6f723f02 100644 --- a/src/design/plone/contenttypes/restapi/services/types/get.py +++ b/src/design/plone/contenttypes/restapi/services/types/get.py @@ -84,6 +84,7 @@ class FieldsetsMismatchError(Exception): ], "Persona": [ "default", + "ruolo", "contatti", "documenti", "informazioni", From af1419595770558cd75530ab2c23d9e075abf193 Mon Sep 17 00:00:00 2001 From: Martina Bustacchini Date: Thu, 5 Jan 2023 14:48:10 +0100 Subject: [PATCH 035/487] fix: add length check on pdc_value field in PuntoDiContatto --- .../adapters/searchabletext_indexers.py | 28 ------------------- .../plone/contenttypes/interfaces/incarico.py | 1 - .../interfaces/punto_di_contatto.py | 3 +- .../plone/contenttypes/upgrades/upgrades.py | 4 +-- 4 files changed, 3 insertions(+), 33 deletions(-) diff --git a/src/design/plone/contenttypes/adapters/searchabletext_indexers.py b/src/design/plone/contenttypes/adapters/searchabletext_indexers.py index 4a0e0dda..d95d2718 100644 --- a/src/design/plone/contenttypes/adapters/searchabletext_indexers.py +++ b/src/design/plone/contenttypes/adapters/searchabletext_indexers.py @@ -1,6 +1,5 @@ # -*- coding: utf-8 -*- from design.plone.contenttypes.interfaces import IDesignPloneContentType -from design.plone.contenttypes.interfaces.punto_di_contatto import IPuntoDiContatto, IPDCValueSchema from plone.app.dexterity.textindexer.converters import ( DefaultDexterityTextIndexFieldConverter, ) @@ -16,8 +15,6 @@ from zope.component import adapter from zope.interface import implementer from zope.publisher.interfaces.browser import IBrowserRequest -from zope.schema.interfaces import IList, IInterface -from collective.z3cform.datagridfield.interfaces import IDataGridFieldWidget @implementer(IDexterityTextIndexFieldConverter) @@ -47,28 +44,3 @@ def convert(self): @adapter(IDesignPloneContentType, IBrowserRequest) class TextBlockSearchableText(BaseTextBlockSearchableText): """ """ - - -@implementer(IDexterityTextIndexFieldConverter) -@adapter(IPuntoDiContatto, IList, IDataGridFieldWidget) -class PDCFieldConverter(DefaultDexterityTextIndexFieldConverter): - def __init__(self): - import pdb; pdb.set_trace() - - def convert(self): - import pdb; pdb.set_trace() - relations = self.field.get(self.context) - if not relations: - return "" - return " ".join([x.to_object.Title() for x in relations if x.to_object]) - - -@implementer(IDexterityTextIndexFieldConverter) -@adapter(IPDCValueSchema, IInterface, IWidget) -class PDCValueFieldConverter(DefaultDexterityTextIndexFieldConverter): - def convert(self): - import pdb; pdb.set_trace() - relations = self.field.get(self.context) - if not relations: - return "" - return " ".join([x.to_object.Title() for x in relations if x.to_object]) diff --git a/src/design/plone/contenttypes/interfaces/incarico.py b/src/design/plone/contenttypes/interfaces/incarico.py index dbf3d3ea..5215411f 100644 --- a/src/design/plone/contenttypes/interfaces/incarico.py +++ b/src/design/plone/contenttypes/interfaces/incarico.py @@ -39,7 +39,6 @@ class IIncarico(model.Schema, IDesignPloneContentType): required=False, ) - unita_organizzativa = RelationList( title=_( "unita_organizzativa_incarico_label", diff --git a/src/design/plone/contenttypes/interfaces/punto_di_contatto.py b/src/design/plone/contenttypes/interfaces/punto_di_contatto.py index c1e9f291..679fe9b5 100644 --- a/src/design/plone/contenttypes/interfaces/punto_di_contatto.py +++ b/src/design/plone/contenttypes/interfaces/punto_di_contatto.py @@ -11,7 +11,6 @@ from collective.z3cform.datagridfield.row import DictRow - class IPDCValueSchema(model.Schema): pdc_type = schema.Choice( title=_("pdc_type_label", default="Tipo"), @@ -31,6 +30,7 @@ class IPDCValueSchema(model.Schema): ), required=True, default="", + max_length=255, ) @@ -76,4 +76,3 @@ class IPuntoDiContatto(model.Schema, IDesignPloneContentType): "selectableTypes": ["Persona"], }, ) - diff --git a/src/design/plone/contenttypes/upgrades/upgrades.py b/src/design/plone/contenttypes/upgrades/upgrades.py index adccd8bf..c7b5bca3 100644 --- a/src/design/plone/contenttypes/upgrades/upgrades.py +++ b/src/design/plone/contenttypes/upgrades/upgrades.py @@ -1103,7 +1103,7 @@ def createPDCandMigrateOldCTs(portal_type): "persona": [] } for key, value in mapping.items(): - import pdb; pdb.set_trace() + # import pdb; pdb.set_trace() if hasattr(item, key): kwargs["value_punto_contatto"].append({ @@ -1118,7 +1118,7 @@ def createPDCandMigrateOldCTs(portal_type): **kwargs, ) intids = getUtility(IIntIds) - import pdb; pdb.set_trace() + # import pdb; pdb.set_trace() item.contact_info = [RelationValue(intids.getId(new_pdc))] fixed_total += 1 From caa5dd41ae50fd00ba63649fd1c077e5c53ae864 Mon Sep 17 00:00:00 2001 From: Martina Bustacchini Date: Thu, 5 Jan 2023 14:54:51 +0100 Subject: [PATCH 036/487] wip: start fixing migration script --- src/design/plone/contenttypes/upgrades/upgrades.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/design/plone/contenttypes/upgrades/upgrades.py b/src/design/plone/contenttypes/upgrades/upgrades.py index c7b5bca3..a0ab4791 100644 --- a/src/design/plone/contenttypes/upgrades/upgrades.py +++ b/src/design/plone/contenttypes/upgrades/upgrades.py @@ -992,7 +992,7 @@ def migrate_pdc_and_incarico(context): type_mapping = { "Persona": { 'PDC': { - "telefono": "phone", + "telefono": "telefono", "fax": "fax", "email": "email", "pec": "pec", @@ -1011,7 +1011,7 @@ def migrate_pdc_and_incarico(context): }, "UnitaOrganizzativa": { 'PDC': { - "telefono": "phone", + "telefono": "telefono", "fax": "fax", "email": "email", "pec": "pec", @@ -1020,7 +1020,7 @@ def migrate_pdc_and_incarico(context): # TODO: tbc "Event": { 'PDC': { - "telefono": "phone", + "telefono": "telefono", "fax": "fax", "email": "email", "pec": "pec", @@ -1029,7 +1029,7 @@ def migrate_pdc_and_incarico(context): # TODO: tbc "Venue": { 'PDC': { - "riferimento_telefonico_struttura": "phone", + "riferimento_telefonico_struttura": "telefono", "riferimento_fax_struttura": "fax", "riferimento_mail_struttura": "email", "riferimento_pec_struttura": "pec", @@ -1039,7 +1039,7 @@ def migrate_pdc_and_incarico(context): "Servizio": { # questi non sono presenti sul ct originale 'PDC': { - "telefono": "phone", + "telefono": "telefono", "fax": "fax", "email": "email", "pec": "pec", @@ -1080,6 +1080,7 @@ def createIncaricoAndMigratePersona(portal_type): incarico.atto_nomina = relation item.atto_nomina = None fixed_total += 1 + commit() logger.info(f"Fixing Punto di Contatto for '{item.title}'...:DONE") # noqa except Exception: logger.error("Error", Exception) @@ -1121,6 +1122,7 @@ def createPDCandMigrateOldCTs(portal_type): # import pdb; pdb.set_trace() item.contact_info = [RelationValue(intids.getId(new_pdc))] fixed_total += 1 + commit() logger.info(f"Fixing Punto di Contatto for '{portal_type}: DONE") logger.info("Updated {} objects".format(fixed_total)) From f90aef3acdb852ddbf9278fb4cd97ba1513df428 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Thu, 5 Jan 2023 17:08:16 +0100 Subject: [PATCH 037/487] fix per ct luogo --- .../plone/contenttypes/behaviors/luogo.py | 36 +++- .../profiles/default/types/Venue.xml | 1 + .../restapi/deserializers/configure.zcml | 1 + .../restapi/deserializers/venue.py | 162 ++++++++++++++++++ .../contenttypes/restapi/serializers/venue.py | 5 +- .../restapi/services/types/get.py | 16 +- 6 files changed, 204 insertions(+), 17 deletions(-) create mode 100644 src/design/plone/contenttypes/restapi/deserializers/venue.py diff --git a/src/design/plone/contenttypes/behaviors/luogo.py b/src/design/plone/contenttypes/behaviors/luogo.py index e8eb421d..aa11f157 100644 --- a/src/design/plone/contenttypes/behaviors/luogo.py +++ b/src/design/plone/contenttypes/behaviors/luogo.py @@ -57,7 +57,7 @@ class ILuogo(model.Schema): default="Indicare tutte le informazioni relative alla modalità di" " accesso al luogo", ), - required=False, + required=True, ) struttura_responsabile_correlati = RelationList( @@ -89,6 +89,16 @@ class ILuogo(model.Schema): ), ) + orario_pubblico = BlocksField( + title=_("orario_pubblico", default="Orario per il pubblico"), + required=False, + description=_( + "orario_pubblico_help", + default="Orario di apertura al pubblico del luogo ed eventuali " + "regole di accesso (es prenotazione).", + ), + ) + # Decisono con Baio di toglierlo: visto il vocabolario, che in realtà sta # qui: https://github.com/italia/daf-ontologie-vocabolari-controllati/tree/master/VocabolariControllati/classifications-for-culture/subject-disciplines # noqa # riteniamo che possa non fregare nulla a nessuno di questa categorizzazione. @@ -105,10 +115,17 @@ class ILuogo(model.Schema): # TODO: importare il db del MIBAC, codice DBUnico / ISIL. # Non compare nel frontend - # identificativo_mibac = schema.TextLine( - # title=_("identificativo_mibac", default="Identificativo"), - # required=False, - # ) + identificativo_mibac = schema.TextLine( + title=_("identificativo_mibac", default="Identificativo"), + required=False, + description=_( + "identificativo_mibac_help", + default="Codice identificativo del luogo. Nel MIBAC c'è" + " il codice del DBUnico per i luoghi della cultura e il codice" + " ISIL per le biblioteche. Non deve comparire nel" + " frontend del sito.", + ), + ) # custom fieldsets and order form.order_after(nome_alternativo="IBasic.title") @@ -124,6 +141,15 @@ class ILuogo(model.Schema): fields=["modalita_accesso"], ) + model.fieldset( + "categorization", fields=["identificativo_mibac"], + ) + + model.fieldset( + "orari", + label=_("orari_label", default="Orari di apertura"), + fields=["orario_pubblico"], + ) # TODO: migration script for these commented fields towards PDC model.fieldset( "contatti", diff --git a/src/design/plone/contenttypes/profiles/default/types/Venue.xml b/src/design/plone/contenttypes/profiles/default/types/Venue.xml index a8c07836..cc1704a2 100644 --- a/src/design/plone/contenttypes/profiles/default/types/Venue.xml +++ b/src/design/plone/contenttypes/profiles/default/types/Venue.xml @@ -31,6 +31,7 @@ + diff --git a/src/design/plone/contenttypes/restapi/deserializers/configure.zcml b/src/design/plone/contenttypes/restapi/deserializers/configure.zcml index a859e49e..3b829c5f 100644 --- a/src/design/plone/contenttypes/restapi/deserializers/configure.zcml +++ b/src/design/plone/contenttypes/restapi/deserializers/configure.zcml @@ -6,5 +6,6 @@ + diff --git a/src/design/plone/contenttypes/restapi/deserializers/venue.py b/src/design/plone/contenttypes/restapi/deserializers/venue.py new file mode 100644 index 00000000..e153f63e --- /dev/null +++ b/src/design/plone/contenttypes/restapi/deserializers/venue.py @@ -0,0 +1,162 @@ +# -*- coding: utf-8 -*- +from collective.venue.interfaces import IVenue +from plone.restapi.deserializer import json_body +from plone.restapi.interfaces import IDeserializeFromJson +from zope.interface import implementer +from zope.component import adapter +from zope.interface import Interface +from plone.restapi.deserializer.dxcontent import DeserializeFromJson +from zExceptions import BadRequest +from plone.restapi.behaviors import IBlocks +from plone.restapi.indexers import SearchableText_blocks + + +TITLE_MAX_LEN = 160 +DESCRIPTION_MAX_LEN = 160 +EMPTY_BLOCK_MARKER = {"@type": "text"} +MANDATORY_RICH_TEXT_FIELDS = ["modalita_accesso"] + + +def new_error(message): + return {"error": "ValidationError", "message": message} + + +def text_in_block(blocks): + @implementer(IBlocks) + class FakeObject(object): + """ + We use a fake object to use SearchableText Indexer + """ + + def Subject(self): + return "" + + def __init__(self, blocks, blocks_layout): + self.blocks = blocks + self.blocks_layout = blocks_layout + self.id = "" + self.title = "" + self.description = "" + + if not blocks: + return None + + fakeObj = FakeObject(blocks.get("blocks", ""), blocks.get("blocks_layout", "")) + return SearchableText_blocks(fakeObj)() + + +@implementer(IDeserializeFromJson) +@adapter(IVenue, Interface) +class DeserializeLuogoFromJson(DeserializeFromJson): + def __call__( + self, validate_all=False, data=None, create=False + ): # noqa: ignore=C901 + + if data is None: + data = json_body(self.request) + + method = self.request.get("method") + is_post = method == "POST" + is_patch = method == "PATCH" + errors = [] + + title = data.get("title") + description = data.get("description") + geolocation = data.get("geolocation") + + if is_post: + # Title validation + if not title: + errors.append(new_error("Il titolo del luogo è obbligatorio")) + elif len(title) > TITLE_MAX_LEN: + errors.append( + new_error( + "Il titolo può avere una lunghezza di massimo {} caratteri".format( + TITLE_MAX_LEN + ) + ) + ) + + # description validation + if not description: + errors.append(new_error("La descrizione del luogo è obbligatorio")) + elif len(description) > DESCRIPTION_MAX_LEN: + errors.append( + new_error( + "La descrizione del luogo deve avere una lunghezza di massimo {} caratteri".format( + DESCRIPTION_MAX_LEN + ) + ) + ) + + if ( + not geolocation + or not geolocation.get("latitude") + or not geolocation.get("longitude") + ): + errors.append( + new_error("La geolocalizzazione del luogo è un dato obbligatorio") + ) + + for field in MANDATORY_RICH_TEXT_FIELDS: + if field not in data: + errors.append(new_error("Il campo {} è obbligatorio".format(field))) + elif field in data and not text_in_block(data.get(field)): + errors.append(new_error("Il campo {} è obbligatorio".format(field))) + + if is_patch: + + # Title validation + if "title" in data and not title: + errors.append(new_error("Il titolo del luogo è obbligatorio")) + if title and len(title) > TITLE_MAX_LEN: + errors.append( + new_error( + "Il titolo può avere una lunghezza di massimo {} caratteri".format( + TITLE_MAX_LEN + ) + ) + ) + # description validation + if "description" in data and not description: + errors.append(new_error("La descrizione del luogo è obbligatorio")) + if description and len(description) > DESCRIPTION_MAX_LEN: + errors.append( + new_error( + "La descrizione del luogo deve avere una lunghezza di massimo {} caratteri".format( + DESCRIPTION_MAX_LEN + ) + ) + ) + + if "geolocation" in data and ( + not geolocation + or not geolocation.get("latitude") + or not geolocation.get("longitude") + ): + errors.append( + new_error("La geolocalizzazione del luogo è un dato obbligatorio") + ) + + for field in MANDATORY_RICH_TEXT_FIELDS: + if field in data and not text_in_block(data.get(field)): + errors.append(new_error("Il campo {} è obbligatorio".format(field))) + + # Se siamo nella patch siamo in modifica. Se siamo in modifica e siamo su un + # sito che ha avuto upgrade alla versione pnrr può essere che dei campi obbligatori + # un tempo non lo fossero e quindi arriviamo fino a qui + if field not in data and not text_in_block( + getattr(self.context, field) + ): + errors.append(new_error("Il campo {} è obbligatorio".format(field))) + + if "geolocation" not in data and not getattr(self.context, "geolocation"): + errors.append( + new_error("La geolocalizzazione del luogo è un dato obbligatorio") + ) + + if errors: + raise BadRequest(errors) + return super(DeserializeLuogoFromJson, self).__call__( + validate_all=False, data=data, create=False + ) diff --git a/src/design/plone/contenttypes/restapi/serializers/venue.py b/src/design/plone/contenttypes/restapi/serializers/venue.py index 51d98917..ff41fc19 100644 --- a/src/design/plone/contenttypes/restapi/serializers/venue.py +++ b/src/design/plone/contenttypes/restapi/serializers/venue.py @@ -48,10 +48,7 @@ def get_venue_offices(self, result): offices = [] for attr in ["sede", "sedi_secondarie"]: relations = catalog.findRelations( - dict( - to_id=intids.getId(aq_inner(self.context)), - from_attribute=attr, - ) + dict(to_id=intids.getId(aq_inner(self.context)), from_attribute=attr,) ) for rel in relations: diff --git a/src/design/plone/contenttypes/restapi/services/types/get.py b/src/design/plone/contenttypes/restapi/services/types/get.py index cfa89976..b78bb4d5 100644 --- a/src/design/plone/contenttypes/restapi/services/types/get.py +++ b/src/design/plone/contenttypes/restapi/services/types/get.py @@ -51,11 +51,7 @@ class FieldsetsMismatchError(Exception): "settings", "ownership", ], - "Incarico": [ - "default", - "informazioni_compensi", - "date_e_informazioni", - ], + "Incarico": ["default", "informazioni_compensi", "date_e_informazioni",], "News Item": [ "default", "dates", @@ -93,9 +89,7 @@ class FieldsetsMismatchError(Exception): "ownership", "settings", ], - "PuntoDiContatto": [ - "default", - ], + "PuntoDiContatto": ["default",], "Servizio": [ "default", "cose", @@ -166,6 +160,12 @@ def customize_venue_schema(self, result): """ Unico modo per spostare il campo "notes" """ + result.get("required").append("description") + result.get("required").append("image") + result.get("required").append("street") + result.get("required").append("city") + result.get("required").append("zip_code") + result.get("required").append("geolocation") if "properties" in result: if "country" in result["properties"]: From 75ab38f3ba0265714f2f53b63c2b314fd40602c5 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Mon, 9 Jan 2023 12:04:29 +0100 Subject: [PATCH 038/487] fix precommit hook --- .../behaviors/contatti_20230104105939.py | 220 ---- .../behaviors/contatti_20230104110153.py | 222 ---- .../behaviors/contatti_20230104110322.py | 212 ---- .../unita_organizzativa_20230104105939.py | 220 ---- .../unita_organizzativa_20230104110033.py | 213 ---- .../unita_organizzativa_20230104110045.py | 212 ---- .../unita_organizzativa_20230104110116.py | 211 --- .../default/types/Persona_20230104105939.xml | 115 -- .../default/types/Persona_20230104110533.xml | 107 -- .../default/types/Servizio_20230104105939.xml | 120 -- .../default/types/Servizio_20230104110559.xml | 110 -- .../profiles/default/types_20230104105939.xml | 59 - .../profiles/default/types_20230104110435.xml | 51 - .../profiles/default/types_20230104110443.xml | 51 - .../profiles/default/types_20230104110501.xml | 49 - .../restapi/types/adapters_20230104105939.py | 109 -- .../restapi/types/adapters_20230104110615.py | 104 -- .../restapi/types/adapters_20230104110625.py | 102 -- .../restapi/types/adapters_20230104110639.py | 100 -- .../upgrades/upgrades_20230104105158.py | 1124 ---------------- .../upgrades/upgrades_20230104110844.py | 1130 ----------------- .../upgrades/upgrades_20230104110851.py | 1129 ---------------- .../upgrades/upgrades_20230104110901.py | 1127 ---------------- .../upgrades/upgrades_20230104110903.py | 1126 ---------------- .pre-commit-config.yaml | 8 +- .../plone/contenttypes/behaviors/contatti.py | 13 +- .../plone/contenttypes/behaviors/luogo.py | 3 +- .../plone/contenttypes/content/incarico.py | 2 +- .../contenttypes/content/punto_di_contatto.py | 2 +- .../plone/contenttypes/events/incarico.py | 2 - .../plone/contenttypes/interfaces/incarico.py | 1 - .../interfaces/punto_di_contatto.py | 10 +- .../plone/contenttypes/interfaces/servizio.py | 6 +- .../contenttypes/profiles/default/rolemap.xml | 26 +- .../contenttypes/profiles/default/types.xml | 56 +- .../profiles/default/types/Event.xml | 2 +- .../profiles/default/types/Incarico.xml | 119 +- .../profiles/default/types/Persona.xml | 12 +- .../default/types/PuntoDiContatto.xml | 117 +- .../profiles/default/types/Servizio.xml | 20 +- .../restapi/deserializers/servizio.py | 18 +- .../restapi/deserializers/venue.py | 25 +- .../restapi/serializers/summary.py | 2 +- .../contenttypes/restapi/serializers/venue.py | 5 +- .../restapi/services/types/get.py | 10 +- .../contenttypes/restapi/types/adapters.py | 15 +- .../plone/contenttypes/setuphandlers.py | 4 +- .../plone/contenttypes/upgrades/upgrades.py | 59 +- 48 files changed, 292 insertions(+), 8468 deletions(-) delete mode 100644 .history/src/design/plone/contenttypes/behaviors/contatti_20230104105939.py delete mode 100644 .history/src/design/plone/contenttypes/behaviors/contatti_20230104110153.py delete mode 100644 .history/src/design/plone/contenttypes/behaviors/contatti_20230104110322.py delete mode 100644 .history/src/design/plone/contenttypes/interfaces/unita_organizzativa_20230104105939.py delete mode 100644 .history/src/design/plone/contenttypes/interfaces/unita_organizzativa_20230104110033.py delete mode 100644 .history/src/design/plone/contenttypes/interfaces/unita_organizzativa_20230104110045.py delete mode 100644 .history/src/design/plone/contenttypes/interfaces/unita_organizzativa_20230104110116.py delete mode 100644 .history/src/design/plone/contenttypes/profiles/default/types/Persona_20230104105939.xml delete mode 100644 .history/src/design/plone/contenttypes/profiles/default/types/Persona_20230104110533.xml delete mode 100644 .history/src/design/plone/contenttypes/profiles/default/types/Servizio_20230104105939.xml delete mode 100644 .history/src/design/plone/contenttypes/profiles/default/types/Servizio_20230104110559.xml delete mode 100644 .history/src/design/plone/contenttypes/profiles/default/types_20230104105939.xml delete mode 100644 .history/src/design/plone/contenttypes/profiles/default/types_20230104110435.xml delete mode 100644 .history/src/design/plone/contenttypes/profiles/default/types_20230104110443.xml delete mode 100644 .history/src/design/plone/contenttypes/profiles/default/types_20230104110501.xml delete mode 100644 .history/src/design/plone/contenttypes/restapi/types/adapters_20230104105939.py delete mode 100644 .history/src/design/plone/contenttypes/restapi/types/adapters_20230104110615.py delete mode 100644 .history/src/design/plone/contenttypes/restapi/types/adapters_20230104110625.py delete mode 100644 .history/src/design/plone/contenttypes/restapi/types/adapters_20230104110639.py delete mode 100644 .history/src/design/plone/contenttypes/upgrades/upgrades_20230104105158.py delete mode 100644 .history/src/design/plone/contenttypes/upgrades/upgrades_20230104110844.py delete mode 100644 .history/src/design/plone/contenttypes/upgrades/upgrades_20230104110851.py delete mode 100644 .history/src/design/plone/contenttypes/upgrades/upgrades_20230104110901.py delete mode 100644 .history/src/design/plone/contenttypes/upgrades/upgrades_20230104110903.py diff --git a/.history/src/design/plone/contenttypes/behaviors/contatti_20230104105939.py b/.history/src/design/plone/contenttypes/behaviors/contatti_20230104105939.py deleted file mode 100644 index 475c051b..00000000 --- a/.history/src/design/plone/contenttypes/behaviors/contatti_20230104105939.py +++ /dev/null @@ -1,220 +0,0 @@ -# -*- coding: utf-8 -*- -from collective.venue.interfaces import IVenue -<<<<<<< HEAD -from collective.volto.blocksfield.field import BlocksField -from design.plone.contenttypes import _ -from design.plone.contenttypes.interfaces.unita_organizzativa import IUnitaOrganizzativa -from plone.app.dexterity import textindexer -======= -from design.plone.contenttypes import _ ->>>>>>> pnrr -from plone.autoform.interfaces import IFormFieldProvider -from plone.supermodel import model -from z3c.relationfield.schema import RelationChoice -from z3c.relationfield.schema import RelationList -from zope.component import adapter -<<<<<<< HEAD -from zope.interface import implementer -from zope.interface import provider -======= -from plone.app.z3cform.widget import RelatedItemsFieldWidget -from plone.autoform import directives as form -from zope.interface import provider, implementer -from design.plone.contenttypes.interfaces.unita_organizzativa import IUnitaOrganizzativa -from design.plone.contenttypes.interfaces.persona import IPersona -from design.plone.contenttypes.interfaces.servizio import IServizio ->>>>>>> pnrr - - -@provider(IFormFieldProvider) -class IContattiUnitaOrganizzativa(model.Schema): - contact_info = RelationList( - title=_( - "contact_info_label", - default="Informazioni di contatto", - ), - description=_( - "contact_info_help", - default="Contatti dell'unità organizzativa.", - ), - required=True, - default=[], - value_type=RelationChoice( - title=_("Informazioni di contatto"), - vocabulary="plone.app.vocabularies.Catalog", - ), - ) - form.widget( - "contact_info", - RelatedItemsFieldWidget, - vocabulary="plone.app.vocabularies.Catalog", - pattern_options={"maximumSelectionSize": 10, "selectableTypes": ["PuntoDiContatto"]}, - ) - - -@provider(IFormFieldProvider) -class IContattiPersona(model.Schema): - contact_info = RelationList( - title=_( - "contact_info_label", - default="Punti di contatto", - ), - description=_( - "contact_info_help", - default="Punti di contatto della persona.", - ), - required=True, - default=[], - value_type=RelationChoice( - title=_("Punti di contatto"), - vocabulary="plone.app.vocabularies.Catalog", - ), - ) - - form.widget( - "contact_info", - RelatedItemsFieldWidget, - vocabulary="plone.app.vocabularies.Catalog", - pattern_options={"maximumSelectionSize": 10, "selectableTypes": ["PuntoDiContatto"]}, - ) - model.fieldset( - "contatti", - label=_("contatti_label", default="Contatti"), - fields=["contact_info"], - ) - - -@provider(IFormFieldProvider) -class IContattiServizio(model.Schema): - contact_info = RelationList( - title=_( - "contact_info_label", - default="Contatti", - ), - description=_( - "contact_info_help", - default="I contatti per il servizio.", - ), - required=True, - default=[], - value_type=RelationChoice( - title=_("Contatti"), - vocabulary="plone.app.vocabularies.Catalog", - ), - ) - form.widget( - "contact_info", - RelatedItemsFieldWidget, - vocabulary="plone.app.vocabularies.Catalog", - pattern_options={"maximumSelectionSize": 10, "selectableTypes": ["PuntoDiContatto"]}, - ) - model.fieldset( - "contatti", - label=_("contatti_label", default="Contatti"), - fields=["contact_info"], - ) - - -@provider(IFormFieldProvider) -class IContattiVenue(model.Schema): - contact_info = RelationList( - title=_( - "contact_info_label", - default="Punti di contatto", - ), - description=_( - "contact_info_help", - default="Telefono, mail o altri punti di contatto.", - ), - required=True, - default=[], - value_type=RelationChoice( - title=_("Punti di contatto"), - vocabulary="plone.app.vocabularies.Catalog", - ), - ) - form.widget( - "contact_info", - RelatedItemsFieldWidget, - vocabulary="plone.app.vocabularies.Catalog", - pattern_options={"maximumSelectionSize": 10, "selectableTypes": ["PuntoDiContatto"]}, - ) - model.fieldset( - "contatti", - label=_("contatti_label", default="Contatti"), - fields=["contact_info"], - ) - - -@provider(IFormFieldProvider) -class IContattiEvent(model.Schema): - contact_info = RelationList( - title=_( - "contact_info_label", - default="Punti di contatto", - ), - description=_( - "contact_info_help", - default="Relazione con i punti di contatto dell'evento.", - ), - required=True, - default=[], - value_type=RelationChoice( - title=_("Punti di contatto"), - vocabulary="plone.app.vocabularies.Catalog", - ), - ) - form.widget( - "contact_info", - RelatedItemsFieldWidget, - vocabulary="plone.app.vocabularies.Catalog", - pattern_options={"maximumSelectionSize": 10, "selectableTypes": ["PuntoDiContatto"]}, - ) - model.fieldset( - "contatti", - label=_("contatti_label", default="Contatti"), - fields=["contact_info"], - ) - -@implementer(IContattiEvent) -@adapter(IContattiEvent) -class ContattiEvent(object): - """ """ - - def __init__(self, context): - self.context = context - - -@implementer(IContattiPersona) -@adapter(IPersona) -class ContattiPersona(object): - """ """ - - def __init__(self, context): - self.context = context - -@implementer(IContattiServizio) -@adapter(IServizio) -class ContattiServizio(object): - """ """ - - def __init__(self, context): - self.context = context - - -@implementer(IContattiUnitaOrganizzativa) -@adapter(IUnitaOrganizzativa) -class ContattiUnitaOrganizzativa(object): - """ """ - - def __init__(self, context): - self.context = context - - -@implementer(IContattiVenue) -@adapter(IVenue) -class ContattiVenue(object): - """ """ - - def __init__(self, context): - self.context = context diff --git a/.history/src/design/plone/contenttypes/behaviors/contatti_20230104110153.py b/.history/src/design/plone/contenttypes/behaviors/contatti_20230104110153.py deleted file mode 100644 index dc59d18d..00000000 --- a/.history/src/design/plone/contenttypes/behaviors/contatti_20230104110153.py +++ /dev/null @@ -1,222 +0,0 @@ -# -*- coding: utf-8 -*- -from collective.venue.interfaces import IVenue -<<<<<<< HEAD -from collective.volto.blocksfield.field import BlocksField -from design.plone.contenttypes import _ -from design.plone.contenttypes.interfaces.unita_organizzativa import IUnitaOrganizzativa -from plone.app.dexterity import textindexer -======= -from design.plone.contenttypes import _ ->>>>>>> pnrr -from plone.autoform.interfaces import IFormFieldProvider -from plone.supermodel import model -from z3c.relationfield.schema import RelationChoice -from z3c.relationfield.schema import RelationList -from zope.component import adapter -<<<<<<< HEAD -from zope.interface import implementer -from zope.interface import provider -======= -from plone.app.z3cform.widget import RelatedItemsFieldWidget -from plone.autoform import directives as form -from zope.interface import provider, implementer -from design.plone.contenttypes.interfaces.unita_organizzativa import IUnitaOrganizzativa -from design.plone.contenttypes.interfaces.persona import IPersona -from design.plone.contenttypes.interfaces.servizio import IServizio ->>>>>>> pnrr - - -@provider(IFormFieldProvider) -class IContattiUnitaOrganizzativa(model.Schema): - contact_info = RelationList( - title=_( - "contact_info_label", - default="Informazioni di contatto", - ), - description=_( - "contact_info_help", - default="Contatti dell'unità organizzativa.", - ), - required=True, - default=[], - value_type=RelationChoice( - title=_("Informazioni di contatto"), - vocabulary="plone.app.vocabularies.Catalog", - ), - ) - form.widget( - "contact_info", - RelatedItemsFieldWidget, - vocabulary="plone.app.vocabularies.Catalog", - pattern_options={"maximumSelectionSize": 10, "selectableTypes": ["PuntoDiContatto"]}, - ) - - -@provider(IFormFieldProvider) -class IContattiPersona(model.Schema): - contact_info = RelationList( - title=_( - "contact_info_label", - default="Punti di contatto", - ), - description=_( - "contact_info_help", - default="Punti di contatto della persona.", - ), - required=True, - default=[], - value_type=RelationChoice( - title=_("Punti di contatto"), - vocabulary="plone.app.vocabularies.Catalog", - ), - ) - - form.widget( - "contact_info", - RelatedItemsFieldWidget, - vocabulary="plone.app.vocabularies.Catalog", - pattern_options={"maximumSelectionSize": 10, "selectableTypes": ["PuntoDiContatto"]}, - ) - model.fieldset( - "contatti", - label=_("contatti_label", default="Contatti"), - fields=["contact_info"], - ) - - -@provider(IFormFieldProvider) -class IContattiServizio(model.Schema): - contact_info = RelationList( - title=_( - "contact_info_label", - default="Contatti", - ), - description=_( - "contact_info_help", - default="I contatti per il servizio.", - ), - required=True, - default=[], - value_type=RelationChoice( - title=_("Contatti"), - vocabulary="plone.app.vocabularies.Catalog", - ), - ) - form.widget( - "contact_info", - RelatedItemsFieldWidget, - vocabulary="plone.app.vocabularies.Catalog", - pattern_options={"maximumSelectionSize": 10, "selectableTypes": ["PuntoDiContatto"]}, - ) - model.fieldset( - "contatti", - label=_("contatti_label", default="Contatti"), - fields=["contact_info"], - ) - - -@provider(IFormFieldProvider) -class IContattiVenue(model.Schema): - contact_info = RelationList( - title=_( - "contact_info_label", - default="Punti di contatto", - ), - description=_( - "contact_info_help", - default="Telefono, mail o altri punti di contatto.", - ), - required=True, - default=[], - value_type=RelationChoice( - title=_("Punti di contatto"), - vocabulary="plone.app.vocabularies.Catalog", - ), - ) - form.widget( - "contact_info", - RelatedItemsFieldWidget, - vocabulary="plone.app.vocabularies.Catalog", - pattern_options={"maximumSelectionSize": 10, "selectableTypes": ["PuntoDiContatto"]}, - ) - model.fieldset( - "contatti", - label=_("contatti_label", default="Contatti"), - fields=["contact_info"], - ) - - -@provider(IFormFieldProvider) -class IContattiEvent(model.Schema): - contact_info = RelationList( - title=_( - "contact_info_label", - default="Punti di contatto", - ), - description=_( - "contact_info_help", - default="Relazione con i punti di contatto dell'evento.", - ), - required=True, - default=[], - value_type=RelationChoice( - title=_("Punti di contatto"), - vocabulary="plone.app.vocabularies.Catalog", - ), - ) - form.widget( - "contact_info", - RelatedItemsFieldWidget, - vocabulary="plone.app.vocabularies.Catalog", - pattern_options={"maximumSelectionSize": 10, "selectableTypes": ["PuntoDiContatto"]}, - ) - model.fieldset( - "contatti", - label=_("contatti_label", default="Contatti"), - fields=["contact_info"], - ) - - -@implementer(IContattiEvent) -@adapter(IContattiEvent) -class ContattiEvent(object): - """ """ - - def __init__(self, context): - self.context = context - - -@implementer(IContattiPersona) -@adapter(IPersona) -class ContattiPersona(object): - """ """ - - def __init__(self, context): - self.context = context - - -@implementer(IContattiServizio) -@adapter(IServizio) -class ContattiServizio(object): - """ """ - - def __init__(self, context): - self.context = context - - -@implementer(IContattiUnitaOrganizzativa) -@adapter(IUnitaOrganizzativa) -class ContattiUnitaOrganizzativa(object): - """ """ - - def __init__(self, context): - self.context = context - - -@implementer(IContattiVenue) -@adapter(IVenue) -class ContattiVenue(object): - """ """ - - def __init__(self, context): - self.context = context diff --git a/.history/src/design/plone/contenttypes/behaviors/contatti_20230104110322.py b/.history/src/design/plone/contenttypes/behaviors/contatti_20230104110322.py deleted file mode 100644 index 0879aeed..00000000 --- a/.history/src/design/plone/contenttypes/behaviors/contatti_20230104110322.py +++ /dev/null @@ -1,212 +0,0 @@ -# -*- coding: utf-8 -*- -from collective.venue.interfaces import IVenue -from collective.volto.blocksfield.field import BlocksField -from design.plone.contenttypes import _ -from plone.app.dexterity import textindexer -from plone.autoform.interfaces import IFormFieldProvider -from plone.supermodel import model -from z3c.relationfield.schema import RelationChoice -from z3c.relationfield.schema import RelationList -from zope.component import adapter -from plone.app.z3cform.widget import RelatedItemsFieldWidget -from plone.autoform import directives as form -from zope.interface import provider, implementer -from design.plone.contenttypes.interfaces.unita_organizzativa import IUnitaOrganizzativa -from design.plone.contenttypes.interfaces.persona import IPersona -from design.plone.contenttypes.interfaces.servizio import IServizio - - -@provider(IFormFieldProvider) -class IContattiUnitaOrganizzativa(model.Schema): - contact_info = RelationList( - title=_( - "contact_info_label", - default="Informazioni di contatto", - ), - description=_( - "contact_info_help", - default="Contatti dell'unità organizzativa.", - ), - required=True, - default=[], - value_type=RelationChoice( - title=_("Informazioni di contatto"), - vocabulary="plone.app.vocabularies.Catalog", - ), - ) - form.widget( - "contact_info", - RelatedItemsFieldWidget, - vocabulary="plone.app.vocabularies.Catalog", - pattern_options={"maximumSelectionSize": 10, "selectableTypes": ["PuntoDiContatto"]}, - ) - - -@provider(IFormFieldProvider) -class IContattiPersona(model.Schema): - contact_info = RelationList( - title=_( - "contact_info_label", - default="Punti di contatto", - ), - description=_( - "contact_info_help", - default="Punti di contatto della persona.", - ), - required=True, - default=[], - value_type=RelationChoice( - title=_("Punti di contatto"), - vocabulary="plone.app.vocabularies.Catalog", - ), - ) - - form.widget( - "contact_info", - RelatedItemsFieldWidget, - vocabulary="plone.app.vocabularies.Catalog", - pattern_options={"maximumSelectionSize": 10, "selectableTypes": ["PuntoDiContatto"]}, - ) - model.fieldset( - "contatti", - label=_("contatti_label", default="Contatti"), - fields=["contact_info"], - ) - - -@provider(IFormFieldProvider) -class IContattiServizio(model.Schema): - contact_info = RelationList( - title=_( - "contact_info_label", - default="Contatti", - ), - description=_( - "contact_info_help", - default="I contatti per il servizio.", - ), - required=True, - default=[], - value_type=RelationChoice( - title=_("Contatti"), - vocabulary="plone.app.vocabularies.Catalog", - ), - ) - form.widget( - "contact_info", - RelatedItemsFieldWidget, - vocabulary="plone.app.vocabularies.Catalog", - pattern_options={"maximumSelectionSize": 10, "selectableTypes": ["PuntoDiContatto"]}, - ) - model.fieldset( - "contatti", - label=_("contatti_label", default="Contatti"), - fields=["contact_info"], - ) - - -@provider(IFormFieldProvider) -class IContattiVenue(model.Schema): - contact_info = RelationList( - title=_( - "contact_info_label", - default="Punti di contatto", - ), - description=_( - "contact_info_help", - default="Telefono, mail o altri punti di contatto.", - ), - required=True, - default=[], - value_type=RelationChoice( - title=_("Punti di contatto"), - vocabulary="plone.app.vocabularies.Catalog", - ), - ) - form.widget( - "contact_info", - RelatedItemsFieldWidget, - vocabulary="plone.app.vocabularies.Catalog", - pattern_options={"maximumSelectionSize": 10, "selectableTypes": ["PuntoDiContatto"]}, - ) - model.fieldset( - "contatti", - label=_("contatti_label", default="Contatti"), - fields=["contact_info"], - ) - - -@provider(IFormFieldProvider) -class IContattiEvent(model.Schema): - contact_info = RelationList( - title=_( - "contact_info_label", - default="Punti di contatto", - ), - description=_( - "contact_info_help", - default="Relazione con i punti di contatto dell'evento.", - ), - required=True, - default=[], - value_type=RelationChoice( - title=_("Punti di contatto"), - vocabulary="plone.app.vocabularies.Catalog", - ), - ) - form.widget( - "contact_info", - RelatedItemsFieldWidget, - vocabulary="plone.app.vocabularies.Catalog", - pattern_options={"maximumSelectionSize": 10, "selectableTypes": ["PuntoDiContatto"]}, - ) - model.fieldset( - "contatti", - label=_("contatti_label", default="Contatti"), - fields=["contact_info"], - ) - - -@implementer(IContattiEvent) -@adapter(IContattiEvent) -class ContattiEvent(object): - """ """ - - def __init__(self, context): - self.context = context - - -@implementer(IContattiPersona) -@adapter(IPersona) -class ContattiPersona(object): - """ """ - - def __init__(self, context): - self.context = context - - -@implementer(IContattiServizio) -@adapter(IServizio) -class ContattiServizio(object): - """ """ - - def __init__(self, context): - self.context = context - - -@implementer(IContattiUnitaOrganizzativa) -@adapter(IUnitaOrganizzativa) -class ContattiUnitaOrganizzativa(object): - """ """ - - def __init__(self, context): - self.context = context - - -@implementer(IContattiVenue) -@adapter(IVenue) -class ContattiVenue(object): - """ """ - - def __init__(self, context): - self.context = context diff --git a/.history/src/design/plone/contenttypes/interfaces/unita_organizzativa_20230104105939.py b/.history/src/design/plone/contenttypes/interfaces/unita_organizzativa_20230104105939.py deleted file mode 100644 index 92166416..00000000 --- a/.history/src/design/plone/contenttypes/interfaces/unita_organizzativa_20230104105939.py +++ /dev/null @@ -1,220 +0,0 @@ -# -*- coding: utf-8 -*- -from collective.volto.blocksfield.field import BlocksField -from design.plone.contenttypes import _ -from design.plone.contenttypes.interfaces import IDesignPloneContentType -from plone.app.dexterity import textindexer -from plone.app.z3cform.widget import RelatedItemsFieldWidget -from plone.autoform import directives as form -from plone.supermodel import model -from z3c.relationfield.schema import RelationChoice -from z3c.relationfield.schema import RelationList - - -# TODO: migration script for these commented fields towards PDC -# contact_info -# Probabilmente non possibile trattandosi di un campo a blocchi -# preferirei si arrangiassero le redazioni. Altrimenti si defaulta -# ad un tipo a caso + tutto il testo e poi si arrangiano comunque -class IUnitaOrganizzativa(model.Schema, IDesignPloneContentType): - """Marker interface for content type UnitaOrganizzativa""" - - competenze = BlocksField( - title=_("uo_competenze_label", default="Competenze"), - description=_( - "uo_competenze_help", - default="Descrizione dei compiti assegnati alla struttura.", - ), - required=False, - ) - - legami_con_altre_strutture = RelationList( - title=_( - "legami_altre_strutture_label", default="Servizi o uffici di riferimento" - ), - default=[], - description=_( - "legami_con_altre_strutture_help", - default="Selezionare la lista di strutture e/o uffici collegati" - " a questa unità organizzativa.", - ), - value_type=RelationChoice( - title=_("Struttura"), vocabulary="plone.app.vocabularies.Catalog" - ), - required=False, - ) - - responsabile = RelationList( - title=_("responsabile_label", default="Responsabile"), - value_type=RelationChoice( - title=_("Responsabile"), - vocabulary="plone.app.vocabularies.Catalog", - ), - description=_( - "responsabile_help", - default="Selezionare il/i responsabile/i della struttura.", - ), - default=[], - required=False, - ) - - assessore_riferimento = RelationList( - title="Assessore di riferimento", - # vocabolario di riferimento sara' dinamico con i content type - # persona presenti all'interno della macro Amministrazione" - value_type=RelationChoice( - title=_("Assessore di riferimento"), - vocabulary="plone.app.vocabularies.Catalog", - ), - description=_( - "assessore_riferimento_help", - default="Inserire l'assessore di riferimento della struttura," - " se esiste.", - ), - required=False, - default=[], - ) - - # vocabolario di riferimento sara' dinamico con i content type persona - persone_struttura = RelationList( - title=_( - "persone_struttura_label", default="Persone che compongono la struttura" - ), - default=[], - value_type=RelationChoice( - title=_("Persone della struttura"), - vocabulary="plone.app.vocabularies.Catalog", - ), - description=_( - "persone_struttura_help", - default="Seleziona la lista delle persone che compongono" " la struttura.", - ), - required=False, - ) - - sede = RelationList( - title=_("sede_label", default="Sede principale"), - default=[], - description=_( - "sede_help", - default="Seleziona il Luogo in cui questa struttura ha sede. " - "Se non è presente un contenuto di tipo Luogo a cui far " - "riferimento, puoi compilare i campi seguenti. Se selezioni un " - "Luogo, puoi usare comunque i campi seguenti per sovrascrivere " - "alcune informazioni.", - ), - value_type=RelationChoice( - title=_("Sede"), vocabulary="plone.app.vocabularies.Catalog" - ), - required=False, - ) - - sedi_secondarie = RelationList( - title=_("sedi_secondarie_label", default="Sedi secondarie"), - default=[], - description=_( - "sedi_secondarie_help", - default="Seleziona una lista di eventuali contenuti di tipo Luogo" - " che sono sedi secondarie di questa struttura. " - "Per queste sedi non sarà possibile sovrascrivere i dati. " - "Nel caso servano informazioni diverse, è possibile usare il campo" - " sottostante.", - ), - value_type=RelationChoice( - title=_("Sede"), vocabulary="plone.app.vocabularies.Catalog" - ), - required=False, - ) - - - #  custom widgets - form.widget( - "persone_struttura", - RelatedItemsFieldWidget, - vocabulary="plone.app.vocabularies.Catalog", - pattern_options={"selectableTypes": ["Persona"], "maximumSelectionSize": 50}, - ) - form.widget( - "legami_con_altre_strutture", - RelatedItemsFieldWidget, - vocabulary="plone.app.vocabularies.Catalog", - pattern_options={ - "maximumSelectionSize": 10, - "selectableTypes": ["UnitaOrganizzativa"], - }, - ) - form.widget( - "responsabile", - RelatedItemsFieldWidget, - vocabulary="plone.app.vocabularies.Catalog", - pattern_options={ - "maximumSelectionSize": 1, - "selectableTypes": ["Persona"], - # "basePath": "/amministrazione", - }, - ) - form.widget( - "assessore_riferimento", - RelatedItemsFieldWidget, - vocabulary="plone.app.vocabularies.Catalog", - pattern_options={ - "maximumSelectionSize": 1, - "selectableTypes": ["Persona"], - # "basePath": "/amministrazione", - }, - ) - form.widget( - "sede", - RelatedItemsFieldWidget, - vocabulary="plone.app.vocabularies.Catalog", - pattern_options={"maximumSelectionSize": 1, "selectableTypes": ["Venue"]}, - ) - form.widget( - "sedi_secondarie", - RelatedItemsFieldWidget, - vocabulary="plone.app.vocabularies.Catalog", - pattern_options={ - "maximumSelectionSize": 10, - "selectableTypes": ["Venue"], - # "basePath": "/servizi", - }, - ) - - # custom fieldsets and order - model.fieldset( - "cosa_fa", - label=_("cosa_fa_label", default="Cosa fa"), - fields=["competenze"], - ) - model.fieldset( - "struttura", - label=_("struttura_label", default="Struttura"), - fields=[ - "legami_con_altre_strutture", - "responsabile", - "assessore_riferimento", - ], - ) - model.fieldset( - "persone", - label=_("persone_label", default="Persone"), - fields=["persone_struttura"], - ) - model.fieldset( - "contatti", - label=_("contatti_label", default="Contatti"), - fields=["sede", "sedi_secondarie"], - ) -<<<<<<< HEAD - form.order_after( - sedi_secondarie="IContattiUnitaOrganizzativa.orario_pubblico" - ) # noqa - form.order_after(contact_info="sedi_secondarie") -======= - form.order_after(sedi_secondarie="IContattiUnitaOrganizzativa.orario_pubblico") - # form.order_after(contact_info="sedi_secondarie") ->>>>>>> pnrr - - # SearchableText indexers - textindexer.searchable("competenze") - textindexer.searchable("assessore_riferimento") - textindexer.searchable("responsabile") diff --git a/.history/src/design/plone/contenttypes/interfaces/unita_organizzativa_20230104110033.py b/.history/src/design/plone/contenttypes/interfaces/unita_organizzativa_20230104110033.py deleted file mode 100644 index 99b47c74..00000000 --- a/.history/src/design/plone/contenttypes/interfaces/unita_organizzativa_20230104110033.py +++ /dev/null @@ -1,213 +0,0 @@ -# -*- coding: utf-8 -*- -from collective.volto.blocksfield.field import BlocksField -from design.plone.contenttypes import _ -from design.plone.contenttypes.interfaces import IDesignPloneContentType -from plone.app.dexterity import textindexer -from plone.app.z3cform.widget import RelatedItemsFieldWidget -from plone.autoform import directives as form -from plone.supermodel import model -from z3c.relationfield.schema import RelationChoice -from z3c.relationfield.schema import RelationList - - -# TODO: migration script for these commented fields towards PDC -# contact_info -# Probabilmente non possibile trattandosi di un campo a blocchi -# preferirei si arrangiassero le redazioni. Altrimenti si defaulta -# ad un tipo a caso + tutto il testo e poi si arrangiano comunque -class IUnitaOrganizzativa(model.Schema, IDesignPloneContentType): - """Marker interface for content type UnitaOrganizzativa""" - - competenze = BlocksField( - title=_("uo_competenze_label", default="Competenze"), - description=_( - "uo_competenze_help", - default="Descrizione dei compiti assegnati alla struttura.", - ), - required=False, - ) - - legami_con_altre_strutture = RelationList( - title=_( - "legami_altre_strutture_label", default="Servizi o uffici di riferimento" - ), - default=[], - description=_( - "legami_con_altre_strutture_help", - default="Selezionare la lista di strutture e/o uffici collegati" - " a questa unità organizzativa.", - ), - value_type=RelationChoice( - title=_("Struttura"), vocabulary="plone.app.vocabularies.Catalog" - ), - required=False, - ) - - responsabile = RelationList( - title=_("responsabile_label", default="Responsabile"), - value_type=RelationChoice( - title=_("Responsabile"), - vocabulary="plone.app.vocabularies.Catalog", - ), - description=_( - "responsabile_help", - default="Selezionare il/i responsabile/i della struttura.", - ), - default=[], - required=False, - ) - - assessore_riferimento = RelationList( - title="Assessore di riferimento", - # vocabolario di riferimento sara' dinamico con i content type - # persona presenti all'interno della macro Amministrazione" - value_type=RelationChoice( - title=_("Assessore di riferimento"), - vocabulary="plone.app.vocabularies.Catalog", - ), - description=_( - "assessore_riferimento_help", - default="Inserire l'assessore di riferimento della struttura," - " se esiste.", - ), - required=False, - default=[], - ) - - # vocabolario di riferimento sara' dinamico con i content type persona - persone_struttura = RelationList( - title=_( - "persone_struttura_label", default="Persone che compongono la struttura" - ), - default=[], - value_type=RelationChoice( - title=_("Persone della struttura"), - vocabulary="plone.app.vocabularies.Catalog", - ), - description=_( - "persone_struttura_help", - default="Seleziona la lista delle persone che compongono" " la struttura.", - ), - required=False, - ) - - sede = RelationList( - title=_("sede_label", default="Sede principale"), - default=[], - description=_( - "sede_help", - default="Seleziona il Luogo in cui questa struttura ha sede. " - "Se non è presente un contenuto di tipo Luogo a cui far " - "riferimento, puoi compilare i campi seguenti. Se selezioni un " - "Luogo, puoi usare comunque i campi seguenti per sovrascrivere " - "alcune informazioni.", - ), - value_type=RelationChoice( - title=_("Sede"), vocabulary="plone.app.vocabularies.Catalog" - ), - required=False, - ) - - sedi_secondarie = RelationList( - title=_("sedi_secondarie_label", default="Sedi secondarie"), - default=[], - description=_( - "sedi_secondarie_help", - default="Seleziona una lista di eventuali contenuti di tipo Luogo" - " che sono sedi secondarie di questa struttura. " - "Per queste sedi non sarà possibile sovrascrivere i dati. " - "Nel caso servano informazioni diverse, è possibile usare il campo" - " sottostante.", - ), - value_type=RelationChoice( - title=_("Sede"), vocabulary="plone.app.vocabularies.Catalog" - ), - required=False, - ) - - - # custom widgets - form.widget( - "persone_struttura", - RelatedItemsFieldWidget, - vocabulary="plone.app.vocabularies.Catalog", - pattern_options={"selectableTypes": ["Persona"], "maximumSelectionSize": 50}, - ) - form.widget( - "legami_con_altre_strutture", - RelatedItemsFieldWidget, - vocabulary="plone.app.vocabularies.Catalog", - pattern_options={ - "maximumSelectionSize": 10, - "selectableTypes": ["UnitaOrganizzativa"], - }, - ) - form.widget( - "responsabile", - RelatedItemsFieldWidget, - vocabulary="plone.app.vocabularies.Catalog", - pattern_options={ - "maximumSelectionSize": 1, - "selectableTypes": ["Persona"], - # "basePath": "/amministrazione", - }, - ) - form.widget( - "assessore_riferimento", - RelatedItemsFieldWidget, - vocabulary="plone.app.vocabularies.Catalog", - pattern_options={ - "maximumSelectionSize": 1, - "selectableTypes": ["Persona"], - # "basePath": "/amministrazione", - }, - ) - form.widget( - "sede", - RelatedItemsFieldWidget, - vocabulary="plone.app.vocabularies.Catalog", - pattern_options={"maximumSelectionSize": 1, "selectableTypes": ["Venue"]}, - ) - form.widget( - "sedi_secondarie", - RelatedItemsFieldWidget, - vocabulary="plone.app.vocabularies.Catalog", - pattern_options={ - "maximumSelectionSize": 10, - "selectableTypes": ["Venue"], - # "basePath": "/servizi", - }, - ) - - # custom fieldsets and order - model.fieldset( - "cosa_fa", - label=_("cosa_fa_label", default="Cosa fa"), - fields=["competenze"], - ) - model.fieldset( - "struttura", - label=_("struttura_label", default="Struttura"), - fields=[ - "legami_con_altre_strutture", - "responsabile", - "assessore_riferimento", - ], - ) - model.fieldset( - "persone", - label=_("persone_label", default="Persone"), - fields=["persone_struttura"], - ) - model.fieldset( - "contatti", - label=_("contatti_label", default="Contatti"), - fields=["sede", "sedi_secondarie"], - ) - form.order_after(sedi_secondarie="IContattiUnitaOrganizzativa.orario_pubblico") - # form.order_after(contact_info="sedi_secondarie") - - # SearchableText indexers - textindexer.searchable("competenze") - textindexer.searchable("assessore_riferimento") - textindexer.searchable("responsabile") diff --git a/.history/src/design/plone/contenttypes/interfaces/unita_organizzativa_20230104110045.py b/.history/src/design/plone/contenttypes/interfaces/unita_organizzativa_20230104110045.py deleted file mode 100644 index d0439a93..00000000 --- a/.history/src/design/plone/contenttypes/interfaces/unita_organizzativa_20230104110045.py +++ /dev/null @@ -1,212 +0,0 @@ -# -*- coding: utf-8 -*- -from collective.volto.blocksfield.field import BlocksField -from design.plone.contenttypes import _ -from design.plone.contenttypes.interfaces import IDesignPloneContentType -from plone.app.dexterity import textindexer -from plone.app.z3cform.widget import RelatedItemsFieldWidget -from plone.autoform import directives as form -from plone.supermodel import model -from z3c.relationfield.schema import RelationChoice -from z3c.relationfield.schema import RelationList - - -# TODO: migration script for these commented fields towards PDC -# contact_info -# Probabilmente non possibile trattandosi di un campo a blocchi -# preferirei si arrangiassero le redazioni. Altrimenti si defaulta -# ad un tipo a caso + tutto il testo e poi si arrangiano comunque -class IUnitaOrganizzativa(model.Schema, IDesignPloneContentType): - """Marker interface for content type UnitaOrganizzativa""" - - competenze = BlocksField( - title=_("uo_competenze_label", default="Competenze"), - description=_( - "uo_competenze_help", - default="Descrizione dei compiti assegnati alla struttura.", - ), - required=False, - ) - - legami_con_altre_strutture = RelationList( - title=_( - "legami_altre_strutture_label", default="Servizi o uffici di riferimento" - ), - default=[], - description=_( - "legami_con_altre_strutture_help", - default="Selezionare la lista di strutture e/o uffici collegati" - " a questa unità organizzativa.", - ), - value_type=RelationChoice( - title=_("Struttura"), vocabulary="plone.app.vocabularies.Catalog" - ), - required=False, - ) - - responsabile = RelationList( - title=_("responsabile_label", default="Responsabile"), - value_type=RelationChoice( - title=_("Responsabile"), - vocabulary="plone.app.vocabularies.Catalog", - ), - description=_( - "responsabile_help", - default="Selezionare il/i responsabile/i della struttura.", - ), - default=[], - required=False, - ) - - assessore_riferimento = RelationList( - title="Assessore di riferimento", - # vocabolario di riferimento sara' dinamico con i content type - # persona presenti all'interno della macro Amministrazione" - value_type=RelationChoice( - title=_("Assessore di riferimento"), - vocabulary="plone.app.vocabularies.Catalog", - ), - description=_( - "assessore_riferimento_help", - default="Inserire l'assessore di riferimento della struttura," - " se esiste.", - ), - required=False, - default=[], - ) - - # vocabolario di riferimento sara' dinamico con i content type persona - persone_struttura = RelationList( - title=_( - "persone_struttura_label", default="Persone che compongono la struttura" - ), - default=[], - value_type=RelationChoice( - title=_("Persone della struttura"), - vocabulary="plone.app.vocabularies.Catalog", - ), - description=_( - "persone_struttura_help", - default="Seleziona la lista delle persone che compongono" " la struttura.", - ), - required=False, - ) - - sede = RelationList( - title=_("sede_label", default="Sede principale"), - default=[], - description=_( - "sede_help", - default="Seleziona il Luogo in cui questa struttura ha sede. " - "Se non è presente un contenuto di tipo Luogo a cui far " - "riferimento, puoi compilare i campi seguenti. Se selezioni un " - "Luogo, puoi usare comunque i campi seguenti per sovrascrivere " - "alcune informazioni.", - ), - value_type=RelationChoice( - title=_("Sede"), vocabulary="plone.app.vocabularies.Catalog" - ), - required=False, - ) - - sedi_secondarie = RelationList( - title=_("sedi_secondarie_label", default="Sedi secondarie"), - default=[], - description=_( - "sedi_secondarie_help", - default="Seleziona una lista di eventuali contenuti di tipo Luogo" - " che sono sedi secondarie di questa struttura. " - "Per queste sedi non sarà possibile sovrascrivere i dati. " - "Nel caso servano informazioni diverse, è possibile usare il campo" - " sottostante.", - ), - value_type=RelationChoice( - title=_("Sede"), vocabulary="plone.app.vocabularies.Catalog" - ), - required=False, - ) - - # custom widgets - form.widget( - "persone_struttura", - RelatedItemsFieldWidget, - vocabulary="plone.app.vocabularies.Catalog", - pattern_options={"selectableTypes": ["Persona"], "maximumSelectionSize": 50}, - ) - form.widget( - "legami_con_altre_strutture", - RelatedItemsFieldWidget, - vocabulary="plone.app.vocabularies.Catalog", - pattern_options={ - "maximumSelectionSize": 10, - "selectableTypes": ["UnitaOrganizzativa"], - }, - ) - form.widget( - "responsabile", - RelatedItemsFieldWidget, - vocabulary="plone.app.vocabularies.Catalog", - pattern_options={ - "maximumSelectionSize": 1, - "selectableTypes": ["Persona"], - # "basePath": "/amministrazione", - }, - ) - form.widget( - "assessore_riferimento", - RelatedItemsFieldWidget, - vocabulary="plone.app.vocabularies.Catalog", - pattern_options={ - "maximumSelectionSize": 1, - "selectableTypes": ["Persona"], - # "basePath": "/amministrazione", - }, - ) - form.widget( - "sede", - RelatedItemsFieldWidget, - vocabulary="plone.app.vocabularies.Catalog", - pattern_options={"maximumSelectionSize": 1, "selectableTypes": ["Venue"]}, - ) - form.widget( - "sedi_secondarie", - RelatedItemsFieldWidget, - vocabulary="plone.app.vocabularies.Catalog", - pattern_options={ - "maximumSelectionSize": 10, - "selectableTypes": ["Venue"], - # "basePath": "/servizi", - }, - ) - - # custom fieldsets and order - model.fieldset( - "cosa_fa", - label=_("cosa_fa_label", default="Cosa fa"), - fields=["competenze"], - ) - model.fieldset( - "struttura", - label=_("struttura_label", default="Struttura"), - fields=[ - "legami_con_altre_strutture", - "responsabile", - "assessore_riferimento", - ], - ) - model.fieldset( - "persone", - label=_("persone_label", default="Persone"), - fields=["persone_struttura"], - ) - model.fieldset( - "contatti", - label=_("contatti_label", default="Contatti"), - fields=["sede", "sedi_secondarie"], - ) - form.order_after(sedi_secondarie="IContattiUnitaOrganizzativa.orario_pubblico") - # form.order_after(contact_info="sedi_secondarie") - - # SearchableText indexers - textindexer.searchable("competenze") - textindexer.searchable("assessore_riferimento") - textindexer.searchable("responsabile") diff --git a/.history/src/design/plone/contenttypes/interfaces/unita_organizzativa_20230104110116.py b/.history/src/design/plone/contenttypes/interfaces/unita_organizzativa_20230104110116.py deleted file mode 100644 index e4fd69f0..00000000 --- a/.history/src/design/plone/contenttypes/interfaces/unita_organizzativa_20230104110116.py +++ /dev/null @@ -1,211 +0,0 @@ -# -*- coding: utf-8 -*- -from collective.volto.blocksfield.field import BlocksField -from design.plone.contenttypes import _ -from design.plone.contenttypes.interfaces import IDesignPloneContentType -from plone.app.dexterity import textindexer -from plone.app.z3cform.widget import RelatedItemsFieldWidget -from plone.autoform import directives as form -from plone.supermodel import model -from z3c.relationfield.schema import RelationChoice -from z3c.relationfield.schema import RelationList - - -# TODO: migration script for these commented fields towards PDC -# contact_info -# Probabilmente non possibile trattandosi di un campo a blocchi -# preferirei si arrangiassero le redazioni. Altrimenti si defaulta -# ad un tipo a caso + tutto il testo e poi si arrangiano comunque -class IUnitaOrganizzativa(model.Schema, IDesignPloneContentType): - """Marker interface for content type UnitaOrganizzativa""" - - competenze = BlocksField( - title=_("uo_competenze_label", default="Competenze"), - description=_( - "uo_competenze_help", - default="Descrizione dei compiti assegnati alla struttura.", - ), - required=False, - ) - - legami_con_altre_strutture = RelationList( - title=_( - "legami_altre_strutture_label", default="Servizi o uffici di riferimento" - ), - default=[], - description=_( - "legami_con_altre_strutture_help", - default="Selezionare la lista di strutture e/o uffici collegati" - " a questa unità organizzativa.", - ), - value_type=RelationChoice( - title=_("Struttura"), vocabulary="plone.app.vocabularies.Catalog" - ), - required=False, - ) - - responsabile = RelationList( - title=_("responsabile_label", default="Responsabile"), - value_type=RelationChoice( - title=_("Responsabile"), - vocabulary="plone.app.vocabularies.Catalog", - ), - description=_( - "responsabile_help", - default="Selezionare il/i responsabile/i della struttura.", - ), - default=[], - required=False, - ) - - assessore_riferimento = RelationList( - title="Assessore di riferimento", - # vocabolario di riferimento sara' dinamico con i content type - # persona presenti all'interno della macro Amministrazione" - value_type=RelationChoice( - title=_("Assessore di riferimento"), - vocabulary="plone.app.vocabularies.Catalog", - ), - description=_( - "assessore_riferimento_help", - default="Inserire l'assessore di riferimento della struttura," - " se esiste.", - ), - required=False, - default=[], - ) - - # vocabolario di riferimento sara' dinamico con i content type persona - persone_struttura = RelationList( - title=_( - "persone_struttura_label", default="Persone che compongono la struttura" - ), - default=[], - value_type=RelationChoice( - title=_("Persone della struttura"), - vocabulary="plone.app.vocabularies.Catalog", - ), - description=_( - "persone_struttura_help", - default="Seleziona la lista delle persone che compongono" " la struttura.", - ), - required=False, - ) - - sede = RelationList( - title=_("sede_label", default="Sede principale"), - default=[], - description=_( - "sede_help", - default="Seleziona il Luogo in cui questa struttura ha sede. " - "Se non è presente un contenuto di tipo Luogo a cui far " - "riferimento, puoi compilare i campi seguenti. Se selezioni un " - "Luogo, puoi usare comunque i campi seguenti per sovrascrivere " - "alcune informazioni.", - ), - value_type=RelationChoice( - title=_("Sede"), vocabulary="plone.app.vocabularies.Catalog" - ), - required=False, - ) - - sedi_secondarie = RelationList( - title=_("sedi_secondarie_label", default="Sedi secondarie"), - default=[], - description=_( - "sedi_secondarie_help", - default="Seleziona una lista di eventuali contenuti di tipo Luogo" - " che sono sedi secondarie di questa struttura. " - "Per queste sedi non sarà possibile sovrascrivere i dati. " - "Nel caso servano informazioni diverse, è possibile usare il campo" - " sottostante.", - ), - value_type=RelationChoice( - title=_("Sede"), vocabulary="plone.app.vocabularies.Catalog" - ), - required=False, - ) - - # custom widgets - form.widget( - "persone_struttura", - RelatedItemsFieldWidget, - vocabulary="plone.app.vocabularies.Catalog", - pattern_options={"selectableTypes": ["Persona"], "maximumSelectionSize": 50}, - ) - form.widget( - "legami_con_altre_strutture", - RelatedItemsFieldWidget, - vocabulary="plone.app.vocabularies.Catalog", - pattern_options={ - "maximumSelectionSize": 10, - "selectableTypes": ["UnitaOrganizzativa"], - }, - ) - form.widget( - "responsabile", - RelatedItemsFieldWidget, - vocabulary="plone.app.vocabularies.Catalog", - pattern_options={ - "maximumSelectionSize": 1, - "selectableTypes": ["Persona"], - # "basePath": "/amministrazione", - }, - ) - form.widget( - "assessore_riferimento", - RelatedItemsFieldWidget, - vocabulary="plone.app.vocabularies.Catalog", - pattern_options={ - "maximumSelectionSize": 1, - "selectableTypes": ["Persona"], - # "basePath": "/amministrazione", - }, - ) - form.widget( - "sede", - RelatedItemsFieldWidget, - vocabulary="plone.app.vocabularies.Catalog", - pattern_options={"maximumSelectionSize": 1, "selectableTypes": ["Venue"]}, - ) - form.widget( - "sedi_secondarie", - RelatedItemsFieldWidget, - vocabulary="plone.app.vocabularies.Catalog", - pattern_options={ - "maximumSelectionSize": 10, - "selectableTypes": ["Venue"], - # "basePath": "/servizi", - }, - ) - - # custom fieldsets and order - model.fieldset( - "cosa_fa", - label=_("cosa_fa_label", default="Cosa fa"), - fields=["competenze"], - ) - model.fieldset( - "struttura", - label=_("struttura_label", default="Struttura"), - fields=[ - "legami_con_altre_strutture", - "responsabile", - "assessore_riferimento", - ], - ) - model.fieldset( - "persone", - label=_("persone_label", default="Persone"), - fields=["persone_struttura"], - ) - model.fieldset( - "contatti", - label=_("contatti_label", default="Contatti"), - fields=["sede", "sedi_secondarie"], - ) - form.order_after(sedi_secondarie="IContattiUnitaOrganizzativa.orario_pubblico") - - # SearchableText indexers - textindexer.searchable("competenze") - textindexer.searchable("assessore_riferimento") - textindexer.searchable("responsabile") diff --git a/.history/src/design/plone/contenttypes/profiles/default/types/Persona_20230104105939.xml b/.history/src/design/plone/contenttypes/profiles/default/types/Persona_20230104105939.xml deleted file mode 100644 index 6a0cf185..00000000 --- a/.history/src/design/plone/contenttypes/profiles/default/types/Persona_20230104105939.xml +++ /dev/null @@ -1,115 +0,0 @@ - - - - - Persona - - - False - Persona - - - - - True - False - - - - - design.plone.contenttypes.AddPersona - design.plone.contenttypes.content.persona.Persona - - - design.plone.contenttypes.interfaces.persona.IPersona - - - - - - - - - - - - - - -<<<<<<< HEAD - - - - - -======= - - - - - - ->>>>>>> pnrr - - - - string:${folder_url}/++add++Persona - view - False - view - - - - - - - - - - - - - - - - - - - diff --git a/.history/src/design/plone/contenttypes/profiles/default/types/Persona_20230104110533.xml b/.history/src/design/plone/contenttypes/profiles/default/types/Persona_20230104110533.xml deleted file mode 100644 index 9578a7df..00000000 --- a/.history/src/design/plone/contenttypes/profiles/default/types/Persona_20230104110533.xml +++ /dev/null @@ -1,107 +0,0 @@ - - - - - Persona - - - False - Persona - - - - - True - False - - - - - design.plone.contenttypes.AddPersona - design.plone.contenttypes.content.persona.Persona - - - design.plone.contenttypes.interfaces.persona.IPersona - - - - - - - - - - - - - - - - - - - - - - - - string:${folder_url}/++add++Persona - view - False - view - - - - - - - - - - - - - - - - - - - diff --git a/.history/src/design/plone/contenttypes/profiles/default/types/Servizio_20230104105939.xml b/.history/src/design/plone/contenttypes/profiles/default/types/Servizio_20230104105939.xml deleted file mode 100644 index 2c82dc6f..00000000 --- a/.history/src/design/plone/contenttypes/profiles/default/types/Servizio_20230104105939.xml +++ /dev/null @@ -1,120 +0,0 @@ - - - - - Servizio - - - False - Servizio - - - - - True - True - - - - - - - - design.plone.contenttypes.AddServizio - design.plone.contenttypes.content.servizio.Servizio - - - design.plone.contenttypes.interfaces.servizio.IServizio - - - - - - - - - - - - - - - -<<<<<<< HEAD - - - - - - - - - -======= - - - - - - - - ->>>>>>> pnrr - - - - string:${folder_url}/++add++Servizio - view - False - view - - - - - - - - - - - - - - - - - - - diff --git a/.history/src/design/plone/contenttypes/profiles/default/types/Servizio_20230104110559.xml b/.history/src/design/plone/contenttypes/profiles/default/types/Servizio_20230104110559.xml deleted file mode 100644 index 241dbc58..00000000 --- a/.history/src/design/plone/contenttypes/profiles/default/types/Servizio_20230104110559.xml +++ /dev/null @@ -1,110 +0,0 @@ - - - - - Servizio - - - False - Servizio - - - - - True - True - - - - - - - - design.plone.contenttypes.AddServizio - design.plone.contenttypes.content.servizio.Servizio - - - design.plone.contenttypes.interfaces.servizio.IServizio - - - - - - - - - - - - - - - - - - - - - - - - - - - - - string:${folder_url}/++add++Servizio - view - False - view - - - - - - - - - - - - - - - - - - - diff --git a/.history/src/design/plone/contenttypes/profiles/default/types_20230104105939.xml b/.history/src/design/plone/contenttypes/profiles/default/types_20230104105939.xml deleted file mode 100644 index a045886e..00000000 --- a/.history/src/design/plone/contenttypes/profiles/default/types_20230104105939.xml +++ /dev/null @@ -1,59 +0,0 @@ - - - Controls the available contenttypes in your portal -<<<<<<< HEAD - - - - - - - - - - - - -======= - - - - - - - - - - - - - - ->>>>>>> pnrr - diff --git a/.history/src/design/plone/contenttypes/profiles/default/types_20230104110435.xml b/.history/src/design/plone/contenttypes/profiles/default/types_20230104110435.xml deleted file mode 100644 index 63795015..00000000 --- a/.history/src/design/plone/contenttypes/profiles/default/types_20230104110435.xml +++ /dev/null @@ -1,51 +0,0 @@ - - - Controls the available contenttypes in your portal -<<<<<<< HEAD - - - - - - - - - - - - - - - - - diff --git a/.history/src/design/plone/contenttypes/profiles/default/types_20230104110443.xml b/.history/src/design/plone/contenttypes/profiles/default/types_20230104110443.xml deleted file mode 100644 index 63795015..00000000 --- a/.history/src/design/plone/contenttypes/profiles/default/types_20230104110443.xml +++ /dev/null @@ -1,51 +0,0 @@ - - - Controls the available contenttypes in your portal -<<<<<<< HEAD - - - - - - - - - - - - - - - - - diff --git a/.history/src/design/plone/contenttypes/profiles/default/types_20230104110501.xml b/.history/src/design/plone/contenttypes/profiles/default/types_20230104110501.xml deleted file mode 100644 index cd0ac12b..00000000 --- a/.history/src/design/plone/contenttypes/profiles/default/types_20230104110501.xml +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/.history/src/design/plone/contenttypes/restapi/types/adapters_20230104105939.py b/.history/src/design/plone/contenttypes/restapi/types/adapters_20230104105939.py deleted file mode 100644 index 6b5f73f5..00000000 --- a/.history/src/design/plone/contenttypes/restapi/types/adapters_20230104105939.py +++ /dev/null @@ -1,109 +0,0 @@ -# -*- coding: utf-8 -*- -from design.plone.contenttypes import _ -from plone.restapi.types.adapters import ObjectJsonSchemaProvider -from plone.restapi.types.interfaces import IJsonSchemaProvider -from zope.component import adapter -from zope.component import getUtility -from zope.i18n import translate -from zope.interface import implementer -from zope.interface import Interface -<<<<<<< HEAD -from zope.schema.interfaces import IField -from zope.schema.interfaces import IVocabularyFactory -======= -from zope.schema.interfaces import IField, IVocabularyFactory -from collective.z3cform.datagridfield.interfaces import IRow -from plone import api -from plone.restapi.types.adapters import ListJsonSchemaProvider -from plone.restapi.types.utils import get_fieldsets -from plone.restapi.types.utils import get_jsonschema_properties -from plone.restapi.types.utils import iter_fields -from zope.schema.interfaces import IList -from design.plone.contenttypes.interfaces import IDesignPloneContenttypesLayer - - -from design.plone.contenttypes import _ ->>>>>>> pnrr - - -@adapter(IField, Interface, Interface) -@implementer(IJsonSchemaProvider) -class LeadImageJsonSchemaProvider(ObjectJsonSchemaProvider): - def get_size_vocabulary(self): - - factory = getUtility( - IVocabularyFactory, "design.plone.vocabularies.leadimage_dimension" - ) - - vocabulary = factory(self.context)._terms - return {term.token: term.title for term in vocabulary if term.token} - - def get_schema(self): - schema = super(LeadImageJsonSchemaProvider, self).get_schema() - sizes = self.get_size_vocabulary() - portal_type = getattr(self.request, "steps")[-1] - portal_type_size = sizes.get(portal_type, None) - if portal_type_size: - msgid = _( - "image_size_help", - default="La dimensione dell'immagine dovrebbe essere di ${size} px", # noqa - mapping={"size": portal_type_size}, - ) - schema["description"] = translate(msgid, context=self.request) - - return schema - - -@adapter(IList, Interface, IDesignPloneContenttypesLayer) -@implementer(IJsonSchemaProvider) -class DataGridFieldJsonSchemaProvider(ListJsonSchemaProvider): - def get_widget(self): - if self.field.getName() == "value_punto_contatto": - return "data_grid" - return super().get_widget() - - -@adapter(IRow, Interface, Interface) -@implementer(IJsonSchemaProvider) -class DataGridRowJsonSchemaProvider(ObjectJsonSchemaProvider): - def __init__(self, field, context, request): - super().__init__(field, context, request) - self.fieldsets = get_fieldsets(context, request, self.field.schema) - - def get_factory(self): - return "DataGridField Row" - - def get_properties(self): - if self.prefix: - prefix = ".".join([self.prefix, self.field.__name__]) - else: - prefix = self.field.__name__ - return get_jsonschema_properties( - self.context, self.request, self.fieldsets, prefix - ) - - def additional(self): - info = super().additional() - properties = self.get_properties() - required = [] - for field in iter_fields(self.fieldsets): - name = field.field.getName() - - # Determine required fields - if field.field.required: - required.append(name) - - # Include field modes - if field.mode: - properties[name]["mode"] = field.mode - - info["fieldsets"] = [ - { - "id": "default", - "title": "Default", - "fields": [x for x in properties.keys()], - }, - ] - info["required"] = required - info["properties"] = properties - return info diff --git a/.history/src/design/plone/contenttypes/restapi/types/adapters_20230104110615.py b/.history/src/design/plone/contenttypes/restapi/types/adapters_20230104110615.py deleted file mode 100644 index d5f2b931..00000000 --- a/.history/src/design/plone/contenttypes/restapi/types/adapters_20230104110615.py +++ /dev/null @@ -1,104 +0,0 @@ -# -*- coding: utf-8 -*- -from design.plone.contenttypes import _ -from plone.restapi.types.adapters import ObjectJsonSchemaProvider -from plone.restapi.types.interfaces import IJsonSchemaProvider -from zope.component import adapter -from zope.component import getUtility -from zope.i18n import translate -from zope.interface import implementer -from zope.interface import Interface -from zope.schema.interfaces import IField, IVocabularyFactory -from collective.z3cform.datagridfield.interfaces import IRow -from plone import api -from plone.restapi.types.adapters import ListJsonSchemaProvider -from plone.restapi.types.utils import get_fieldsets -from plone.restapi.types.utils import get_jsonschema_properties -from plone.restapi.types.utils import iter_fields -from zope.schema.interfaces import IList -from design.plone.contenttypes.interfaces import IDesignPloneContenttypesLayer - - -from design.plone.contenttypes import _ - - -@adapter(IField, Interface, Interface) -@implementer(IJsonSchemaProvider) -class LeadImageJsonSchemaProvider(ObjectJsonSchemaProvider): - def get_size_vocabulary(self): - - factory = getUtility( - IVocabularyFactory, "design.plone.vocabularies.leadimage_dimension" - ) - - vocabulary = factory(self.context)._terms - return {term.token: term.title for term in vocabulary if term.token} - - def get_schema(self): - schema = super(LeadImageJsonSchemaProvider, self).get_schema() - sizes = self.get_size_vocabulary() - portal_type = getattr(self.request, "steps")[-1] - portal_type_size = sizes.get(portal_type, None) - if portal_type_size: - msgid = _( - "image_size_help", - default="La dimensione dell'immagine dovrebbe essere di ${size} px", # noqa - mapping={"size": portal_type_size}, - ) - schema["description"] = translate(msgid, context=self.request) - - return schema - - -@adapter(IList, Interface, IDesignPloneContenttypesLayer) -@implementer(IJsonSchemaProvider) -class DataGridFieldJsonSchemaProvider(ListJsonSchemaProvider): - def get_widget(self): - if self.field.getName() == "value_punto_contatto": - return "data_grid" - return super().get_widget() - - -@adapter(IRow, Interface, Interface) -@implementer(IJsonSchemaProvider) -class DataGridRowJsonSchemaProvider(ObjectJsonSchemaProvider): - def __init__(self, field, context, request): - super().__init__(field, context, request) - self.fieldsets = get_fieldsets(context, request, self.field.schema) - - def get_factory(self): - return "DataGridField Row" - - def get_properties(self): - if self.prefix: - prefix = ".".join([self.prefix, self.field.__name__]) - else: - prefix = self.field.__name__ - return get_jsonschema_properties( - self.context, self.request, self.fieldsets, prefix - ) - - def additional(self): - info = super().additional() - properties = self.get_properties() - required = [] - for field in iter_fields(self.fieldsets): - name = field.field.getName() - - # Determine required fields - if field.field.required: - required.append(name) - - # Include field modes - if field.mode: - properties[name]["mode"] = field.mode - - info["fieldsets"] = [ - { - "id": "default", - "title": "Default", - "fields": [x for x in properties.keys()], - }, - ] - info["required"] = required - info["properties"] = properties - return info diff --git a/.history/src/design/plone/contenttypes/restapi/types/adapters_20230104110625.py b/.history/src/design/plone/contenttypes/restapi/types/adapters_20230104110625.py deleted file mode 100644 index b3617553..00000000 --- a/.history/src/design/plone/contenttypes/restapi/types/adapters_20230104110625.py +++ /dev/null @@ -1,102 +0,0 @@ -# -*- coding: utf-8 -*- -from design.plone.contenttypes import _ -from plone.restapi.types.adapters import ObjectJsonSchemaProvider -from plone.restapi.types.interfaces import IJsonSchemaProvider -from zope.component import adapter -from zope.component import getUtility -from zope.i18n import translate -from zope.interface import implementer -from zope.interface import Interface -from zope.schema.interfaces import IField, IVocabularyFactory -from collective.z3cform.datagridfield.interfaces import IRow -from plone import api -from plone.restapi.types.adapters import ListJsonSchemaProvider -from plone.restapi.types.utils import get_fieldsets -from plone.restapi.types.utils import get_jsonschema_properties -from plone.restapi.types.utils import iter_fields -from zope.schema.interfaces import IList -from design.plone.contenttypes.interfaces import IDesignPloneContenttypesLayer -from design.plone.contenttypes import _ - - -@adapter(IField, Interface, Interface) -@implementer(IJsonSchemaProvider) -class LeadImageJsonSchemaProvider(ObjectJsonSchemaProvider): - def get_size_vocabulary(self): - - factory = getUtility( - IVocabularyFactory, "design.plone.vocabularies.leadimage_dimension" - ) - - vocabulary = factory(self.context)._terms - return {term.token: term.title for term in vocabulary if term.token} - - def get_schema(self): - schema = super(LeadImageJsonSchemaProvider, self).get_schema() - sizes = self.get_size_vocabulary() - portal_type = getattr(self.request, "steps")[-1] - portal_type_size = sizes.get(portal_type, None) - if portal_type_size: - msgid = _( - "image_size_help", - default="La dimensione dell'immagine dovrebbe essere di ${size} px", # noqa - mapping={"size": portal_type_size}, - ) - schema["description"] = translate(msgid, context=self.request) - - return schema - - -@adapter(IList, Interface, IDesignPloneContenttypesLayer) -@implementer(IJsonSchemaProvider) -class DataGridFieldJsonSchemaProvider(ListJsonSchemaProvider): - def get_widget(self): - if self.field.getName() == "value_punto_contatto": - return "data_grid" - return super().get_widget() - - -@adapter(IRow, Interface, Interface) -@implementer(IJsonSchemaProvider) -class DataGridRowJsonSchemaProvider(ObjectJsonSchemaProvider): - def __init__(self, field, context, request): - super().__init__(field, context, request) - self.fieldsets = get_fieldsets(context, request, self.field.schema) - - def get_factory(self): - return "DataGridField Row" - - def get_properties(self): - if self.prefix: - prefix = ".".join([self.prefix, self.field.__name__]) - else: - prefix = self.field.__name__ - return get_jsonschema_properties( - self.context, self.request, self.fieldsets, prefix - ) - - def additional(self): - info = super().additional() - properties = self.get_properties() - required = [] - for field in iter_fields(self.fieldsets): - name = field.field.getName() - - # Determine required fields - if field.field.required: - required.append(name) - - # Include field modes - if field.mode: - properties[name]["mode"] = field.mode - - info["fieldsets"] = [ - { - "id": "default", - "title": "Default", - "fields": [x for x in properties.keys()], - }, - ] - info["required"] = required - info["properties"] = properties - return info diff --git a/.history/src/design/plone/contenttypes/restapi/types/adapters_20230104110639.py b/.history/src/design/plone/contenttypes/restapi/types/adapters_20230104110639.py deleted file mode 100644 index 11c712d2..00000000 --- a/.history/src/design/plone/contenttypes/restapi/types/adapters_20230104110639.py +++ /dev/null @@ -1,100 +0,0 @@ -# -*- coding: utf-8 -*- -from design.plone.contenttypes import _ -from plone.restapi.types.adapters import ObjectJsonSchemaProvider -from plone.restapi.types.interfaces import IJsonSchemaProvider -from zope.component import adapter -from zope.component import getUtility -from zope.i18n import translate -from zope.interface import implementer -from zope.interface import Interface -from zope.schema.interfaces import IField, IVocabularyFactory -from collective.z3cform.datagridfield.interfaces import IRow -from plone.restapi.types.adapters import ListJsonSchemaProvider -from plone.restapi.types.utils import get_fieldsets -from plone.restapi.types.utils import get_jsonschema_properties -from plone.restapi.types.utils import iter_fields -from zope.schema.interfaces import IList -from design.plone.contenttypes.interfaces import IDesignPloneContenttypesLayer - - -@adapter(IField, Interface, Interface) -@implementer(IJsonSchemaProvider) -class LeadImageJsonSchemaProvider(ObjectJsonSchemaProvider): - def get_size_vocabulary(self): - - factory = getUtility( - IVocabularyFactory, "design.plone.vocabularies.leadimage_dimension" - ) - - vocabulary = factory(self.context)._terms - return {term.token: term.title for term in vocabulary if term.token} - - def get_schema(self): - schema = super(LeadImageJsonSchemaProvider, self).get_schema() - sizes = self.get_size_vocabulary() - portal_type = getattr(self.request, "steps")[-1] - portal_type_size = sizes.get(portal_type, None) - if portal_type_size: - msgid = _( - "image_size_help", - default="La dimensione dell'immagine dovrebbe essere di ${size} px", # noqa - mapping={"size": portal_type_size}, - ) - schema["description"] = translate(msgid, context=self.request) - - return schema - - -@adapter(IList, Interface, IDesignPloneContenttypesLayer) -@implementer(IJsonSchemaProvider) -class DataGridFieldJsonSchemaProvider(ListJsonSchemaProvider): - def get_widget(self): - if self.field.getName() == "value_punto_contatto": - return "data_grid" - return super().get_widget() - - -@adapter(IRow, Interface, Interface) -@implementer(IJsonSchemaProvider) -class DataGridRowJsonSchemaProvider(ObjectJsonSchemaProvider): - def __init__(self, field, context, request): - super().__init__(field, context, request) - self.fieldsets = get_fieldsets(context, request, self.field.schema) - - def get_factory(self): - return "DataGridField Row" - - def get_properties(self): - if self.prefix: - prefix = ".".join([self.prefix, self.field.__name__]) - else: - prefix = self.field.__name__ - return get_jsonschema_properties( - self.context, self.request, self.fieldsets, prefix - ) - - def additional(self): - info = super().additional() - properties = self.get_properties() - required = [] - for field in iter_fields(self.fieldsets): - name = field.field.getName() - - # Determine required fields - if field.field.required: - required.append(name) - - # Include field modes - if field.mode: - properties[name]["mode"] = field.mode - - info["fieldsets"] = [ - { - "id": "default", - "title": "Default", - "fields": [x for x in properties.keys()], - }, - ] - info["required"] = required - info["properties"] = properties - return info diff --git a/.history/src/design/plone/contenttypes/upgrades/upgrades_20230104105158.py b/.history/src/design/plone/contenttypes/upgrades/upgrades_20230104105158.py deleted file mode 100644 index 1456f582..00000000 --- a/.history/src/design/plone/contenttypes/upgrades/upgrades_20230104105158.py +++ /dev/null @@ -1,1124 +0,0 @@ -# -*- coding: utf-8 -*- -from Acquisition import aq_base -from collective.volto.blocksfield.field import BlocksField -from copy import deepcopy -from design.plone.contenttypes.controlpanels.settings import IDesignPloneSettings -from design.plone.contenttypes.upgrades.draftjs_converter import to_draftjs -from design.plone.contenttypes.setuphandlers import remove_blocks_behavior -from plone import api -from plone.app.textfield.value import RichTextValue -from plone.app.upgrade.utils import installOrReinstallProduct -from plone.dexterity.utils import iterSchemata -from redturtle.bandi.interfaces.settings import IBandoSettings -from transaction import commit -from z3c.relationfield import RelationValue -from zope.component import getUtility -from zope.event import notify -from zope.intid.interfaces import IIntIds -from zope.lifecycleevent import ObjectModifiedEvent -from zope.schema import getFields - -import logging -import json -import six - -logger = logging.getLogger(__name__) - -DEFAULT_PROFILE = "profile-design.plone.contenttypes:default" - -# standard upgrades # - - -def update_profile(context, profile, run_dependencies=True): - context.runImportStepFromProfile(DEFAULT_PROFILE, profile, run_dependencies) - - -def update_types(context): - update_profile(context, "typeinfo") - - -def update_rolemap(context): - update_profile(context, "rolemap") - - -def update_registry(context): - update_profile(context, "plone.app.registry", run_dependencies=False) - - -def update_catalog(context): - update_profile(context, "catalog") - - -def update_controlpanel(context): - update_profile(context, "controlpanel") - - -def remap_fields(mapping): - pc = api.portal.get_tool(name="portal_catalog") - brains = pc() - tot = len(brains) - logger.info("Trovati {} elementi da sistemare.".format(tot)) - # remap fields - for brain in brains: - item = brain.getObject() - for old, new in mapping.items(): - value = getattr(item, old, None) - if value: - setattr(item, new, value) - setattr(item, old, None) - logger.info( - "- {url}: {old} -> {new}".format( - url=brain.getURL(), old=old, new=new - ) - ) - delattr(item, old) - - -# custom ones # - - -def to_1001(context): - - update_types(context) - - # cleanup event behaviors - portal_types = api.portal.get_tool(name="portal_types") - behaviors = portal_types["Event"].behaviors - to_remove = [ - "design.plone.contenttypes.behavior.luoghi_correlati", - "design.plone.contenttypes.behavior.argomenti_evento", - "design.plone.contenttypes.behavior.additional_help_infos_evento", - ] - portal_types["Event"].behaviors = tuple( - [x for x in behaviors if x not in to_remove] - ) - - mapping = { - # "descrizione_destinatari": "a_chi_si_rivolge", - "canale_fisico": "dove_rivolgersi_extra", - "canale_fisico_prenotazione": "prenota_appuntamento", - "fasi_scadenze": "tempi_e_scadenze", - "sedi_e_luoghi": "dove_rivolgersi", - "box_aiuto": "ulteriori_informazioni", - "riferimento_telefonico_luogo": "telefono", - "riferimento_mail_luogo": "email", - } - remap_fields(mapping=mapping) - - -def to_1003(context): - - update_types(context) - - mapping = { - "unita_amministrativa_responsabile": "unita_amministrative_responsabili", # noqa - "sedi": "sede", - "contatto_reperibilita": "reperibilita", - "evento_supportato_da": "supportato_da", - } - remap_fields(mapping=mapping) - - -def to_1005(context): - def fix_index(blocks): - for block in blocks.values(): - if block.get("@type", "") == "listing": - for query in block.get("query", []): - if ( - query["i"] == "argomenti_correlati" - or query["i"] == "tassonomia_argomenti" - ): # noqa - query["i"] = "argomenti" - logger.info(" - {}".format(brain.getURL())) - - # fix root - portal = api.portal.get() - portal_blocks = json.loads(portal.blocks) - fix_index(portal_blocks) - portal.blocks = json.dumps(portal_blocks) - - logger.info("Fixing listing blocks.") - for brain in api.content.find(object_provides="plone.restapi.behaviors.IBlocks"): - item = brain.getObject() - blocks = deepcopy(getattr(item, "blocks", {})) - if blocks: - fix_index(blocks) - item.blocks = blocks - logger.info("** Reindexing items that refers to an argument **") - for brain in api.portal.get_tool("portal_catalog")(): - item = brain.getObject() - if getattr(item.aq_base, "tassonomia_argomenti", []): - logger.info(" - {}".format(brain.getURL())) - item.reindexObject(idxs=["argomenti"]) - - -def to_1006(context): - def fix_index(blocks): - for block in blocks.values(): - if block.get("@type", "") == "listing": - for query in block.get("query", []): - if ( - query["i"] == "argomenti_correlati" - or query["i"] == "tassonomia_argomenti" - or query["i"] == "argomenti" - ): # noqa - query["i"] = "argomenti" - query["v"] = [x.Title for x in api.content.find(UID=query["v"])] - logger.info(" - {}".format(brain.getURL())) - - # fix root - portal = api.portal.get() - portal_blocks = json.loads(portal.blocks) - fix_index(portal_blocks) - portal.blocks = json.dumps(portal_blocks) - - logger.info("Fixing listing blocks.") - for brain in api.content.find(object_provides="plone.restapi.behaviors.IBlocks"): - item = brain.getObject() - blocks = deepcopy(getattr(item, "blocks", {})) - if blocks: - fix_index(blocks) - item.blocks = blocks - - -def to_1007(context): - for brain in api.content.find(portal_type="Persona"): - item = brain.getObject() - if item.email: - item.email = [item.email] - if item.telefono: - item.telefono = [item.telefono] - - -def to_1008(context): - installOrReinstallProduct(api.portal.get(), "redturtle.bandi") - - -def to_1009(context): - def fix_index(blocks): - """ - revert to tassonomia_argomenti - """ - for block in blocks.values(): - if block.get("@type", "") == "listing": - for query in block.get("query", []): - if query["i"] == "argomenti": - query["i"] = "tassonomia_argomenti" - logger.info(" - {}".format(brain.getURL())) - - # fix root - portal = api.portal.get() - portal_blocks = json.loads(portal.blocks) - fix_index(portal_blocks) - portal.blocks = json.dumps(portal_blocks) - - logger.info("Fixing listing blocks.") - for brain in api.content.find(object_provides="plone.restapi.behaviors.IBlocks"): - item = brain.getObject() - blocks = deepcopy(getattr(item, "blocks", {})) - if blocks: - fix_index(blocks) - item.blocks = blocks - logger.info("** Reindexing items that refers to an argument **") - for brain in api.portal.get_tool("portal_catalog")(): - item = brain.getObject() - if getattr(item.aq_base, "tassonomia_argomenti", []): - logger.info(" - {}".format(brain.getURL())) - item.reindexObject(idxs=["tassonomia_argomenti"]) - - -def to_1010(context): - pc = api.portal.get_tool(name="portal_catalog") - pc.manage_reindexIndex(ids=["event_location"]) - - -def to_1013(context): - def fix_template_name(blocks): - """ - revert to tassonomia_argomenti - """ - found = False - for block in blocks.values(): - if ( - block.get("@type", "") == "listing" - and block.get("template", "") == "imageGallery" - ): - block["template"] = "photogallery" - found = True - return found - - # fix root - logger.info('Changing listing block template from "imageGallery" to "photogallery') - portal = api.portal.get() - portal_blocks = json.loads(portal.blocks) - to_update = fix_template_name(portal_blocks) - fixed_items = [] - if to_update: - portal.blocks = json.dumps(portal_blocks) - fixed_items.append("Root") - i = 0 - brains = api.content.find(object_provides="plone.restapi.behaviors.IBlocks") - tot = len(brains) - for brain in brains: - i += 1 - if i % 1000 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - item = brain.getObject() - blocks = deepcopy(getattr(item, "blocks", {})) - if blocks: - to_update = fix_template_name(blocks) - if to_update: - item.blocks = blocks - fixed_items.append(brain.getPath()) - - logger.info("Finish") - if fixed_items: - logger.info("Updated items:") - for fixed in fixed_items: - logger.info("- {}".format(fixed)) - else: - logger.info("No items affected.") - - -def to_1014(context): - update_types(context) - portal_types = api.portal.get_tool(name="portal_types") - portal_types["Bando"].behaviors = tuple( - [ - x - for x in portal_types["Bando"].behaviors - if x != "design.plone.contenttypes.behavior.argomenti" - ] - ) - - -def to_1015(context): - update_types(context) - - # cleanup trasparenza behavior from CTs - portal_types = api.portal.get_tool(name="portal_types") - service_behaviors = portal_types["Servizio"].behaviors - to_remove = [ - "design.plone.contenttypes.behavior.trasparenza", - ] - portal_types["Servizio"].behaviors = tuple( - [x for x in service_behaviors if x not in to_remove] - ) - persona_behaviors = portal_types["Persona"].behaviors - portal_types["Persona"].behaviors = tuple( - [x for x in persona_behaviors if x not in to_remove] - ) - - -def to_1016(context): - section_ids = ["amministrazione", "servizi", "novita", "documenti-e-dati"] - sections = [] - portal = api.portal.get() - for id in section_ids: - item = portal.get(id, None) - if item: - sections.append({"title": item.title, "linkUrl": [item.UID()]}) - settings = [{"rootPath": "/", "items": sections}] - api.portal.set_registry_record( - "search_sections", - json.dumps(settings), - interface=IDesignPloneSettings, - ) - - -def to_2000(context): # noqa: C901 - # remove volto.blocks behavior from news and events and add new one - update_types(context) - portal_types = api.portal.get_tool(name="portal_types") - for ptype in ["News Item", "Event"]: - portal_types[ptype].behaviors = tuple( - [x for x in portal_types[ptype].behaviors if x != "volto.blocks"] - ) - portal_types["Pagina Argomento"].behaviors = tuple( - [ - x - for x in portal_types["Pagina Argomento"].behaviors - if x != "design.plone.contenttypes.behavior.additional_help_infos" - ] - ) - # now copy values in new fields - pc = api.portal.get_tool(name="portal_catalog") - brains = pc() - tot = len(brains) - i = 0 - logger.info("### START CONVERSION FIELDS RICHTEXT -> DRAFTJS ###") - for brain in brains: - i += 1 - if i % 1000 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - item = brain.getObject() - if brain.portal_type in ["Event", "News Item"]: - blocks = getattr(item, "blocks", {}) - blocks_layout = getattr(item, "blocks_layout", {"items": []})["items"] - if not blocks: - continue - title_uid = "" - new_blocks = {} - for uid, block in blocks.items(): - if block.get("@type", "") == "title": - title_uid = uid - else: - new_blocks[uid] = block - item.descrizione_estesa = { - "blocks": new_blocks, - "blocks_layout": { - "items": [x for x in blocks_layout if x != title_uid] - }, - } - item.blocks = None - item.blocks_layout = None - for schema in iterSchemata(item): - for name, field in getFields(schema).items(): - if not isinstance(field, BlocksField): - continue - value = field.get(item) - if not value: - continue - if isinstance(value, six.string_types): - value = "

{}

".format(value) - elif isinstance(value, RichTextValue): - value = value.raw - else: - continue - if value == "


": - value = "" - try: - new_value = to_draftjs(value) - except Exception as e: - logger.error( - "[NOT MIGRATED] - {}: {}".format(brain.getPath(), name) - ) - raise e - setattr(item, name, new_value) - - -def to_2002(context): - """Per l'aggiornamento del vocabolario tipologie_persona, sistemiamo - tutti quelli già presenti. - """ - type_mapping = { - "altro": "Altro tipo", - "politica": "Politica", - "amministrativa": "Amministrativa", - } - logger.info("Fixing 'Tipologia Persona'...") - fixed_total = 0 - for brain in api.content.find(portal_type="Persona"): - item = brain.getObject() - if hasattr(item, "tipologia_persona") and item.tipologia_persona in type_mapping: # noqa - item.tipologia_persona = type_mapping[item.tipologia_persona] - fixed_total += 1 - commit() - logger.info("Fixing 'Tipologia Persona': DONE") - logger.info("Updated {} objects".format(fixed_total)) - - -def to_3000(context): - """ """ - update_registry(context) - update_controlpanel(context) - multilanguage = [ - "tipologie_notizia", - "tipologie_unita_organizzativa", - # "tipologie_documento", - "tipologie_persona", - ] - simple = ["lead_image_dimension", "search_sections"] - old_entry = "design.plone.contenttypes.controlpanels.vocabularies.IVocabulariesControlPanel.{}" # noqa - for field in simple: - value = api.portal.get_registry_record(old_entry.format(field)) - api.portal.set_registry_record(field, value, interface=IDesignPloneSettings) - - for field in multilanguage: - try: - value = api.portal.get_registry_record(old_entry.format(field)) - api.portal.set_registry_record( - field, - json.dumps({"it": value}), - interface=IDesignPloneSettings, - ) - except Exception: - continue - - context.runAllImportStepsFromProfile("profile-design.plone.contenttypes:to_3000") - - -def to_3101(context): - intids = getUtility(IIntIds) - logger.info("Fixing Documento references...") - fixed_total = 0 - for brain in api.content.find(portal_type="Documento"): - item = brain.getObject() - for rel in getattr(item, "servizi_collegati", []): - service = rel.to_object - if service: - service.altri_documenti.append(RelationValue(intids.getId(item))) - notify(ObjectModifiedEvent(service)) - logger.info("Fixed item {}".format("/".join(service.getPhysicalPath()))) - - if getattr(item, "servizi_collegati", []): - delattr(item, "servizi_collegati") - notify(ObjectModifiedEvent(item)) - fixed_total += 1 - logger.info("Fixed item {}".format("/".join(item.getPhysicalPath()))) - - logger.info("Fixing 'Documento': DONE") - logger.info("Updated {} objects Documento".format(fixed_total)) - - -def to_3102(context): - update_types(context) - - # cleanup trasparenza behavior from CTs - portal_types = api.portal.get_tool(name="portal_types") - to_remove = [ - "design.plone.contenttypes.behavior.trasparenza", - ] - for key, value in portal_types.items(): - ct_behaviors = getattr(value, "behaviors", None) - if ct_behaviors is not None: - portal_types[key].behaviors = tuple( - [x for x in ct_behaviors if x not in to_remove] - ) - - -def to_volto13(context): # noqa: C901 - # convert listing blocks with new standard - - logger.info("### START CONVERSION TO VOLTO 13: default => simpleCard ###") - - def fix_listing(blocks, url): - for block in blocks.values(): - if block.get("@type", "") == "listing": - if block.get("template", False) and not block.get("variation", False): - # import pdb - - # pdb.set_trace() - logger.error("- {}".format(url)) - if block.get("template", False) and block.get("variation", False): - logger.error("- {}".format(url)) - if block.get("variation", "") == "default": - block["variation"] = "simpleCard" - logger.info("- {}".format(url)) - - # fix root - portal = api.portal.get() - portal_blocks = json.loads(portal.blocks) - fix_listing(portal_blocks, portal.absolute_url()) - portal.blocks = json.dumps(portal_blocks) - - # fix blocks in contents - pc = api.portal.get_tool(name="portal_catalog") - brains = pc() - tot = len(brains) - i = 0 - for brain in brains: - i += 1 - if i % 1000 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - item = aq_base(brain.getObject()) - if getattr(item, "blocks", {}): - blocks = deepcopy(item.blocks) - if blocks: - fix_listing(blocks, brain.getURL()) - item.blocks = blocks - for schema in iterSchemata(item): - # fix blocks in blocksfields - for name, field in getFields(schema).items(): - if name == "blocks": - blocks = deepcopy(item.blocks) - if blocks: - fix_listing(blocks, brain.getURL()) - item.blocks = blocks - elif isinstance(field, BlocksField): - value = deepcopy(field.get(item)) - if not value: - continue - if isinstance(value, str): - if value == "": - setattr( - item, - name, - {"blocks": {}, "blocks_layout": {"items": []}}, - ) - continue - try: - blocks = value.get("blocks", {}) - except AttributeError: - logger.warning( - "[RICHTEXT] - {} (not converted)".format(brain.getURL()) - ) - if blocks: - fix_listing(blocks, brain.getURL()) - setattr(item, name, value) - - -def to_3400(context): # noqa: C901 - logger.info("### START CONVERSION BLOCKS: newsHome -> highlitedContent ###") - - def fix_block(blocks, url): - for block in blocks.values(): - if block.get("@type", "") == "newsHome": - block["@type"] = "highlitedContent" - - # fix root - portal = api.portal.get() - portal_blocks = json.loads(portal.blocks) - fix_block(portal_blocks, portal.absolute_url()) - portal.blocks = json.dumps(portal_blocks) - - # fix blocks in contents - pc = api.portal.get_tool(name="portal_catalog") - brains = pc() - tot = len(brains) - i = 0 - for brain in brains: - i += 1 - if i % 1000 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - item = aq_base(brain.getObject()) - if getattr(item, "blocks", {}): - blocks = deepcopy(item.blocks) - if blocks: - fix_block(blocks, brain.getURL()) - item.blocks = blocks - for schema in iterSchemata(item): - # fix blocks in blocksfields - for name, field in getFields(schema).items(): - if name == "blocks": - blocks = deepcopy(item.blocks) - if blocks: - fix_block(blocks, brain.getURL()) - item.blocks = blocks - elif isinstance(field, BlocksField): - value = deepcopy(field.get(item)) - if not value: - continue - if isinstance(value, str): - if value == "": - setattr( - item, - name, - {"blocks": {}, "blocks_layout": {"items": []}}, - ) - continue - try: - blocks = value.get("blocks", {}) - except AttributeError: - logger.warning( - "[RICHTEXT] - {} (not converted)".format(brain.getURL()) - ) - if blocks: - fix_block(blocks, brain.getURL()) - setattr(item, name, value) - - -def to_3401(context): # noqa: C901 - logger.info("File type can now be added inside a CartellaModulistica") - update_types(context) - - -def to_3500(context): - logger.info("Add new index and reindex UO") - update_catalog(context) - - # remove unused index - catalog = api.portal.get_tool(name="portal_catalog") - if "office_venue" in catalog.indexes(): - catalog.manage_delIndex("office_venue") - - # reindex - brains = api.content.find(portal_type="UnitaOrganizzativa") - tot = len(brains) - logger.info("Found {} UO.".format(tot)) - i = 0 - for brain in brains: - i += 1 - if i % 1000 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - uo = brain.getObject() - uo.reindexObject(idxs=["uo_location", "tipologia_organizzazione"]) - - -def to_3501(context): - logger.info("Reindex UO for new SearchableText fields") - - brains = api.content.find(portal_type="UnitaOrganizzativa") - tot = len(brains) - logger.info("Found {} UO.".format(tot)) - i = 0 - for brain in brains: - i += 1 - if i % 1000 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - uo = brain.getObject() - uo.reindexObject(idxs=["SearchableText"]) - - -def to_3600(context): - logger.info("Enable kitconcept.seo behavior") - types_list = [ - "UnitaOrganizzativa", - "Bando", - "Subsite", - "Venue", - "Persona", - "Event", - "News Item", - "Document", - "Documento", - "Servizio", - "CartellaModulistica", - "Pagina Argomento", - ] - portal_types = api.portal.get_tool(name="portal_types") - for ct_type in types_list: - if "kitconcept.seo" not in portal_types[ct_type].behaviors: - portal_types[ct_type].behaviors += ("kitconcept.seo",) - logger.info("Enabled kitconcept.seo on: {}".format(ct_type)) - - logger.info("Bandi customizations") - update_catalog(context) - api.portal.set_registry_record("default_ente", (), interface=IBandoSettings) - - portal_types = api.portal.get_tool(name="portal_types") - portal_types["Bando Folder Deepening"].allowed_content_types = ( - "Modulo", - "File", - "Link", - ) - portal_types["Bando"].default_view = "view" - portal_types["Bando"].view_methods = ("view",) - - logger.info("Reindex SearchableText") - pc = api.portal.get_tool(name="portal_catalog") - pc.reindexIndex("SearchableText", context.REQUEST) - - logger.info("Reindex Bandi") - i = 0 - brains = api.content.find(portal_type="Bando") - tot = len(brains) - for brain in brains: - i += 1 - if i % 1000 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - bando = brain.getObject() - bando.reindexObject(idxs=["ufficio_responsabile_bando", "Subject_bando"]) - - -def to_3700(context): - logger.info("Set show_modified_default as True") - - api.portal.set_registry_record( - "show_modified_default", True, interface=IDesignPloneSettings - ) - - -def to_3800(context): - logger.info("Fix Venue addable types") - - portal_types = api.portal.get_tool(name="portal_types") - portal_types["Venue"].allowed_content_types = ( - "Folder", - "Image", - "File", - "Link", - ) - - -def to_3900(context): - logger.info("Add new metadata: ruolo") - - brains = api.content.find(portal_type="Persona") - for brain in brains: - persona = brain.getObject() - persona.reindexObject() - - -def to_4000(context): - logger.info("Move ruolo to a choice field") - ruoli = {"it": [], "en": []} - brains = api.content.find(portal_type="Persona") - for brain in brains: - persona = brain.getObject() - ruolo = getattr(persona, "ruolo", "") - lang = brain.language - if ruolo not in ruoli[lang]: - ruoli[lang].append(ruolo) - - if api.portal.get_registry_record( - "ruoli_persona", - interface=IDesignPloneSettings, - default=None - ): - api.portal.set_registry_record( - "ruoli_persona", json.dumps(ruoli), interface=IDesignPloneSettings - ) - - -def to_4100(context): - logger.info("Add constrainttypes behavior to Document") - - portal_types = api.portal.get_tool(name="portal_types") - document_behaviors = list(portal_types["Document"].behaviors) + [ - "plone.constraintypes" - ] - portal_types["Document"].behaviors = tuple(document_behaviors) - - -def to_4200(context): - logger.info("Add criteria and indexes to Persona") - - update_catalog(context) - update_registry(context) - - brains = api.content.find(portal_type="Persona") - for brain in brains: - persona = brain.getObject() - persona.reindexObject(idxs=["data_conclusione_incarico"]) - - -def to_5000(context): - logger.info("Enable preview_image behavior in all content types") - - portal_types = api.portal.get_tool(name="portal_types") - - for portal_type, fti in portal_types.items(): - behaviors = list(getattr(fti, "behaviors", ())) - if not behaviors: - continue - if portal_type == "Document": - behaviors = [ - x - for x in behaviors - if x not in ["plone.leadimage", "volto.preview_image"] - ] - behaviors.extend(["plone.leadimage", "volto.preview_image"]) - else: - if "plone.leadimage" not in behaviors or "volto.preview_image" in behaviors: - continue - behaviors.insert(behaviors.index("plone.leadimage") + 1, "volto.preview_image") - fti.behaviors = tuple(behaviors) - - logger.info("Move immagine_testata to image") - catalog = api.portal.get_tool("portal_catalog") - i = 0 - brains = catalog() - tot = len(brains) - for brain in brains: - i += 1 - if i % 500 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - obj = brain.getObject() - if "image" in obj.keys(): - api.content.rename(obj=obj["image"], new_id="image-1") - if brain.portal_type == "Document": - immagine_testata = getattr(obj, "immagine_testata", None) - if immagine_testata: - obj.image = immagine_testata - obj.immagine_testata = None - catalog.catalog_object(obj) - - -def to_5001(context): - catalog = api.portal.get_tool("portal_catalog") - i = 0 - brains = catalog(portal_type="Pagina Argomento") - tot = len(brains) - logger.info("Add icona metadata to {}".format(tot)) - for brain in brains: - i += 1 - if i % 500 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - obj = brain.getObject() - catalog.catalog_object(obj) - - -def to_5002(context): - """ - Reindex non-folderish items because there were some metadata not updated - """ - catalog = api.portal.get_tool("portal_catalog") - i = 0 - brains = catalog(is_folderish=False) - tot = len(brains) - for brain in brains: - i += 1 - if i % 500 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - obj = brain.getObject() - catalog.catalog_object(obj) - - -def to_5200(context): - """ - add new behavior for Bando - """ - portal_types = api.portal.get_tool(name="portal_types") - fti = portal_types["Bando"] - behaviors = list(getattr(fti, "behaviors", ())) - if "design.plone.contenttypes.behavior.update_note" not in behaviors: - behaviors.append("design.plone.contenttypes.behavior.update_note") - fti.behaviors = tuple(behaviors) - - -def to_5210(context): - logger.info("Enable preview_image behavior in Bandi content types") - - portal_types = api.portal.get_tool(name="portal_types") - fti = portal_types["Bando"] - behaviors = list(getattr(fti, "behaviors", ())) - if "volto.preview_image" not in behaviors: - behaviors.append("volto.preview_image") - fti.behaviors = tuple(behaviors) - - -def to_5220(context): - """ - Reindex Venues - """ - logger.info("Reindex SearchableText for Venue items.") - catalog = api.portal.get_tool("portal_catalog") - i = 0 - brains = catalog(portal_type="Venue") - tot = len(brains) - for brain in brains: - i += 1 - if i % 500 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - obj = brain.getObject() - obj.reindexObject(idxs=["SearchableText", "object_provides"]) - - -def to_5300(context): - update_profile(context, "plone-difftool") - update_profile(context, "repositorytool") - - portal_types = api.portal.get_tool(name="portal_types") - for portal_type, fti in portal_types.items(): - if portal_type in [ - "CartellaModulistica", - "Documento", - "Link", - "Pagina Argomento", - "Persona", - "Servizio", - "UnitaOrganizzativa", - "Venue", - ]: - behaviors = list(getattr(fti, "behaviors", ())) - if "plone.versioning" not in behaviors: - behaviors.append("plone.versioning") - fti.behaviors = tuple(behaviors) - - -def to_5310(context): - """ - Reindex Bandi - """ - logger.info("Reindex SearchableText for Bandi items.") - catalog = api.portal.get_tool("portal_catalog") - i = 0 - brains = catalog(portal_type="Bando") - tot = len(brains) - for brain in brains: - i += 1 - if i % 500 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - brain.getObject().reindexObject(idxs=["SearchableText"]) - - -def to_5400(context): - logger.info('Remove "volto.blocks" behavior from News Item and Event.') - remove_blocks_behavior(context) - - -def to_5410(context): - - # cleanup Document behaviors - portal_types = api.portal.get_tool(name="portal_types") - behaviors = portal_types["Document"].behaviors - to_remove = [ - "plone.tableofcontents", - ] - portal_types["Document"].behaviors = tuple( - [x for x in behaviors if x not in to_remove] - ) - - -def to_6000(context): - """ """ - logger.info( - "Convert behavior: collective.dexteritytextindexer => plone.textindexer" # noqa - ) - portal_types = api.portal.get_tool(name="portal_types") - for fti in portal_types.values(): - behaviors = [] - for behavior in getattr(fti, "behaviors", ()): - if behavior == "collective.dexteritytextindexer": - behavior = "plone.textindexer" - behaviors.append(behavior) - - fti.behaviors = tuple(behaviors) - - -def to_6010(context): - """ """ - update_types(context) - update_registry(context) - update_catalog(context) - update_rolemap(context) - - -def migrate_pdc_and_incarico(context): - # Cannot test rn, blind coding - update_types(context) - update_registry(context) - update_catalog(context) - update_rolemap(context) - # "field name in original ct": "field name in new ct" - type_mapping = { - "Persona": { - 'PDC': { - "telefono": "phone", - "fax": "fax", - "email": "email", - "pec": "pec", - }, - "Incarico": { - # HOW? Need taxonomies also - # We could do: - # persona.ruolo.title = incarico.title - # persona.items.compensi = incarico.items.compensi? - "ruolo?": "incarico?", - # BlobFile to relation with Documento - "atto_nomina": "atto_nomina", - "data_conclusione_incarico": "data_conclusione_incarico", - "data_insediamento": "data_insediamento", - } - }, - "UnitaOrganizzativa": { - 'PDC': { - "telefono": "phone", - "fax": "fax", - "email": "email", - "pec": "pec", - }, - }, - # TODO: tbc - "Event": { - 'PDC': { - "telefono": "phone", - "fax": "fax", - "email": "email", - "pec": "pec", - }, - }, - # TODO: tbc - "Venue": { - 'PDC': { - "riferimento_telefonico_struttura": "phone", - "riferimento_fax_struttura": "fax", - "riferimento_mail_struttura": "email", - "riferimento_pec_struttura": "pec", - }, - }, - # TODO: tbc - "Servizio": { - # questi non sono presenti sul ct originale - 'PDC': { - "telefono": "phone", - "fax": "fax", - "email": "email", - "pec": "pec", - }, - }, - } - - def createIncaricoAndMigratePersona(portal_type): - # Taxonomies work needs to be completed before, blind coding ahead - if portal_type == 'Persona': - fixed_total = 0 - for brain in api.content.find(portal_type=portal_type): - item = brain.getObject() - atto_nomina = item.atto_nomina - logger.info(f"Fixing Punto di Contatto for '{item.title}'...") # noqa - file_bog = api.content.find(context=item, depth=1, id='atti-nomina') - if not file_bog: - try: - file_bog = api.content.create( - type="Document", id="atti-nomina", title="Atti Nomina", container=item - ) - except Exception: - logger.error("Error", Exception) - - try: - new_atto_nomina = api.content.create( - type="File", - id=atto_nomina.id, - title=atto_nomina.title, - container=item, - **{'file': atto_nomina} - ) - intids = getUtility(IIntIds) - relation = [RelationValue(intids.getId(new_atto_nomina))] - incarico = api.content.create( - type="Incarico", title=item.ruolo.title, container=item - ) - incarico.atto_nomina = relation - item.atto_nomina = None - fixed_total += 1 - logger.info(f"Fixing Punto di Contatto for '{item.title}'...:DONE") # noqa - except Exception: - logger.error("Error", Exception) - logger.info("Updated {} objects".format(fixed_total)) - - pass - - def createPDCandMigrateOldCTs(portal_type): - logger.info(f"Fixing Punto di Contatto for '{portal_type}'...") # noqa - fixed_total = 0 - mapping = None - # mapping = type_mapping[portal_type]["PDC"] - # Reenable mapping to use - if not mapping: - logger.info(f"No need to fix Punto di Contatto for '{portal_type}: DONE") - return - for brain in api.content.find(portal_type=portal_type): - item = brain.getObject() - kwargs = { - "value_punto_contatto": [], - "persona": [] - } - for key, value in mapping.items(): - import pdb; pdb.set_trace() - - if hasattr(item, key): - kwargs["value_punto_contatto"].append({ - 'pdc_type': value, - 'pdc_value': item[key] - }) - - new_pdc = api.content.create( - type='PuntoDiContatto', - title=f"Punto di Contatto {item.id}", - container=item, - **kwargs, - ) - intids = getUtility(IIntIds) - import pdb; pdb.set_trace() - item.contact_info = [RelationValue(intids.getId(new_pdc))] - fixed_total += 1 - - logger.info(f"Fixing Punto di Contatto for '{portal_type}: DONE") - logger.info("Updated {} objects".format(fixed_total)) - - for pt in type_mapping: - logger.info("Migrating existing CTs for use with new Incarico and PDC Content Types") - createPDCandMigrateOldCTs(pt) - createIncaricoAndMigratePersona(pt) diff --git a/.history/src/design/plone/contenttypes/upgrades/upgrades_20230104110844.py b/.history/src/design/plone/contenttypes/upgrades/upgrades_20230104110844.py deleted file mode 100644 index 74acdebb..00000000 --- a/.history/src/design/plone/contenttypes/upgrades/upgrades_20230104110844.py +++ /dev/null @@ -1,1130 +0,0 @@ -# -*- coding: utf-8 -*- -from Acquisition import aq_base -from collective.volto.blocksfield.field import BlocksField -from copy import deepcopy -from design.plone.contenttypes.controlpanels.settings import IDesignPloneSettings -from design.plone.contenttypes.upgrades.draftjs_converter import to_draftjs -from design.plone.contenttypes.setuphandlers import remove_blocks_behavior -from plone import api -from plone.app.textfield.value import RichTextValue -from plone.app.upgrade.utils import installOrReinstallProduct -from plone.dexterity.utils import iterSchemata -from redturtle.bandi.interfaces.settings import IBandoSettings -from transaction import commit -from z3c.relationfield import RelationValue -from zope.component import getUtility -from zope.event import notify -from zope.intid.interfaces import IIntIds -from zope.lifecycleevent import ObjectModifiedEvent -from zope.schema import getFields -from zope.component import getUtility -from zope.intid.interfaces import IIntIds -from z3c.relationfield import RelationValue - -import json -import logging -import json -import six - - -logger = logging.getLogger(__name__) - -DEFAULT_PROFILE = "profile-design.plone.contenttypes:default" - -# standard upgrades # - - -def update_profile(context, profile, run_dependencies=True): - context.runImportStepFromProfile(DEFAULT_PROFILE, profile, run_dependencies) - - -def update_types(context): - update_profile(context, "typeinfo") - - -def update_rolemap(context): - update_profile(context, "rolemap") - - -def update_registry(context): - update_profile(context, "plone.app.registry", run_dependencies=False) - - -def update_catalog(context): - update_profile(context, "catalog") - - -def update_controlpanel(context): - update_profile(context, "controlpanel") - - -def remap_fields(mapping): - pc = api.portal.get_tool(name="portal_catalog") - brains = pc() - tot = len(brains) - logger.info("Trovati {} elementi da sistemare.".format(tot)) - # remap fields - for brain in brains: - item = brain.getObject() - for old, new in mapping.items(): - value = getattr(item, old, None) - if value: - setattr(item, new, value) - setattr(item, old, None) - logger.info( - "- {url}: {old} -> {new}".format( - url=brain.getURL(), old=old, new=new - ) - ) - delattr(item, old) - - -# custom ones # - - -def to_1001(context): - - update_types(context) - - # cleanup event behaviors - portal_types = api.portal.get_tool(name="portal_types") - behaviors = portal_types["Event"].behaviors - to_remove = [ - "design.plone.contenttypes.behavior.luoghi_correlati", - "design.plone.contenttypes.behavior.argomenti_evento", - "design.plone.contenttypes.behavior.additional_help_infos_evento", - ] - portal_types["Event"].behaviors = tuple( - [x for x in behaviors if x not in to_remove] - ) - - mapping = { - # "descrizione_destinatari": "a_chi_si_rivolge", - "canale_fisico": "dove_rivolgersi_extra", - "canale_fisico_prenotazione": "prenota_appuntamento", - "fasi_scadenze": "tempi_e_scadenze", - "sedi_e_luoghi": "dove_rivolgersi", - "box_aiuto": "ulteriori_informazioni", - "riferimento_telefonico_luogo": "telefono", - "riferimento_mail_luogo": "email", - } - remap_fields(mapping=mapping) - - -def to_1003(context): - - update_types(context) - - mapping = { - "unita_amministrativa_responsabile": "unita_amministrative_responsabili", # noqa - "sedi": "sede", - "contatto_reperibilita": "reperibilita", - "evento_supportato_da": "supportato_da", - } - remap_fields(mapping=mapping) - - -def to_1005(context): - def fix_index(blocks): - for block in blocks.values(): - if block.get("@type", "") == "listing": - for query in block.get("query", []): - if ( - query["i"] == "argomenti_correlati" - or query["i"] == "tassonomia_argomenti" - ): # noqa - query["i"] = "argomenti" - logger.info(" - {}".format(brain.getURL())) - - # fix root - portal = api.portal.get() - portal_blocks = json.loads(portal.blocks) - fix_index(portal_blocks) - portal.blocks = json.dumps(portal_blocks) - - logger.info("Fixing listing blocks.") - for brain in api.content.find(object_provides="plone.restapi.behaviors.IBlocks"): - item = brain.getObject() - blocks = deepcopy(getattr(item, "blocks", {})) - if blocks: - fix_index(blocks) - item.blocks = blocks - logger.info("** Reindexing items that refers to an argument **") - for brain in api.portal.get_tool("portal_catalog")(): - item = brain.getObject() - if getattr(item.aq_base, "tassonomia_argomenti", []): - logger.info(" - {}".format(brain.getURL())) - item.reindexObject(idxs=["argomenti"]) - - -def to_1006(context): - def fix_index(blocks): - for block in blocks.values(): - if block.get("@type", "") == "listing": - for query in block.get("query", []): - if ( - query["i"] == "argomenti_correlati" - or query["i"] == "tassonomia_argomenti" - or query["i"] == "argomenti" - ): # noqa - query["i"] = "argomenti" - query["v"] = [x.Title for x in api.content.find(UID=query["v"])] - logger.info(" - {}".format(brain.getURL())) - - # fix root - portal = api.portal.get() - portal_blocks = json.loads(portal.blocks) - fix_index(portal_blocks) - portal.blocks = json.dumps(portal_blocks) - - logger.info("Fixing listing blocks.") - for brain in api.content.find(object_provides="plone.restapi.behaviors.IBlocks"): - item = brain.getObject() - blocks = deepcopy(getattr(item, "blocks", {})) - if blocks: - fix_index(blocks) - item.blocks = blocks - - -def to_1007(context): - for brain in api.content.find(portal_type="Persona"): - item = brain.getObject() - if item.email: - item.email = [item.email] - if item.telefono: - item.telefono = [item.telefono] - - -def to_1008(context): - installOrReinstallProduct(api.portal.get(), "redturtle.bandi") - - -def to_1009(context): - def fix_index(blocks): - """ - revert to tassonomia_argomenti - """ - for block in blocks.values(): - if block.get("@type", "") == "listing": - for query in block.get("query", []): - if query["i"] == "argomenti": - query["i"] = "tassonomia_argomenti" - logger.info(" - {}".format(brain.getURL())) - - # fix root - portal = api.portal.get() - portal_blocks = json.loads(portal.blocks) - fix_index(portal_blocks) - portal.blocks = json.dumps(portal_blocks) - - logger.info("Fixing listing blocks.") - for brain in api.content.find(object_provides="plone.restapi.behaviors.IBlocks"): - item = brain.getObject() - blocks = deepcopy(getattr(item, "blocks", {})) - if blocks: - fix_index(blocks) - item.blocks = blocks - logger.info("** Reindexing items that refers to an argument **") - for brain in api.portal.get_tool("portal_catalog")(): - item = brain.getObject() - if getattr(item.aq_base, "tassonomia_argomenti", []): - logger.info(" - {}".format(brain.getURL())) - item.reindexObject(idxs=["tassonomia_argomenti"]) - - -def to_1010(context): - pc = api.portal.get_tool(name="portal_catalog") - pc.manage_reindexIndex(ids=["event_location"]) - - -def to_1013(context): - def fix_template_name(blocks): - """ - revert to tassonomia_argomenti - """ - found = False - for block in blocks.values(): - if ( - block.get("@type", "") == "listing" - and block.get("template", "") == "imageGallery" - ): - block["template"] = "photogallery" - found = True - return found - - # fix root - logger.info('Changing listing block template from "imageGallery" to "photogallery') - portal = api.portal.get() - portal_blocks = json.loads(portal.blocks) - to_update = fix_template_name(portal_blocks) - fixed_items = [] - if to_update: - portal.blocks = json.dumps(portal_blocks) - fixed_items.append("Root") - i = 0 - brains = api.content.find(object_provides="plone.restapi.behaviors.IBlocks") - tot = len(brains) - for brain in brains: - i += 1 - if i % 1000 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - item = brain.getObject() - blocks = deepcopy(getattr(item, "blocks", {})) - if blocks: - to_update = fix_template_name(blocks) - if to_update: - item.blocks = blocks - fixed_items.append(brain.getPath()) - - logger.info("Finish") - if fixed_items: - logger.info("Updated items:") - for fixed in fixed_items: - logger.info("- {}".format(fixed)) - else: - logger.info("No items affected.") - - -def to_1014(context): - update_types(context) - portal_types = api.portal.get_tool(name="portal_types") - portal_types["Bando"].behaviors = tuple( - [ - x - for x in portal_types["Bando"].behaviors - if x != "design.plone.contenttypes.behavior.argomenti" - ] - ) - - -def to_1015(context): - update_types(context) - - # cleanup trasparenza behavior from CTs - portal_types = api.portal.get_tool(name="portal_types") - service_behaviors = portal_types["Servizio"].behaviors - to_remove = [ - "design.plone.contenttypes.behavior.trasparenza", - ] - portal_types["Servizio"].behaviors = tuple( - [x for x in service_behaviors if x not in to_remove] - ) - persona_behaviors = portal_types["Persona"].behaviors - portal_types["Persona"].behaviors = tuple( - [x for x in persona_behaviors if x not in to_remove] - ) - - -def to_1016(context): - section_ids = ["amministrazione", "servizi", "novita", "documenti-e-dati"] - sections = [] - portal = api.portal.get() - for id in section_ids: - item = portal.get(id, None) - if item: - sections.append({"title": item.title, "linkUrl": [item.UID()]}) - settings = [{"rootPath": "/", "items": sections}] - api.portal.set_registry_record( - "search_sections", - json.dumps(settings), - interface=IDesignPloneSettings, - ) - - -def to_2000(context): # noqa: C901 - # remove volto.blocks behavior from news and events and add new one - update_types(context) - portal_types = api.portal.get_tool(name="portal_types") - for ptype in ["News Item", "Event"]: - portal_types[ptype].behaviors = tuple( - [x for x in portal_types[ptype].behaviors if x != "volto.blocks"] - ) - portal_types["Pagina Argomento"].behaviors = tuple( - [ - x - for x in portal_types["Pagina Argomento"].behaviors - if x != "design.plone.contenttypes.behavior.additional_help_infos" - ] - ) - # now copy values in new fields - pc = api.portal.get_tool(name="portal_catalog") - brains = pc() - tot = len(brains) - i = 0 - logger.info("### START CONVERSION FIELDS RICHTEXT -> DRAFTJS ###") - for brain in brains: - i += 1 - if i % 1000 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - item = brain.getObject() - if brain.portal_type in ["Event", "News Item"]: - blocks = getattr(item, "blocks", {}) - blocks_layout = getattr(item, "blocks_layout", {"items": []})["items"] - if not blocks: - continue - title_uid = "" - new_blocks = {} - for uid, block in blocks.items(): - if block.get("@type", "") == "title": - title_uid = uid - else: - new_blocks[uid] = block - item.descrizione_estesa = { - "blocks": new_blocks, - "blocks_layout": { - "items": [x for x in blocks_layout if x != title_uid] - }, - } - item.blocks = None - item.blocks_layout = None - for schema in iterSchemata(item): - for name, field in getFields(schema).items(): - if not isinstance(field, BlocksField): - continue - value = field.get(item) - if not value: - continue - if isinstance(value, six.string_types): - value = "

{}

".format(value) - elif isinstance(value, RichTextValue): - value = value.raw - else: - continue - if value == "


": - value = "" - try: - new_value = to_draftjs(value) - except Exception as e: - logger.error( - "[NOT MIGRATED] - {}: {}".format(brain.getPath(), name) - ) - raise e - setattr(item, name, new_value) - - -def to_2002(context): - """Per l'aggiornamento del vocabolario tipologie_persona, sistemiamo - tutti quelli già presenti. - """ - type_mapping = { - "altro": "Altro tipo", - "politica": "Politica", - "amministrativa": "Amministrativa", - } - logger.info("Fixing 'Tipologia Persona'...") - fixed_total = 0 - for brain in api.content.find(portal_type="Persona"): - item = brain.getObject() - if ( - hasattr(item, "tipologia_persona") - and item.tipologia_persona in type_mapping - ): # noqa - item.tipologia_persona = type_mapping[item.tipologia_persona] - fixed_total += 1 - commit() - logger.info("Fixing 'Tipologia Persona': DONE") - logger.info("Updated {} objects".format(fixed_total)) - - -def to_3000(context): - """ """ - update_registry(context) - update_controlpanel(context) - multilanguage = [ - "tipologie_notizia", - "tipologie_unita_organizzativa", - # "tipologie_documento", - "tipologie_persona", - ] - simple = ["lead_image_dimension", "search_sections"] - old_entry = "design.plone.contenttypes.controlpanels.vocabularies.IVocabulariesControlPanel.{}" # noqa - for field in simple: - value = api.portal.get_registry_record(old_entry.format(field)) - api.portal.set_registry_record(field, value, interface=IDesignPloneSettings) - - for field in multilanguage: - try: - value = api.portal.get_registry_record(old_entry.format(field)) - api.portal.set_registry_record( - field, - json.dumps({"it": value}), - interface=IDesignPloneSettings, - ) - except Exception: - continue - - context.runAllImportStepsFromProfile("profile-design.plone.contenttypes:to_3000") - - -def to_3101(context): - intids = getUtility(IIntIds) - logger.info("Fixing Documento references...") - fixed_total = 0 - for brain in api.content.find(portal_type="Documento"): - item = brain.getObject() - for rel in getattr(item, "servizi_collegati", []): - service = rel.to_object - if service: - service.altri_documenti.append(RelationValue(intids.getId(item))) - notify(ObjectModifiedEvent(service)) - logger.info("Fixed item {}".format("/".join(service.getPhysicalPath()))) - - if getattr(item, "servizi_collegati", []): - delattr(item, "servizi_collegati") - notify(ObjectModifiedEvent(item)) - fixed_total += 1 - logger.info("Fixed item {}".format("/".join(item.getPhysicalPath()))) - - logger.info("Fixing 'Documento': DONE") - logger.info("Updated {} objects Documento".format(fixed_total)) - - -def to_3102(context): - update_types(context) - - # cleanup trasparenza behavior from CTs - portal_types = api.portal.get_tool(name="portal_types") - to_remove = [ - "design.plone.contenttypes.behavior.trasparenza", - ] - for key, value in portal_types.items(): - ct_behaviors = getattr(value, "behaviors", None) - if ct_behaviors is not None: - portal_types[key].behaviors = tuple( - [x for x in ct_behaviors if x not in to_remove] - ) - - -def to_volto13(context): # noqa: C901 - # convert listing blocks with new standard - - logger.info("### START CONVERSION TO VOLTO 13: default => simpleCard ###") - - def fix_listing(blocks, url): - for block in blocks.values(): - if block.get("@type", "") == "listing": - if block.get("template", False) and not block.get("variation", False): - # import pdb - - # pdb.set_trace() - logger.error("- {}".format(url)) - if block.get("template", False) and block.get("variation", False): - logger.error("- {}".format(url)) - if block.get("variation", "") == "default": - block["variation"] = "simpleCard" - logger.info("- {}".format(url)) - - # fix root - portal = api.portal.get() - portal_blocks = json.loads(portal.blocks) - fix_listing(portal_blocks, portal.absolute_url()) - portal.blocks = json.dumps(portal_blocks) - - # fix blocks in contents - pc = api.portal.get_tool(name="portal_catalog") - brains = pc() - tot = len(brains) - i = 0 - for brain in brains: - i += 1 - if i % 1000 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - item = aq_base(brain.getObject()) - if getattr(item, "blocks", {}): - blocks = deepcopy(item.blocks) - if blocks: - fix_listing(blocks, brain.getURL()) - item.blocks = blocks - for schema in iterSchemata(item): - # fix blocks in blocksfields - for name, field in getFields(schema).items(): - if name == "blocks": - blocks = deepcopy(item.blocks) - if blocks: - fix_listing(blocks, brain.getURL()) - item.blocks = blocks - elif isinstance(field, BlocksField): - value = deepcopy(field.get(item)) - if not value: - continue - if isinstance(value, str): - if value == "": - setattr( - item, - name, - {"blocks": {}, "blocks_layout": {"items": []}}, - ) - continue - try: - blocks = value.get("blocks", {}) - except AttributeError: - logger.warning( - "[RICHTEXT] - {} (not converted)".format(brain.getURL()) - ) - if blocks: - fix_listing(blocks, brain.getURL()) - setattr(item, name, value) - - -def to_3400(context): # noqa: C901 - logger.info("### START CONVERSION BLOCKS: newsHome -> highlitedContent ###") - - def fix_block(blocks, url): - for block in blocks.values(): - if block.get("@type", "") == "newsHome": - block["@type"] = "highlitedContent" - - # fix root - portal = api.portal.get() - portal_blocks = json.loads(portal.blocks) - fix_block(portal_blocks, portal.absolute_url()) - portal.blocks = json.dumps(portal_blocks) - - # fix blocks in contents - pc = api.portal.get_tool(name="portal_catalog") - brains = pc() - tot = len(brains) - i = 0 - for brain in brains: - i += 1 - if i % 1000 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - item = aq_base(brain.getObject()) - if getattr(item, "blocks", {}): - blocks = deepcopy(item.blocks) - if blocks: - fix_block(blocks, brain.getURL()) - item.blocks = blocks - for schema in iterSchemata(item): - # fix blocks in blocksfields - for name, field in getFields(schema).items(): - if name == "blocks": - blocks = deepcopy(item.blocks) - if blocks: - fix_block(blocks, brain.getURL()) - item.blocks = blocks - elif isinstance(field, BlocksField): - value = deepcopy(field.get(item)) - if not value: - continue - if isinstance(value, str): - if value == "": - setattr( - item, - name, - {"blocks": {}, "blocks_layout": {"items": []}}, - ) - continue - try: - blocks = value.get("blocks", {}) - except AttributeError: - logger.warning( - "[RICHTEXT] - {} (not converted)".format(brain.getURL()) - ) - if blocks: - fix_block(blocks, brain.getURL()) - setattr(item, name, value) - - -def to_3401(context): # noqa: C901 - logger.info("File type can now be added inside a CartellaModulistica") - update_types(context) - - -def to_3500(context): - logger.info("Add new index and reindex UO") - update_catalog(context) - - # remove unused index - catalog = api.portal.get_tool(name="portal_catalog") - if "office_venue" in catalog.indexes(): - catalog.manage_delIndex("office_venue") - - # reindex - brains = api.content.find(portal_type="UnitaOrganizzativa") - tot = len(brains) - logger.info("Found {} UO.".format(tot)) - i = 0 - for brain in brains: - i += 1 - if i % 1000 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - uo = brain.getObject() - uo.reindexObject(idxs=["uo_location", "tipologia_organizzazione"]) - - -def to_3501(context): - logger.info("Reindex UO for new SearchableText fields") - - brains = api.content.find(portal_type="UnitaOrganizzativa") - tot = len(brains) - logger.info("Found {} UO.".format(tot)) - i = 0 - for brain in brains: - i += 1 - if i % 1000 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - uo = brain.getObject() - uo.reindexObject(idxs=["SearchableText"]) - - -def to_3600(context): - logger.info("Enable kitconcept.seo behavior") - types_list = [ - "UnitaOrganizzativa", - "Bando", - "Subsite", - "Venue", - "Persona", - "Event", - "News Item", - "Document", - "Documento", - "Servizio", - "CartellaModulistica", - "Pagina Argomento", - ] - portal_types = api.portal.get_tool(name="portal_types") - for ct_type in types_list: - if "kitconcept.seo" not in portal_types[ct_type].behaviors: - portal_types[ct_type].behaviors += ("kitconcept.seo",) - logger.info("Enabled kitconcept.seo on: {}".format(ct_type)) - - logger.info("Bandi customizations") - update_catalog(context) - api.portal.set_registry_record("default_ente", (), interface=IBandoSettings) - - portal_types = api.portal.get_tool(name="portal_types") - portal_types["Bando Folder Deepening"].allowed_content_types = ( - "Modulo", - "File", - "Link", - ) - portal_types["Bando"].default_view = "view" - portal_types["Bando"].view_methods = ("view",) - - logger.info("Reindex SearchableText") - pc = api.portal.get_tool(name="portal_catalog") - pc.reindexIndex("SearchableText", context.REQUEST) - - logger.info("Reindex Bandi") - i = 0 - brains = api.content.find(portal_type="Bando") - tot = len(brains) - for brain in brains: - i += 1 - if i % 1000 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - bando = brain.getObject() - bando.reindexObject(idxs=["ufficio_responsabile_bando", "Subject_bando"]) - - -def to_3700(context): - logger.info("Set show_modified_default as True") - - api.portal.set_registry_record( - "show_modified_default", True, interface=IDesignPloneSettings - ) - - -def to_3800(context): - logger.info("Fix Venue addable types") - - portal_types = api.portal.get_tool(name="portal_types") - portal_types["Venue"].allowed_content_types = ( - "Folder", - "Image", - "File", - "Link", - ) - - -def to_3900(context): - logger.info("Add new metadata: ruolo") - - brains = api.content.find(portal_type="Persona") - for brain in brains: - persona = brain.getObject() - persona.reindexObject() - - -def to_4000(context): - logger.info("Move ruolo to a choice field") - ruoli = {"it": [], "en": []} - brains = api.content.find(portal_type="Persona") - for brain in brains: - persona = brain.getObject() - ruolo = getattr(persona, "ruolo", "") - lang = brain.language - if ruolo not in ruoli[lang]: - ruoli[lang].append(ruolo) - - if api.portal.get_registry_record( - "ruoli_persona", interface=IDesignPloneSettings, default=None - ): - api.portal.set_registry_record( - "ruoli_persona", json.dumps(ruoli), interface=IDesignPloneSettings - ) - - -def to_4100(context): - logger.info("Add constrainttypes behavior to Document") - - portal_types = api.portal.get_tool(name="portal_types") - document_behaviors = list(portal_types["Document"].behaviors) + [ - "plone.constraintypes" - ] - portal_types["Document"].behaviors = tuple(document_behaviors) - - -def to_4200(context): - logger.info("Add criteria and indexes to Persona") - - update_catalog(context) - update_registry(context) - - brains = api.content.find(portal_type="Persona") - for brain in brains: - persona = brain.getObject() - persona.reindexObject(idxs=["data_conclusione_incarico"]) - - -def to_5000(context): - logger.info("Enable preview_image behavior in all content types") - - portal_types = api.portal.get_tool(name="portal_types") - - for portal_type, fti in portal_types.items(): - behaviors = list(getattr(fti, "behaviors", ())) - if not behaviors: - continue - if portal_type == "Document": - behaviors = [ - x - for x in behaviors - if x not in ["plone.leadimage", "volto.preview_image"] - ] - behaviors.extend(["plone.leadimage", "volto.preview_image"]) - else: - if "plone.leadimage" not in behaviors or "volto.preview_image" in behaviors: - continue - behaviors.insert(behaviors.index("plone.leadimage") + 1, "volto.preview_image") - fti.behaviors = tuple(behaviors) - - logger.info("Move immagine_testata to image") - catalog = api.portal.get_tool("portal_catalog") - i = 0 - brains = catalog() - tot = len(brains) - for brain in brains: - i += 1 - if i % 500 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - obj = brain.getObject() - if "image" in obj.keys(): - api.content.rename(obj=obj["image"], new_id="image-1") - if brain.portal_type == "Document": - immagine_testata = getattr(obj, "immagine_testata", None) - if immagine_testata: - obj.image = immagine_testata - obj.immagine_testata = None - catalog.catalog_object(obj) - - -def to_5001(context): - catalog = api.portal.get_tool("portal_catalog") - i = 0 - brains = catalog(portal_type="Pagina Argomento") - tot = len(brains) - logger.info("Add icona metadata to {}".format(tot)) - for brain in brains: - i += 1 - if i % 500 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - obj = brain.getObject() - catalog.catalog_object(obj) - - -def to_5002(context): - """ - Reindex non-folderish items because there were some metadata not updated - """ - catalog = api.portal.get_tool("portal_catalog") - i = 0 - brains = catalog(is_folderish=False) - tot = len(brains) - for brain in brains: - i += 1 - if i % 500 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - obj = brain.getObject() - catalog.catalog_object(obj) - - -def to_5200(context): - """ - add new behavior for Bando - """ - portal_types = api.portal.get_tool(name="portal_types") - fti = portal_types["Bando"] - behaviors = list(getattr(fti, "behaviors", ())) - if "design.plone.contenttypes.behavior.update_note" not in behaviors: - behaviors.append("design.plone.contenttypes.behavior.update_note") - fti.behaviors = tuple(behaviors) - - -def to_5210(context): - logger.info("Enable preview_image behavior in Bandi content types") - - portal_types = api.portal.get_tool(name="portal_types") - fti = portal_types["Bando"] - behaviors = list(getattr(fti, "behaviors", ())) - if "volto.preview_image" not in behaviors: - behaviors.append("volto.preview_image") - fti.behaviors = tuple(behaviors) - - -def to_5220(context): - """ - Reindex Venues - """ - logger.info("Reindex SearchableText for Venue items.") - catalog = api.portal.get_tool("portal_catalog") - i = 0 - brains = catalog(portal_type="Venue") - tot = len(brains) - for brain in brains: - i += 1 - if i % 500 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - obj = brain.getObject() - obj.reindexObject(idxs=["SearchableText", "object_provides"]) - - -def to_5300(context): - update_profile(context, "plone-difftool") - update_profile(context, "repositorytool") - - portal_types = api.portal.get_tool(name="portal_types") - for portal_type, fti in portal_types.items(): - if portal_type in [ - "CartellaModulistica", - "Documento", - "Link", - "Pagina Argomento", - "Persona", - "Servizio", - "UnitaOrganizzativa", - "Venue", - ]: - behaviors = list(getattr(fti, "behaviors", ())) - if "plone.versioning" not in behaviors: - behaviors.append("plone.versioning") - fti.behaviors = tuple(behaviors) - - -def to_5310(context): - """ - Reindex Bandi - """ - logger.info("Reindex SearchableText for Bandi items.") - catalog = api.portal.get_tool("portal_catalog") - i = 0 - brains = catalog(portal_type="Bando") - tot = len(brains) - for brain in brains: - i += 1 - if i % 500 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - brain.getObject().reindexObject(idxs=["SearchableText"]) - - -def to_5400(context): - logger.info('Remove "volto.blocks" behavior from News Item and Event.') - remove_blocks_behavior(context) - - -def to_5410(context): - - # cleanup Document behaviors - portal_types = api.portal.get_tool(name="portal_types") - behaviors = portal_types["Document"].behaviors - to_remove = [ - "plone.tableofcontents", - ] - portal_types["Document"].behaviors = tuple( - [x for x in behaviors if x not in to_remove] - ) - - -def to_6000(context): - """ """ - logger.info( - "Convert behavior: collective.dexteritytextindexer => plone.textindexer" # noqa - ) - portal_types = api.portal.get_tool(name="portal_types") - for fti in portal_types.values(): - behaviors = [] - for behavior in getattr(fti, "behaviors", ()): - if behavior == "collective.dexteritytextindexer": - behavior = "plone.textindexer" - behaviors.append(behavior) - - fti.behaviors = tuple(behaviors) - - -def to_6010(context): - """ """ - update_types(context) - update_registry(context) - update_catalog(context) - update_rolemap(context) - - -def migrate_pdc_and_incarico(context): - # Cannot test rn, blind coding - update_types(context) - update_registry(context) - update_catalog(context) - update_rolemap(context) - # "field name in original ct": "field name in new ct" - type_mapping = { - "Persona": { - 'PDC': { - "telefono": "phone", - "fax": "fax", - "email": "email", - "pec": "pec", - }, - "Incarico": { - # HOW? Need taxonomies also - # We could do: - # persona.ruolo.title = incarico.title - # persona.items.compensi = incarico.items.compensi? - "ruolo?": "incarico?", - # BlobFile to relation with Documento - "atto_nomina": "atto_nomina", - "data_conclusione_incarico": "data_conclusione_incarico", - "data_insediamento": "data_insediamento", - } - }, - "UnitaOrganizzativa": { - 'PDC': { - "telefono": "phone", - "fax": "fax", - "email": "email", - "pec": "pec", - }, - }, - # TODO: tbc - "Event": { - 'PDC': { - "telefono": "phone", - "fax": "fax", - "email": "email", - "pec": "pec", - }, - }, - # TODO: tbc - "Venue": { - 'PDC': { - "riferimento_telefonico_struttura": "phone", - "riferimento_fax_struttura": "fax", - "riferimento_mail_struttura": "email", - "riferimento_pec_struttura": "pec", - }, - }, - # TODO: tbc - "Servizio": { - # questi non sono presenti sul ct originale - 'PDC': { - "telefono": "phone", - "fax": "fax", - "email": "email", - "pec": "pec", - }, - }, - } - - def createIncaricoAndMigratePersona(portal_type): - # Taxonomies work needs to be completed before, blind coding ahead - if portal_type == 'Persona': - fixed_total = 0 - for brain in api.content.find(portal_type=portal_type): - item = brain.getObject() - atto_nomina = item.atto_nomina - logger.info(f"Fixing Punto di Contatto for '{item.title}'...") # noqa - file_bog = api.content.find(context=item, depth=1, id='atti-nomina') - if not file_bog: - try: - file_bog = api.content.create( - type="Document", id="atti-nomina", title="Atti Nomina", container=item - ) - except Exception: - logger.error("Error", Exception) - - try: - new_atto_nomina = api.content.create( - type="File", - id=atto_nomina.id, - title=atto_nomina.title, - container=item, - **{'file': atto_nomina} - ) - intids = getUtility(IIntIds) - relation = [RelationValue(intids.getId(new_atto_nomina))] - incarico = api.content.create( - type="Incarico", title=item.ruolo.title, container=item - ) - incarico.atto_nomina = relation - item.atto_nomina = None - fixed_total += 1 - logger.info(f"Fixing Punto di Contatto for '{item.title}'...:DONE") # noqa - except Exception: - logger.error("Error", Exception) - logger.info("Updated {} objects".format(fixed_total)) - - pass - - def createPDCandMigrateOldCTs(portal_type): - logger.info(f"Fixing Punto di Contatto for '{portal_type}'...") # noqa - fixed_total = 0 - mapping = None - # mapping = type_mapping[portal_type]["PDC"] - # Reenable mapping to use - if not mapping: - logger.info(f"No need to fix Punto di Contatto for '{portal_type}: DONE") - return - for brain in api.content.find(portal_type=portal_type): - item = brain.getObject() - kwargs = { - "value_punto_contatto": [], - "persona": [] - } - for key, value in mapping.items(): - import pdb; pdb.set_trace() - - if hasattr(item, key): - kwargs["value_punto_contatto"].append({ - 'pdc_type': value, - 'pdc_value': item[key] - }) - - new_pdc = api.content.create( - type='PuntoDiContatto', - title=f"Punto di Contatto {item.id}", - container=item, - **kwargs, - ) - intids = getUtility(IIntIds) - import pdb; pdb.set_trace() - item.contact_info = [RelationValue(intids.getId(new_pdc))] - fixed_total += 1 - - logger.info(f"Fixing Punto di Contatto for '{portal_type}: DONE") - logger.info("Updated {} objects".format(fixed_total)) - - for pt in type_mapping: - logger.info("Migrating existing CTs for use with new Incarico and PDC Content Types") - createPDCandMigrateOldCTs(pt) - createIncaricoAndMigratePersona(pt) diff --git a/.history/src/design/plone/contenttypes/upgrades/upgrades_20230104110851.py b/.history/src/design/plone/contenttypes/upgrades/upgrades_20230104110851.py deleted file mode 100644 index 68fcecb5..00000000 --- a/.history/src/design/plone/contenttypes/upgrades/upgrades_20230104110851.py +++ /dev/null @@ -1,1129 +0,0 @@ -# -*- coding: utf-8 -*- -from Acquisition import aq_base -from collective.volto.blocksfield.field import BlocksField -from copy import deepcopy -from design.plone.contenttypes.controlpanels.settings import IDesignPloneSettings -from design.plone.contenttypes.upgrades.draftjs_converter import to_draftjs -from design.plone.contenttypes.setuphandlers import remove_blocks_behavior -from plone import api -from plone.app.textfield.value import RichTextValue -from plone.app.upgrade.utils import installOrReinstallProduct -from plone.dexterity.utils import iterSchemata -from redturtle.bandi.interfaces.settings import IBandoSettings -from transaction import commit -from z3c.relationfield import RelationValue -from zope.component import getUtility -from zope.event import notify -from zope.intid.interfaces import IIntIds -from zope.lifecycleevent import ObjectModifiedEvent -from zope.schema import getFields -from zope.component import getUtility -from zope.intid.interfaces import IIntIds -from z3c.relationfield import RelationValue - -import json -import logging -import six - - -logger = logging.getLogger(__name__) - -DEFAULT_PROFILE = "profile-design.plone.contenttypes:default" - -# standard upgrades # - - -def update_profile(context, profile, run_dependencies=True): - context.runImportStepFromProfile(DEFAULT_PROFILE, profile, run_dependencies) - - -def update_types(context): - update_profile(context, "typeinfo") - - -def update_rolemap(context): - update_profile(context, "rolemap") - - -def update_registry(context): - update_profile(context, "plone.app.registry", run_dependencies=False) - - -def update_catalog(context): - update_profile(context, "catalog") - - -def update_controlpanel(context): - update_profile(context, "controlpanel") - - -def remap_fields(mapping): - pc = api.portal.get_tool(name="portal_catalog") - brains = pc() - tot = len(brains) - logger.info("Trovati {} elementi da sistemare.".format(tot)) - # remap fields - for brain in brains: - item = brain.getObject() - for old, new in mapping.items(): - value = getattr(item, old, None) - if value: - setattr(item, new, value) - setattr(item, old, None) - logger.info( - "- {url}: {old} -> {new}".format( - url=brain.getURL(), old=old, new=new - ) - ) - delattr(item, old) - - -# custom ones # - - -def to_1001(context): - - update_types(context) - - # cleanup event behaviors - portal_types = api.portal.get_tool(name="portal_types") - behaviors = portal_types["Event"].behaviors - to_remove = [ - "design.plone.contenttypes.behavior.luoghi_correlati", - "design.plone.contenttypes.behavior.argomenti_evento", - "design.plone.contenttypes.behavior.additional_help_infos_evento", - ] - portal_types["Event"].behaviors = tuple( - [x for x in behaviors if x not in to_remove] - ) - - mapping = { - # "descrizione_destinatari": "a_chi_si_rivolge", - "canale_fisico": "dove_rivolgersi_extra", - "canale_fisico_prenotazione": "prenota_appuntamento", - "fasi_scadenze": "tempi_e_scadenze", - "sedi_e_luoghi": "dove_rivolgersi", - "box_aiuto": "ulteriori_informazioni", - "riferimento_telefonico_luogo": "telefono", - "riferimento_mail_luogo": "email", - } - remap_fields(mapping=mapping) - - -def to_1003(context): - - update_types(context) - - mapping = { - "unita_amministrativa_responsabile": "unita_amministrative_responsabili", # noqa - "sedi": "sede", - "contatto_reperibilita": "reperibilita", - "evento_supportato_da": "supportato_da", - } - remap_fields(mapping=mapping) - - -def to_1005(context): - def fix_index(blocks): - for block in blocks.values(): - if block.get("@type", "") == "listing": - for query in block.get("query", []): - if ( - query["i"] == "argomenti_correlati" - or query["i"] == "tassonomia_argomenti" - ): # noqa - query["i"] = "argomenti" - logger.info(" - {}".format(brain.getURL())) - - # fix root - portal = api.portal.get() - portal_blocks = json.loads(portal.blocks) - fix_index(portal_blocks) - portal.blocks = json.dumps(portal_blocks) - - logger.info("Fixing listing blocks.") - for brain in api.content.find(object_provides="plone.restapi.behaviors.IBlocks"): - item = brain.getObject() - blocks = deepcopy(getattr(item, "blocks", {})) - if blocks: - fix_index(blocks) - item.blocks = blocks - logger.info("** Reindexing items that refers to an argument **") - for brain in api.portal.get_tool("portal_catalog")(): - item = brain.getObject() - if getattr(item.aq_base, "tassonomia_argomenti", []): - logger.info(" - {}".format(brain.getURL())) - item.reindexObject(idxs=["argomenti"]) - - -def to_1006(context): - def fix_index(blocks): - for block in blocks.values(): - if block.get("@type", "") == "listing": - for query in block.get("query", []): - if ( - query["i"] == "argomenti_correlati" - or query["i"] == "tassonomia_argomenti" - or query["i"] == "argomenti" - ): # noqa - query["i"] = "argomenti" - query["v"] = [x.Title for x in api.content.find(UID=query["v"])] - logger.info(" - {}".format(brain.getURL())) - - # fix root - portal = api.portal.get() - portal_blocks = json.loads(portal.blocks) - fix_index(portal_blocks) - portal.blocks = json.dumps(portal_blocks) - - logger.info("Fixing listing blocks.") - for brain in api.content.find(object_provides="plone.restapi.behaviors.IBlocks"): - item = brain.getObject() - blocks = deepcopy(getattr(item, "blocks", {})) - if blocks: - fix_index(blocks) - item.blocks = blocks - - -def to_1007(context): - for brain in api.content.find(portal_type="Persona"): - item = brain.getObject() - if item.email: - item.email = [item.email] - if item.telefono: - item.telefono = [item.telefono] - - -def to_1008(context): - installOrReinstallProduct(api.portal.get(), "redturtle.bandi") - - -def to_1009(context): - def fix_index(blocks): - """ - revert to tassonomia_argomenti - """ - for block in blocks.values(): - if block.get("@type", "") == "listing": - for query in block.get("query", []): - if query["i"] == "argomenti": - query["i"] = "tassonomia_argomenti" - logger.info(" - {}".format(brain.getURL())) - - # fix root - portal = api.portal.get() - portal_blocks = json.loads(portal.blocks) - fix_index(portal_blocks) - portal.blocks = json.dumps(portal_blocks) - - logger.info("Fixing listing blocks.") - for brain in api.content.find(object_provides="plone.restapi.behaviors.IBlocks"): - item = brain.getObject() - blocks = deepcopy(getattr(item, "blocks", {})) - if blocks: - fix_index(blocks) - item.blocks = blocks - logger.info("** Reindexing items that refers to an argument **") - for brain in api.portal.get_tool("portal_catalog")(): - item = brain.getObject() - if getattr(item.aq_base, "tassonomia_argomenti", []): - logger.info(" - {}".format(brain.getURL())) - item.reindexObject(idxs=["tassonomia_argomenti"]) - - -def to_1010(context): - pc = api.portal.get_tool(name="portal_catalog") - pc.manage_reindexIndex(ids=["event_location"]) - - -def to_1013(context): - def fix_template_name(blocks): - """ - revert to tassonomia_argomenti - """ - found = False - for block in blocks.values(): - if ( - block.get("@type", "") == "listing" - and block.get("template", "") == "imageGallery" - ): - block["template"] = "photogallery" - found = True - return found - - # fix root - logger.info('Changing listing block template from "imageGallery" to "photogallery') - portal = api.portal.get() - portal_blocks = json.loads(portal.blocks) - to_update = fix_template_name(portal_blocks) - fixed_items = [] - if to_update: - portal.blocks = json.dumps(portal_blocks) - fixed_items.append("Root") - i = 0 - brains = api.content.find(object_provides="plone.restapi.behaviors.IBlocks") - tot = len(brains) - for brain in brains: - i += 1 - if i % 1000 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - item = brain.getObject() - blocks = deepcopy(getattr(item, "blocks", {})) - if blocks: - to_update = fix_template_name(blocks) - if to_update: - item.blocks = blocks - fixed_items.append(brain.getPath()) - - logger.info("Finish") - if fixed_items: - logger.info("Updated items:") - for fixed in fixed_items: - logger.info("- {}".format(fixed)) - else: - logger.info("No items affected.") - - -def to_1014(context): - update_types(context) - portal_types = api.portal.get_tool(name="portal_types") - portal_types["Bando"].behaviors = tuple( - [ - x - for x in portal_types["Bando"].behaviors - if x != "design.plone.contenttypes.behavior.argomenti" - ] - ) - - -def to_1015(context): - update_types(context) - - # cleanup trasparenza behavior from CTs - portal_types = api.portal.get_tool(name="portal_types") - service_behaviors = portal_types["Servizio"].behaviors - to_remove = [ - "design.plone.contenttypes.behavior.trasparenza", - ] - portal_types["Servizio"].behaviors = tuple( - [x for x in service_behaviors if x not in to_remove] - ) - persona_behaviors = portal_types["Persona"].behaviors - portal_types["Persona"].behaviors = tuple( - [x for x in persona_behaviors if x not in to_remove] - ) - - -def to_1016(context): - section_ids = ["amministrazione", "servizi", "novita", "documenti-e-dati"] - sections = [] - portal = api.portal.get() - for id in section_ids: - item = portal.get(id, None) - if item: - sections.append({"title": item.title, "linkUrl": [item.UID()]}) - settings = [{"rootPath": "/", "items": sections}] - api.portal.set_registry_record( - "search_sections", - json.dumps(settings), - interface=IDesignPloneSettings, - ) - - -def to_2000(context): # noqa: C901 - # remove volto.blocks behavior from news and events and add new one - update_types(context) - portal_types = api.portal.get_tool(name="portal_types") - for ptype in ["News Item", "Event"]: - portal_types[ptype].behaviors = tuple( - [x for x in portal_types[ptype].behaviors if x != "volto.blocks"] - ) - portal_types["Pagina Argomento"].behaviors = tuple( - [ - x - for x in portal_types["Pagina Argomento"].behaviors - if x != "design.plone.contenttypes.behavior.additional_help_infos" - ] - ) - # now copy values in new fields - pc = api.portal.get_tool(name="portal_catalog") - brains = pc() - tot = len(brains) - i = 0 - logger.info("### START CONVERSION FIELDS RICHTEXT -> DRAFTJS ###") - for brain in brains: - i += 1 - if i % 1000 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - item = brain.getObject() - if brain.portal_type in ["Event", "News Item"]: - blocks = getattr(item, "blocks", {}) - blocks_layout = getattr(item, "blocks_layout", {"items": []})["items"] - if not blocks: - continue - title_uid = "" - new_blocks = {} - for uid, block in blocks.items(): - if block.get("@type", "") == "title": - title_uid = uid - else: - new_blocks[uid] = block - item.descrizione_estesa = { - "blocks": new_blocks, - "blocks_layout": { - "items": [x for x in blocks_layout if x != title_uid] - }, - } - item.blocks = None - item.blocks_layout = None - for schema in iterSchemata(item): - for name, field in getFields(schema).items(): - if not isinstance(field, BlocksField): - continue - value = field.get(item) - if not value: - continue - if isinstance(value, six.string_types): - value = "

{}

".format(value) - elif isinstance(value, RichTextValue): - value = value.raw - else: - continue - if value == "


": - value = "" - try: - new_value = to_draftjs(value) - except Exception as e: - logger.error( - "[NOT MIGRATED] - {}: {}".format(brain.getPath(), name) - ) - raise e - setattr(item, name, new_value) - - -def to_2002(context): - """Per l'aggiornamento del vocabolario tipologie_persona, sistemiamo - tutti quelli già presenti. - """ - type_mapping = { - "altro": "Altro tipo", - "politica": "Politica", - "amministrativa": "Amministrativa", - } - logger.info("Fixing 'Tipologia Persona'...") - fixed_total = 0 - for brain in api.content.find(portal_type="Persona"): - item = brain.getObject() - if ( - hasattr(item, "tipologia_persona") - and item.tipologia_persona in type_mapping - ): # noqa - item.tipologia_persona = type_mapping[item.tipologia_persona] - fixed_total += 1 - commit() - logger.info("Fixing 'Tipologia Persona': DONE") - logger.info("Updated {} objects".format(fixed_total)) - - -def to_3000(context): - """ """ - update_registry(context) - update_controlpanel(context) - multilanguage = [ - "tipologie_notizia", - "tipologie_unita_organizzativa", - # "tipologie_documento", - "tipologie_persona", - ] - simple = ["lead_image_dimension", "search_sections"] - old_entry = "design.plone.contenttypes.controlpanels.vocabularies.IVocabulariesControlPanel.{}" # noqa - for field in simple: - value = api.portal.get_registry_record(old_entry.format(field)) - api.portal.set_registry_record(field, value, interface=IDesignPloneSettings) - - for field in multilanguage: - try: - value = api.portal.get_registry_record(old_entry.format(field)) - api.portal.set_registry_record( - field, - json.dumps({"it": value}), - interface=IDesignPloneSettings, - ) - except Exception: - continue - - context.runAllImportStepsFromProfile("profile-design.plone.contenttypes:to_3000") - - -def to_3101(context): - intids = getUtility(IIntIds) - logger.info("Fixing Documento references...") - fixed_total = 0 - for brain in api.content.find(portal_type="Documento"): - item = brain.getObject() - for rel in getattr(item, "servizi_collegati", []): - service = rel.to_object - if service: - service.altri_documenti.append(RelationValue(intids.getId(item))) - notify(ObjectModifiedEvent(service)) - logger.info("Fixed item {}".format("/".join(service.getPhysicalPath()))) - - if getattr(item, "servizi_collegati", []): - delattr(item, "servizi_collegati") - notify(ObjectModifiedEvent(item)) - fixed_total += 1 - logger.info("Fixed item {}".format("/".join(item.getPhysicalPath()))) - - logger.info("Fixing 'Documento': DONE") - logger.info("Updated {} objects Documento".format(fixed_total)) - - -def to_3102(context): - update_types(context) - - # cleanup trasparenza behavior from CTs - portal_types = api.portal.get_tool(name="portal_types") - to_remove = [ - "design.plone.contenttypes.behavior.trasparenza", - ] - for key, value in portal_types.items(): - ct_behaviors = getattr(value, "behaviors", None) - if ct_behaviors is not None: - portal_types[key].behaviors = tuple( - [x for x in ct_behaviors if x not in to_remove] - ) - - -def to_volto13(context): # noqa: C901 - # convert listing blocks with new standard - - logger.info("### START CONVERSION TO VOLTO 13: default => simpleCard ###") - - def fix_listing(blocks, url): - for block in blocks.values(): - if block.get("@type", "") == "listing": - if block.get("template", False) and not block.get("variation", False): - # import pdb - - # pdb.set_trace() - logger.error("- {}".format(url)) - if block.get("template", False) and block.get("variation", False): - logger.error("- {}".format(url)) - if block.get("variation", "") == "default": - block["variation"] = "simpleCard" - logger.info("- {}".format(url)) - - # fix root - portal = api.portal.get() - portal_blocks = json.loads(portal.blocks) - fix_listing(portal_blocks, portal.absolute_url()) - portal.blocks = json.dumps(portal_blocks) - - # fix blocks in contents - pc = api.portal.get_tool(name="portal_catalog") - brains = pc() - tot = len(brains) - i = 0 - for brain in brains: - i += 1 - if i % 1000 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - item = aq_base(brain.getObject()) - if getattr(item, "blocks", {}): - blocks = deepcopy(item.blocks) - if blocks: - fix_listing(blocks, brain.getURL()) - item.blocks = blocks - for schema in iterSchemata(item): - # fix blocks in blocksfields - for name, field in getFields(schema).items(): - if name == "blocks": - blocks = deepcopy(item.blocks) - if blocks: - fix_listing(blocks, brain.getURL()) - item.blocks = blocks - elif isinstance(field, BlocksField): - value = deepcopy(field.get(item)) - if not value: - continue - if isinstance(value, str): - if value == "": - setattr( - item, - name, - {"blocks": {}, "blocks_layout": {"items": []}}, - ) - continue - try: - blocks = value.get("blocks", {}) - except AttributeError: - logger.warning( - "[RICHTEXT] - {} (not converted)".format(brain.getURL()) - ) - if blocks: - fix_listing(blocks, brain.getURL()) - setattr(item, name, value) - - -def to_3400(context): # noqa: C901 - logger.info("### START CONVERSION BLOCKS: newsHome -> highlitedContent ###") - - def fix_block(blocks, url): - for block in blocks.values(): - if block.get("@type", "") == "newsHome": - block["@type"] = "highlitedContent" - - # fix root - portal = api.portal.get() - portal_blocks = json.loads(portal.blocks) - fix_block(portal_blocks, portal.absolute_url()) - portal.blocks = json.dumps(portal_blocks) - - # fix blocks in contents - pc = api.portal.get_tool(name="portal_catalog") - brains = pc() - tot = len(brains) - i = 0 - for brain in brains: - i += 1 - if i % 1000 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - item = aq_base(brain.getObject()) - if getattr(item, "blocks", {}): - blocks = deepcopy(item.blocks) - if blocks: - fix_block(blocks, brain.getURL()) - item.blocks = blocks - for schema in iterSchemata(item): - # fix blocks in blocksfields - for name, field in getFields(schema).items(): - if name == "blocks": - blocks = deepcopy(item.blocks) - if blocks: - fix_block(blocks, brain.getURL()) - item.blocks = blocks - elif isinstance(field, BlocksField): - value = deepcopy(field.get(item)) - if not value: - continue - if isinstance(value, str): - if value == "": - setattr( - item, - name, - {"blocks": {}, "blocks_layout": {"items": []}}, - ) - continue - try: - blocks = value.get("blocks", {}) - except AttributeError: - logger.warning( - "[RICHTEXT] - {} (not converted)".format(brain.getURL()) - ) - if blocks: - fix_block(blocks, brain.getURL()) - setattr(item, name, value) - - -def to_3401(context): # noqa: C901 - logger.info("File type can now be added inside a CartellaModulistica") - update_types(context) - - -def to_3500(context): - logger.info("Add new index and reindex UO") - update_catalog(context) - - # remove unused index - catalog = api.portal.get_tool(name="portal_catalog") - if "office_venue" in catalog.indexes(): - catalog.manage_delIndex("office_venue") - - # reindex - brains = api.content.find(portal_type="UnitaOrganizzativa") - tot = len(brains) - logger.info("Found {} UO.".format(tot)) - i = 0 - for brain in brains: - i += 1 - if i % 1000 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - uo = brain.getObject() - uo.reindexObject(idxs=["uo_location", "tipologia_organizzazione"]) - - -def to_3501(context): - logger.info("Reindex UO for new SearchableText fields") - - brains = api.content.find(portal_type="UnitaOrganizzativa") - tot = len(brains) - logger.info("Found {} UO.".format(tot)) - i = 0 - for brain in brains: - i += 1 - if i % 1000 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - uo = brain.getObject() - uo.reindexObject(idxs=["SearchableText"]) - - -def to_3600(context): - logger.info("Enable kitconcept.seo behavior") - types_list = [ - "UnitaOrganizzativa", - "Bando", - "Subsite", - "Venue", - "Persona", - "Event", - "News Item", - "Document", - "Documento", - "Servizio", - "CartellaModulistica", - "Pagina Argomento", - ] - portal_types = api.portal.get_tool(name="portal_types") - for ct_type in types_list: - if "kitconcept.seo" not in portal_types[ct_type].behaviors: - portal_types[ct_type].behaviors += ("kitconcept.seo",) - logger.info("Enabled kitconcept.seo on: {}".format(ct_type)) - - logger.info("Bandi customizations") - update_catalog(context) - api.portal.set_registry_record("default_ente", (), interface=IBandoSettings) - - portal_types = api.portal.get_tool(name="portal_types") - portal_types["Bando Folder Deepening"].allowed_content_types = ( - "Modulo", - "File", - "Link", - ) - portal_types["Bando"].default_view = "view" - portal_types["Bando"].view_methods = ("view",) - - logger.info("Reindex SearchableText") - pc = api.portal.get_tool(name="portal_catalog") - pc.reindexIndex("SearchableText", context.REQUEST) - - logger.info("Reindex Bandi") - i = 0 - brains = api.content.find(portal_type="Bando") - tot = len(brains) - for brain in brains: - i += 1 - if i % 1000 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - bando = brain.getObject() - bando.reindexObject(idxs=["ufficio_responsabile_bando", "Subject_bando"]) - - -def to_3700(context): - logger.info("Set show_modified_default as True") - - api.portal.set_registry_record( - "show_modified_default", True, interface=IDesignPloneSettings - ) - - -def to_3800(context): - logger.info("Fix Venue addable types") - - portal_types = api.portal.get_tool(name="portal_types") - portal_types["Venue"].allowed_content_types = ( - "Folder", - "Image", - "File", - "Link", - ) - - -def to_3900(context): - logger.info("Add new metadata: ruolo") - - brains = api.content.find(portal_type="Persona") - for brain in brains: - persona = brain.getObject() - persona.reindexObject() - - -def to_4000(context): - logger.info("Move ruolo to a choice field") - ruoli = {"it": [], "en": []} - brains = api.content.find(portal_type="Persona") - for brain in brains: - persona = brain.getObject() - ruolo = getattr(persona, "ruolo", "") - lang = brain.language - if ruolo not in ruoli[lang]: - ruoli[lang].append(ruolo) - - if api.portal.get_registry_record( - "ruoli_persona", interface=IDesignPloneSettings, default=None - ): - api.portal.set_registry_record( - "ruoli_persona", json.dumps(ruoli), interface=IDesignPloneSettings - ) - - -def to_4100(context): - logger.info("Add constrainttypes behavior to Document") - - portal_types = api.portal.get_tool(name="portal_types") - document_behaviors = list(portal_types["Document"].behaviors) + [ - "plone.constraintypes" - ] - portal_types["Document"].behaviors = tuple(document_behaviors) - - -def to_4200(context): - logger.info("Add criteria and indexes to Persona") - - update_catalog(context) - update_registry(context) - - brains = api.content.find(portal_type="Persona") - for brain in brains: - persona = brain.getObject() - persona.reindexObject(idxs=["data_conclusione_incarico"]) - - -def to_5000(context): - logger.info("Enable preview_image behavior in all content types") - - portal_types = api.portal.get_tool(name="portal_types") - - for portal_type, fti in portal_types.items(): - behaviors = list(getattr(fti, "behaviors", ())) - if not behaviors: - continue - if portal_type == "Document": - behaviors = [ - x - for x in behaviors - if x not in ["plone.leadimage", "volto.preview_image"] - ] - behaviors.extend(["plone.leadimage", "volto.preview_image"]) - else: - if "plone.leadimage" not in behaviors or "volto.preview_image" in behaviors: - continue - behaviors.insert(behaviors.index("plone.leadimage") + 1, "volto.preview_image") - fti.behaviors = tuple(behaviors) - - logger.info("Move immagine_testata to image") - catalog = api.portal.get_tool("portal_catalog") - i = 0 - brains = catalog() - tot = len(brains) - for brain in brains: - i += 1 - if i % 500 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - obj = brain.getObject() - if "image" in obj.keys(): - api.content.rename(obj=obj["image"], new_id="image-1") - if brain.portal_type == "Document": - immagine_testata = getattr(obj, "immagine_testata", None) - if immagine_testata: - obj.image = immagine_testata - obj.immagine_testata = None - catalog.catalog_object(obj) - - -def to_5001(context): - catalog = api.portal.get_tool("portal_catalog") - i = 0 - brains = catalog(portal_type="Pagina Argomento") - tot = len(brains) - logger.info("Add icona metadata to {}".format(tot)) - for brain in brains: - i += 1 - if i % 500 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - obj = brain.getObject() - catalog.catalog_object(obj) - - -def to_5002(context): - """ - Reindex non-folderish items because there were some metadata not updated - """ - catalog = api.portal.get_tool("portal_catalog") - i = 0 - brains = catalog(is_folderish=False) - tot = len(brains) - for brain in brains: - i += 1 - if i % 500 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - obj = brain.getObject() - catalog.catalog_object(obj) - - -def to_5200(context): - """ - add new behavior for Bando - """ - portal_types = api.portal.get_tool(name="portal_types") - fti = portal_types["Bando"] - behaviors = list(getattr(fti, "behaviors", ())) - if "design.plone.contenttypes.behavior.update_note" not in behaviors: - behaviors.append("design.plone.contenttypes.behavior.update_note") - fti.behaviors = tuple(behaviors) - - -def to_5210(context): - logger.info("Enable preview_image behavior in Bandi content types") - - portal_types = api.portal.get_tool(name="portal_types") - fti = portal_types["Bando"] - behaviors = list(getattr(fti, "behaviors", ())) - if "volto.preview_image" not in behaviors: - behaviors.append("volto.preview_image") - fti.behaviors = tuple(behaviors) - - -def to_5220(context): - """ - Reindex Venues - """ - logger.info("Reindex SearchableText for Venue items.") - catalog = api.portal.get_tool("portal_catalog") - i = 0 - brains = catalog(portal_type="Venue") - tot = len(brains) - for brain in brains: - i += 1 - if i % 500 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - obj = brain.getObject() - obj.reindexObject(idxs=["SearchableText", "object_provides"]) - - -def to_5300(context): - update_profile(context, "plone-difftool") - update_profile(context, "repositorytool") - - portal_types = api.portal.get_tool(name="portal_types") - for portal_type, fti in portal_types.items(): - if portal_type in [ - "CartellaModulistica", - "Documento", - "Link", - "Pagina Argomento", - "Persona", - "Servizio", - "UnitaOrganizzativa", - "Venue", - ]: - behaviors = list(getattr(fti, "behaviors", ())) - if "plone.versioning" not in behaviors: - behaviors.append("plone.versioning") - fti.behaviors = tuple(behaviors) - - -def to_5310(context): - """ - Reindex Bandi - """ - logger.info("Reindex SearchableText for Bandi items.") - catalog = api.portal.get_tool("portal_catalog") - i = 0 - brains = catalog(portal_type="Bando") - tot = len(brains) - for brain in brains: - i += 1 - if i % 500 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - brain.getObject().reindexObject(idxs=["SearchableText"]) - - -def to_5400(context): - logger.info('Remove "volto.blocks" behavior from News Item and Event.') - remove_blocks_behavior(context) - - -def to_5410(context): - - # cleanup Document behaviors - portal_types = api.portal.get_tool(name="portal_types") - behaviors = portal_types["Document"].behaviors - to_remove = [ - "plone.tableofcontents", - ] - portal_types["Document"].behaviors = tuple( - [x for x in behaviors if x not in to_remove] - ) - - -def to_6000(context): - """ """ - logger.info( - "Convert behavior: collective.dexteritytextindexer => plone.textindexer" # noqa - ) - portal_types = api.portal.get_tool(name="portal_types") - for fti in portal_types.values(): - behaviors = [] - for behavior in getattr(fti, "behaviors", ()): - if behavior == "collective.dexteritytextindexer": - behavior = "plone.textindexer" - behaviors.append(behavior) - - fti.behaviors = tuple(behaviors) - - -def to_6010(context): - """ """ - update_types(context) - update_registry(context) - update_catalog(context) - update_rolemap(context) - - -def migrate_pdc_and_incarico(context): - # Cannot test rn, blind coding - update_types(context) - update_registry(context) - update_catalog(context) - update_rolemap(context) - # "field name in original ct": "field name in new ct" - type_mapping = { - "Persona": { - 'PDC': { - "telefono": "phone", - "fax": "fax", - "email": "email", - "pec": "pec", - }, - "Incarico": { - # HOW? Need taxonomies also - # We could do: - # persona.ruolo.title = incarico.title - # persona.items.compensi = incarico.items.compensi? - "ruolo?": "incarico?", - # BlobFile to relation with Documento - "atto_nomina": "atto_nomina", - "data_conclusione_incarico": "data_conclusione_incarico", - "data_insediamento": "data_insediamento", - } - }, - "UnitaOrganizzativa": { - 'PDC': { - "telefono": "phone", - "fax": "fax", - "email": "email", - "pec": "pec", - }, - }, - # TODO: tbc - "Event": { - 'PDC': { - "telefono": "phone", - "fax": "fax", - "email": "email", - "pec": "pec", - }, - }, - # TODO: tbc - "Venue": { - 'PDC': { - "riferimento_telefonico_struttura": "phone", - "riferimento_fax_struttura": "fax", - "riferimento_mail_struttura": "email", - "riferimento_pec_struttura": "pec", - }, - }, - # TODO: tbc - "Servizio": { - # questi non sono presenti sul ct originale - 'PDC': { - "telefono": "phone", - "fax": "fax", - "email": "email", - "pec": "pec", - }, - }, - } - - def createIncaricoAndMigratePersona(portal_type): - # Taxonomies work needs to be completed before, blind coding ahead - if portal_type == 'Persona': - fixed_total = 0 - for brain in api.content.find(portal_type=portal_type): - item = brain.getObject() - atto_nomina = item.atto_nomina - logger.info(f"Fixing Punto di Contatto for '{item.title}'...") # noqa - file_bog = api.content.find(context=item, depth=1, id='atti-nomina') - if not file_bog: - try: - file_bog = api.content.create( - type="Document", id="atti-nomina", title="Atti Nomina", container=item - ) - except Exception: - logger.error("Error", Exception) - - try: - new_atto_nomina = api.content.create( - type="File", - id=atto_nomina.id, - title=atto_nomina.title, - container=item, - **{'file': atto_nomina} - ) - intids = getUtility(IIntIds) - relation = [RelationValue(intids.getId(new_atto_nomina))] - incarico = api.content.create( - type="Incarico", title=item.ruolo.title, container=item - ) - incarico.atto_nomina = relation - item.atto_nomina = None - fixed_total += 1 - logger.info(f"Fixing Punto di Contatto for '{item.title}'...:DONE") # noqa - except Exception: - logger.error("Error", Exception) - logger.info("Updated {} objects".format(fixed_total)) - - pass - - def createPDCandMigrateOldCTs(portal_type): - logger.info(f"Fixing Punto di Contatto for '{portal_type}'...") # noqa - fixed_total = 0 - mapping = None - # mapping = type_mapping[portal_type]["PDC"] - # Reenable mapping to use - if not mapping: - logger.info(f"No need to fix Punto di Contatto for '{portal_type}: DONE") - return - for brain in api.content.find(portal_type=portal_type): - item = brain.getObject() - kwargs = { - "value_punto_contatto": [], - "persona": [] - } - for key, value in mapping.items(): - import pdb; pdb.set_trace() - - if hasattr(item, key): - kwargs["value_punto_contatto"].append({ - 'pdc_type': value, - 'pdc_value': item[key] - }) - - new_pdc = api.content.create( - type='PuntoDiContatto', - title=f"Punto di Contatto {item.id}", - container=item, - **kwargs, - ) - intids = getUtility(IIntIds) - import pdb; pdb.set_trace() - item.contact_info = [RelationValue(intids.getId(new_pdc))] - fixed_total += 1 - - logger.info(f"Fixing Punto di Contatto for '{portal_type}: DONE") - logger.info("Updated {} objects".format(fixed_total)) - - for pt in type_mapping: - logger.info("Migrating existing CTs for use with new Incarico and PDC Content Types") - createPDCandMigrateOldCTs(pt) - createIncaricoAndMigratePersona(pt) diff --git a/.history/src/design/plone/contenttypes/upgrades/upgrades_20230104110901.py b/.history/src/design/plone/contenttypes/upgrades/upgrades_20230104110901.py deleted file mode 100644 index e90dedb6..00000000 --- a/.history/src/design/plone/contenttypes/upgrades/upgrades_20230104110901.py +++ /dev/null @@ -1,1127 +0,0 @@ -# -*- coding: utf-8 -*- -from Acquisition import aq_base -from collective.volto.blocksfield.field import BlocksField -from copy import deepcopy -from design.plone.contenttypes.controlpanels.settings import IDesignPloneSettings -from design.plone.contenttypes.upgrades.draftjs_converter import to_draftjs -from design.plone.contenttypes.setuphandlers import remove_blocks_behavior -from plone import api -from plone.app.textfield.value import RichTextValue -from plone.app.upgrade.utils import installOrReinstallProduct -from plone.dexterity.utils import iterSchemata -from redturtle.bandi.interfaces.settings import IBandoSettings -from transaction import commit -from z3c.relationfield import RelationValue -from zope.component import getUtility -from zope.event import notify -from zope.intid.interfaces import IIntIds -from zope.lifecycleevent import ObjectModifiedEvent -from zope.schema import getFields - - -import json -import logging -import six - - -logger = logging.getLogger(__name__) - -DEFAULT_PROFILE = "profile-design.plone.contenttypes:default" - -# standard upgrades # - - -def update_profile(context, profile, run_dependencies=True): - context.runImportStepFromProfile(DEFAULT_PROFILE, profile, run_dependencies) - - -def update_types(context): - update_profile(context, "typeinfo") - - -def update_rolemap(context): - update_profile(context, "rolemap") - - -def update_registry(context): - update_profile(context, "plone.app.registry", run_dependencies=False) - - -def update_catalog(context): - update_profile(context, "catalog") - - -def update_controlpanel(context): - update_profile(context, "controlpanel") - - -def remap_fields(mapping): - pc = api.portal.get_tool(name="portal_catalog") - brains = pc() - tot = len(brains) - logger.info("Trovati {} elementi da sistemare.".format(tot)) - # remap fields - for brain in brains: - item = brain.getObject() - for old, new in mapping.items(): - value = getattr(item, old, None) - if value: - setattr(item, new, value) - setattr(item, old, None) - logger.info( - "- {url}: {old} -> {new}".format( - url=brain.getURL(), old=old, new=new - ) - ) - delattr(item, old) - - -# custom ones # - - -def to_1001(context): - - update_types(context) - - # cleanup event behaviors - portal_types = api.portal.get_tool(name="portal_types") - behaviors = portal_types["Event"].behaviors - to_remove = [ - "design.plone.contenttypes.behavior.luoghi_correlati", - "design.plone.contenttypes.behavior.argomenti_evento", - "design.plone.contenttypes.behavior.additional_help_infos_evento", - ] - portal_types["Event"].behaviors = tuple( - [x for x in behaviors if x not in to_remove] - ) - - mapping = { - # "descrizione_destinatari": "a_chi_si_rivolge", - "canale_fisico": "dove_rivolgersi_extra", - "canale_fisico_prenotazione": "prenota_appuntamento", - "fasi_scadenze": "tempi_e_scadenze", - "sedi_e_luoghi": "dove_rivolgersi", - "box_aiuto": "ulteriori_informazioni", - "riferimento_telefonico_luogo": "telefono", - "riferimento_mail_luogo": "email", - } - remap_fields(mapping=mapping) - - -def to_1003(context): - - update_types(context) - - mapping = { - "unita_amministrativa_responsabile": "unita_amministrative_responsabili", # noqa - "sedi": "sede", - "contatto_reperibilita": "reperibilita", - "evento_supportato_da": "supportato_da", - } - remap_fields(mapping=mapping) - - -def to_1005(context): - def fix_index(blocks): - for block in blocks.values(): - if block.get("@type", "") == "listing": - for query in block.get("query", []): - if ( - query["i"] == "argomenti_correlati" - or query["i"] == "tassonomia_argomenti" - ): # noqa - query["i"] = "argomenti" - logger.info(" - {}".format(brain.getURL())) - - # fix root - portal = api.portal.get() - portal_blocks = json.loads(portal.blocks) - fix_index(portal_blocks) - portal.blocks = json.dumps(portal_blocks) - - logger.info("Fixing listing blocks.") - for brain in api.content.find(object_provides="plone.restapi.behaviors.IBlocks"): - item = brain.getObject() - blocks = deepcopy(getattr(item, "blocks", {})) - if blocks: - fix_index(blocks) - item.blocks = blocks - logger.info("** Reindexing items that refers to an argument **") - for brain in api.portal.get_tool("portal_catalog")(): - item = brain.getObject() - if getattr(item.aq_base, "tassonomia_argomenti", []): - logger.info(" - {}".format(brain.getURL())) - item.reindexObject(idxs=["argomenti"]) - - -def to_1006(context): - def fix_index(blocks): - for block in blocks.values(): - if block.get("@type", "") == "listing": - for query in block.get("query", []): - if ( - query["i"] == "argomenti_correlati" - or query["i"] == "tassonomia_argomenti" - or query["i"] == "argomenti" - ): # noqa - query["i"] = "argomenti" - query["v"] = [x.Title for x in api.content.find(UID=query["v"])] - logger.info(" - {}".format(brain.getURL())) - - # fix root - portal = api.portal.get() - portal_blocks = json.loads(portal.blocks) - fix_index(portal_blocks) - portal.blocks = json.dumps(portal_blocks) - - logger.info("Fixing listing blocks.") - for brain in api.content.find(object_provides="plone.restapi.behaviors.IBlocks"): - item = brain.getObject() - blocks = deepcopy(getattr(item, "blocks", {})) - if blocks: - fix_index(blocks) - item.blocks = blocks - - -def to_1007(context): - for brain in api.content.find(portal_type="Persona"): - item = brain.getObject() - if item.email: - item.email = [item.email] - if item.telefono: - item.telefono = [item.telefono] - - -def to_1008(context): - installOrReinstallProduct(api.portal.get(), "redturtle.bandi") - - -def to_1009(context): - def fix_index(blocks): - """ - revert to tassonomia_argomenti - """ - for block in blocks.values(): - if block.get("@type", "") == "listing": - for query in block.get("query", []): - if query["i"] == "argomenti": - query["i"] = "tassonomia_argomenti" - logger.info(" - {}".format(brain.getURL())) - - # fix root - portal = api.portal.get() - portal_blocks = json.loads(portal.blocks) - fix_index(portal_blocks) - portal.blocks = json.dumps(portal_blocks) - - logger.info("Fixing listing blocks.") - for brain in api.content.find(object_provides="plone.restapi.behaviors.IBlocks"): - item = brain.getObject() - blocks = deepcopy(getattr(item, "blocks", {})) - if blocks: - fix_index(blocks) - item.blocks = blocks - logger.info("** Reindexing items that refers to an argument **") - for brain in api.portal.get_tool("portal_catalog")(): - item = brain.getObject() - if getattr(item.aq_base, "tassonomia_argomenti", []): - logger.info(" - {}".format(brain.getURL())) - item.reindexObject(idxs=["tassonomia_argomenti"]) - - -def to_1010(context): - pc = api.portal.get_tool(name="portal_catalog") - pc.manage_reindexIndex(ids=["event_location"]) - - -def to_1013(context): - def fix_template_name(blocks): - """ - revert to tassonomia_argomenti - """ - found = False - for block in blocks.values(): - if ( - block.get("@type", "") == "listing" - and block.get("template", "") == "imageGallery" - ): - block["template"] = "photogallery" - found = True - return found - - # fix root - logger.info('Changing listing block template from "imageGallery" to "photogallery') - portal = api.portal.get() - portal_blocks = json.loads(portal.blocks) - to_update = fix_template_name(portal_blocks) - fixed_items = [] - if to_update: - portal.blocks = json.dumps(portal_blocks) - fixed_items.append("Root") - i = 0 - brains = api.content.find(object_provides="plone.restapi.behaviors.IBlocks") - tot = len(brains) - for brain in brains: - i += 1 - if i % 1000 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - item = brain.getObject() - blocks = deepcopy(getattr(item, "blocks", {})) - if blocks: - to_update = fix_template_name(blocks) - if to_update: - item.blocks = blocks - fixed_items.append(brain.getPath()) - - logger.info("Finish") - if fixed_items: - logger.info("Updated items:") - for fixed in fixed_items: - logger.info("- {}".format(fixed)) - else: - logger.info("No items affected.") - - -def to_1014(context): - update_types(context) - portal_types = api.portal.get_tool(name="portal_types") - portal_types["Bando"].behaviors = tuple( - [ - x - for x in portal_types["Bando"].behaviors - if x != "design.plone.contenttypes.behavior.argomenti" - ] - ) - - -def to_1015(context): - update_types(context) - - # cleanup trasparenza behavior from CTs - portal_types = api.portal.get_tool(name="portal_types") - service_behaviors = portal_types["Servizio"].behaviors - to_remove = [ - "design.plone.contenttypes.behavior.trasparenza", - ] - portal_types["Servizio"].behaviors = tuple( - [x for x in service_behaviors if x not in to_remove] - ) - persona_behaviors = portal_types["Persona"].behaviors - portal_types["Persona"].behaviors = tuple( - [x for x in persona_behaviors if x not in to_remove] - ) - - -def to_1016(context): - section_ids = ["amministrazione", "servizi", "novita", "documenti-e-dati"] - sections = [] - portal = api.portal.get() - for id in section_ids: - item = portal.get(id, None) - if item: - sections.append({"title": item.title, "linkUrl": [item.UID()]}) - settings = [{"rootPath": "/", "items": sections}] - api.portal.set_registry_record( - "search_sections", - json.dumps(settings), - interface=IDesignPloneSettings, - ) - - -def to_2000(context): # noqa: C901 - # remove volto.blocks behavior from news and events and add new one - update_types(context) - portal_types = api.portal.get_tool(name="portal_types") - for ptype in ["News Item", "Event"]: - portal_types[ptype].behaviors = tuple( - [x for x in portal_types[ptype].behaviors if x != "volto.blocks"] - ) - portal_types["Pagina Argomento"].behaviors = tuple( - [ - x - for x in portal_types["Pagina Argomento"].behaviors - if x != "design.plone.contenttypes.behavior.additional_help_infos" - ] - ) - # now copy values in new fields - pc = api.portal.get_tool(name="portal_catalog") - brains = pc() - tot = len(brains) - i = 0 - logger.info("### START CONVERSION FIELDS RICHTEXT -> DRAFTJS ###") - for brain in brains: - i += 1 - if i % 1000 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - item = brain.getObject() - if brain.portal_type in ["Event", "News Item"]: - blocks = getattr(item, "blocks", {}) - blocks_layout = getattr(item, "blocks_layout", {"items": []})["items"] - if not blocks: - continue - title_uid = "" - new_blocks = {} - for uid, block in blocks.items(): - if block.get("@type", "") == "title": - title_uid = uid - else: - new_blocks[uid] = block - item.descrizione_estesa = { - "blocks": new_blocks, - "blocks_layout": { - "items": [x for x in blocks_layout if x != title_uid] - }, - } - item.blocks = None - item.blocks_layout = None - for schema in iterSchemata(item): - for name, field in getFields(schema).items(): - if not isinstance(field, BlocksField): - continue - value = field.get(item) - if not value: - continue - if isinstance(value, six.string_types): - value = "

{}

".format(value) - elif isinstance(value, RichTextValue): - value = value.raw - else: - continue - if value == "


": - value = "" - try: - new_value = to_draftjs(value) - except Exception as e: - logger.error( - "[NOT MIGRATED] - {}: {}".format(brain.getPath(), name) - ) - raise e - setattr(item, name, new_value) - - -def to_2002(context): - """Per l'aggiornamento del vocabolario tipologie_persona, sistemiamo - tutti quelli già presenti. - """ - type_mapping = { - "altro": "Altro tipo", - "politica": "Politica", - "amministrativa": "Amministrativa", - } - logger.info("Fixing 'Tipologia Persona'...") - fixed_total = 0 - for brain in api.content.find(portal_type="Persona"): - item = brain.getObject() - if ( - hasattr(item, "tipologia_persona") - and item.tipologia_persona in type_mapping - ): # noqa - item.tipologia_persona = type_mapping[item.tipologia_persona] - fixed_total += 1 - commit() - logger.info("Fixing 'Tipologia Persona': DONE") - logger.info("Updated {} objects".format(fixed_total)) - - -def to_3000(context): - """ """ - update_registry(context) - update_controlpanel(context) - multilanguage = [ - "tipologie_notizia", - "tipologie_unita_organizzativa", - # "tipologie_documento", - "tipologie_persona", - ] - simple = ["lead_image_dimension", "search_sections"] - old_entry = "design.plone.contenttypes.controlpanels.vocabularies.IVocabulariesControlPanel.{}" # noqa - for field in simple: - value = api.portal.get_registry_record(old_entry.format(field)) - api.portal.set_registry_record(field, value, interface=IDesignPloneSettings) - - for field in multilanguage: - try: - value = api.portal.get_registry_record(old_entry.format(field)) - api.portal.set_registry_record( - field, - json.dumps({"it": value}), - interface=IDesignPloneSettings, - ) - except Exception: - continue - - context.runAllImportStepsFromProfile("profile-design.plone.contenttypes:to_3000") - - -def to_3101(context): - intids = getUtility(IIntIds) - logger.info("Fixing Documento references...") - fixed_total = 0 - for brain in api.content.find(portal_type="Documento"): - item = brain.getObject() - for rel in getattr(item, "servizi_collegati", []): - service = rel.to_object - if service: - service.altri_documenti.append(RelationValue(intids.getId(item))) - notify(ObjectModifiedEvent(service)) - logger.info("Fixed item {}".format("/".join(service.getPhysicalPath()))) - - if getattr(item, "servizi_collegati", []): - delattr(item, "servizi_collegati") - notify(ObjectModifiedEvent(item)) - fixed_total += 1 - logger.info("Fixed item {}".format("/".join(item.getPhysicalPath()))) - - logger.info("Fixing 'Documento': DONE") - logger.info("Updated {} objects Documento".format(fixed_total)) - - -def to_3102(context): - update_types(context) - - # cleanup trasparenza behavior from CTs - portal_types = api.portal.get_tool(name="portal_types") - to_remove = [ - "design.plone.contenttypes.behavior.trasparenza", - ] - for key, value in portal_types.items(): - ct_behaviors = getattr(value, "behaviors", None) - if ct_behaviors is not None: - portal_types[key].behaviors = tuple( - [x for x in ct_behaviors if x not in to_remove] - ) - - -def to_volto13(context): # noqa: C901 - # convert listing blocks with new standard - - logger.info("### START CONVERSION TO VOLTO 13: default => simpleCard ###") - - def fix_listing(blocks, url): - for block in blocks.values(): - if block.get("@type", "") == "listing": - if block.get("template", False) and not block.get("variation", False): - # import pdb - - # pdb.set_trace() - logger.error("- {}".format(url)) - if block.get("template", False) and block.get("variation", False): - logger.error("- {}".format(url)) - if block.get("variation", "") == "default": - block["variation"] = "simpleCard" - logger.info("- {}".format(url)) - - # fix root - portal = api.portal.get() - portal_blocks = json.loads(portal.blocks) - fix_listing(portal_blocks, portal.absolute_url()) - portal.blocks = json.dumps(portal_blocks) - - # fix blocks in contents - pc = api.portal.get_tool(name="portal_catalog") - brains = pc() - tot = len(brains) - i = 0 - for brain in brains: - i += 1 - if i % 1000 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - item = aq_base(brain.getObject()) - if getattr(item, "blocks", {}): - blocks = deepcopy(item.blocks) - if blocks: - fix_listing(blocks, brain.getURL()) - item.blocks = blocks - for schema in iterSchemata(item): - # fix blocks in blocksfields - for name, field in getFields(schema).items(): - if name == "blocks": - blocks = deepcopy(item.blocks) - if blocks: - fix_listing(blocks, brain.getURL()) - item.blocks = blocks - elif isinstance(field, BlocksField): - value = deepcopy(field.get(item)) - if not value: - continue - if isinstance(value, str): - if value == "": - setattr( - item, - name, - {"blocks": {}, "blocks_layout": {"items": []}}, - ) - continue - try: - blocks = value.get("blocks", {}) - except AttributeError: - logger.warning( - "[RICHTEXT] - {} (not converted)".format(brain.getURL()) - ) - if blocks: - fix_listing(blocks, brain.getURL()) - setattr(item, name, value) - - -def to_3400(context): # noqa: C901 - logger.info("### START CONVERSION BLOCKS: newsHome -> highlitedContent ###") - - def fix_block(blocks, url): - for block in blocks.values(): - if block.get("@type", "") == "newsHome": - block["@type"] = "highlitedContent" - - # fix root - portal = api.portal.get() - portal_blocks = json.loads(portal.blocks) - fix_block(portal_blocks, portal.absolute_url()) - portal.blocks = json.dumps(portal_blocks) - - # fix blocks in contents - pc = api.portal.get_tool(name="portal_catalog") - brains = pc() - tot = len(brains) - i = 0 - for brain in brains: - i += 1 - if i % 1000 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - item = aq_base(brain.getObject()) - if getattr(item, "blocks", {}): - blocks = deepcopy(item.blocks) - if blocks: - fix_block(blocks, brain.getURL()) - item.blocks = blocks - for schema in iterSchemata(item): - # fix blocks in blocksfields - for name, field in getFields(schema).items(): - if name == "blocks": - blocks = deepcopy(item.blocks) - if blocks: - fix_block(blocks, brain.getURL()) - item.blocks = blocks - elif isinstance(field, BlocksField): - value = deepcopy(field.get(item)) - if not value: - continue - if isinstance(value, str): - if value == "": - setattr( - item, - name, - {"blocks": {}, "blocks_layout": {"items": []}}, - ) - continue - try: - blocks = value.get("blocks", {}) - except AttributeError: - logger.warning( - "[RICHTEXT] - {} (not converted)".format(brain.getURL()) - ) - if blocks: - fix_block(blocks, brain.getURL()) - setattr(item, name, value) - - -def to_3401(context): # noqa: C901 - logger.info("File type can now be added inside a CartellaModulistica") - update_types(context) - - -def to_3500(context): - logger.info("Add new index and reindex UO") - update_catalog(context) - - # remove unused index - catalog = api.portal.get_tool(name="portal_catalog") - if "office_venue" in catalog.indexes(): - catalog.manage_delIndex("office_venue") - - # reindex - brains = api.content.find(portal_type="UnitaOrganizzativa") - tot = len(brains) - logger.info("Found {} UO.".format(tot)) - i = 0 - for brain in brains: - i += 1 - if i % 1000 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - uo = brain.getObject() - uo.reindexObject(idxs=["uo_location", "tipologia_organizzazione"]) - - -def to_3501(context): - logger.info("Reindex UO for new SearchableText fields") - - brains = api.content.find(portal_type="UnitaOrganizzativa") - tot = len(brains) - logger.info("Found {} UO.".format(tot)) - i = 0 - for brain in brains: - i += 1 - if i % 1000 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - uo = brain.getObject() - uo.reindexObject(idxs=["SearchableText"]) - - -def to_3600(context): - logger.info("Enable kitconcept.seo behavior") - types_list = [ - "UnitaOrganizzativa", - "Bando", - "Subsite", - "Venue", - "Persona", - "Event", - "News Item", - "Document", - "Documento", - "Servizio", - "CartellaModulistica", - "Pagina Argomento", - ] - portal_types = api.portal.get_tool(name="portal_types") - for ct_type in types_list: - if "kitconcept.seo" not in portal_types[ct_type].behaviors: - portal_types[ct_type].behaviors += ("kitconcept.seo",) - logger.info("Enabled kitconcept.seo on: {}".format(ct_type)) - - logger.info("Bandi customizations") - update_catalog(context) - api.portal.set_registry_record("default_ente", (), interface=IBandoSettings) - - portal_types = api.portal.get_tool(name="portal_types") - portal_types["Bando Folder Deepening"].allowed_content_types = ( - "Modulo", - "File", - "Link", - ) - portal_types["Bando"].default_view = "view" - portal_types["Bando"].view_methods = ("view",) - - logger.info("Reindex SearchableText") - pc = api.portal.get_tool(name="portal_catalog") - pc.reindexIndex("SearchableText", context.REQUEST) - - logger.info("Reindex Bandi") - i = 0 - brains = api.content.find(portal_type="Bando") - tot = len(brains) - for brain in brains: - i += 1 - if i % 1000 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - bando = brain.getObject() - bando.reindexObject(idxs=["ufficio_responsabile_bando", "Subject_bando"]) - - -def to_3700(context): - logger.info("Set show_modified_default as True") - - api.portal.set_registry_record( - "show_modified_default", True, interface=IDesignPloneSettings - ) - - -def to_3800(context): - logger.info("Fix Venue addable types") - - portal_types = api.portal.get_tool(name="portal_types") - portal_types["Venue"].allowed_content_types = ( - "Folder", - "Image", - "File", - "Link", - ) - - -def to_3900(context): - logger.info("Add new metadata: ruolo") - - brains = api.content.find(portal_type="Persona") - for brain in brains: - persona = brain.getObject() - persona.reindexObject() - - -def to_4000(context): - logger.info("Move ruolo to a choice field") - ruoli = {"it": [], "en": []} - brains = api.content.find(portal_type="Persona") - for brain in brains: - persona = brain.getObject() - ruolo = getattr(persona, "ruolo", "") - lang = brain.language - if ruolo not in ruoli[lang]: - ruoli[lang].append(ruolo) - - if api.portal.get_registry_record( - "ruoli_persona", interface=IDesignPloneSettings, default=None - ): - api.portal.set_registry_record( - "ruoli_persona", json.dumps(ruoli), interface=IDesignPloneSettings - ) - - -def to_4100(context): - logger.info("Add constrainttypes behavior to Document") - - portal_types = api.portal.get_tool(name="portal_types") - document_behaviors = list(portal_types["Document"].behaviors) + [ - "plone.constraintypes" - ] - portal_types["Document"].behaviors = tuple(document_behaviors) - - -def to_4200(context): - logger.info("Add criteria and indexes to Persona") - - update_catalog(context) - update_registry(context) - - brains = api.content.find(portal_type="Persona") - for brain in brains: - persona = brain.getObject() - persona.reindexObject(idxs=["data_conclusione_incarico"]) - - -def to_5000(context): - logger.info("Enable preview_image behavior in all content types") - - portal_types = api.portal.get_tool(name="portal_types") - - for portal_type, fti in portal_types.items(): - behaviors = list(getattr(fti, "behaviors", ())) - if not behaviors: - continue - if portal_type == "Document": - behaviors = [ - x - for x in behaviors - if x not in ["plone.leadimage", "volto.preview_image"] - ] - behaviors.extend(["plone.leadimage", "volto.preview_image"]) - else: - if "plone.leadimage" not in behaviors or "volto.preview_image" in behaviors: - continue - behaviors.insert(behaviors.index("plone.leadimage") + 1, "volto.preview_image") - fti.behaviors = tuple(behaviors) - - logger.info("Move immagine_testata to image") - catalog = api.portal.get_tool("portal_catalog") - i = 0 - brains = catalog() - tot = len(brains) - for brain in brains: - i += 1 - if i % 500 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - obj = brain.getObject() - if "image" in obj.keys(): - api.content.rename(obj=obj["image"], new_id="image-1") - if brain.portal_type == "Document": - immagine_testata = getattr(obj, "immagine_testata", None) - if immagine_testata: - obj.image = immagine_testata - obj.immagine_testata = None - catalog.catalog_object(obj) - - -def to_5001(context): - catalog = api.portal.get_tool("portal_catalog") - i = 0 - brains = catalog(portal_type="Pagina Argomento") - tot = len(brains) - logger.info("Add icona metadata to {}".format(tot)) - for brain in brains: - i += 1 - if i % 500 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - obj = brain.getObject() - catalog.catalog_object(obj) - - -def to_5002(context): - """ - Reindex non-folderish items because there were some metadata not updated - """ - catalog = api.portal.get_tool("portal_catalog") - i = 0 - brains = catalog(is_folderish=False) - tot = len(brains) - for brain in brains: - i += 1 - if i % 500 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - obj = brain.getObject() - catalog.catalog_object(obj) - - -def to_5200(context): - """ - add new behavior for Bando - """ - portal_types = api.portal.get_tool(name="portal_types") - fti = portal_types["Bando"] - behaviors = list(getattr(fti, "behaviors", ())) - if "design.plone.contenttypes.behavior.update_note" not in behaviors: - behaviors.append("design.plone.contenttypes.behavior.update_note") - fti.behaviors = tuple(behaviors) - - -def to_5210(context): - logger.info("Enable preview_image behavior in Bandi content types") - - portal_types = api.portal.get_tool(name="portal_types") - fti = portal_types["Bando"] - behaviors = list(getattr(fti, "behaviors", ())) - if "volto.preview_image" not in behaviors: - behaviors.append("volto.preview_image") - fti.behaviors = tuple(behaviors) - - -def to_5220(context): - """ - Reindex Venues - """ - logger.info("Reindex SearchableText for Venue items.") - catalog = api.portal.get_tool("portal_catalog") - i = 0 - brains = catalog(portal_type="Venue") - tot = len(brains) - for brain in brains: - i += 1 - if i % 500 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - obj = brain.getObject() - obj.reindexObject(idxs=["SearchableText", "object_provides"]) - - -def to_5300(context): - update_profile(context, "plone-difftool") - update_profile(context, "repositorytool") - - portal_types = api.portal.get_tool(name="portal_types") - for portal_type, fti in portal_types.items(): - if portal_type in [ - "CartellaModulistica", - "Documento", - "Link", - "Pagina Argomento", - "Persona", - "Servizio", - "UnitaOrganizzativa", - "Venue", - ]: - behaviors = list(getattr(fti, "behaviors", ())) - if "plone.versioning" not in behaviors: - behaviors.append("plone.versioning") - fti.behaviors = tuple(behaviors) - - -def to_5310(context): - """ - Reindex Bandi - """ - logger.info("Reindex SearchableText for Bandi items.") - catalog = api.portal.get_tool("portal_catalog") - i = 0 - brains = catalog(portal_type="Bando") - tot = len(brains) - for brain in brains: - i += 1 - if i % 500 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - brain.getObject().reindexObject(idxs=["SearchableText"]) - - -def to_5400(context): - logger.info('Remove "volto.blocks" behavior from News Item and Event.') - remove_blocks_behavior(context) - - -def to_5410(context): - - # cleanup Document behaviors - portal_types = api.portal.get_tool(name="portal_types") - behaviors = portal_types["Document"].behaviors - to_remove = [ - "plone.tableofcontents", - ] - portal_types["Document"].behaviors = tuple( - [x for x in behaviors if x not in to_remove] - ) - - -def to_6000(context): - """ """ - logger.info( - "Convert behavior: collective.dexteritytextindexer => plone.textindexer" # noqa - ) - portal_types = api.portal.get_tool(name="portal_types") - for fti in portal_types.values(): - behaviors = [] - for behavior in getattr(fti, "behaviors", ()): - if behavior == "collective.dexteritytextindexer": - behavior = "plone.textindexer" - behaviors.append(behavior) - - fti.behaviors = tuple(behaviors) - - -def to_6010(context): - """ """ - update_types(context) - update_registry(context) - update_catalog(context) - update_rolemap(context) - - -def migrate_pdc_and_incarico(context): - # Cannot test rn, blind coding - update_types(context) - update_registry(context) - update_catalog(context) - update_rolemap(context) - # "field name in original ct": "field name in new ct" - type_mapping = { - "Persona": { - 'PDC': { - "telefono": "phone", - "fax": "fax", - "email": "email", - "pec": "pec", - }, - "Incarico": { - # HOW? Need taxonomies also - # We could do: - # persona.ruolo.title = incarico.title - # persona.items.compensi = incarico.items.compensi? - "ruolo?": "incarico?", - # BlobFile to relation with Documento - "atto_nomina": "atto_nomina", - "data_conclusione_incarico": "data_conclusione_incarico", - "data_insediamento": "data_insediamento", - } - }, - "UnitaOrganizzativa": { - 'PDC': { - "telefono": "phone", - "fax": "fax", - "email": "email", - "pec": "pec", - }, - }, - # TODO: tbc - "Event": { - 'PDC': { - "telefono": "phone", - "fax": "fax", - "email": "email", - "pec": "pec", - }, - }, - # TODO: tbc - "Venue": { - 'PDC': { - "riferimento_telefonico_struttura": "phone", - "riferimento_fax_struttura": "fax", - "riferimento_mail_struttura": "email", - "riferimento_pec_struttura": "pec", - }, - }, - # TODO: tbc - "Servizio": { - # questi non sono presenti sul ct originale - 'PDC': { - "telefono": "phone", - "fax": "fax", - "email": "email", - "pec": "pec", - }, - }, - } - - def createIncaricoAndMigratePersona(portal_type): - # Taxonomies work needs to be completed before, blind coding ahead - if portal_type == 'Persona': - fixed_total = 0 - for brain in api.content.find(portal_type=portal_type): - item = brain.getObject() - atto_nomina = item.atto_nomina - logger.info(f"Fixing Punto di Contatto for '{item.title}'...") # noqa - file_bog = api.content.find(context=item, depth=1, id='atti-nomina') - if not file_bog: - try: - file_bog = api.content.create( - type="Document", id="atti-nomina", title="Atti Nomina", container=item - ) - except Exception: - logger.error("Error", Exception) - - try: - new_atto_nomina = api.content.create( - type="File", - id=atto_nomina.id, - title=atto_nomina.title, - container=item, - **{'file': atto_nomina} - ) - intids = getUtility(IIntIds) - relation = [RelationValue(intids.getId(new_atto_nomina))] - incarico = api.content.create( - type="Incarico", title=item.ruolo.title, container=item - ) - incarico.atto_nomina = relation - item.atto_nomina = None - fixed_total += 1 - logger.info(f"Fixing Punto di Contatto for '{item.title}'...:DONE") # noqa - except Exception: - logger.error("Error", Exception) - logger.info("Updated {} objects".format(fixed_total)) - - pass - - def createPDCandMigrateOldCTs(portal_type): - logger.info(f"Fixing Punto di Contatto for '{portal_type}'...") # noqa - fixed_total = 0 - mapping = None - # mapping = type_mapping[portal_type]["PDC"] - # Reenable mapping to use - if not mapping: - logger.info(f"No need to fix Punto di Contatto for '{portal_type}: DONE") - return - for brain in api.content.find(portal_type=portal_type): - item = brain.getObject() - kwargs = { - "value_punto_contatto": [], - "persona": [] - } - for key, value in mapping.items(): - import pdb; pdb.set_trace() - - if hasattr(item, key): - kwargs["value_punto_contatto"].append({ - 'pdc_type': value, - 'pdc_value': item[key] - }) - - new_pdc = api.content.create( - type='PuntoDiContatto', - title=f"Punto di Contatto {item.id}", - container=item, - **kwargs, - ) - intids = getUtility(IIntIds) - import pdb; pdb.set_trace() - item.contact_info = [RelationValue(intids.getId(new_pdc))] - fixed_total += 1 - - logger.info(f"Fixing Punto di Contatto for '{portal_type}: DONE") - logger.info("Updated {} objects".format(fixed_total)) - - for pt in type_mapping: - logger.info("Migrating existing CTs for use with new Incarico and PDC Content Types") - createPDCandMigrateOldCTs(pt) - createIncaricoAndMigratePersona(pt) diff --git a/.history/src/design/plone/contenttypes/upgrades/upgrades_20230104110903.py b/.history/src/design/plone/contenttypes/upgrades/upgrades_20230104110903.py deleted file mode 100644 index 5db2695d..00000000 --- a/.history/src/design/plone/contenttypes/upgrades/upgrades_20230104110903.py +++ /dev/null @@ -1,1126 +0,0 @@ -# -*- coding: utf-8 -*- -from Acquisition import aq_base -from collective.volto.blocksfield.field import BlocksField -from copy import deepcopy -from design.plone.contenttypes.controlpanels.settings import IDesignPloneSettings -from design.plone.contenttypes.upgrades.draftjs_converter import to_draftjs -from design.plone.contenttypes.setuphandlers import remove_blocks_behavior -from plone import api -from plone.app.textfield.value import RichTextValue -from plone.app.upgrade.utils import installOrReinstallProduct -from plone.dexterity.utils import iterSchemata -from redturtle.bandi.interfaces.settings import IBandoSettings -from transaction import commit -from z3c.relationfield import RelationValue -from zope.component import getUtility -from zope.event import notify -from zope.intid.interfaces import IIntIds -from zope.lifecycleevent import ObjectModifiedEvent -from zope.schema import getFields - -import json -import logging -import six - - -logger = logging.getLogger(__name__) - -DEFAULT_PROFILE = "profile-design.plone.contenttypes:default" - -# standard upgrades # - - -def update_profile(context, profile, run_dependencies=True): - context.runImportStepFromProfile(DEFAULT_PROFILE, profile, run_dependencies) - - -def update_types(context): - update_profile(context, "typeinfo") - - -def update_rolemap(context): - update_profile(context, "rolemap") - - -def update_registry(context): - update_profile(context, "plone.app.registry", run_dependencies=False) - - -def update_catalog(context): - update_profile(context, "catalog") - - -def update_controlpanel(context): - update_profile(context, "controlpanel") - - -def remap_fields(mapping): - pc = api.portal.get_tool(name="portal_catalog") - brains = pc() - tot = len(brains) - logger.info("Trovati {} elementi da sistemare.".format(tot)) - # remap fields - for brain in brains: - item = brain.getObject() - for old, new in mapping.items(): - value = getattr(item, old, None) - if value: - setattr(item, new, value) - setattr(item, old, None) - logger.info( - "- {url}: {old} -> {new}".format( - url=brain.getURL(), old=old, new=new - ) - ) - delattr(item, old) - - -# custom ones # - - -def to_1001(context): - - update_types(context) - - # cleanup event behaviors - portal_types = api.portal.get_tool(name="portal_types") - behaviors = portal_types["Event"].behaviors - to_remove = [ - "design.plone.contenttypes.behavior.luoghi_correlati", - "design.plone.contenttypes.behavior.argomenti_evento", - "design.plone.contenttypes.behavior.additional_help_infos_evento", - ] - portal_types["Event"].behaviors = tuple( - [x for x in behaviors if x not in to_remove] - ) - - mapping = { - # "descrizione_destinatari": "a_chi_si_rivolge", - "canale_fisico": "dove_rivolgersi_extra", - "canale_fisico_prenotazione": "prenota_appuntamento", - "fasi_scadenze": "tempi_e_scadenze", - "sedi_e_luoghi": "dove_rivolgersi", - "box_aiuto": "ulteriori_informazioni", - "riferimento_telefonico_luogo": "telefono", - "riferimento_mail_luogo": "email", - } - remap_fields(mapping=mapping) - - -def to_1003(context): - - update_types(context) - - mapping = { - "unita_amministrativa_responsabile": "unita_amministrative_responsabili", # noqa - "sedi": "sede", - "contatto_reperibilita": "reperibilita", - "evento_supportato_da": "supportato_da", - } - remap_fields(mapping=mapping) - - -def to_1005(context): - def fix_index(blocks): - for block in blocks.values(): - if block.get("@type", "") == "listing": - for query in block.get("query", []): - if ( - query["i"] == "argomenti_correlati" - or query["i"] == "tassonomia_argomenti" - ): # noqa - query["i"] = "argomenti" - logger.info(" - {}".format(brain.getURL())) - - # fix root - portal = api.portal.get() - portal_blocks = json.loads(portal.blocks) - fix_index(portal_blocks) - portal.blocks = json.dumps(portal_blocks) - - logger.info("Fixing listing blocks.") - for brain in api.content.find(object_provides="plone.restapi.behaviors.IBlocks"): - item = brain.getObject() - blocks = deepcopy(getattr(item, "blocks", {})) - if blocks: - fix_index(blocks) - item.blocks = blocks - logger.info("** Reindexing items that refers to an argument **") - for brain in api.portal.get_tool("portal_catalog")(): - item = brain.getObject() - if getattr(item.aq_base, "tassonomia_argomenti", []): - logger.info(" - {}".format(brain.getURL())) - item.reindexObject(idxs=["argomenti"]) - - -def to_1006(context): - def fix_index(blocks): - for block in blocks.values(): - if block.get("@type", "") == "listing": - for query in block.get("query", []): - if ( - query["i"] == "argomenti_correlati" - or query["i"] == "tassonomia_argomenti" - or query["i"] == "argomenti" - ): # noqa - query["i"] = "argomenti" - query["v"] = [x.Title for x in api.content.find(UID=query["v"])] - logger.info(" - {}".format(brain.getURL())) - - # fix root - portal = api.portal.get() - portal_blocks = json.loads(portal.blocks) - fix_index(portal_blocks) - portal.blocks = json.dumps(portal_blocks) - - logger.info("Fixing listing blocks.") - for brain in api.content.find(object_provides="plone.restapi.behaviors.IBlocks"): - item = brain.getObject() - blocks = deepcopy(getattr(item, "blocks", {})) - if blocks: - fix_index(blocks) - item.blocks = blocks - - -def to_1007(context): - for brain in api.content.find(portal_type="Persona"): - item = brain.getObject() - if item.email: - item.email = [item.email] - if item.telefono: - item.telefono = [item.telefono] - - -def to_1008(context): - installOrReinstallProduct(api.portal.get(), "redturtle.bandi") - - -def to_1009(context): - def fix_index(blocks): - """ - revert to tassonomia_argomenti - """ - for block in blocks.values(): - if block.get("@type", "") == "listing": - for query in block.get("query", []): - if query["i"] == "argomenti": - query["i"] = "tassonomia_argomenti" - logger.info(" - {}".format(brain.getURL())) - - # fix root - portal = api.portal.get() - portal_blocks = json.loads(portal.blocks) - fix_index(portal_blocks) - portal.blocks = json.dumps(portal_blocks) - - logger.info("Fixing listing blocks.") - for brain in api.content.find(object_provides="plone.restapi.behaviors.IBlocks"): - item = brain.getObject() - blocks = deepcopy(getattr(item, "blocks", {})) - if blocks: - fix_index(blocks) - item.blocks = blocks - logger.info("** Reindexing items that refers to an argument **") - for brain in api.portal.get_tool("portal_catalog")(): - item = brain.getObject() - if getattr(item.aq_base, "tassonomia_argomenti", []): - logger.info(" - {}".format(brain.getURL())) - item.reindexObject(idxs=["tassonomia_argomenti"]) - - -def to_1010(context): - pc = api.portal.get_tool(name="portal_catalog") - pc.manage_reindexIndex(ids=["event_location"]) - - -def to_1013(context): - def fix_template_name(blocks): - """ - revert to tassonomia_argomenti - """ - found = False - for block in blocks.values(): - if ( - block.get("@type", "") == "listing" - and block.get("template", "") == "imageGallery" - ): - block["template"] = "photogallery" - found = True - return found - - # fix root - logger.info('Changing listing block template from "imageGallery" to "photogallery') - portal = api.portal.get() - portal_blocks = json.loads(portal.blocks) - to_update = fix_template_name(portal_blocks) - fixed_items = [] - if to_update: - portal.blocks = json.dumps(portal_blocks) - fixed_items.append("Root") - i = 0 - brains = api.content.find(object_provides="plone.restapi.behaviors.IBlocks") - tot = len(brains) - for brain in brains: - i += 1 - if i % 1000 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - item = brain.getObject() - blocks = deepcopy(getattr(item, "blocks", {})) - if blocks: - to_update = fix_template_name(blocks) - if to_update: - item.blocks = blocks - fixed_items.append(brain.getPath()) - - logger.info("Finish") - if fixed_items: - logger.info("Updated items:") - for fixed in fixed_items: - logger.info("- {}".format(fixed)) - else: - logger.info("No items affected.") - - -def to_1014(context): - update_types(context) - portal_types = api.portal.get_tool(name="portal_types") - portal_types["Bando"].behaviors = tuple( - [ - x - for x in portal_types["Bando"].behaviors - if x != "design.plone.contenttypes.behavior.argomenti" - ] - ) - - -def to_1015(context): - update_types(context) - - # cleanup trasparenza behavior from CTs - portal_types = api.portal.get_tool(name="portal_types") - service_behaviors = portal_types["Servizio"].behaviors - to_remove = [ - "design.plone.contenttypes.behavior.trasparenza", - ] - portal_types["Servizio"].behaviors = tuple( - [x for x in service_behaviors if x not in to_remove] - ) - persona_behaviors = portal_types["Persona"].behaviors - portal_types["Persona"].behaviors = tuple( - [x for x in persona_behaviors if x not in to_remove] - ) - - -def to_1016(context): - section_ids = ["amministrazione", "servizi", "novita", "documenti-e-dati"] - sections = [] - portal = api.portal.get() - for id in section_ids: - item = portal.get(id, None) - if item: - sections.append({"title": item.title, "linkUrl": [item.UID()]}) - settings = [{"rootPath": "/", "items": sections}] - api.portal.set_registry_record( - "search_sections", - json.dumps(settings), - interface=IDesignPloneSettings, - ) - - -def to_2000(context): # noqa: C901 - # remove volto.blocks behavior from news and events and add new one - update_types(context) - portal_types = api.portal.get_tool(name="portal_types") - for ptype in ["News Item", "Event"]: - portal_types[ptype].behaviors = tuple( - [x for x in portal_types[ptype].behaviors if x != "volto.blocks"] - ) - portal_types["Pagina Argomento"].behaviors = tuple( - [ - x - for x in portal_types["Pagina Argomento"].behaviors - if x != "design.plone.contenttypes.behavior.additional_help_infos" - ] - ) - # now copy values in new fields - pc = api.portal.get_tool(name="portal_catalog") - brains = pc() - tot = len(brains) - i = 0 - logger.info("### START CONVERSION FIELDS RICHTEXT -> DRAFTJS ###") - for brain in brains: - i += 1 - if i % 1000 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - item = brain.getObject() - if brain.portal_type in ["Event", "News Item"]: - blocks = getattr(item, "blocks", {}) - blocks_layout = getattr(item, "blocks_layout", {"items": []})["items"] - if not blocks: - continue - title_uid = "" - new_blocks = {} - for uid, block in blocks.items(): - if block.get("@type", "") == "title": - title_uid = uid - else: - new_blocks[uid] = block - item.descrizione_estesa = { - "blocks": new_blocks, - "blocks_layout": { - "items": [x for x in blocks_layout if x != title_uid] - }, - } - item.blocks = None - item.blocks_layout = None - for schema in iterSchemata(item): - for name, field in getFields(schema).items(): - if not isinstance(field, BlocksField): - continue - value = field.get(item) - if not value: - continue - if isinstance(value, six.string_types): - value = "

{}

".format(value) - elif isinstance(value, RichTextValue): - value = value.raw - else: - continue - if value == "


": - value = "" - try: - new_value = to_draftjs(value) - except Exception as e: - logger.error( - "[NOT MIGRATED] - {}: {}".format(brain.getPath(), name) - ) - raise e - setattr(item, name, new_value) - - -def to_2002(context): - """Per l'aggiornamento del vocabolario tipologie_persona, sistemiamo - tutti quelli già presenti. - """ - type_mapping = { - "altro": "Altro tipo", - "politica": "Politica", - "amministrativa": "Amministrativa", - } - logger.info("Fixing 'Tipologia Persona'...") - fixed_total = 0 - for brain in api.content.find(portal_type="Persona"): - item = brain.getObject() - if ( - hasattr(item, "tipologia_persona") - and item.tipologia_persona in type_mapping - ): # noqa - item.tipologia_persona = type_mapping[item.tipologia_persona] - fixed_total += 1 - commit() - logger.info("Fixing 'Tipologia Persona': DONE") - logger.info("Updated {} objects".format(fixed_total)) - - -def to_3000(context): - """ """ - update_registry(context) - update_controlpanel(context) - multilanguage = [ - "tipologie_notizia", - "tipologie_unita_organizzativa", - # "tipologie_documento", - "tipologie_persona", - ] - simple = ["lead_image_dimension", "search_sections"] - old_entry = "design.plone.contenttypes.controlpanels.vocabularies.IVocabulariesControlPanel.{}" # noqa - for field in simple: - value = api.portal.get_registry_record(old_entry.format(field)) - api.portal.set_registry_record(field, value, interface=IDesignPloneSettings) - - for field in multilanguage: - try: - value = api.portal.get_registry_record(old_entry.format(field)) - api.portal.set_registry_record( - field, - json.dumps({"it": value}), - interface=IDesignPloneSettings, - ) - except Exception: - continue - - context.runAllImportStepsFromProfile("profile-design.plone.contenttypes:to_3000") - - -def to_3101(context): - intids = getUtility(IIntIds) - logger.info("Fixing Documento references...") - fixed_total = 0 - for brain in api.content.find(portal_type="Documento"): - item = brain.getObject() - for rel in getattr(item, "servizi_collegati", []): - service = rel.to_object - if service: - service.altri_documenti.append(RelationValue(intids.getId(item))) - notify(ObjectModifiedEvent(service)) - logger.info("Fixed item {}".format("/".join(service.getPhysicalPath()))) - - if getattr(item, "servizi_collegati", []): - delattr(item, "servizi_collegati") - notify(ObjectModifiedEvent(item)) - fixed_total += 1 - logger.info("Fixed item {}".format("/".join(item.getPhysicalPath()))) - - logger.info("Fixing 'Documento': DONE") - logger.info("Updated {} objects Documento".format(fixed_total)) - - -def to_3102(context): - update_types(context) - - # cleanup trasparenza behavior from CTs - portal_types = api.portal.get_tool(name="portal_types") - to_remove = [ - "design.plone.contenttypes.behavior.trasparenza", - ] - for key, value in portal_types.items(): - ct_behaviors = getattr(value, "behaviors", None) - if ct_behaviors is not None: - portal_types[key].behaviors = tuple( - [x for x in ct_behaviors if x not in to_remove] - ) - - -def to_volto13(context): # noqa: C901 - # convert listing blocks with new standard - - logger.info("### START CONVERSION TO VOLTO 13: default => simpleCard ###") - - def fix_listing(blocks, url): - for block in blocks.values(): - if block.get("@type", "") == "listing": - if block.get("template", False) and not block.get("variation", False): - # import pdb - - # pdb.set_trace() - logger.error("- {}".format(url)) - if block.get("template", False) and block.get("variation", False): - logger.error("- {}".format(url)) - if block.get("variation", "") == "default": - block["variation"] = "simpleCard" - logger.info("- {}".format(url)) - - # fix root - portal = api.portal.get() - portal_blocks = json.loads(portal.blocks) - fix_listing(portal_blocks, portal.absolute_url()) - portal.blocks = json.dumps(portal_blocks) - - # fix blocks in contents - pc = api.portal.get_tool(name="portal_catalog") - brains = pc() - tot = len(brains) - i = 0 - for brain in brains: - i += 1 - if i % 1000 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - item = aq_base(brain.getObject()) - if getattr(item, "blocks", {}): - blocks = deepcopy(item.blocks) - if blocks: - fix_listing(blocks, brain.getURL()) - item.blocks = blocks - for schema in iterSchemata(item): - # fix blocks in blocksfields - for name, field in getFields(schema).items(): - if name == "blocks": - blocks = deepcopy(item.blocks) - if blocks: - fix_listing(blocks, brain.getURL()) - item.blocks = blocks - elif isinstance(field, BlocksField): - value = deepcopy(field.get(item)) - if not value: - continue - if isinstance(value, str): - if value == "": - setattr( - item, - name, - {"blocks": {}, "blocks_layout": {"items": []}}, - ) - continue - try: - blocks = value.get("blocks", {}) - except AttributeError: - logger.warning( - "[RICHTEXT] - {} (not converted)".format(brain.getURL()) - ) - if blocks: - fix_listing(blocks, brain.getURL()) - setattr(item, name, value) - - -def to_3400(context): # noqa: C901 - logger.info("### START CONVERSION BLOCKS: newsHome -> highlitedContent ###") - - def fix_block(blocks, url): - for block in blocks.values(): - if block.get("@type", "") == "newsHome": - block["@type"] = "highlitedContent" - - # fix root - portal = api.portal.get() - portal_blocks = json.loads(portal.blocks) - fix_block(portal_blocks, portal.absolute_url()) - portal.blocks = json.dumps(portal_blocks) - - # fix blocks in contents - pc = api.portal.get_tool(name="portal_catalog") - brains = pc() - tot = len(brains) - i = 0 - for brain in brains: - i += 1 - if i % 1000 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - item = aq_base(brain.getObject()) - if getattr(item, "blocks", {}): - blocks = deepcopy(item.blocks) - if blocks: - fix_block(blocks, brain.getURL()) - item.blocks = blocks - for schema in iterSchemata(item): - # fix blocks in blocksfields - for name, field in getFields(schema).items(): - if name == "blocks": - blocks = deepcopy(item.blocks) - if blocks: - fix_block(blocks, brain.getURL()) - item.blocks = blocks - elif isinstance(field, BlocksField): - value = deepcopy(field.get(item)) - if not value: - continue - if isinstance(value, str): - if value == "": - setattr( - item, - name, - {"blocks": {}, "blocks_layout": {"items": []}}, - ) - continue - try: - blocks = value.get("blocks", {}) - except AttributeError: - logger.warning( - "[RICHTEXT] - {} (not converted)".format(brain.getURL()) - ) - if blocks: - fix_block(blocks, brain.getURL()) - setattr(item, name, value) - - -def to_3401(context): # noqa: C901 - logger.info("File type can now be added inside a CartellaModulistica") - update_types(context) - - -def to_3500(context): - logger.info("Add new index and reindex UO") - update_catalog(context) - - # remove unused index - catalog = api.portal.get_tool(name="portal_catalog") - if "office_venue" in catalog.indexes(): - catalog.manage_delIndex("office_venue") - - # reindex - brains = api.content.find(portal_type="UnitaOrganizzativa") - tot = len(brains) - logger.info("Found {} UO.".format(tot)) - i = 0 - for brain in brains: - i += 1 - if i % 1000 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - uo = brain.getObject() - uo.reindexObject(idxs=["uo_location", "tipologia_organizzazione"]) - - -def to_3501(context): - logger.info("Reindex UO for new SearchableText fields") - - brains = api.content.find(portal_type="UnitaOrganizzativa") - tot = len(brains) - logger.info("Found {} UO.".format(tot)) - i = 0 - for brain in brains: - i += 1 - if i % 1000 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - uo = brain.getObject() - uo.reindexObject(idxs=["SearchableText"]) - - -def to_3600(context): - logger.info("Enable kitconcept.seo behavior") - types_list = [ - "UnitaOrganizzativa", - "Bando", - "Subsite", - "Venue", - "Persona", - "Event", - "News Item", - "Document", - "Documento", - "Servizio", - "CartellaModulistica", - "Pagina Argomento", - ] - portal_types = api.portal.get_tool(name="portal_types") - for ct_type in types_list: - if "kitconcept.seo" not in portal_types[ct_type].behaviors: - portal_types[ct_type].behaviors += ("kitconcept.seo",) - logger.info("Enabled kitconcept.seo on: {}".format(ct_type)) - - logger.info("Bandi customizations") - update_catalog(context) - api.portal.set_registry_record("default_ente", (), interface=IBandoSettings) - - portal_types = api.portal.get_tool(name="portal_types") - portal_types["Bando Folder Deepening"].allowed_content_types = ( - "Modulo", - "File", - "Link", - ) - portal_types["Bando"].default_view = "view" - portal_types["Bando"].view_methods = ("view",) - - logger.info("Reindex SearchableText") - pc = api.portal.get_tool(name="portal_catalog") - pc.reindexIndex("SearchableText", context.REQUEST) - - logger.info("Reindex Bandi") - i = 0 - brains = api.content.find(portal_type="Bando") - tot = len(brains) - for brain in brains: - i += 1 - if i % 1000 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - bando = brain.getObject() - bando.reindexObject(idxs=["ufficio_responsabile_bando", "Subject_bando"]) - - -def to_3700(context): - logger.info("Set show_modified_default as True") - - api.portal.set_registry_record( - "show_modified_default", True, interface=IDesignPloneSettings - ) - - -def to_3800(context): - logger.info("Fix Venue addable types") - - portal_types = api.portal.get_tool(name="portal_types") - portal_types["Venue"].allowed_content_types = ( - "Folder", - "Image", - "File", - "Link", - ) - - -def to_3900(context): - logger.info("Add new metadata: ruolo") - - brains = api.content.find(portal_type="Persona") - for brain in brains: - persona = brain.getObject() - persona.reindexObject() - - -def to_4000(context): - logger.info("Move ruolo to a choice field") - ruoli = {"it": [], "en": []} - brains = api.content.find(portal_type="Persona") - for brain in brains: - persona = brain.getObject() - ruolo = getattr(persona, "ruolo", "") - lang = brain.language - if ruolo not in ruoli[lang]: - ruoli[lang].append(ruolo) - - if api.portal.get_registry_record( - "ruoli_persona", interface=IDesignPloneSettings, default=None - ): - api.portal.set_registry_record( - "ruoli_persona", json.dumps(ruoli), interface=IDesignPloneSettings - ) - - -def to_4100(context): - logger.info("Add constrainttypes behavior to Document") - - portal_types = api.portal.get_tool(name="portal_types") - document_behaviors = list(portal_types["Document"].behaviors) + [ - "plone.constraintypes" - ] - portal_types["Document"].behaviors = tuple(document_behaviors) - - -def to_4200(context): - logger.info("Add criteria and indexes to Persona") - - update_catalog(context) - update_registry(context) - - brains = api.content.find(portal_type="Persona") - for brain in brains: - persona = brain.getObject() - persona.reindexObject(idxs=["data_conclusione_incarico"]) - - -def to_5000(context): - logger.info("Enable preview_image behavior in all content types") - - portal_types = api.portal.get_tool(name="portal_types") - - for portal_type, fti in portal_types.items(): - behaviors = list(getattr(fti, "behaviors", ())) - if not behaviors: - continue - if portal_type == "Document": - behaviors = [ - x - for x in behaviors - if x not in ["plone.leadimage", "volto.preview_image"] - ] - behaviors.extend(["plone.leadimage", "volto.preview_image"]) - else: - if "plone.leadimage" not in behaviors or "volto.preview_image" in behaviors: - continue - behaviors.insert(behaviors.index("plone.leadimage") + 1, "volto.preview_image") - fti.behaviors = tuple(behaviors) - - logger.info("Move immagine_testata to image") - catalog = api.portal.get_tool("portal_catalog") - i = 0 - brains = catalog() - tot = len(brains) - for brain in brains: - i += 1 - if i % 500 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - obj = brain.getObject() - if "image" in obj.keys(): - api.content.rename(obj=obj["image"], new_id="image-1") - if brain.portal_type == "Document": - immagine_testata = getattr(obj, "immagine_testata", None) - if immagine_testata: - obj.image = immagine_testata - obj.immagine_testata = None - catalog.catalog_object(obj) - - -def to_5001(context): - catalog = api.portal.get_tool("portal_catalog") - i = 0 - brains = catalog(portal_type="Pagina Argomento") - tot = len(brains) - logger.info("Add icona metadata to {}".format(tot)) - for brain in brains: - i += 1 - if i % 500 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - obj = brain.getObject() - catalog.catalog_object(obj) - - -def to_5002(context): - """ - Reindex non-folderish items because there were some metadata not updated - """ - catalog = api.portal.get_tool("portal_catalog") - i = 0 - brains = catalog(is_folderish=False) - tot = len(brains) - for brain in brains: - i += 1 - if i % 500 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - obj = brain.getObject() - catalog.catalog_object(obj) - - -def to_5200(context): - """ - add new behavior for Bando - """ - portal_types = api.portal.get_tool(name="portal_types") - fti = portal_types["Bando"] - behaviors = list(getattr(fti, "behaviors", ())) - if "design.plone.contenttypes.behavior.update_note" not in behaviors: - behaviors.append("design.plone.contenttypes.behavior.update_note") - fti.behaviors = tuple(behaviors) - - -def to_5210(context): - logger.info("Enable preview_image behavior in Bandi content types") - - portal_types = api.portal.get_tool(name="portal_types") - fti = portal_types["Bando"] - behaviors = list(getattr(fti, "behaviors", ())) - if "volto.preview_image" not in behaviors: - behaviors.append("volto.preview_image") - fti.behaviors = tuple(behaviors) - - -def to_5220(context): - """ - Reindex Venues - """ - logger.info("Reindex SearchableText for Venue items.") - catalog = api.portal.get_tool("portal_catalog") - i = 0 - brains = catalog(portal_type="Venue") - tot = len(brains) - for brain in brains: - i += 1 - if i % 500 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - obj = brain.getObject() - obj.reindexObject(idxs=["SearchableText", "object_provides"]) - - -def to_5300(context): - update_profile(context, "plone-difftool") - update_profile(context, "repositorytool") - - portal_types = api.portal.get_tool(name="portal_types") - for portal_type, fti in portal_types.items(): - if portal_type in [ - "CartellaModulistica", - "Documento", - "Link", - "Pagina Argomento", - "Persona", - "Servizio", - "UnitaOrganizzativa", - "Venue", - ]: - behaviors = list(getattr(fti, "behaviors", ())) - if "plone.versioning" not in behaviors: - behaviors.append("plone.versioning") - fti.behaviors = tuple(behaviors) - - -def to_5310(context): - """ - Reindex Bandi - """ - logger.info("Reindex SearchableText for Bandi items.") - catalog = api.portal.get_tool("portal_catalog") - i = 0 - brains = catalog(portal_type="Bando") - tot = len(brains) - for brain in brains: - i += 1 - if i % 500 == 0: - logger.info("Progress: {}/{}".format(i, tot)) - brain.getObject().reindexObject(idxs=["SearchableText"]) - - -def to_5400(context): - logger.info('Remove "volto.blocks" behavior from News Item and Event.') - remove_blocks_behavior(context) - - -def to_5410(context): - - # cleanup Document behaviors - portal_types = api.portal.get_tool(name="portal_types") - behaviors = portal_types["Document"].behaviors - to_remove = [ - "plone.tableofcontents", - ] - portal_types["Document"].behaviors = tuple( - [x for x in behaviors if x not in to_remove] - ) - - -def to_6000(context): - """ """ - logger.info( - "Convert behavior: collective.dexteritytextindexer => plone.textindexer" # noqa - ) - portal_types = api.portal.get_tool(name="portal_types") - for fti in portal_types.values(): - behaviors = [] - for behavior in getattr(fti, "behaviors", ()): - if behavior == "collective.dexteritytextindexer": - behavior = "plone.textindexer" - behaviors.append(behavior) - - fti.behaviors = tuple(behaviors) - - -def to_6010(context): - """ """ - update_types(context) - update_registry(context) - update_catalog(context) - update_rolemap(context) - - -def migrate_pdc_and_incarico(context): - # Cannot test rn, blind coding - update_types(context) - update_registry(context) - update_catalog(context) - update_rolemap(context) - # "field name in original ct": "field name in new ct" - type_mapping = { - "Persona": { - 'PDC': { - "telefono": "phone", - "fax": "fax", - "email": "email", - "pec": "pec", - }, - "Incarico": { - # HOW? Need taxonomies also - # We could do: - # persona.ruolo.title = incarico.title - # persona.items.compensi = incarico.items.compensi? - "ruolo?": "incarico?", - # BlobFile to relation with Documento - "atto_nomina": "atto_nomina", - "data_conclusione_incarico": "data_conclusione_incarico", - "data_insediamento": "data_insediamento", - } - }, - "UnitaOrganizzativa": { - 'PDC': { - "telefono": "phone", - "fax": "fax", - "email": "email", - "pec": "pec", - }, - }, - # TODO: tbc - "Event": { - 'PDC': { - "telefono": "phone", - "fax": "fax", - "email": "email", - "pec": "pec", - }, - }, - # TODO: tbc - "Venue": { - 'PDC': { - "riferimento_telefonico_struttura": "phone", - "riferimento_fax_struttura": "fax", - "riferimento_mail_struttura": "email", - "riferimento_pec_struttura": "pec", - }, - }, - # TODO: tbc - "Servizio": { - # questi non sono presenti sul ct originale - 'PDC': { - "telefono": "phone", - "fax": "fax", - "email": "email", - "pec": "pec", - }, - }, - } - - def createIncaricoAndMigratePersona(portal_type): - # Taxonomies work needs to be completed before, blind coding ahead - if portal_type == 'Persona': - fixed_total = 0 - for brain in api.content.find(portal_type=portal_type): - item = brain.getObject() - atto_nomina = item.atto_nomina - logger.info(f"Fixing Punto di Contatto for '{item.title}'...") # noqa - file_bog = api.content.find(context=item, depth=1, id='atti-nomina') - if not file_bog: - try: - file_bog = api.content.create( - type="Document", id="atti-nomina", title="Atti Nomina", container=item - ) - except Exception: - logger.error("Error", Exception) - - try: - new_atto_nomina = api.content.create( - type="File", - id=atto_nomina.id, - title=atto_nomina.title, - container=item, - **{'file': atto_nomina} - ) - intids = getUtility(IIntIds) - relation = [RelationValue(intids.getId(new_atto_nomina))] - incarico = api.content.create( - type="Incarico", title=item.ruolo.title, container=item - ) - incarico.atto_nomina = relation - item.atto_nomina = None - fixed_total += 1 - logger.info(f"Fixing Punto di Contatto for '{item.title}'...:DONE") # noqa - except Exception: - logger.error("Error", Exception) - logger.info("Updated {} objects".format(fixed_total)) - - pass - - def createPDCandMigrateOldCTs(portal_type): - logger.info(f"Fixing Punto di Contatto for '{portal_type}'...") # noqa - fixed_total = 0 - mapping = None - # mapping = type_mapping[portal_type]["PDC"] - # Reenable mapping to use - if not mapping: - logger.info(f"No need to fix Punto di Contatto for '{portal_type}: DONE") - return - for brain in api.content.find(portal_type=portal_type): - item = brain.getObject() - kwargs = { - "value_punto_contatto": [], - "persona": [] - } - for key, value in mapping.items(): - import pdb; pdb.set_trace() - - if hasattr(item, key): - kwargs["value_punto_contatto"].append({ - 'pdc_type': value, - 'pdc_value': item[key] - }) - - new_pdc = api.content.create( - type='PuntoDiContatto', - title=f"Punto di Contatto {item.id}", - container=item, - **kwargs, - ) - intids = getUtility(IIntIds) - import pdb; pdb.set_trace() - item.contact_info = [RelationValue(intids.getId(new_pdc))] - fixed_total += 1 - - logger.info(f"Fixing Punto di Contatto for '{portal_type}: DONE") - logger.info("Updated {} objects".format(fixed_total)) - - for pt in type_mapping: - logger.info("Migrating existing CTs for use with new Incarico and PDC Content Types") - createPDCandMigrateOldCTs(pt) - createIncaricoAndMigratePersona(pt) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f2ff3233..39c0d06c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -2,7 +2,7 @@ # See https://pre-commit.com/hooks.html for more hooks default_language_version: - python: python3.8 + python: python3.9 default_stages: [commit, push] @@ -17,11 +17,11 @@ repos: rev: 22.6.0 hooks: - id: black - args: ["--line-length=88", "--check", "--diff", "--force-exclude=migrations", "src/"] -# args: ["--line-length=88", "--force-exclude=migrations", "src/"] +# args: ["--line-length=88", "--check", "--diff", "--force-exclude=migrations", "src/"] + args: ["--line-length=88", "--force-exclude=migrations", "src/"] types: [python] entry: black - - repo: https://gitlab.com/pycqa/flake8 + - repo: https://github.com/PyCQA/flake8.git rev: "3.9.2" hooks: - id: flake8 diff --git a/src/design/plone/contenttypes/behaviors/contatti.py b/src/design/plone/contenttypes/behaviors/contatti.py index 2666bb32..84cde3d1 100644 --- a/src/design/plone/contenttypes/behaviors/contatti.py +++ b/src/design/plone/contenttypes/behaviors/contatti.py @@ -1,17 +1,18 @@ # -*- coding: utf-8 -*- from collective.venue.interfaces import IVenue from design.plone.contenttypes import _ +from design.plone.contenttypes.interfaces.persona import IPersona +from design.plone.contenttypes.interfaces.servizio import IServizio +from design.plone.contenttypes.interfaces.unita_organizzativa import IUnitaOrganizzativa +from plone.app.z3cform.widget import RelatedItemsFieldWidget +from plone.autoform import directives as form from plone.autoform.interfaces import IFormFieldProvider from plone.supermodel import model from z3c.relationfield.schema import RelationChoice from z3c.relationfield.schema import RelationList from zope.component import adapter -from plone.app.z3cform.widget import RelatedItemsFieldWidget -from plone.autoform import directives as form -from zope.interface import provider, implementer -from design.plone.contenttypes.interfaces.unita_organizzativa import IUnitaOrganizzativa -from design.plone.contenttypes.interfaces.persona import IPersona -from design.plone.contenttypes.interfaces.servizio import IServizio +from zope.interface import implementer +from zope.interface import provider @provider(IFormFieldProvider) diff --git a/src/design/plone/contenttypes/behaviors/luogo.py b/src/design/plone/contenttypes/behaviors/luogo.py index aa11f157..753bdfd0 100644 --- a/src/design/plone/contenttypes/behaviors/luogo.py +++ b/src/design/plone/contenttypes/behaviors/luogo.py @@ -142,7 +142,8 @@ class ILuogo(model.Schema): ) model.fieldset( - "categorization", fields=["identificativo_mibac"], + "categorization", + fields=["identificativo_mibac"], ) model.fieldset( diff --git a/src/design/plone/contenttypes/content/incarico.py b/src/design/plone/contenttypes/content/incarico.py index 3c536b06..b4b89392 100644 --- a/src/design/plone/contenttypes/content/incarico.py +++ b/src/design/plone/contenttypes/content/incarico.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- +from design.plone.contenttypes.interfaces.incarico import IIncarico from plone.dexterity.content import Container from zope.interface import implementer -from design.plone.contenttypes.interfaces.incarico import IIncarico @implementer(IIncarico) diff --git a/src/design/plone/contenttypes/content/punto_di_contatto.py b/src/design/plone/contenttypes/content/punto_di_contatto.py index 1bbdaf3c..ada9a476 100644 --- a/src/design/plone/contenttypes/content/punto_di_contatto.py +++ b/src/design/plone/contenttypes/content/punto_di_contatto.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- +from design.plone.contenttypes.interfaces.punto_di_contatto import IPuntoDiContatto from plone.dexterity.content import Container from zope.interface import implementer -from design.plone.contenttypes.interfaces.punto_di_contatto import IPuntoDiContatto @implementer(IPuntoDiContatto) diff --git a/src/design/plone/contenttypes/events/incarico.py b/src/design/plone/contenttypes/events/incarico.py index 4e52ae22..08269022 100644 --- a/src/design/plone/contenttypes/events/incarico.py +++ b/src/design/plone/contenttypes/events/incarico.py @@ -15,14 +15,12 @@ def incaricoCreateHandler(incarico, event): """ FOLDERS = [ - {"id": "compensi-file", "title": "Compensi", "contains": ("File",)}, { "id": "importi-di-viaggio-e-o-servizi", "title": "Importi di viaggio e/o servizi", "contains": ("File",), }, - ] for folder in FOLDERS: if folder["id"] in incarico: diff --git a/src/design/plone/contenttypes/interfaces/incarico.py b/src/design/plone/contenttypes/interfaces/incarico.py index dbf3d3ea..5215411f 100644 --- a/src/design/plone/contenttypes/interfaces/incarico.py +++ b/src/design/plone/contenttypes/interfaces/incarico.py @@ -39,7 +39,6 @@ class IIncarico(model.Schema, IDesignPloneContentType): required=False, ) - unita_organizzativa = RelationList( title=_( "unita_organizzativa_incarico_label", diff --git a/src/design/plone/contenttypes/interfaces/punto_di_contatto.py b/src/design/plone/contenttypes/interfaces/punto_di_contatto.py index deb10582..a25f2c99 100644 --- a/src/design/plone/contenttypes/interfaces/punto_di_contatto.py +++ b/src/design/plone/contenttypes/interfaces/punto_di_contatto.py @@ -1,14 +1,11 @@ # -*- coding: utf-8 -*- +from collective.z3cform.datagridfield.datagridfield import DataGridFieldFactory +from collective.z3cform.datagridfield.row import DictRow from design.plone.contenttypes import _ from design.plone.contenttypes.interfaces import IDesignPloneContentType -from plone.app.z3cform.widget import RelatedItemsFieldWidget from plone.autoform import directives as form from plone.supermodel import model -from z3c.relationfield.schema import RelationChoice -from z3c.relationfield.schema import RelationList from zope import schema -from collective.z3cform.datagridfield.datagridfield import DataGridFieldFactory -from collective.z3cform.datagridfield.row import DictRow class IPDCValueSchema(model.Schema): @@ -43,7 +40,7 @@ class IPuntoDiContatto(model.Schema, IDesignPloneContentType): description=_( "value_punto_contatto_help", default="Il valore del punto di contatto: il numero compreso di prefisso " - "internazionale (se telefono), l'account (se social network), l'URL (se sito o pagina web), l'indirizzo email (se email).", + "internazionale (se telefono), l'account (se social network), l'URL (se sito o pagina web), l'indirizzo email (se email).", # noqa ), required=True, ) @@ -52,4 +49,3 @@ class IPuntoDiContatto(model.Schema, IDesignPloneContentType): "value_punto_contatto", DataGridFieldFactory, ) - diff --git a/src/design/plone/contenttypes/interfaces/servizio.py b/src/design/plone/contenttypes/interfaces/servizio.py index 2eddd3d2..155406b9 100644 --- a/src/design/plone/contenttypes/interfaces/servizio.py +++ b/src/design/plone/contenttypes/interfaces/servizio.py @@ -5,10 +5,10 @@ from plone.app.dexterity import textindexer from plone.app.z3cform.widget import RelatedItemsFieldWidget from plone.autoform import directives as form +from plone.namedfile import field from plone.supermodel import model from z3c.relationfield.schema import RelationChoice from z3c.relationfield.schema import RelationList -from plone.namedfile import field from zope import schema @@ -32,7 +32,7 @@ class IServizio(model.Schema, IDesignPloneContentType): required=False, description=_( "stato_servizio_help", - default="Indica se il servizio è effettivamente fruibile; spuntare se non è fruibile.", + default="Indica se il servizio è effettivamente fruibile; spuntare se non è fruibile.", # noqa ), ) @@ -44,7 +44,7 @@ class IServizio(model.Schema, IDesignPloneContentType): required=False, description=_( "motivo_stato_servizio_help", - default="Descrizione del motivo per cui il servizio non è attivo. È obbligatorio se il campo precedente è spuntato.", + default="Descrizione del motivo per cui il servizio non è attivo. È obbligatorio se il campo precedente è spuntato.", # noqa ), ) diff --git a/src/design/plone/contenttypes/profiles/default/rolemap.xml b/src/design/plone/contenttypes/profiles/default/rolemap.xml index f11c831f..6c7eebca 100644 --- a/src/design/plone/contenttypes/profiles/default/rolemap.xml +++ b/src/design/plone/contenttypes/profiles/default/rolemap.xml @@ -147,17 +147,21 @@ - - - - - - - - - - - + + + + + + + + + + + diff --git a/src/design/plone/contenttypes/profiles/default/types.xml b/src/design/plone/contenttypes/profiles/default/types.xml index 8f0f1622..6fe44d1c 100644 --- a/src/design/plone/contenttypes/profiles/default/types.xml +++ b/src/design/plone/contenttypes/profiles/default/types.xml @@ -3,18 +3,46 @@ name="portal_types" > Controls the available contenttypes in your portal - - - - - - - - - - - - - - + + + + + + + + + + + + + + diff --git a/src/design/plone/contenttypes/profiles/default/types/Event.xml b/src/design/plone/contenttypes/profiles/default/types/Event.xml index cd3acfc0..cc06954f 100644 --- a/src/design/plone/contenttypes/profiles/default/types/Event.xml +++ b/src/design/plone/contenttypes/profiles/default/types/Event.xml @@ -25,7 +25,7 @@ - + diff --git a/src/design/plone/contenttypes/profiles/default/types/Incarico.xml b/src/design/plone/contenttypes/profiles/default/types/Incarico.xml index 10862784..91d6bc85 100644 --- a/src/design/plone/contenttypes/profiles/default/types/Incarico.xml +++ b/src/design/plone/contenttypes/profiles/default/types/Incarico.xml @@ -1,27 +1,28 @@ - + + meta_type="Dexterity FTI" + name="Incarico" + i18n:domain="design.plone.contenttypes" +> - Incarico - + Incarico + False Incarico - - + + True False - @@ -29,30 +30,32 @@ design.plone.contenttypes.AddIncarico design.plone.contenttypes.content.incarico.Incarico - - + + design.plone.contenttypes.interfaces.incarico.IIncarico - + - - - - - - + + + + + + - - + + - - - - - + + + + + @@ -61,47 +64,43 @@ False view - + - - - - - - + + - - + + diff --git a/src/design/plone/contenttypes/profiles/default/types/Persona.xml b/src/design/plone/contenttypes/profiles/default/types/Persona.xml index 9578a7df..745c0def 100644 --- a/src/design/plone/contenttypes/profiles/default/types/Persona.xml +++ b/src/design/plone/contenttypes/profiles/default/types/Persona.xml @@ -51,12 +51,12 @@ - - - - - - + + + + + + diff --git a/src/design/plone/contenttypes/profiles/default/types/PuntoDiContatto.xml b/src/design/plone/contenttypes/profiles/default/types/PuntoDiContatto.xml index cfe4b273..24facf25 100644 --- a/src/design/plone/contenttypes/profiles/default/types/PuntoDiContatto.xml +++ b/src/design/plone/contenttypes/profiles/default/types/PuntoDiContatto.xml @@ -1,27 +1,28 @@ - + + meta_type="Dexterity FTI" + name="PuntoDiContatto" + i18n:domain="design.plone.contenttypes" +> - Punto di Contatto - + Punto di Contatto + False PuntoDiContatto - - + + True False - @@ -29,29 +30,31 @@ design.plone.contenttypes.AddPuntoDiContatto design.plone.contenttypes.content.punto_di_contatto.PuntoDiContatto - - + + design.plone.contenttypes.interfaces.punto_di_contatto.IPuntoDiContatto - + - - - - - - + + + + + + - - + + - - - - + + + + @@ -60,47 +63,43 @@ False view - + - - - - - - + + - - + + diff --git a/src/design/plone/contenttypes/profiles/default/types/Servizio.xml b/src/design/plone/contenttypes/profiles/default/types/Servizio.xml index 9b99a9dd..65e7b976 100644 --- a/src/design/plone/contenttypes/profiles/default/types/Servizio.xml +++ b/src/design/plone/contenttypes/profiles/default/types/Servizio.xml @@ -50,15 +50,17 @@ - - - - - - - - - + + + + + + + + + diff --git a/src/design/plone/contenttypes/restapi/deserializers/servizio.py b/src/design/plone/contenttypes/restapi/deserializers/servizio.py index d316af07..89837279 100644 --- a/src/design/plone/contenttypes/restapi/deserializers/servizio.py +++ b/src/design/plone/contenttypes/restapi/deserializers/servizio.py @@ -1,14 +1,14 @@ # -*- coding: utf-8 -*- from design.plone.contenttypes.interfaces.servizio import IServizio +from plone.restapi.behaviors import IBlocks from plone.restapi.deserializer import json_body +from plone.restapi.deserializer.dxcontent import DeserializeFromJson +from plone.restapi.indexers import SearchableText_blocks from plone.restapi.interfaces import IDeserializeFromJson -from zope.interface import implementer +from zExceptions import BadRequest from zope.component import adapter +from zope.interface import implementer from zope.interface import Interface -from plone.restapi.deserializer.dxcontent import DeserializeFromJson -from zExceptions import BadRequest -from plone.restapi.behaviors import IBlocks -from plone.restapi.indexers import SearchableText_blocks TITLE_MAX_LEN = 160 @@ -76,7 +76,7 @@ def __call__( elif len(title) > TITLE_MAX_LEN: errors.append( new_error( - "Il titolo può avere una lunghezza di massimo {} caratteri".format( + "Il titolo può avere una lunghezza di massimo {} caratteri".format( # noqa TITLE_MAX_LEN ) ) @@ -88,7 +88,7 @@ def __call__( elif len(description) > DESCRIPTION_MAX_LEN: errors.append( new_error( - "La descrizione del servizio deve avere una lunghezza di massimo {} caratteri".format( + "La descrizione del servizio deve avere una lunghezza di massimo {} caratteri".format( # noqa DESCRIPTION_MAX_LEN ) ) @@ -107,7 +107,7 @@ def __call__( if title and len(title) > TITLE_MAX_LEN: errors.append( new_error( - "Il titolo può avere una lunghezza di massimo {} caratteri".format( + "Il titolo può avere una lunghezza di massimo {} caratteri".format( # noqa TITLE_MAX_LEN ) ) @@ -118,7 +118,7 @@ def __call__( if description and len(description) > DESCRIPTION_MAX_LEN: errors.append( new_error( - "La descrizione del servizio deve avere una lunghezza di massimo {} caratteri".format( + "La descrizione del servizio deve avere una lunghezza di massimo {} caratteri".format( # noqa DESCRIPTION_MAX_LEN ) ) diff --git a/src/design/plone/contenttypes/restapi/deserializers/venue.py b/src/design/plone/contenttypes/restapi/deserializers/venue.py index e153f63e..f46ebead 100644 --- a/src/design/plone/contenttypes/restapi/deserializers/venue.py +++ b/src/design/plone/contenttypes/restapi/deserializers/venue.py @@ -1,14 +1,14 @@ # -*- coding: utf-8 -*- from collective.venue.interfaces import IVenue +from plone.restapi.behaviors import IBlocks from plone.restapi.deserializer import json_body +from plone.restapi.deserializer.dxcontent import DeserializeFromJson +from plone.restapi.indexers import SearchableText_blocks from plone.restapi.interfaces import IDeserializeFromJson -from zope.interface import implementer +from zExceptions import BadRequest from zope.component import adapter +from zope.interface import implementer from zope.interface import Interface -from plone.restapi.deserializer.dxcontent import DeserializeFromJson -from zExceptions import BadRequest -from plone.restapi.behaviors import IBlocks -from plone.restapi.indexers import SearchableText_blocks TITLE_MAX_LEN = 160 @@ -71,7 +71,7 @@ def __call__( elif len(title) > TITLE_MAX_LEN: errors.append( new_error( - "Il titolo può avere una lunghezza di massimo {} caratteri".format( + "Il titolo può avere una lunghezza di massimo {} caratteri".format( # noqa TITLE_MAX_LEN ) ) @@ -83,7 +83,7 @@ def __call__( elif len(description) > DESCRIPTION_MAX_LEN: errors.append( new_error( - "La descrizione del luogo deve avere una lunghezza di massimo {} caratteri".format( + "La descrizione del luogo deve avere una lunghezza di massimo {} caratteri".format( # noqa DESCRIPTION_MAX_LEN ) ) @@ -112,7 +112,7 @@ def __call__( if title and len(title) > TITLE_MAX_LEN: errors.append( new_error( - "Il titolo può avere una lunghezza di massimo {} caratteri".format( + "Il titolo può avere una lunghezza di massimo {} caratteri".format( # noqa TITLE_MAX_LEN ) ) @@ -123,7 +123,7 @@ def __call__( if description and len(description) > DESCRIPTION_MAX_LEN: errors.append( new_error( - "La descrizione del luogo deve avere una lunghezza di massimo {} caratteri".format( + "La descrizione del luogo deve avere una lunghezza di massimo {} caratteri".format( # noqa DESCRIPTION_MAX_LEN ) ) @@ -142,9 +142,10 @@ def __call__( if field in data and not text_in_block(data.get(field)): errors.append(new_error("Il campo {} è obbligatorio".format(field))) - # Se siamo nella patch siamo in modifica. Se siamo in modifica e siamo su un - # sito che ha avuto upgrade alla versione pnrr può essere che dei campi obbligatori - # un tempo non lo fossero e quindi arriviamo fino a qui + # Se siamo nella patch siamo in modifica. Se siamo in modifica e siamo + # su un sito che ha avuto upgrade alla versione pnrr può essere che dei + # campi obbligatori #un tempo non lo fossero e quindi arriviamo fino a + # qui if field not in data and not text_in_block( getattr(self.context, field) ): diff --git a/src/design/plone/contenttypes/restapi/serializers/summary.py b/src/design/plone/contenttypes/restapi/serializers/summary.py index 7d2e7304..18873aad 100644 --- a/src/design/plone/contenttypes/restapi/serializers/summary.py +++ b/src/design/plone/contenttypes/restapi/serializers/summary.py @@ -119,4 +119,4 @@ def get_incarichi(self): except AttributeError: obj = self.context - return ', '.join([x.to_object.title for x in obj.incarichi]) + return ", ".join([x.to_object.title for x in obj.incarichi]) diff --git a/src/design/plone/contenttypes/restapi/serializers/venue.py b/src/design/plone/contenttypes/restapi/serializers/venue.py index ff41fc19..51d98917 100644 --- a/src/design/plone/contenttypes/restapi/serializers/venue.py +++ b/src/design/plone/contenttypes/restapi/serializers/venue.py @@ -48,7 +48,10 @@ def get_venue_offices(self, result): offices = [] for attr in ["sede", "sedi_secondarie"]: relations = catalog.findRelations( - dict(to_id=intids.getId(aq_inner(self.context)), from_attribute=attr,) + dict( + to_id=intids.getId(aq_inner(self.context)), + from_attribute=attr, + ) ) for rel in relations: diff --git a/src/design/plone/contenttypes/restapi/services/types/get.py b/src/design/plone/contenttypes/restapi/services/types/get.py index b78bb4d5..8d1c66c9 100644 --- a/src/design/plone/contenttypes/restapi/services/types/get.py +++ b/src/design/plone/contenttypes/restapi/services/types/get.py @@ -51,7 +51,11 @@ class FieldsetsMismatchError(Exception): "settings", "ownership", ], - "Incarico": ["default", "informazioni_compensi", "date_e_informazioni",], + "Incarico": [ + "default", + "informazioni_compensi", + "date_e_informazioni", + ], "News Item": [ "default", "dates", @@ -89,7 +93,9 @@ class FieldsetsMismatchError(Exception): "ownership", "settings", ], - "PuntoDiContatto": ["default",], + "PuntoDiContatto": [ + "default", + ], "Servizio": [ "default", "cose", diff --git a/src/design/plone/contenttypes/restapi/types/adapters.py b/src/design/plone/contenttypes/restapi/types/adapters.py index 11c712d2..a0fadc9d 100644 --- a/src/design/plone/contenttypes/restapi/types/adapters.py +++ b/src/design/plone/contenttypes/restapi/types/adapters.py @@ -1,20 +1,21 @@ # -*- coding: utf-8 -*- +from collective.z3cform.datagridfield.interfaces import IRow from design.plone.contenttypes import _ +from design.plone.contenttypes.interfaces import IDesignPloneContenttypesLayer +from plone.restapi.types.adapters import ListJsonSchemaProvider from plone.restapi.types.adapters import ObjectJsonSchemaProvider from plone.restapi.types.interfaces import IJsonSchemaProvider +from plone.restapi.types.utils import get_fieldsets +from plone.restapi.types.utils import get_jsonschema_properties +from plone.restapi.types.utils import iter_fields from zope.component import adapter from zope.component import getUtility from zope.i18n import translate from zope.interface import implementer from zope.interface import Interface -from zope.schema.interfaces import IField, IVocabularyFactory -from collective.z3cform.datagridfield.interfaces import IRow -from plone.restapi.types.adapters import ListJsonSchemaProvider -from plone.restapi.types.utils import get_fieldsets -from plone.restapi.types.utils import get_jsonschema_properties -from plone.restapi.types.utils import iter_fields +from zope.schema.interfaces import IField from zope.schema.interfaces import IList -from design.plone.contenttypes.interfaces import IDesignPloneContenttypesLayer +from zope.schema.interfaces import IVocabularyFactory @adapter(IField, Interface, Interface) diff --git a/src/design/plone/contenttypes/setuphandlers.py b/src/design/plone/contenttypes/setuphandlers.py index 7f97ea44..76e1e675 100644 --- a/src/design/plone/contenttypes/setuphandlers.py +++ b/src/design/plone/contenttypes/setuphandlers.py @@ -49,7 +49,9 @@ def post_install(context): def post_install_taxonomy(context): - context.runImportStepFromProfile("profile-design.plone.contenttypes:default", "typeinfo", True) + context.runImportStepFromProfile( + "profile-design.plone.contenttypes:default", "typeinfo", True + ) def uninstall(context): diff --git a/src/design/plone/contenttypes/upgrades/upgrades.py b/src/design/plone/contenttypes/upgrades/upgrades.py index adccd8bf..32d965ec 100644 --- a/src/design/plone/contenttypes/upgrades/upgrades.py +++ b/src/design/plone/contenttypes/upgrades/upgrades.py @@ -3,8 +3,8 @@ from collective.volto.blocksfield.field import BlocksField from copy import deepcopy from design.plone.contenttypes.controlpanels.settings import IDesignPloneSettings -from design.plone.contenttypes.upgrades.draftjs_converter import to_draftjs from design.plone.contenttypes.setuphandlers import remove_blocks_behavior +from design.plone.contenttypes.upgrades.draftjs_converter import to_draftjs from plone import api from plone.app.textfield.value import RichTextValue from plone.app.upgrade.utils import installOrReinstallProduct @@ -991,7 +991,7 @@ def migrate_pdc_and_incarico(context): # "field name in original ct": "field name in new ct" type_mapping = { "Persona": { - 'PDC': { + "PDC": { "telefono": "phone", "fax": "fax", "email": "email", @@ -1007,10 +1007,10 @@ def migrate_pdc_and_incarico(context): "atto_nomina": "atto_nomina", "data_conclusione_incarico": "data_conclusione_incarico", "data_insediamento": "data_insediamento", - } + }, }, "UnitaOrganizzativa": { - 'PDC': { + "PDC": { "telefono": "phone", "fax": "fax", "email": "email", @@ -1019,7 +1019,7 @@ def migrate_pdc_and_incarico(context): }, # TODO: tbc "Event": { - 'PDC': { + "PDC": { "telefono": "phone", "fax": "fax", "email": "email", @@ -1028,7 +1028,7 @@ def migrate_pdc_and_incarico(context): }, # TODO: tbc "Venue": { - 'PDC': { + "PDC": { "riferimento_telefonico_struttura": "phone", "riferimento_fax_struttura": "fax", "riferimento_mail_struttura": "email", @@ -1038,7 +1038,7 @@ def migrate_pdc_and_incarico(context): # TODO: tbc "Servizio": { # questi non sono presenti sul ct originale - 'PDC': { + "PDC": { "telefono": "phone", "fax": "fax", "email": "email", @@ -1049,17 +1049,20 @@ def migrate_pdc_and_incarico(context): def createIncaricoAndMigratePersona(portal_type): # Taxonomies work needs to be completed before, blind coding ahead - if portal_type == 'Persona': + if portal_type == "Persona": fixed_total = 0 for brain in api.content.find(portal_type=portal_type): item = brain.getObject() atto_nomina = item.atto_nomina - logger.info(f"Fixing Punto di Contatto for '{item.title}'...") # noqa - file_bog = api.content.find(context=item, depth=1, id='atti-nomina') + logger.info(f"Fixing Punto di Contatto for '{item.title}'...") # noqa + file_bog = api.content.find(context=item, depth=1, id="atti-nomina") if not file_bog: try: file_bog = api.content.create( - type="Document", id="atti-nomina", title="Atti Nomina", container=item + type="Document", + id="atti-nomina", + title="Atti Nomina", + container=item, ) except Exception: logger.error("Error", Exception) @@ -1070,7 +1073,7 @@ def createIncaricoAndMigratePersona(portal_type): id=atto_nomina.id, title=atto_nomina.title, container=item, - **{'file': atto_nomina} + **{"file": atto_nomina}, ) intids = getUtility(IIntIds) relation = [RelationValue(intids.getId(new_atto_nomina))] @@ -1080,7 +1083,9 @@ def createIncaricoAndMigratePersona(portal_type): incarico.atto_nomina = relation item.atto_nomina = None fixed_total += 1 - logger.info(f"Fixing Punto di Contatto for '{item.title}'...:DONE") # noqa + logger.info( + f"Fixing Punto di Contatto for '{item.title}'...:DONE" + ) # noqa except Exception: logger.error("Error", Exception) logger.info("Updated {} objects".format(fixed_total)) @@ -1088,7 +1093,7 @@ def createIncaricoAndMigratePersona(portal_type): pass def createPDCandMigrateOldCTs(portal_type): - logger.info(f"Fixing Punto di Contatto for '{portal_type}'...") # noqa + logger.info(f"Fixing Punto di Contatto for '{portal_type}'...") # noqa fixed_total = 0 mapping = None # mapping = type_mapping[portal_type]["PDC"] @@ -1098,27 +1103,27 @@ def createPDCandMigrateOldCTs(portal_type): return for brain in api.content.find(portal_type=portal_type): item = brain.getObject() - kwargs = { - "value_punto_contatto": [], - "persona": [] - } + kwargs = {"value_punto_contatto": [], "persona": []} for key, value in mapping.items(): - import pdb; pdb.set_trace() + # import pdb + + # pdb.set_trace() if hasattr(item, key): - kwargs["value_punto_contatto"].append({ - 'pdc_type': value, - 'pdc_value': item[key] - }) + kwargs["value_punto_contatto"].append( + {"pdc_type": value, "pdc_value": item[key]} + ) new_pdc = api.content.create( - type='PuntoDiContatto', + type="PuntoDiContatto", title=f"Punto di Contatto {item.id}", container=item, **kwargs, ) intids = getUtility(IIntIds) - import pdb; pdb.set_trace() + # import pdb + + # pdb.set_trace() item.contact_info = [RelationValue(intids.getId(new_pdc))] fixed_total += 1 @@ -1126,6 +1131,8 @@ def createPDCandMigrateOldCTs(portal_type): logger.info("Updated {} objects".format(fixed_total)) for pt in type_mapping: - logger.info("Migrating existing CTs for use with new Incarico and PDC Content Types") + logger.info( + "Migrating existing CTs for use with new Incarico and PDC Content Types" + ) createPDCandMigrateOldCTs(pt) createIncaricoAndMigratePersona(pt) From 1eddacbf8687cc0d20abcaf56c11f4f69fa4f403 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Mon, 9 Jan 2023 12:16:29 +0100 Subject: [PATCH 039/487] update .pre-commit-config.yaml --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 39c0d06c..f4916d1e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -17,8 +17,8 @@ repos: rev: 22.6.0 hooks: - id: black -# args: ["--line-length=88", "--check", "--diff", "--force-exclude=migrations", "src/"] - args: ["--line-length=88", "--force-exclude=migrations", "src/"] + args: ["--line-length=88", "--check", "--diff", "--force-exclude=migrations", "src/"] +# args: ["--line-length=88", "--force-exclude=migrations", "src/"] types: [python] entry: black - repo: https://github.com/PyCQA/flake8.git From 28bbeece23eada58a20fae008aa0e3581883cd0b Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Mon, 9 Jan 2023 13:03:44 +0100 Subject: [PATCH 040/487] update with news constrain --- .pre-commit-config.yaml | 4 +-- .../plone/contenttypes/behaviors/argomenti.py | 29 +++++++++++++++++++ .../contenttypes/behaviors/configure.zcml | 9 ++++++ .../behaviors/news_additional_fields.py | 4 +-- .../contenttypes/patches/baseserializer.py | 7 ++++- .../profiles/default/types/News_Item.xml | 2 +- .../restapi/deserializers/configure.zcml | 1 + .../restapi/serializers/dxcontent.py | 7 ++++- .../restapi/services/types/get.py | 14 +++++++++ 9 files changed, 70 insertions(+), 7 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f4916d1e..39c0d06c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -17,8 +17,8 @@ repos: rev: 22.6.0 hooks: - id: black - args: ["--line-length=88", "--check", "--diff", "--force-exclude=migrations", "src/"] -# args: ["--line-length=88", "--force-exclude=migrations", "src/"] +# args: ["--line-length=88", "--check", "--diff", "--force-exclude=migrations", "src/"] + args: ["--line-length=88", "--force-exclude=migrations", "src/"] types: [python] entry: black - repo: https://github.com/PyCQA/flake8.git diff --git a/src/design/plone/contenttypes/behaviors/argomenti.py b/src/design/plone/contenttypes/behaviors/argomenti.py index b3ae91e6..a561ba63 100644 --- a/src/design/plone/contenttypes/behaviors/argomenti.py +++ b/src/design/plone/contenttypes/behaviors/argomenti.py @@ -80,6 +80,26 @@ class IArgomenti(IArgomentiSchema): form.order_after(correlato_in_evidenza="IRelatedItems.relatedItems") +@provider(IFormFieldProvider) +class IArgomentiNews(IArgomentiSchema): + """ """ + + tassonomia_argomenti = RelationList( + title=_("tassonomia_argomenti_label", default="Argomenti"), + description=_( + "tassonomia_argomenti_help", + default="Seleziona una lista di argomenti d'interesse per questo" + " contenuto.", + ), + value_type=RelationChoice( + title=_("Argomenti correlati"), + vocabulary="plone.app.vocabularies.Catalog", + ), + required=True, + default=[], + ) + + @provider(IFormFieldProvider) class IArgomentiServizio(IArgomentiSchema): @@ -186,3 +206,12 @@ class ArgomentiServizio(object): def __init__(self, context): self.context = context + + +@implementer(IArgomentiNews) +@adapter(IServizio) +class ArgomentiNews(object): + """""" + + def __init__(self, context): + self.context = context diff --git a/src/design/plone/contenttypes/behaviors/configure.zcml b/src/design/plone/contenttypes/behaviors/configure.zcml index a2870264..375689bf 100644 --- a/src/design/plone/contenttypes/behaviors/configure.zcml +++ b/src/design/plone/contenttypes/behaviors/configure.zcml @@ -47,6 +47,15 @@ for="plone.dexterity.interfaces.IDexterityContent" marker=".argomenti.IArgomenti" /> + - + diff --git a/src/design/plone/contenttypes/restapi/deserializers/configure.zcml b/src/design/plone/contenttypes/restapi/deserializers/configure.zcml index 3eff9013..4c385e98 100644 --- a/src/design/plone/contenttypes/restapi/deserializers/configure.zcml +++ b/src/design/plone/contenttypes/restapi/deserializers/configure.zcml @@ -9,4 +9,5 @@ + diff --git a/src/design/plone/contenttypes/restapi/serializers/dxcontent.py b/src/design/plone/contenttypes/restapi/serializers/dxcontent.py index f7ae2be1..747954c1 100644 --- a/src/design/plone/contenttypes/restapi/serializers/dxcontent.py +++ b/src/design/plone/contenttypes/restapi/serializers/dxcontent.py @@ -40,7 +40,12 @@ def __call__(self, version=None, include_items=True): result["@id"] = self.context.absolute_url() ttool = api.portal.get_tool("portal_types") if self.context.portal_type == "News Item": - result["design_italia_meta_type"] = self.context.tipologia_notizia + try: + tipologia_news = self.context.taxonomy_tipologia_notizia + except AttributeError: + # fallback if we don't have c.taxonomy configured yet + tipologia_news = self.context.tipologia_notizia + result["design_italia_meta_type"] = tipologia_news else: result["design_italia_meta_type"] = translate( ttool[self.context.portal_type].Title(), context=self.request diff --git a/src/design/plone/contenttypes/restapi/services/types/get.py b/src/design/plone/contenttypes/restapi/services/types/get.py index 64d625e1..a86e1efa 100644 --- a/src/design/plone/contenttypes/restapi/services/types/get.py +++ b/src/design/plone/contenttypes/restapi/services/types/get.py @@ -251,6 +251,18 @@ def customize_uo_schema(self, result): fieldset["fields"].insert(0, field) return result + def customize_news_schema(self, result): + result.get("required").append("description") + if self.context.portal_type == "News Item": + # we are in a news and not in container + review_state = self.context.portal_workflow.getInfoFor( + self.context, "review_state" + ) + if review_state == "published": + result.get("required").append("effective") + + return result + def reply(self): result = super(TypesGet, self).reply() @@ -273,6 +285,8 @@ def reply(self): result = self.customize_servizio_schema(result) if pt == "UnitaOrganizzativa": result = self.customize_uo_schema(result) + if pt == "News Item": + result = self.customize_news_schema(result) result = self.customize_versioning_fields_fieldset(result) return result From e163560c85d1ccd4aee7fe44c62735fb7c9e4bfc Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Mon, 9 Jan 2023 13:03:57 +0100 Subject: [PATCH 041/487] update with news constrain --- .../restapi/deserializers/news.py | 141 ++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 src/design/plone/contenttypes/restapi/deserializers/news.py diff --git a/src/design/plone/contenttypes/restapi/deserializers/news.py b/src/design/plone/contenttypes/restapi/deserializers/news.py new file mode 100644 index 00000000..7ad890d9 --- /dev/null +++ b/src/design/plone/contenttypes/restapi/deserializers/news.py @@ -0,0 +1,141 @@ +# -*- coding: utf-8 -*- +from plone.app.contenttypes.interfaces import INewsItem +from plone.restapi.behaviors import IBlocks +from plone.restapi.deserializer import json_body +from plone.restapi.deserializer.dxcontent import DeserializeFromJson +from plone.restapi.indexers import SearchableText_blocks +from plone.restapi.interfaces import IDeserializeFromJson +from zExceptions import BadRequest +from zope.component import adapter +from zope.interface import implementer +from zope.interface import Interface + + +TITLE_MAX_LEN = 160 +DESCRIPTION_MAX_LEN = 160 +EMPTY_BLOCK_MARKER = {"@type": "text"} +MANDATORY_RICH_TEXT_FIELDS = [ + "descrizione_estesa", +] + + +def new_error(message): + return {"error": "ValidationError", "message": message} + + +def text_in_block(blocks): + @implementer(IBlocks) + class FakeObject(object): + """ + We use a fake object to use SearchableText Indexer + """ + + def Subject(self): + return "" + + def __init__(self, blocks, blocks_layout): + self.blocks = blocks + self.blocks_layout = blocks_layout + self.id = "" + self.title = "" + self.description = "" + + if not blocks: + return None + + fakeObj = FakeObject(blocks.get("blocks", ""), blocks.get("blocks_layout", "")) + return SearchableText_blocks(fakeObj)() + + +@implementer(IDeserializeFromJson) +@adapter(INewsItem, Interface) +class DeserializeNewsFromJson(DeserializeFromJson): + def __call__( + self, validate_all=False, data=None, create=False + ): # noqa: ignore=C901 + + if data is None: + data = json_body(self.request) + + method = self.request.get("method") + is_post = method == "POST" + is_patch = method == "PATCH" + errors = [] + + title = data.get("title") + description = data.get("description") + + if is_post: + # Title validation + if not title: + errors.append(new_error("Il titolo del servizio è obbligatorio")) + elif len(title) > TITLE_MAX_LEN: + errors.append( + new_error( + "Il titolo può avere una lunghezza di massimo {} caratteri".format( # noqa + TITLE_MAX_LEN + ) + ) + ) + + # description validation + if not description: + errors.append(new_error("La descrizione del servizio è obbligatorio")) + elif len(description) > DESCRIPTION_MAX_LEN: + errors.append( + new_error( + "La descrizione del servizio deve avere una lunghezza di massimo {} caratteri".format( # noqa + DESCRIPTION_MAX_LEN + ) + ) + ) + + for field in MANDATORY_RICH_TEXT_FIELDS: + if field not in data: + errors.append(new_error("Il campo {} è obbligatorio".format(field))) + elif field in data and not text_in_block(data.get(field)): + errors.append(new_error("Il campo {} è obbligatorio".format(field))) + + if is_patch: + # Title validation + if "title" in data and not title: + errors.append(new_error("Il titolo del servizio è obbligatorio")) + if title and len(title) > TITLE_MAX_LEN: + errors.append( + new_error( + "Il titolo può avere una lunghezza di massimo {} caratteri".format( # noqa + TITLE_MAX_LEN + ) + ) + ) + # description validation + if "description" in data and not description: + errors.append(new_error("La descrizione del servizio è obbligatorio")) + if description and len(description) > DESCRIPTION_MAX_LEN: + errors.append( + new_error( + "La descrizione del servizio deve avere una lunghezza di massimo {} caratteri".format( # noqa + DESCRIPTION_MAX_LEN + ) + ) + ) + if "description" not in data and not self.context.description: + errors.append(new_error("La descrizione del servizio è obbligatorio")) + + for field in MANDATORY_RICH_TEXT_FIELDS: + if field in data and not text_in_block(data.get(field)): + errors.append(new_error("Il campo {} è obbligatorio".format(field))) + # Se siamo nella patch siamo in modifica. Se siamo in modifica e siamo + # su un sito che ha avuto upgrade alla versione pnrr può essere che + # dei campi obbligatori un tempo non lo fossero e quindi arriviamo + # fino a qui + if field not in data and not text_in_block( + getattr(self.context, field) + ): + errors.append(new_error("Il campo {} è obbligatorio".format(field))) + + if errors: + raise BadRequest(errors) + return super(DeserializeNewsFromJson, self).__call__( + validate_all=False, data=data, create=False + ) From efe67c4be64b88b2ab0a295d143796f58a0e4189 Mon Sep 17 00:00:00 2001 From: Martina Bustacchini Date: Mon, 9 Jan 2023 15:35:29 +0100 Subject: [PATCH 042/487] feat: add datagridfield timeline_tempi-scadenze field in servizio, patch serializers and deserializers to use this field in Volto, code cleanup and formatting --- .../plone/contenttypes/interfaces/incarico.py | 1 - .../interfaces/punto_di_contatto.py | 4 - .../plone/contenttypes/interfaces/servizio.py | 75 ++++++++++++++++++- .../restapi/deserializers/configure.zcml | 1 + .../restapi/deserializers/dxfields.py | 34 +++++++++ .../restapi/serializers/configure.zcml | 1 + .../restapi/serializers/dxfields.py | 19 ++++- .../restapi/services/types/get.py | 2 + .../contenttypes/restapi/types/adapters.py | 5 +- .../plone/contenttypes/upgrades/upgrades.py | 2 - 10 files changed, 134 insertions(+), 10 deletions(-) diff --git a/src/design/plone/contenttypes/interfaces/incarico.py b/src/design/plone/contenttypes/interfaces/incarico.py index dbf3d3ea..5215411f 100644 --- a/src/design/plone/contenttypes/interfaces/incarico.py +++ b/src/design/plone/contenttypes/interfaces/incarico.py @@ -39,7 +39,6 @@ class IIncarico(model.Schema, IDesignPloneContentType): required=False, ) - unita_organizzativa = RelationList( title=_( "unita_organizzativa_incarico_label", diff --git a/src/design/plone/contenttypes/interfaces/punto_di_contatto.py b/src/design/plone/contenttypes/interfaces/punto_di_contatto.py index deb10582..947e93cf 100644 --- a/src/design/plone/contenttypes/interfaces/punto_di_contatto.py +++ b/src/design/plone/contenttypes/interfaces/punto_di_contatto.py @@ -1,11 +1,8 @@ # -*- coding: utf-8 -*- from design.plone.contenttypes import _ from design.plone.contenttypes.interfaces import IDesignPloneContentType -from plone.app.z3cform.widget import RelatedItemsFieldWidget from plone.autoform import directives as form from plone.supermodel import model -from z3c.relationfield.schema import RelationChoice -from z3c.relationfield.schema import RelationList from zope import schema from collective.z3cform.datagridfield.datagridfield import DataGridFieldFactory from collective.z3cform.datagridfield.row import DictRow @@ -52,4 +49,3 @@ class IPuntoDiContatto(model.Schema, IDesignPloneContentType): "value_punto_contatto", DataGridFieldFactory, ) - diff --git a/src/design/plone/contenttypes/interfaces/servizio.py b/src/design/plone/contenttypes/interfaces/servizio.py index 2eddd3d2..543ea92d 100644 --- a/src/design/plone/contenttypes/interfaces/servizio.py +++ b/src/design/plone/contenttypes/interfaces/servizio.py @@ -10,6 +10,62 @@ from z3c.relationfield.schema import RelationList from plone.namedfile import field from zope import schema +from collective.z3cform.datagridfield.row import DictRow +from collective.z3cform.datagridfield.datagridfield import DataGridFieldFactory +from plone.app.z3cform.widget import DateFieldWidget + + +class ITempiEScadenzeValueSchema(model.Schema): + data_scadenza = schema.Date( + title=_("data_scadenza_label", default="Data scadenza"), + description=_( + "data_scadenza_help", + default="Data di scadenza della fase", + ), + required=False, + ) + milestone = schema.TextLine( + title=_("milestone_label", default="Titolo"), + description=_( + "milestone_help", + default="Titolo della fase", + ), + required=True, + default="", + ) + milestone_description = schema.TextLine( + title=_("milestone_description_label", default="Sottotitolo"), + description=_( + "milestone_description_help", + default="Sottotitolo della fase", + ), + required=False, + default="", + ) + interval_qt = schema.TextLine( + title=_("interval_qt_label", default="Intervallo"), + description=_( + "interval_qt_help", + default="Intervallo della fase", + ), + required=False, + default="", + ) + interval_type = schema.TextLine( + title=_("interval_type_label", default="Tipo intervallo"), + description=_( + "interval_type_help", + default="Tipo di intervallo della fase, possono essere " + "ore, giorni, settimane, mesi, anni.", + ), + required=False, + default="", + ) + + form.widget( + "data_scadenza", + DateFieldWidget, + ) class IServizio(model.Schema, IDesignPloneContentType): @@ -187,6 +243,19 @@ class IServizio(model.Schema, IDesignPloneContentType): required=False, ) + timeline_tempi_scadenze = schema.List( + title=_("timeline_tempi_scadenze", default="Timeline tempi e scadenze"), + default=[], + value_type=DictRow(schema=ITempiEScadenzeValueSchema), + description=_( + "timeline_tempi_scadenze_help", + default="Timeline tempi e scadenze del servizio: indicare per ogni scadenza " + "un titolo descritttivo di tale scadenza e, opzionalmente, informazioni sulle" + " date o gli intervalli di tempo che intercorrono tra una fase e la successiva.", + ), + required=True, + ) + tempi_e_scadenze = BlocksField( title=_("tempi_e_scadenze", default="Tempi e scadenze"), required=True, @@ -391,6 +460,10 @@ class IServizio(model.Schema, IDesignPloneContentType): # "basePath": "/", }, ) + form.widget( + "timeline_tempi_scadenze", + DataGridFieldFactory, + ) # custom fieldset and order model.fieldset( @@ -429,7 +502,7 @@ class IServizio(model.Schema, IDesignPloneContentType): model.fieldset( "tempi_e_scadenze", label=_("tempi_e_scadenze_label", default="Tempi e scadenze"), - fields=["tempi_e_scadenze"], + fields=["timeline_tempi_scadenze", "tempi_e_scadenze"], ) model.fieldset( diff --git a/src/design/plone/contenttypes/restapi/deserializers/configure.zcml b/src/design/plone/contenttypes/restapi/deserializers/configure.zcml index a859e49e..30dfef6a 100644 --- a/src/design/plone/contenttypes/restapi/deserializers/configure.zcml +++ b/src/design/plone/contenttypes/restapi/deserializers/configure.zcml @@ -7,4 +7,5 @@ + diff --git a/src/design/plone/contenttypes/restapi/deserializers/dxfields.py b/src/design/plone/contenttypes/restapi/deserializers/dxfields.py index 7958cad9..f59cff73 100644 --- a/src/design/plone/contenttypes/restapi/deserializers/dxfields.py +++ b/src/design/plone/contenttypes/restapi/deserializers/dxfields.py @@ -12,6 +12,9 @@ from zope.i18n import translate from zope.interface import implementer from zope.schema.interfaces import ISourceText +from datetime import datetime +from design.plone.contenttypes.interfaces.servizio import IServizio +from zope.schema.interfaces import IList import json @@ -75,3 +78,34 @@ def __call__(self, value): blocks[id] = block_value value = json.dumps(data) return value + + +@implementer(IFieldDeserializer) +@adapter(IList, IServizio, IDesignPloneContenttypesLayer) +class TimelineTempiEScadenzeFieldDeserializer(DefaultFieldDeserializer): + """ + Volto returns a string in date field, Plone expects + and throws error during validation. Patched. + Since I cannot have an empty value in data_scadenza (which is NOT a required + field), I'll have to do some serializing magic in Servizio serializer. + """ + def __call__(self, value): + if self.field.getName() != "timeline_tempi_scadenze": + return super().__call__(value) + timeline = [] + for item in value: + data_scadenza = datetime.strptime( + item.get("data_scadenza", "1969-01-01"), "%Y-%m-%d" + ).date() + entry = { + "milestone": item.get("milestone", ""), + "milestone_description": item.get("milestone_description", ""), + "interval_qt": item.get("interval_qt", ""), + "interval_type": item.get("interval_type", ""), + "data_scadenza": data_scadenza + } + + timeline.append(entry) + + self.field.validate(timeline) + return timeline diff --git a/src/design/plone/contenttypes/restapi/serializers/configure.zcml b/src/design/plone/contenttypes/restapi/serializers/configure.zcml index 69d79f8d..d9f8987f 100644 --- a/src/design/plone/contenttypes/restapi/serializers/configure.zcml +++ b/src/design/plone/contenttypes/restapi/serializers/configure.zcml @@ -9,6 +9,7 @@ + diff --git a/src/design/plone/contenttypes/restapi/serializers/dxfields.py b/src/design/plone/contenttypes/restapi/serializers/dxfields.py index 1b2046d9..18a5f06e 100644 --- a/src/design/plone/contenttypes/restapi/serializers/dxfields.py +++ b/src/design/plone/contenttypes/restapi/serializers/dxfields.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- from AccessControl.unauthorized import Unauthorized from design.plone.contenttypes.interfaces import IDesignPloneContenttypesLayer +from design.plone.contenttypes.interfaces.servizio import IServizio from plone import api from plone.dexterity.interfaces import IDexterityContent from plone.restapi.interfaces import IBlockFieldSerializationTransformer @@ -13,7 +14,7 @@ from zope.component import subscribers from zope.globalrequest import getRequest from zope.interface import implementer -from zope.schema.interfaces import ISourceText +from zope.schema.interfaces import ISourceText, IList import json @@ -31,6 +32,22 @@ def __call__(self): return value +@implementer(IFieldSerializer) +@adapter(IList, IServizio, IDesignPloneContenttypesLayer) +class TempiEScadenzeValueSerializer(DefaultFieldSerializer): + def __call__(self): + value = super(TempiEScadenzeValueSerializer, self).__call__() + + patched_timeline = [] + if self.field.getName() == 'timeline_tempi_scadenze': + for entry in value: + if entry.get("data_scadenza", "1969-01-01") == "1969-01-01": + entry["data_scadenza"] = "" + patched_timeline.append(entry) + return json_compatible(patched_timeline) + return value + + def serialize_data(context, json_data, show_children=False): request = getRequest() if not json_data: diff --git a/src/design/plone/contenttypes/restapi/services/types/get.py b/src/design/plone/contenttypes/restapi/services/types/get.py index cfa89976..59d395e3 100644 --- a/src/design/plone/contenttypes/restapi/services/types/get.py +++ b/src/design/plone/contenttypes/restapi/services/types/get.py @@ -232,6 +232,8 @@ def customize_versioning_fields_fieldset(self, result): def customize_servizio_schema(self, result): result.get("required").append("description") + result.get("required").append("milestone_description") + result.get("required").append("milestone") return result def reply(self): diff --git a/src/design/plone/contenttypes/restapi/types/adapters.py b/src/design/plone/contenttypes/restapi/types/adapters.py index 11c712d2..12b8d338 100644 --- a/src/design/plone/contenttypes/restapi/types/adapters.py +++ b/src/design/plone/contenttypes/restapi/types/adapters.py @@ -17,6 +17,9 @@ from design.plone.contenttypes.interfaces import IDesignPloneContenttypesLayer +DATAGRID_FIELDS = ["value_punto_contatto", "timeline_tempi_scadenze"] + + @adapter(IField, Interface, Interface) @implementer(IJsonSchemaProvider) class LeadImageJsonSchemaProvider(ObjectJsonSchemaProvider): @@ -49,7 +52,7 @@ def get_schema(self): @implementer(IJsonSchemaProvider) class DataGridFieldJsonSchemaProvider(ListJsonSchemaProvider): def get_widget(self): - if self.field.getName() == "value_punto_contatto": + if self.field.getName() in DATAGRID_FIELDS: return "data_grid" return super().get_widget() diff --git a/src/design/plone/contenttypes/upgrades/upgrades.py b/src/design/plone/contenttypes/upgrades/upgrades.py index adccd8bf..4763b831 100644 --- a/src/design/plone/contenttypes/upgrades/upgrades.py +++ b/src/design/plone/contenttypes/upgrades/upgrades.py @@ -1103,7 +1103,6 @@ def createPDCandMigrateOldCTs(portal_type): "persona": [] } for key, value in mapping.items(): - import pdb; pdb.set_trace() if hasattr(item, key): kwargs["value_punto_contatto"].append({ @@ -1118,7 +1117,6 @@ def createPDCandMigrateOldCTs(portal_type): **kwargs, ) intids = getUtility(IIntIds) - import pdb; pdb.set_trace() item.contact_info = [RelationValue(intids.getId(new_pdc))] fixed_total += 1 From 8fe16d0fbb225043f916bc31a93c359930c33035 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Mon, 9 Jan 2023 17:38:35 +0100 Subject: [PATCH 043/487] update ct argomento --- .../plone/contenttypes/behaviors/argomenti.py | 15 ++ .../behaviors/descrizione_estesa.py | 9 ++ .../contenttypes/interfaces/documento.py | 104 ++++++++++++- .../restapi/deserializers/configure.zcml | 1 + .../restapi/deserializers/documento.py | 142 ++++++++++++++++++ .../restapi/services/types/get.py | 6 + 6 files changed, 274 insertions(+), 3 deletions(-) create mode 100644 src/design/plone/contenttypes/restapi/deserializers/documento.py diff --git a/src/design/plone/contenttypes/behaviors/argomenti.py b/src/design/plone/contenttypes/behaviors/argomenti.py index a561ba63..2f4de3df 100644 --- a/src/design/plone/contenttypes/behaviors/argomenti.py +++ b/src/design/plone/contenttypes/behaviors/argomenti.py @@ -123,6 +123,21 @@ class IArgomentiServizio(IArgomentiSchema): class IArgomentiDocumento(IArgomentiSchema): """ """ + tassonomia_argomenti = RelationList( + title=_("tassonomia_argomenti_label", default="Argomenti"), + description=_( + "tassonomia_argomenti_help", + default="Seleziona una lista di argomenti d'interesse per questo" + " contenuto.", + ), + value_type=RelationChoice( + title=_("Argomenti correlati"), + vocabulary="plone.app.vocabularies.Catalog", + ), + required=True, + default=[], + ) + model.fieldset( "correlati", label=_("correlati_label", default="Contenuti collegati"), diff --git a/src/design/plone/contenttypes/behaviors/descrizione_estesa.py b/src/design/plone/contenttypes/behaviors/descrizione_estesa.py index bcf7a05d..4e3e0f00 100644 --- a/src/design/plone/contenttypes/behaviors/descrizione_estesa.py +++ b/src/design/plone/contenttypes/behaviors/descrizione_estesa.py @@ -58,6 +58,15 @@ class IDescrizioneEstesaServizio(model.Schema): class IDescrizioneEstesaDocumento(IDescrizioneEstesaSchema): """ """ + descrizione_estesa = BlocksField( + title=_("descrizione_estesa", default="Descrizione estesa"), + required=True, + description=_( + "descrizione_estesa_help", + default="Descrizione dettagliata e completa.", + ), + ) + model.fieldset( "descrizione", label=_("descrizione_label", default="Descrizione"), diff --git a/src/design/plone/contenttypes/interfaces/documento.py b/src/design/plone/contenttypes/interfaces/documento.py index 85320ce3..afd92240 100644 --- a/src/design/plone/contenttypes/interfaces/documento.py +++ b/src/design/plone/contenttypes/interfaces/documento.py @@ -4,6 +4,7 @@ from design.plone.contenttypes.interfaces import IDesignPloneContentType from plone.app.z3cform.widget import RelatedItemsFieldWidget from plone.autoform import directives as form +from plone.namedfile import field from plone.supermodel import model from z3c.relationfield.schema import RelationChoice from z3c.relationfield.schema import RelationList @@ -25,6 +26,46 @@ class IDocumento(model.Schema, IDesignPloneContentType): required=False, ) + protocollo = schema.TextLine( + title=_( + "protocollo_documento_label", + default="Numero di protocollo", + ), + description=_( + "protocollo_documento_help", + default="Il numero di protocollo del documento.", + ), + max_length=255, + required=True, + ) + data_protocollo = schema.Date( + title=_("data_protocollo", default="Data del protocollo"), + required=True, + ) + # descrizione = BlocksField( + # title=_("descrizione_label", default="Descrizione"), + # description=_( + # "descrizione_help", + # default="L'oggetto del documento spiegato in modo semplice per il cittadino", # noqa + # ), + # required=True, + # ) + url = schema.URI( + title=_("url_documento_label", default="Link al documento"), + description=_( + "url_documento_help", + default="Link al documento vero e proprio, in un formato scaricabile attraverso una URL.", # noqa + ), + required=False, + ) + file_correlato = field.NamedBlobFile( + title=_("file_correlato_label", default="File correlato"), + description=_( + "file_correlato_help", + default="Se non è presente un link ad una risorsa esterna, ricordarsi di caricare l'allegato vero e proprio", # noqa + ), + required=False, + ) ufficio_responsabile = RelationList( title=_( "ufficio_responsabile_documento_label", @@ -34,7 +75,7 @@ class IDocumento(model.Schema, IDesignPloneContentType): "ufficio_responsabile_documento_help", default="Seleziona l'ufficio responsabile di questo documento.", ), - required=False, + required=True, default=[], value_type=RelationChoice( title=_("Ufficio responsabile"), @@ -72,14 +113,21 @@ class IDocumento(model.Schema, IDesignPloneContentType): required=False, default=[], ) - + formati_disponibili = BlocksField( + title=_("formati_disponibili_label", default="Formati disponibili"), + description=_( + "formati_disponibili_help", + default="Lista dei formati in cui è disponibile il documento", + ), + required=True, + ) licenza_distribuzione = schema.TextLine( title=_("licenza_distribuzione_label", default="Licenza di distribuzione"), description=_( "licenza_distribuzione_help", default="La licenza con il quale viene distribuito questo documento.", ), - required=False, + required=True, ) riferimenti_normativi = BlocksField( @@ -95,6 +143,56 @@ class IDocumento(model.Schema, IDesignPloneContentType): required=False, ) + dataset = RelationList( + title=_( + "dataset_label", + default="Dataset collegati", + ), + description=_( + "dataset_collegati_help", + default="Schede dataset collegate al documento", + ), + default=[], + required=False, + value_type=RelationChoice(vocabulary="plone.app.vocabularies.Catalog"), + ) + + # custom widgets + form.widget( + "dataset", + RelatedItemsFieldWidget, + vocabulary="plone.app.vocabularies.Catalog", + pattern_options={ + "maximumSelectionSize": 10, + "selectableTypes": ["Dataset"], + }, + ) + + servizi = RelationList( + title=_( + "servizi_label", + default="Servizi collegati", + ), + description=_( + "servizi_help", + default="Servizi collegati al documento", + ), + default=[], + required=False, + value_type=RelationChoice(vocabulary="plone.app.vocabularies.Catalog"), + ) + + # custom widgets + form.widget( + "servizi", + RelatedItemsFieldWidget, + vocabulary="plone.app.vocabularies.Catalog", + pattern_options={ + "maximumSelectionSize": 20, + "selectableTypes": ["Servizio"], + }, + ) + documenti_allegati = RelationList( title=_( "documenti_allegati_label", diff --git a/src/design/plone/contenttypes/restapi/deserializers/configure.zcml b/src/design/plone/contenttypes/restapi/deserializers/configure.zcml index 4c385e98..f32a7ea1 100644 --- a/src/design/plone/contenttypes/restapi/deserializers/configure.zcml +++ b/src/design/plone/contenttypes/restapi/deserializers/configure.zcml @@ -10,4 +10,5 @@ + diff --git a/src/design/plone/contenttypes/restapi/deserializers/documento.py b/src/design/plone/contenttypes/restapi/deserializers/documento.py new file mode 100644 index 00000000..20be6cc5 --- /dev/null +++ b/src/design/plone/contenttypes/restapi/deserializers/documento.py @@ -0,0 +1,142 @@ +# -*- coding: utf-8 -*- +from design.plone.contenttypes.interfaces.documento import IDocumento +from plone.restapi.behaviors import IBlocks +from plone.restapi.deserializer import json_body +from plone.restapi.deserializer.dxcontent import DeserializeFromJson +from plone.restapi.indexers import SearchableText_blocks +from plone.restapi.interfaces import IDeserializeFromJson +from zExceptions import BadRequest +from zope.component import adapter +from zope.interface import implementer +from zope.interface import Interface + + +TITLE_MAX_LEN = 160 +DESCRIPTION_MAX_LEN = 160 +EMPTY_BLOCK_MARKER = {"@type": "text"} +MANDATORY_RICH_TEXT_FIELDS = [ + "descrizione_estesa", + "formati_disponibili", +] + + +def new_error(message): + return {"error": "ValidationError", "message": message} + + +def text_in_block(blocks): + @implementer(IBlocks) + class FakeObject(object): + """ + We use a fake object to use SearchableText Indexer + """ + + def Subject(self): + return "" + + def __init__(self, blocks, blocks_layout): + self.blocks = blocks + self.blocks_layout = blocks_layout + self.id = "" + self.title = "" + self.description = "" + + if not blocks: + return None + + fakeObj = FakeObject(blocks.get("blocks", ""), blocks.get("blocks_layout", "")) + return SearchableText_blocks(fakeObj)() + + +@implementer(IDeserializeFromJson) +@adapter(IDocumento, Interface) +class DeserializeDocumentoFromJson(DeserializeFromJson): + def __call__( + self, validate_all=False, data=None, create=False + ): # noqa: ignore=C901 + + if data is None: + data = json_body(self.request) + + method = self.request.get("method") + is_post = method == "POST" + is_patch = method == "PATCH" + errors = [] + + title = data.get("title") + description = data.get("description") + + if is_post: + # Title validation + if not title: + errors.append(new_error("Il titolo del servizio è obbligatorio")) + elif len(title) > TITLE_MAX_LEN: + errors.append( + new_error( + "Il titolo può avere una lunghezza di massimo {} caratteri".format( # noqa + TITLE_MAX_LEN + ) + ) + ) + + # description validation + if not description: + errors.append(new_error("La descrizione del servizio è obbligatorio")) + elif len(description) > DESCRIPTION_MAX_LEN: + errors.append( + new_error( + "La descrizione del servizio deve avere una lunghezza di massimo {} caratteri".format( # noqa + DESCRIPTION_MAX_LEN + ) + ) + ) + + for field in MANDATORY_RICH_TEXT_FIELDS: + if field not in data: + errors.append(new_error("Il campo {} è obbligatorio".format(field))) + elif field in data and not text_in_block(data.get(field)): + errors.append(new_error("Il campo {} è obbligatorio".format(field))) + + if is_patch: + # Title validation + if "title" in data and not title: + errors.append(new_error("Il titolo del servizio è obbligatorio")) + if title and len(title) > TITLE_MAX_LEN: + errors.append( + new_error( + "Il titolo può avere una lunghezza di massimo {} caratteri".format( # noqa + TITLE_MAX_LEN + ) + ) + ) + # description validation + if "description" in data and not description: + errors.append(new_error("La descrizione del servizio è obbligatorio")) + if description and len(description) > DESCRIPTION_MAX_LEN: + errors.append( + new_error( + "La descrizione del servizio deve avere una lunghezza di massimo {} caratteri".format( # noqa + DESCRIPTION_MAX_LEN + ) + ) + ) + if "description" not in data and not self.context.description: + errors.append(new_error("La descrizione del servizio è obbligatorio")) + + for field in MANDATORY_RICH_TEXT_FIELDS: + if field in data and not text_in_block(data.get(field)): + errors.append(new_error("Il campo {} è obbligatorio".format(field))) + # Se siamo nella patch siamo in modifica. Se siamo in modifica e siamo + # su un sito che ha avuto upgrade alla versione pnrr può essere che + # dei campi obbligatori un tempo non lo fossero e quindi arriviamo + # fino a qui + if field not in data and not text_in_block( + getattr(self.context, field) + ): + errors.append(new_error("Il campo {} è obbligatorio".format(field))) + + if errors: + raise BadRequest(errors) + return super(DeserializeDocumentoFromJson, self).__call__( + validate_all=False, data=data, create=False + ) diff --git a/src/design/plone/contenttypes/restapi/services/types/get.py b/src/design/plone/contenttypes/restapi/services/types/get.py index a86e1efa..74e6d61a 100644 --- a/src/design/plone/contenttypes/restapi/services/types/get.py +++ b/src/design/plone/contenttypes/restapi/services/types/get.py @@ -263,6 +263,10 @@ def customize_news_schema(self, result): return result + def customize_documento_schema(self, result): + result.get("required").append("description") + return result + def reply(self): result = super(TypesGet, self).reply() @@ -287,6 +291,8 @@ def reply(self): result = self.customize_uo_schema(result) if pt == "News Item": result = self.customize_news_schema(result) + if pt == "Documento": + result = self.customize_documento_schema(result) result = self.customize_versioning_fields_fieldset(result) return result From 9757285f66d6b4231cf9d90ce14d444743cb9619 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Tue, 10 Jan 2023 09:35:04 +0100 Subject: [PATCH 044/487] update documento --- .../contenttypes/interfaces/documento.py | 20 ++++++++----------- .../taxonomies/tipologia_licenze.cfg | 2 +- .../restapi/serializers/servizio.py | 4 ++++ 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/design/plone/contenttypes/interfaces/documento.py b/src/design/plone/contenttypes/interfaces/documento.py index afd92240..4c71007f 100644 --- a/src/design/plone/contenttypes/interfaces/documento.py +++ b/src/design/plone/contenttypes/interfaces/documento.py @@ -36,11 +36,11 @@ class IDocumento(model.Schema, IDesignPloneContentType): default="Il numero di protocollo del documento.", ), max_length=255, - required=True, + required=False, ) data_protocollo = schema.Date( title=_("data_protocollo", default="Data del protocollo"), - required=True, + required=False, ) # descrizione = BlocksField( # title=_("descrizione_label", default="Descrizione"), @@ -127,7 +127,7 @@ class IDocumento(model.Schema, IDesignPloneContentType): "licenza_distribuzione_help", default="La licenza con il quale viene distribuito questo documento.", ), - required=True, + required=False, ) riferimenti_normativi = BlocksField( @@ -162,10 +162,7 @@ class IDocumento(model.Schema, IDesignPloneContentType): "dataset", RelatedItemsFieldWidget, vocabulary="plone.app.vocabularies.Catalog", - pattern_options={ - "maximumSelectionSize": 10, - "selectableTypes": ["Dataset"], - }, + pattern_options={"maximumSelectionSize": 10, "selectableTypes": ["Dataset"]}, ) servizi = RelationList( @@ -187,10 +184,7 @@ class IDocumento(model.Schema, IDesignPloneContentType): "servizi", RelatedItemsFieldWidget, vocabulary="plone.app.vocabularies.Catalog", - pattern_options={ - "maximumSelectionSize": 20, - "selectableTypes": ["Servizio"], - }, + pattern_options={"maximumSelectionSize": 20, "selectableTypes": ["Servizio"]}, ) documenti_allegati = RelationList( @@ -268,7 +262,9 @@ class IDocumento(model.Schema, IDesignPloneContentType): ) form.order_after(area_responsabile="ufficio_responsabile") form.order_after(autori="area_responsabile") - form.order_after(licenza_distribuzione="autori") + form.order_after( + licenza_distribuzione="IDescrizioneEstesaDocumento.descrizione_estesa" + ) form.order_after( riferimenti_normativi="IAdditionalHelpInfos.ulteriori_informazioni" ) diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_licenze.cfg b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_licenze.cfg index 343c0bc3..d09bdaf6 100644 --- a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_licenze.cfg +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_licenze.cfg @@ -4,6 +4,6 @@ title = Licenze description = Il sistema di gestione contenuti basato su React default_language = it field_title = Licenze -taxonomy_fieldset = default +taxonomy_fieldset = descrizione is_single_select = true is_required = true diff --git a/src/design/plone/contenttypes/restapi/serializers/servizio.py b/src/design/plone/contenttypes/restapi/serializers/servizio.py index 484637b8..5d1e9856 100644 --- a/src/design/plone/contenttypes/restapi/serializers/servizio.py +++ b/src/design/plone/contenttypes/restapi/serializers/servizio.py @@ -30,4 +30,8 @@ def __call__(self, force_all_metadata=False): ) value = serializer() summary[name] = value + + parent = self.context.aq_inner.aq_parent + summary["parent_title"] = parent.title + summary["parent_url"] = parent.absolute_url() return summary From 170f1818fe3ff9a4886757ebd5058441deac79e6 Mon Sep 17 00:00:00 2001 From: Martina Bustacchini Date: Tue, 10 Jan 2023 11:38:18 +0100 Subject: [PATCH 045/487] fix: fields order in Servizio, remove useless required field in types/get for servizio, fix validation in deserializer --- .../plone/contenttypes/interfaces/servizio.py | 46 +++++++++---------- .../restapi/deserializers/dxfields.py | 14 ++++-- .../restapi/services/types/get.py | 2 - 3 files changed, 33 insertions(+), 29 deletions(-) diff --git a/src/design/plone/contenttypes/interfaces/servizio.py b/src/design/plone/contenttypes/interfaces/servizio.py index 543ea92d..4da2782b 100644 --- a/src/design/plone/contenttypes/interfaces/servizio.py +++ b/src/design/plone/contenttypes/interfaces/servizio.py @@ -33,15 +33,6 @@ class ITempiEScadenzeValueSchema(model.Schema): required=True, default="", ) - milestone_description = schema.TextLine( - title=_("milestone_description_label", default="Sottotitolo"), - description=_( - "milestone_description_help", - default="Sottotitolo della fase", - ), - required=False, - default="", - ) interval_qt = schema.TextLine( title=_("interval_qt_label", default="Intervallo"), description=_( @@ -55,8 +46,17 @@ class ITempiEScadenzeValueSchema(model.Schema): title=_("interval_type_label", default="Tipo intervallo"), description=_( "interval_type_help", - default="Tipo di intervallo della fase, possono essere " - "ore, giorni, settimane, mesi, anni.", + default="Ad esempio: " + "ore, giorni, settimane, mesi.", + ), + required=False, + default="", + ) + milestone_description = schema.TextLine( + title=_("milestone_description_label", default="Sottotitolo"), + description=_( + "milestone_description_help", + default="Sottotitolo della fase", ), required=False, default="", @@ -243,6 +243,16 @@ class IServizio(model.Schema, IDesignPloneContentType): required=False, ) + tempi_e_scadenze = BlocksField( + title=_("tempi_e_scadenze", default="Tempi e scadenze"), + required=True, + description=_( + "tempi_e_scadenze_help", + default="Descrivere le informazioni dettagliate riguardo eventuali tempi" + " e scadenze di questo servizio.", + ), + ) + timeline_tempi_scadenze = schema.List( title=_("timeline_tempi_scadenze", default="Timeline tempi e scadenze"), default=[], @@ -253,17 +263,7 @@ class IServizio(model.Schema, IDesignPloneContentType): "un titolo descritttivo di tale scadenza e, opzionalmente, informazioni sulle" " date o gli intervalli di tempo che intercorrono tra una fase e la successiva.", ), - required=True, - ) - - tempi_e_scadenze = BlocksField( - title=_("tempi_e_scadenze", default="Tempi e scadenze"), - required=True, - description=_( - "tempi_e_scadenze_help", - default="Descrivere le informazioni dettagliate riguardo eventuali tempi" - " e scadenze di questo servizio.", - ), + required=False, ) cosa_serve = BlocksField( @@ -502,7 +502,7 @@ class IServizio(model.Schema, IDesignPloneContentType): model.fieldset( "tempi_e_scadenze", label=_("tempi_e_scadenze_label", default="Tempi e scadenze"), - fields=["timeline_tempi_scadenze", "tempi_e_scadenze"], + fields=["tempi_e_scadenze", "timeline_tempi_scadenze"], ) model.fieldset( diff --git a/src/design/plone/contenttypes/restapi/deserializers/dxfields.py b/src/design/plone/contenttypes/restapi/deserializers/dxfields.py index f59cff73..edbe9ec3 100644 --- a/src/design/plone/contenttypes/restapi/deserializers/dxfields.py +++ b/src/design/plone/contenttypes/restapi/deserializers/dxfields.py @@ -15,6 +15,7 @@ from datetime import datetime from design.plone.contenttypes.interfaces.servizio import IServizio from zope.schema.interfaces import IList +from zExceptions import BadRequest import json @@ -88,21 +89,26 @@ class TimelineTempiEScadenzeFieldDeserializer(DefaultFieldDeserializer): and throws error during validation. Patched. Since I cannot have an empty value in data_scadenza (which is NOT a required field), I'll have to do some serializing magic in Servizio serializer. + Also validate milestone field, frontend should take care of it, but you never know. """ def __call__(self, value): if self.field.getName() != "timeline_tempi_scadenze": return super().__call__(value) timeline = [] for item in value: - data_scadenza = datetime.strptime( - item.get("data_scadenza", "1969-01-01"), "%Y-%m-%d" - ).date() + if not item.get("milestone", None): + raise BadRequest({ + "error": "ValidationError", + "message": "Il campo {} è obbligatorio".format("Titolo della fase") + }) entry = { "milestone": item.get("milestone", ""), "milestone_description": item.get("milestone_description", ""), "interval_qt": item.get("interval_qt", ""), "interval_type": item.get("interval_type", ""), - "data_scadenza": data_scadenza + "data_scadenza": datetime.strptime( + item.get("data_scadenza") or "1969-01-01", "%Y-%m-%d" + ).date() } timeline.append(entry) diff --git a/src/design/plone/contenttypes/restapi/services/types/get.py b/src/design/plone/contenttypes/restapi/services/types/get.py index 59d395e3..cfa89976 100644 --- a/src/design/plone/contenttypes/restapi/services/types/get.py +++ b/src/design/plone/contenttypes/restapi/services/types/get.py @@ -232,8 +232,6 @@ def customize_versioning_fields_fieldset(self, result): def customize_servizio_schema(self, result): result.get("required").append("description") - result.get("required").append("milestone_description") - result.get("required").append("milestone") return result def reply(self): From 7c7c3b4e152b054c346807e66b92190f4c04b56b Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Tue, 10 Jan 2023 12:31:56 +0100 Subject: [PATCH 046/487] [dev] ct evento --- .../plone/contenttypes/behaviors/evento.py | 99 +++++++++++++++---- .../plone/contenttypes/events/evento.py | 27 ++++- .../behaviors/taxonomies/tipologia_pdc.xml | 2 +- 3 files changed, 104 insertions(+), 24 deletions(-) diff --git a/src/design/plone/contenttypes/behaviors/evento.py b/src/design/plone/contenttypes/behaviors/evento.py index 067a1569..a7b60da6 100644 --- a/src/design/plone/contenttypes/behaviors/evento.py +++ b/src/design/plone/contenttypes/behaviors/evento.py @@ -27,6 +27,7 @@ class IEvento(model.Schema): ), required=False, ) + descrizione_estesa = BlocksField( title=_("descrizione_estesa", default="Descrizione estesa"), required=False, @@ -35,6 +36,7 @@ class IEvento(model.Schema): default="Descrizione dettagliata e completa.", ), ) + descrizione_destinatari = BlocksField( title=_("descrizione_destinatari", default="Descrizione destinatari"), required=False, @@ -69,14 +71,16 @@ class IEvento(model.Schema): ) prezzo = BlocksField( - title=_("prezzo", default="Prezzo"), + title=_("prezzo", default="Costo"), required=False, description=_( "prezzo_help", - default="Indicare il prezzo dell'evento, se presente, specificando" - " se esistono formati diversi.", + default="Eventuale costo dell'evento (se ci sono uno o più biglietti), " + "con link all'alcquisto se disponibile", ), ) + + # campi presenti nelle vecchie grafiche che abbiamo deciso di continuare a mostrare organizzato_da_interno = RelationList( title=_("organizzato_da_interno_label", default="Organizzato da"), default=[], @@ -91,7 +95,6 @@ class IEvento(model.Schema): "sovrascrivere alcuni dati di contatto, utilizzare i seguenti campi.", # noqa ), ) - organizzato_da_esterno = BlocksField( title=_("organizzato_da_esterno_label", default="Organizzatore"), required=False, @@ -101,7 +104,6 @@ class IEvento(model.Schema): " indicare il nome del contatto.", ), ) - supportato_da = RelationList( title=_("supportato_da_label", default="Evento supportato da"), required=False, @@ -113,8 +115,7 @@ class IEvento(model.Schema): ), ) - # TODO: come fare il rating/recensione dell'evento - + # campi aggiunti con il pnrr patrocinato_da = schema.TextLine( title=_("patrocinato_da_label", default="Patrocinato da"), required=False, @@ -124,7 +125,78 @@ class IEvento(model.Schema): ), ) + evento_genitore = RelationList( + title=_("evento_genitore_label", default="Evento genitore"), + required=False, + default=[], + value_type=RelationChoice(vocabulary="plone.app.vocabularies.Catalog"), + description=_( + "evento_genitore_help", + default="Un evento può essere parte di un altro evento definito come " + '"genitore" (ad es. "Mostra sul Rinascimento" è parte ' + "dell'evento \"Festival dell'Arte\")", + ), + ) + + appuntamenti = RelationList( + title=_("appuntamenti_label", default="Appuntamenti"), + required=False, + default=[], + value_type=RelationChoice(vocabulary="plone.app.vocabularies.Catalog"), + description=_( + "appuntamenti_help", + default="Link agli eventi figlio (solo se l'evento in questione è " + "evento genitore)", + ), + ) + + parteciperanno = RelationList( + title=_("parteciperanno_label", default="Parteciperanno (Persone)"), + required=False, + default=[], + value_type=RelationChoice(vocabulary="plone.app.vocabularies.Catalog"), + description=_( + "parteciperanno_help", + default="Link a persone dell'amministrazione che interverranno all'evento", + ), + ) + + a_chi_si_rivolge = BlocksField( + title=_("a_chi_si_rivolge_label", default="A chi è rivolto"), + required=True, + description=_( + "a_chi_si_rivolge_help", + default="Descrizione testuale dei principali destinatari dell'Evento", + ), + ) + # custom widgets + form.widget( + "evento_genitore", + RelatedItemsFieldWidget, + vocabulary="plone.app.vocabularies.Catalog", + pattern_options={ + "maximumSelectionSize": 1, + "selectableTypes": ["Evento"], + }, + ) + form.widget( + "appuntamenti", + RelatedItemsFieldWidget, + vocabulary="plone.app.vocabularies.Catalog", + pattern_options={ + "selectableTypes": ["Evento"], + }, + ) + form.widget( + "parteciperanno", + RelatedItemsFieldWidget, + vocabulary="plone.app.vocabularies.Catalog", + pattern_options={ + "maximumSelectionSize": 1, + "selectableTypes": ["Persone"], + }, + ) form.widget( "supportato_da", RelatedItemsFieldWidget, @@ -171,27 +243,16 @@ class IEvento(model.Schema): fields=["orari"], ) model.fieldset("costi", label=_("costi_label", default="Costi"), fields=["prezzo"]) - - # TODO: migration script for these commented fields towards PDC model.fieldset( "contatti", label=_("contatti_label", default="Contatti"), fields=[ "organizzato_da_interno", "organizzato_da_esterno", - # "telefono", - # "fax", - # "reperibilita", - # "email", - # "web", "supportato_da", + "patrocinato_da", ], ) - model.fieldset( - "informazioni", - label=_("informazioni_label", default="Ulteriori informazioni"), - fields=["patrocinato_da"], - ) textindexer.searchable("descrizione_estesa") diff --git a/src/design/plone/contenttypes/events/evento.py b/src/design/plone/contenttypes/events/evento.py index e017f89a..7a6861d9 100644 --- a/src/design/plone/contenttypes/events/evento.py +++ b/src/design/plone/contenttypes/events/evento.py @@ -16,12 +16,12 @@ def eventoCreateHandler(evento, event): """ if not IDesignPloneContenttypesLayer.providedBy(evento.REQUEST): return - if "multimedia" not in evento.keys(): + if "immagini" not in evento.keys(): galleria = api.content.create( container=evento, type="Document", - title="Multimedia", - id="multimedia", + title="Immagini", + id="immagini", ) create_default_blocks(context=galleria) @@ -33,6 +33,25 @@ def eventoCreateHandler(evento, event): with api.env.adopt_roles(["Reviewer"]): api.content.transition(obj=galleria, transition="publish") + if not IDesignPloneContenttypesLayer.providedBy(evento.REQUEST): + return + if "video" not in evento.keys(): + galleria_video = api.content.create( + container=evento, + type="Document", + title="Video", + id="video", + ) + create_default_blocks(context=galleria_video) + + # select constraints + constraintsGalleriaVideo = ISelectableConstrainTypes(galleria_video) + constraintsGalleriaVideo.setConstrainTypesMode(1) + constraintsGalleriaVideo.setLocallyAllowedTypes(("Link")) + + with api.env.adopt_roles(["Reviewer"]): + api.content.transition(obj=galleria_video, transition="publish") + if "sponsor_evento" not in evento.keys(): sponsor = api.content.create( container=evento, @@ -53,7 +72,7 @@ def eventoCreateHandler(evento, event): documenti = api.content.create( container=evento, type="Document", - title="Documenti", + title="Allegati", id="documenti", ) create_default_blocks(context=documenti) diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_pdc.xml b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_pdc.xml index 3eac84c2..6b723795 100644 --- a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_pdc.xml +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_pdc.xml @@ -38,7 +38,7 @@ account - Accout + Account whatsapp From dfb51b301168d937fd708ef5b226abc74df4a2be Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Tue, 10 Jan 2023 14:55:58 +0100 Subject: [PATCH 047/487] [dev] add field_profix and field_description to all taxonomies --- .../profiles/behaviors/taxonomies/business_events.cfg | 2 ++ .../profiles/behaviors/taxonomies/person_life_events.cfg | 2 ++ .../contenttypes/profiles/behaviors/taxonomies/temi_dataset.cfg | 1 + .../behaviors/taxonomies/tipologia_documenti_albopretorio.cfg | 2 ++ .../profiles/behaviors/taxonomies/tipologia_documento.cfg | 1 + .../profiles/behaviors/taxonomies/tipologia_evento.cfg | 2 ++ .../behaviors/taxonomies/tipologia_frequenza_aggiornamento.cfg | 2 ++ .../profiles/behaviors/taxonomies/tipologia_incarico.cfg | 2 ++ .../profiles/behaviors/taxonomies/tipologia_licenze.cfg | 2 ++ .../profiles/behaviors/taxonomies/tipologia_luogo.cfg | 2 ++ .../profiles/behaviors/taxonomies/tipologia_notizia.cfg | 1 + .../profiles/behaviors/taxonomies/tipologia_organizzazione.cfg | 1 + .../profiles/behaviors/taxonomies/tipologia_pdc.cfg | 2 ++ .../profiles/behaviors/taxonomies/tipologia_stati_pratica.cfg | 2 ++ .../contenttypes/profiles/default/types/PuntoDiContatto.xml | 1 + 15 files changed, 25 insertions(+) diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/business_events.cfg b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/business_events.cfg index 35123908..5e4cadb5 100644 --- a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/business_events.cfg +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/business_events.cfg @@ -4,4 +4,6 @@ title = Eventi della vita delle imprese description = Il sistema di gestione contenuti basato su React default_language = it field_title = Eventi della vita delle imprese +field_description = Seleziona la tipologia di evento dell'impresa +field_prefix = taxonomy_fieldset = default diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/person_life_events.cfg b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/person_life_events.cfg index f72dca69..c657dc5b 100644 --- a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/person_life_events.cfg +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/person_life_events.cfg @@ -4,4 +4,6 @@ title = Eventi della vita delle persone description = Il sistema di gestione contenuti basato su React default_language = it field_title = Eventi della vita delle persone +field_description = Seleziona la tipologia dell'evento della vita delle persone +field_prefix = taxonomy_fieldset = default diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/temi_dataset.cfg b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/temi_dataset.cfg index cf7724f1..3058e1f6 100644 --- a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/temi_dataset.cfg +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/temi_dataset.cfg @@ -5,5 +5,6 @@ description = Il sistema di gestione contenuti basato su React default_language = it field_title = Temi di un dataset field_description = Scegli i temi di un dataset +field_prefix = taxonomy_fieldset = default is_required = true diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_documenti_albopretorio.cfg b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_documenti_albopretorio.cfg index 38d76887..76ea0d29 100644 --- a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_documenti_albopretorio.cfg +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_documenti_albopretorio.cfg @@ -4,5 +4,7 @@ title = Tipologia di Documento albo pretorio description = Il sistema di gestione contenuti basato su React default_language = it field_title = Tipologia di Documento albo pretorio +field_description = Seleziona la tipologia di documento di albo pretorio +field_prefix = taxonomy_fieldset = default is_single_select = true diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_documento.cfg b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_documento.cfg index 6a337225..dda13e16 100644 --- a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_documento.cfg +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_documento.cfg @@ -5,5 +5,6 @@ description = Seleziona la tipologia del documento default_language = it field_title = Tipologia del documento field_description = Seleziona la tipologia del documento +field_prefix = taxonomy_fieldset = default is_required = true diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_evento.cfg b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_evento.cfg index 7f9be887..ae23182c 100644 --- a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_evento.cfg +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_evento.cfg @@ -4,6 +4,8 @@ title = Tipo di evento description = Il sistema di gestione contenuti basato su React default_language = it field_title = Tipo di evento +field_description = Seleziona la tipologia dell'evento +field_prefix = taxonomy_fieldset = default is_single_select = true is_required = true diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_frequenza_aggiornamento.cfg b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_frequenza_aggiornamento.cfg index f1bf4e7c..26099864 100644 --- a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_frequenza_aggiornamento.cfg +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_frequenza_aggiornamento.cfg @@ -4,6 +4,8 @@ title = Tipologia di Frequenza di aggiornamento description = Il sistema di gestione contenuti basato su React default_language = it field_title = Tipologia di Frequenza di aggiornamento +field_description = Seleziona la tipologia di frequenza di aggiornamento +field_prefix = taxonomy_fieldset = default is_single_select = true is_required = true diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_incarico.cfg b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_incarico.cfg index 24a0aab1..48a8d418 100644 --- a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_incarico.cfg +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_incarico.cfg @@ -4,6 +4,8 @@ title = Tipo di incarico description = Tipologie di incarico default_language = it field_title = Tipo di incarico +field_description = Seleziona la tipologia di incarico +field_prefix = taxonomy_fieldset = default is_single_select = true is_required = true diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_licenze.cfg b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_licenze.cfg index d09bdaf6..7061dc89 100644 --- a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_licenze.cfg +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_licenze.cfg @@ -4,6 +4,8 @@ title = Licenze description = Il sistema di gestione contenuti basato su React default_language = it field_title = Licenze +field_description = Seleziona la tipologia di licenza +field_prefix = taxonomy_fieldset = descrizione is_single_select = true is_required = true diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_luogo.cfg b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_luogo.cfg index 825096ec..c084ead6 100644 --- a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_luogo.cfg +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_luogo.cfg @@ -4,4 +4,6 @@ title = Tipo di luogo description = Il sistema di gestione contenuti basato su React default_language = it field_title = Tipo di luogo +field_description = Seleziona la tipologia del luogo +field_prefix = taxonomy_fieldset = default diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_notizia.cfg b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_notizia.cfg index a94b8435..c001de21 100644 --- a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_notizia.cfg +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_notizia.cfg @@ -5,6 +5,7 @@ description = Il sistema di gestione contenuti basato su React default_language = it field_title = Tipologia notizia field_description = Seleziona la tipologia della notizia +field_prefix = taxonomy_fieldset = default is_single_select = true is_required = true diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_organizzazione.cfg b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_organizzazione.cfg index a81020c6..d651776a 100644 --- a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_organizzazione.cfg +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_organizzazione.cfg @@ -5,5 +5,6 @@ description = Selezione la tipologia dell'unità organizzativa default_language = it field_title = Tipologia organizzazione field_description = Selezione la tipologia dell'unità organizzativa +field_prefix = taxonomy_fieldset = struttura is_required = true diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_pdc.cfg b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_pdc.cfg index c75a99eb..1fef87f0 100644 --- a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_pdc.cfg +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_pdc.cfg @@ -4,6 +4,8 @@ title = Tipo di punto di contatto description = Il sistema di gestione contenuti basato su React default_language = it field_title = Tipo di punto di contatto +field_description = Seleziona la tipologia del punto di contatto +field_prefix = taxonomy_fieldset = default is_single_select = true is_required = true diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_stati_pratica.cfg b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_stati_pratica.cfg index 0961755d..b9fcc72d 100644 --- a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_stati_pratica.cfg +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_stati_pratica.cfg @@ -4,6 +4,8 @@ title = Stati di una Pratica description = Il sistema di gestione contenuti basato su React default_language = it field_title = Stati di una Pratica +field_description = Seleziona la tipologia di stati di una pratica +field_prefix = taxonomy_fieldset = default is_single_select = true is_required = true diff --git a/src/design/plone/contenttypes/profiles/default/types/PuntoDiContatto.xml b/src/design/plone/contenttypes/profiles/default/types/PuntoDiContatto.xml index 24facf25..e22f0ccb 100644 --- a/src/design/plone/contenttypes/profiles/default/types/PuntoDiContatto.xml +++ b/src/design/plone/contenttypes/profiles/default/types/PuntoDiContatto.xml @@ -55,6 +55,7 @@ + From d94c6cf2978093d12c54163290e080dc62cb3652 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Tue, 10 Jan 2023 14:55:58 +0100 Subject: [PATCH 048/487] creazione incarichi --- .../plone/contenttypes/events/persona.py | 13 +- .../plone/contenttypes/interfaces/incarico.py | 27 ++++ .../plone/contenttypes/interfaces/persona.py | 7 +- .../profiles/default/metadata.xml | 2 +- .../profiles/default/types/Incarico.xml | 1 + .../restapi/serializers/summary.py | 2 +- .../contenttypes/upgrades/configure.zcml | 16 +++ .../plone/contenttypes/upgrades/upgrades.py | 115 ++++++++++++++++++ 8 files changed, 167 insertions(+), 16 deletions(-) diff --git a/src/design/plone/contenttypes/events/persona.py b/src/design/plone/contenttypes/events/persona.py index 40e5395d..0da34496 100644 --- a/src/design/plone/contenttypes/events/persona.py +++ b/src/design/plone/contenttypes/events/persona.py @@ -31,21 +31,14 @@ def personaCreateHandler(persona, event): "title": "Dichiarazione dei redditi", "contains": ("File",), }, - { - "id": "spese-elettorali", - "title": "Spese elettorali", - "contains": ("File",), - }, + {"id": "spese-elettorali", "title": "Spese elettorali", "contains": ("File",)}, { "id": "variazione-situazione-patrimoniale", "title": "Variazione situazione patrimoniale", "contains": ("File",), }, - { - "id": "altre-cariche", - "title": "Altre cariche", - "contains": ("File",), - }, + {"id": "altre-cariche", "title": "Altre cariche", "contains": ("File",)}, + {"id": "incarichi", "title": "Incarichi", "contains": ("Incarico",)}, ] for folder in FOLDERS: if folder["id"] in persona: diff --git a/src/design/plone/contenttypes/interfaces/incarico.py b/src/design/plone/contenttypes/interfaces/incarico.py index 5215411f..3810196f 100644 --- a/src/design/plone/contenttypes/interfaces/incarico.py +++ b/src/design/plone/contenttypes/interfaces/incarico.py @@ -39,6 +39,23 @@ class IIncarico(model.Schema, IDesignPloneContentType): required=False, ) + persona = RelationList( + title=_( + "persona_incarico_label", + default="La persona che ha la carica e l'incarico", + ), + description=_( + "persona_incarico_help", + default="Seleziona la persona che ha questo incarico", + ), + required=False, + default=[], + value_type=RelationChoice( + title=_("Persona"), + vocabulary="plone.app.vocabularies.Catalog", + ), + ) + unita_organizzativa = RelationList( title=_( "unita_organizzativa_incarico_label", @@ -117,6 +134,16 @@ class IIncarico(model.Schema, IDesignPloneContentType): }, ) + form.widget( + "persona", + RelatedItemsFieldWidget, + vocabulary="plone.app.vocabularies.Catalog", + pattern_options={ + "maximumSelectionSize": 1, + "selectableTypes": ["Persona"], + }, + ) + form.widget( "responsabile_struttura", RelatedItemsFieldWidget, diff --git a/src/design/plone/contenttypes/interfaces/persona.py b/src/design/plone/contenttypes/interfaces/persona.py index 03a9fe7d..276b7c34 100644 --- a/src/design/plone/contenttypes/interfaces/persona.py +++ b/src/design/plone/contenttypes/interfaces/persona.py @@ -33,7 +33,6 @@ class IPersona(model.Schema, IDesignPloneContentType): "La dimensione suggerita è 180x100 px.", ), ) - organizzazione_riferimento = RelationList( title=_( "organizzazione_riferimento_label", @@ -51,7 +50,7 @@ class IPersona(model.Schema, IDesignPloneContentType): default=[], required=False, ) - incarichi = RelationList( + incarichi_persona = RelationList( title=_( "incarichi_label", default="Incarichi", @@ -118,7 +117,7 @@ class IPersona(model.Schema, IDesignPloneContentType): ) form.widget( - "incarichi", + "incarichi_persona", RelatedItemsFieldWidget, vocabulary="plone.app.vocabularies.Catalog", pattern_options={ @@ -132,7 +131,7 @@ class IPersona(model.Schema, IDesignPloneContentType): "ruolo", label=_("ruolo_label", default="Ruolo"), fields=[ - "incarichi", + "incarichi_persona", "organizzazione_riferimento", "competenze", "deleghe", diff --git a/src/design/plone/contenttypes/profiles/default/metadata.xml b/src/design/plone/contenttypes/profiles/default/metadata.xml index 329909a5..1994221a 100644 --- a/src/design/plone/contenttypes/profiles/default/metadata.xml +++ b/src/design/plone/contenttypes/profiles/default/metadata.xml @@ -1,6 +1,6 @@ - 6011 + 7000 profile-redturtle.bandi:default profile-collective.venue:default diff --git a/src/design/plone/contenttypes/profiles/default/types/Incarico.xml b/src/design/plone/contenttypes/profiles/default/types/Incarico.xml index 91d6bc85..d5c91cf8 100644 --- a/src/design/plone/contenttypes/profiles/default/types/Incarico.xml +++ b/src/design/plone/contenttypes/profiles/default/types/Incarico.xml @@ -56,6 +56,7 @@ + diff --git a/src/design/plone/contenttypes/restapi/serializers/summary.py b/src/design/plone/contenttypes/restapi/serializers/summary.py index 22ff95af..fbd2fa58 100644 --- a/src/design/plone/contenttypes/restapi/serializers/summary.py +++ b/src/design/plone/contenttypes/restapi/serializers/summary.py @@ -124,7 +124,7 @@ def get_incarichi(self): except AttributeError: obj = self.context - return ", ".join([x.to_object.title for x in obj.incarichi]) + return ", ".join([x.to_object.title for x in obj.incarichi_persona]) @implementer(ISerializeToJsonSummary) diff --git a/src/design/plone/contenttypes/upgrades/configure.zcml b/src/design/plone/contenttypes/upgrades/configure.zcml index 73dbeaf4..bdd78fd2 100644 --- a/src/design/plone/contenttypes/upgrades/configure.zcml +++ b/src/design/plone/contenttypes/upgrades/configure.zcml @@ -599,4 +599,20 @@ destination="6011" handler=".upgrades.to_6011" /> + + + + diff --git a/src/design/plone/contenttypes/upgrades/upgrades.py b/src/design/plone/contenttypes/upgrades/upgrades.py index 32d965ec..93d90df2 100644 --- a/src/design/plone/contenttypes/upgrades/upgrades.py +++ b/src/design/plone/contenttypes/upgrades/upgrades.py @@ -9,6 +9,9 @@ from plone.app.textfield.value import RichTextValue from plone.app.upgrade.utils import installOrReinstallProduct from plone.dexterity.utils import iterSchemata +from plone.namedfile.file import NamedBlobFile +from Products.CMFPlone.interfaces import ISelectableConstrainTypes +from Products.CMFPlone.utils import safe_hasattr from redturtle.bandi.interfaces.settings import IBandoSettings from transaction import commit from z3c.relationfield import RelationValue @@ -1136,3 +1139,115 @@ def createPDCandMigrateOldCTs(portal_type): ) createPDCandMigrateOldCTs(pt) createIncaricoAndMigratePersona(pt) + + +class colors(object): + GREEN = "\033[92m" + ENDC = "\033[0m" + RED = "\033[91m" + DARKCYAN = "\033[36m" + YELLOW = "\033[93m" + + +def create_incarichi_folder(context): + logger.info( + f"{colors.DARKCYAN} Inizio a creare la cartella Incarichi nelle persone {colors.ENDC}" # noqa + ) + pc = api.portal.get_tool(name="portal_catalog") + wftool = api.portal.get_tool(name="portal_workflow") + brains = pc({"portal_type": "Persona"}) + target = {"id": "incarichi", "title": "Incarichi", "contains": ("Incarico",)} + for brain in brains: + persona = brain.getObject() + if target["id"] in persona: + logger.info( + f"{colors.YELLOW} {persona.title} contiene già la cartella incrichi {colors.ENDC}" # noqa + ) + continue + suboject = api.content.create( + type="Document", id=target["id"], title=target["title"], container=persona + ) + subobjectConstraints = ISelectableConstrainTypes(suboject) + subobjectConstraints.setConstrainTypesMode(1) + subobjectConstraints.setLocallyAllowedTypes(target["contains"]) + + if api.content.get_state(obj=persona) == "published": + wftool.doActionFor(suboject, "publish") + + logger.info( + f"{colors.GREEN} Creato la cartella incarichi per {persona.title}{colors.ENDC}" # noqa + ) + logger.info( + f"{colors.DARKCYAN} Finito di creare la cartella Incarichi{colors.ENDC}" + ) + + +def create_incarico_for_persona(context): + logger.info( + f"{colors.DARKCYAN} Inizio a creare gli incarichi delle persone {colors.ENDC}" + ) + intids = getUtility(IIntIds) + pc = api.portal.get_tool(name="portal_catalog") + wftool = api.portal.get_tool(name="portal_workflow") + brains = pc({"portal_type": "Persona"}) + MAPPING_TIPO = { + "Amministrativa": "amministrativo", + "Politica": "politico", + "Altro tipo": "altro", + } + for brain in brains: + + persona = brain.getObject() + + incarichi_folder = persona["incarichi"] + + incarico = api.content.create( + type="Incarico", title=persona.ruolo, container=incarichi_folder + ) + incarico.persona = [RelationValue(intids.getId(persona))] + if safe_hasattr(persona, "organizzazione_riferimento"): + incarico.unita_organizzativa = persona.organizzazione_riferimento + + if safe_hasattr(persona, "data_insediamento"): + incarico.data_inizio_incarico = persona.data_insediamento + incarico.data_insediamento = persona.data_insediamento + + if safe_hasattr(persona, "data_conclusione_incarico"): + incarico.data_conclusione_incarico = persona.data_conclusione_incarico + + atto_nomina = None + if safe_hasattr(persona, "atto_nomina"): + atto_nomina = api.content.create( + type="Documento", + id="atto-di-nomina", + title="Atto di nomina", + container=incarico, + ) + atto_nomina.description = f"Atto di nomina di {persona.title} per il ruolo di {persona.ruolo}" # noqa + atto_nomina.file_correlato = NamedBlobFile( + data=persona.atto_nomina.data, + filename=persona.atto_nomina.filename, + contentType="application/pdf", + ) + atto_nomina.taxonomy_tipologia_documento = ["documento_attivita_politica"] + incarico.atto_nomina = [RelationValue(intids.getId(atto_nomina))] + + if safe_hasattr(persona, "tipologia_persona"): + incarico.taxonomy_tipologia_incarico = MAPPING_TIPO[ + persona.tipologia_persona + ] + + persona.incarichi_persona = [RelationValue(intids.getId(incarico))] + + if api.content.get_state(obj=persona) == "published": + wftool.doActionFor(incarico, "publish") + wftool.doActionFor(incarico["compensi-file"], "publish") + wftool.doActionFor(incarico["importi-di-viaggio-e-o-servizi"], "publish") + if atto_nomina: + wftool.doActionFor(atto_nomina, "publish") + + logger.info(f"{colors.GREEN} Creato incarico per {persona.title}{colors.ENDC}") + + logger.info( + f"{colors.DARKCYAN} Finito di creare gli incarichi delle persone{colors.ENDC}" + ) From 0d598a43beb2c738b7420c19a03f5ad339926228 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Tue, 10 Jan 2023 15:33:58 +0100 Subject: [PATCH 049/487] [fix] fixed pdc vocabularies --- .../plone/contenttypes/events/evento.py | 2 +- .../interfaces/punto_di_contatto.py | 2 +- .../default/types/PuntoDiContatto.xml | 1 - .../contenttypes/vocabularies/configure.zcml | 5 -- .../vocabularies/pdc_value_type.py | 48 ------------------- 5 files changed, 2 insertions(+), 56 deletions(-) delete mode 100644 src/design/plone/contenttypes/vocabularies/pdc_value_type.py diff --git a/src/design/plone/contenttypes/events/evento.py b/src/design/plone/contenttypes/events/evento.py index 7a6861d9..aa67f6c6 100644 --- a/src/design/plone/contenttypes/events/evento.py +++ b/src/design/plone/contenttypes/events/evento.py @@ -47,7 +47,7 @@ def eventoCreateHandler(evento, event): # select constraints constraintsGalleriaVideo = ISelectableConstrainTypes(galleria_video) constraintsGalleriaVideo.setConstrainTypesMode(1) - constraintsGalleriaVideo.setLocallyAllowedTypes(("Link")) + constraintsGalleriaVideo.setLocallyAllowedTypes(("Link",)) with api.env.adopt_roles(["Reviewer"]): api.content.transition(obj=galleria_video, transition="publish") diff --git a/src/design/plone/contenttypes/interfaces/punto_di_contatto.py b/src/design/plone/contenttypes/interfaces/punto_di_contatto.py index a25f2c99..c4721b6e 100644 --- a/src/design/plone/contenttypes/interfaces/punto_di_contatto.py +++ b/src/design/plone/contenttypes/interfaces/punto_di_contatto.py @@ -15,7 +15,7 @@ class IPDCValueSchema(model.Schema): "type_help", default="Tipo", ), - vocabulary="design.plone.contenttypes.pdc_value_type", + vocabulary="collective.taxonomy.tipologia_pdc", required=True, default="", ) diff --git a/src/design/plone/contenttypes/profiles/default/types/PuntoDiContatto.xml b/src/design/plone/contenttypes/profiles/default/types/PuntoDiContatto.xml index e22f0ccb..24facf25 100644 --- a/src/design/plone/contenttypes/profiles/default/types/PuntoDiContatto.xml +++ b/src/design/plone/contenttypes/profiles/default/types/PuntoDiContatto.xml @@ -55,7 +55,6 @@ - diff --git a/src/design/plone/contenttypes/vocabularies/configure.zcml b/src/design/plone/contenttypes/vocabularies/configure.zcml index 17badf2c..2115dfb7 100644 --- a/src/design/plone/contenttypes/vocabularies/configure.zcml +++ b/src/design/plone/contenttypes/vocabularies/configure.zcml @@ -53,10 +53,5 @@ name="design.plone.vocabularies.uo_locations" component=".reference_vocabularies.UOLocationVocabularyFactory" /> - - diff --git a/src/design/plone/contenttypes/vocabularies/pdc_value_type.py b/src/design/plone/contenttypes/vocabularies/pdc_value_type.py deleted file mode 100644 index 5d4cca08..00000000 --- a/src/design/plone/contenttypes/vocabularies/pdc_value_type.py +++ /dev/null @@ -1,48 +0,0 @@ -# -*- coding: utf-8 -*- -from design.plone.contenttypes import _ -from plone.dexterity.interfaces import IDexterityContent -from zope.globalrequest import getRequest -from zope.interface import implementer -from zope.schema.interfaces import IVocabularyFactory -from zope.schema.vocabulary import SimpleTerm -from zope.schema.vocabulary import SimpleVocabulary - - -class VocabItem(object): - def __init__(self, token, value): - self.token = token - self.value = value - - -@implementer(IVocabularyFactory) -class PDCValueType(object): - """ """ - - def __call__(self, context): - # Just an example list of content for our vocabulary, - # this can be any static or dynamic data, a catalog result for example. - items = [ - VocabItem("phone", _("Telefono")), - VocabItem("web", _("URL")), - VocabItem("email", _("Email")), - VocabItem("pec", _("PEC")), - VocabItem("social", _("Social")), - VocabItem("fax", _("Fax")), - ] - # Fix context if you are using the vocabulary in DataGridField. - # See https://github.com/collective/collective.z3cform.datagridfield/issues/31: # NOQA: 501 - if not IDexterityContent.providedBy(context): - req = getRequest() - context = req.PARENTS[0] - - # create a list of SimpleTerm items: - terms = [] - for item in items: - terms.append( - SimpleTerm(value=item.token, token=str(item.token), title=item.value) - ) - # Create a SimpleVocabulary from the terms list and return it: - return SimpleVocabulary(terms) - - -PDCValueTypeFactory = PDCValueType() From 173d64fb65f34abff45100468d42391fe8eb0206 Mon Sep 17 00:00:00 2001 From: Martina Bustacchini Date: Tue, 10 Jan 2023 19:04:12 +0100 Subject: [PATCH 050/487] fix: override jsonsummary serialier for PDC --- .../restapi/serializers/configure.zcml | 1 + .../restapi/serializers/punto_di_contatto.py | 28 +++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/src/design/plone/contenttypes/restapi/serializers/configure.zcml b/src/design/plone/contenttypes/restapi/serializers/configure.zcml index 69edf3b3..3ce095a9 100644 --- a/src/design/plone/contenttypes/restapi/serializers/configure.zcml +++ b/src/design/plone/contenttypes/restapi/serializers/configure.zcml @@ -23,4 +23,5 @@ + diff --git a/src/design/plone/contenttypes/restapi/serializers/punto_di_contatto.py b/src/design/plone/contenttypes/restapi/serializers/punto_di_contatto.py index 799f1388..37d433a7 100644 --- a/src/design/plone/contenttypes/restapi/serializers/punto_di_contatto.py +++ b/src/design/plone/contenttypes/restapi/serializers/punto_di_contatto.py @@ -1,20 +1,48 @@ # -*- coding: utf-8 -*- from .related_news_serializer import SerializeFolderToJson from Acquisition import aq_inner +from design.plone.contenttypes.restapi.serializers.summary import ( + DefaultJSONSummarySerializer, +) from design.plone.contenttypes.interfaces.punto_di_contatto import IPuntoDiContatto +from plone.dexterity.utils import iterSchemata +from plone.restapi.interfaces import IFieldSerializer from plone.restapi.interfaces import ISerializeToJson from plone.restapi.interfaces import ISerializeToJsonSummary from zc.relation.interfaces import ICatalog from zope.component import adapter from zope.component import getMultiAdapter from zope.component import getUtility +from zope.component import queryMultiAdapter from zope.globalrequest import getRequest from zope.interface import implementer from zope.interface import Interface from zope.intid.interfaces import IIntIds +from zope.schema import getFields from zope.security import checkPermission +@implementer(ISerializeToJsonSummary) +@adapter(IPuntoDiContatto, Interface) +class SerializePuntoDiContattoToJsonSummary(DefaultJSONSummarySerializer): + def __call__(self, force_all_metadata=False): + summary = super().__call__(force_all_metadata=force_all_metadata) + fields = ["value_punto_contatto"] + for schema in iterSchemata(self.context): + for name, field in getFields(schema).items(): + if name not in fields: + continue + + # serialize the field + serializer = queryMultiAdapter( + (field, self.context, self.request), IFieldSerializer + ) + value = serializer() + summary[name] = value + + return summary + + @implementer(ISerializeToJson) @adapter(IPuntoDiContatto, Interface) class PuntoDiContattoSerializer(SerializeFolderToJson): From 8eb031e7f9f5191c512faf365f0408e1039b21af Mon Sep 17 00:00:00 2001 From: Martina Bustacchini Date: Tue, 10 Jan 2023 19:44:36 +0100 Subject: [PATCH 051/487] fix: cannot adapt UOs in canale fisico field for servizio --- .../plone/contenttypes/restapi/deserializers/dxfields.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/design/plone/contenttypes/restapi/deserializers/dxfields.py b/src/design/plone/contenttypes/restapi/deserializers/dxfields.py index edbe9ec3..d95d713d 100644 --- a/src/design/plone/contenttypes/restapi/deserializers/dxfields.py +++ b/src/design/plone/contenttypes/restapi/deserializers/dxfields.py @@ -4,7 +4,7 @@ from plone.dexterity.interfaces import IDexterityContent from plone.formwidget.geolocation.geolocation import Geolocation from plone.formwidget.geolocation.interfaces import IGeolocationField -from plone.restapi.deserializer.dxfields import DefaultFieldDeserializer +from plone.restapi.deserializer.dxfields import DefaultFieldDeserializer, CollectionFieldDeserializer from plone.restapi.interfaces import IBlockFieldDeserializationTransformer from plone.restapi.interfaces import IFieldDeserializer from zope.component import adapter @@ -83,7 +83,7 @@ def __call__(self, value): @implementer(IFieldDeserializer) @adapter(IList, IServizio, IDesignPloneContenttypesLayer) -class TimelineTempiEScadenzeFieldDeserializer(DefaultFieldDeserializer): +class TimelineTempiEScadenzeFieldDeserializer(CollectionFieldDeserializer): """ Volto returns a string in date field, Plone expects and throws error during validation. Patched. @@ -92,7 +92,7 @@ class TimelineTempiEScadenzeFieldDeserializer(DefaultFieldDeserializer): Also validate milestone field, frontend should take care of it, but you never know. """ def __call__(self, value): - if self.field.getName() != "timeline_tempi_scadenze": + if self.field.getName() != "timeline_tempi_scadenze" or not value: return super().__call__(value) timeline = [] for item in value: From da4b5de72e1517ba0e50f20338aca7a30b5e1838 Mon Sep 17 00:00:00 2001 From: Martina Bustacchini Date: Tue, 10 Jan 2023 20:09:27 +0100 Subject: [PATCH 052/487] fix: TempiEScadenzeValueSerializer missing check for falsish value --- src/design/plone/contenttypes/restapi/serializers/dxfields.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/design/plone/contenttypes/restapi/serializers/dxfields.py b/src/design/plone/contenttypes/restapi/serializers/dxfields.py index 18a5f06e..159928f5 100644 --- a/src/design/plone/contenttypes/restapi/serializers/dxfields.py +++ b/src/design/plone/contenttypes/restapi/serializers/dxfields.py @@ -39,7 +39,7 @@ def __call__(self): value = super(TempiEScadenzeValueSerializer, self).__call__() patched_timeline = [] - if self.field.getName() == 'timeline_tempi_scadenze': + if self.field.getName() == 'timeline_tempi_scadenze' and value: for entry in value: if entry.get("data_scadenza", "1969-01-01") == "1969-01-01": entry["data_scadenza"] = "" From 73309d6b5924ca0c730ac7dacc8ae6759c7b13d4 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Wed, 11 Jan 2023 09:00:14 +0100 Subject: [PATCH 053/487] add serialization of image for IPersona --- .../restapi/serializers/configure.zcml | 2 ++ .../restapi/serializers/relationfield.py | 6 +++++- .../contenttypes/restapi/serializers/summary.py | 17 +++++++++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/design/plone/contenttypes/restapi/serializers/configure.zcml b/src/design/plone/contenttypes/restapi/serializers/configure.zcml index 9ce01e87..1fb1049d 100644 --- a/src/design/plone/contenttypes/restapi/serializers/configure.zcml +++ b/src/design/plone/contenttypes/restapi/serializers/configure.zcml @@ -6,6 +6,7 @@ + @@ -22,4 +23,5 @@ + diff --git a/src/design/plone/contenttypes/restapi/serializers/relationfield.py b/src/design/plone/contenttypes/restapi/serializers/relationfield.py index 5163bcd1..bb4a9e9c 100644 --- a/src/design/plone/contenttypes/restapi/serializers/relationfield.py +++ b/src/design/plone/contenttypes/restapi/serializers/relationfield.py @@ -23,7 +23,11 @@ def __call__(self): for value in self.get_value(): if not value: continue - content = value.to_object + try: + content = value.to_object + except AttributeError: + # we'll migrate to PDC, right now we have Blocks + continue if not content: continue if not api.user.has_permission("View", obj=content): diff --git a/src/design/plone/contenttypes/restapi/serializers/summary.py b/src/design/plone/contenttypes/restapi/serializers/summary.py index fbd2fa58..0bfa9e24 100644 --- a/src/design/plone/contenttypes/restapi/serializers/summary.py +++ b/src/design/plone/contenttypes/restapi/serializers/summary.py @@ -3,6 +3,7 @@ from collective.taxonomy.interfaces import ITaxonomy from design.plone.contenttypes.interfaces import IDesignPloneContenttypesLayer from design.plone.contenttypes.interfaces.incarico import IIncarico +from design.plone.contenttypes.interfaces.persona import IPersona from plone import api from plone.restapi.interfaces import ISerializeToJsonSummary from plone.restapi.serializer.converters import json_compatible @@ -15,6 +16,7 @@ from zope.i18n import translate from zope.interface import implementer from zope.interface import Interface +from zope.schema import getFieldsInOrder import re @@ -145,3 +147,18 @@ def __call__(self, force_all_metadata=False): if "compensi" not in res: res["compensi"] = json_compatible(self.context.compensi) return res + + +@implementer(ISerializeToJsonSummary) +@adapter(IPersona, IDesignPloneContenttypesLayer) +class PersonaDefaultJSONSummarySerializer(DefaultJSONSummarySerializer): + def __call__(self, force_all_metadata=False): + res = super().__call__(force_all_metadata=force_all_metadata) + fields = dict(getFieldsInOrder(IPersona)) + field = fields["foto_persona"] + images_info_adapter = getMultiAdapter( + (field, self.context, IDesignPloneContenttypesLayer) + ) + if images_info_adapter: + res["foto_persona"] = images_info_adapter() + return res From 932d9a454991bb14515e22c38726a6759080ddfb Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Wed, 11 Jan 2023 09:22:25 +0100 Subject: [PATCH 054/487] fix taxonomies naming --- .../contenttypes/patches/baseserializer.py | 2 +- .../restapi/serializers/dxcontent.py | 2 +- .../restapi/serializers/summary.py | 6 ++--- .../plone/contenttypes/upgrades/upgrades.py | 23 +++++++++++-------- 4 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/design/plone/contenttypes/patches/baseserializer.py b/src/design/plone/contenttypes/patches/baseserializer.py index 321525dd..cc5220a9 100644 --- a/src/design/plone/contenttypes/patches/baseserializer.py +++ b/src/design/plone/contenttypes/patches/baseserializer.py @@ -33,7 +33,7 @@ def design_italia_serialize_to_json_call(self, version=None, include_items=True) ) if self.context.portal_type == "News Item": try: - tipologia_news = self.context.taxonomy_tipologia_notizia + tipologia_news = self.context.tipologia_notizia except AttributeError: # fallback if we don't have c.taxonomy configured yet tipologia_news = self.context.tipologia_notizia diff --git a/src/design/plone/contenttypes/restapi/serializers/dxcontent.py b/src/design/plone/contenttypes/restapi/serializers/dxcontent.py index 747954c1..2dcfd28e 100644 --- a/src/design/plone/contenttypes/restapi/serializers/dxcontent.py +++ b/src/design/plone/contenttypes/restapi/serializers/dxcontent.py @@ -41,7 +41,7 @@ def __call__(self, version=None, include_items=True): ttool = api.portal.get_tool("portal_types") if self.context.portal_type == "News Item": try: - tipologia_news = self.context.taxonomy_tipologia_notizia + tipologia_news = self.context.tipologia_notizia except AttributeError: # fallback if we don't have c.taxonomy configured yet tipologia_news = self.context.tipologia_notizia diff --git a/src/design/plone/contenttypes/restapi/serializers/summary.py b/src/design/plone/contenttypes/restapi/serializers/summary.py index 0bfa9e24..4abe6eed 100644 --- a/src/design/plone/contenttypes/restapi/serializers/summary.py +++ b/src/design/plone/contenttypes/restapi/serializers/summary.py @@ -136,9 +136,9 @@ def __call__(self, force_all_metadata=False): res = super().__call__(force_all_metadata=force_all_metadata) taxonomy = getUtility(ITaxonomy, name="collective.taxonomy.tipologia_incarico") taxonomy_voc = taxonomy.makeVocabulary(self.request.get("LANGUAGE")) - if "taxonomy_tipologia_incarico" not in res: - res["taxonomy_tipologia_incarico"] = taxonomy_voc.inv_data.get( - self.context.taxonomy_tipologia_incarico + if "tipologia_incarico" not in res: + res["tipologia_incarico"] = taxonomy_voc.inv_data.get( + self.context.tipologia_incarico ).replace(PATH_SEPARATOR, "") if "data_inizio_incarico" not in res: res["data_inizio_incarico"] = json_compatible( diff --git a/src/design/plone/contenttypes/upgrades/upgrades.py b/src/design/plone/contenttypes/upgrades/upgrades.py index 93d90df2..2bd0239a 100644 --- a/src/design/plone/contenttypes/upgrades/upgrades.py +++ b/src/design/plone/contenttypes/upgrades/upgrades.py @@ -1161,7 +1161,7 @@ def create_incarichi_folder(context): persona = brain.getObject() if target["id"] in persona: logger.info( - f"{colors.YELLOW} {persona.title} contiene già la cartella incrichi {colors.ENDC}" # noqa + f"{colors.YELLOW} {persona.title} contiene già la cartella incarichi {colors.ENDC}" # noqa ) continue suboject = api.content.create( @@ -1186,7 +1186,7 @@ def create_incarico_for_persona(context): logger.info( f"{colors.DARKCYAN} Inizio a creare gli incarichi delle persone {colors.ENDC}" ) - intids = getUtility(IIntIds) + # intids = getUtility(IIntIds) pc = api.portal.get_tool(name="portal_catalog") wftool = api.portal.get_tool(name="portal_workflow") brains = pc({"portal_type": "Persona"}) @@ -1204,7 +1204,8 @@ def create_incarico_for_persona(context): incarico = api.content.create( type="Incarico", title=persona.ruolo, container=incarichi_folder ) - incarico.persona = [RelationValue(intids.getId(persona))] + # incarico.persona = [RelationValue(intids.getId(persona))] + api.relation.create(source=incarico, target=persona, relationship="persona") if safe_hasattr(persona, "organizzazione_riferimento"): incarico.unita_organizzativa = persona.organizzazione_riferimento @@ -1229,15 +1230,19 @@ def create_incarico_for_persona(context): filename=persona.atto_nomina.filename, contentType="application/pdf", ) - atto_nomina.taxonomy_tipologia_documento = ["documento_attivita_politica"] - incarico.atto_nomina = [RelationValue(intids.getId(atto_nomina))] + atto_nomina.tipologia_documento = ["documento_attivita_politica"] + # incarico.atto_nomina = [RelationValue(intids.getId(atto_nomina))] + api.relation.create( + source=incarico, target=atto_nomina, relationship="atto_nomina" + ) if safe_hasattr(persona, "tipologia_persona"): - incarico.taxonomy_tipologia_incarico = MAPPING_TIPO[ - persona.tipologia_persona - ] + incarico.tipologia_incarico = MAPPING_TIPO[persona.tipologia_persona] - persona.incarichi_persona = [RelationValue(intids.getId(incarico))] + # persona.incarichi_persona = [RelationValue(intids.getId(incarico))] + api.relation.create( + source=persona, target=incarico, relationship="incarichi_persona" + ) if api.content.get_state(obj=persona) == "published": wftool.doActionFor(incarico, "publish") From f01a35c41ffb3d99639b3b8fbcf33171f361607a Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Wed, 11 Jan 2023 14:08:58 +0100 Subject: [PATCH 055/487] update delle informazioni di migrazione --- .../contenttypes/interfaces/documento.py | 73 +++++++------- .../behaviors/taxonomies/tipologia_pdc.xml | 6 ++ .../contenttypes/upgrades/configure.zcml | 5 + .../plone/contenttypes/upgrades/upgrades.py | 95 +++++++++++++++++++ 4 files changed, 142 insertions(+), 37 deletions(-) diff --git a/src/design/plone/contenttypes/interfaces/documento.py b/src/design/plone/contenttypes/interfaces/documento.py index 4c71007f..3e89a07d 100644 --- a/src/design/plone/contenttypes/interfaces/documento.py +++ b/src/design/plone/contenttypes/interfaces/documento.py @@ -4,7 +4,6 @@ from design.plone.contenttypes.interfaces import IDesignPloneContentType from plone.app.z3cform.widget import RelatedItemsFieldWidget from plone.autoform import directives as form -from plone.namedfile import field from plone.supermodel import model from z3c.relationfield.schema import RelationChoice from z3c.relationfield.schema import RelationList @@ -50,22 +49,22 @@ class IDocumento(model.Schema, IDesignPloneContentType): # ), # required=True, # ) - url = schema.URI( - title=_("url_documento_label", default="Link al documento"), - description=_( - "url_documento_help", - default="Link al documento vero e proprio, in un formato scaricabile attraverso una URL.", # noqa - ), - required=False, - ) - file_correlato = field.NamedBlobFile( - title=_("file_correlato_label", default="File correlato"), - description=_( - "file_correlato_help", - default="Se non è presente un link ad una risorsa esterna, ricordarsi di caricare l'allegato vero e proprio", # noqa - ), - required=False, - ) + # url = schema.URI( + # title=_("url_documento_label", default="Link al documento"), + # description=_( + # "url_documento_help", + # default="Link al documento vero e proprio, in un formato scaricabile attraverso una URL.", # noqa + # ), + # required=False, + # ) + # file_correlato = field.NamedBlobFile( + # title=_("file_correlato_label", default="File correlato"), + # description=_( + # "file_correlato_help", + # default="Se non è presente un link ad una risorsa esterna, ricordarsi di caricare l'allegato vero e proprio", # noqa + # ), + # required=False, + # ) ufficio_responsabile = RelationList( title=_( "ufficio_responsabile_documento_label", @@ -165,27 +164,27 @@ class IDocumento(model.Schema, IDesignPloneContentType): pattern_options={"maximumSelectionSize": 10, "selectableTypes": ["Dataset"]}, ) - servizi = RelationList( - title=_( - "servizi_label", - default="Servizi collegati", - ), - description=_( - "servizi_help", - default="Servizi collegati al documento", - ), - default=[], - required=False, - value_type=RelationChoice(vocabulary="plone.app.vocabularies.Catalog"), - ) + # servizi = RelationList( + # title=_( + # "servizi_label", + # default="Servizi collegati", + # ), + # description=_( + # "servizi_help", + # default="Servizi collegati al documento", + # ), + # default=[], + # required=False, + # value_type=RelationChoice(vocabulary="plone.app.vocabularies.Catalog"), + # ) - # custom widgets - form.widget( - "servizi", - RelatedItemsFieldWidget, - vocabulary="plone.app.vocabularies.Catalog", - pattern_options={"maximumSelectionSize": 20, "selectableTypes": ["Servizio"]}, - ) + # # custom widgets + # form.widget( + # "servizi", + # RelatedItemsFieldWidget, + # vocabulary="plone.app.vocabularies.Catalog", + # pattern_options={"maximumSelectionSize": 20, "selectableTypes": ["Servizio"]}, + # ) documenti_allegati = RelationList( title=_( diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_pdc.xml b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_pdc.xml index 6b723795..acbbc7aa 100644 --- a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_pdc.xml +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_pdc.xml @@ -22,6 +22,12 @@ Telefono + + fax + + Fax + + url diff --git a/src/design/plone/contenttypes/upgrades/configure.zcml b/src/design/plone/contenttypes/upgrades/configure.zcml index bdd78fd2..8a6ccc5c 100644 --- a/src/design/plone/contenttypes/upgrades/configure.zcml +++ b/src/design/plone/contenttypes/upgrades/configure.zcml @@ -614,5 +614,10 @@ description="Create incarichi objects" handler=".upgrades.create_incarico_for_persona" /> + diff --git a/src/design/plone/contenttypes/upgrades/upgrades.py b/src/design/plone/contenttypes/upgrades/upgrades.py index 2bd0239a..e5fbe179 100644 --- a/src/design/plone/contenttypes/upgrades/upgrades.py +++ b/src/design/plone/contenttypes/upgrades/upgrades.py @@ -1018,6 +1018,7 @@ def migrate_pdc_and_incarico(context): "fax": "fax", "email": "email", "pec": "pec", + "web": "web", }, }, # TODO: tbc @@ -1201,6 +1202,11 @@ def create_incarico_for_persona(context): incarichi_folder = persona["incarichi"] + if incarichi_folder.values(): + logger.info( + f"{colors.RED}{persona.title} ha già un incarico creato {colors.ENDC}" + ) # noqa + incarico = api.content.create( type="Incarico", title=persona.ruolo, container=incarichi_folder ) @@ -1256,3 +1262,92 @@ def create_incarico_for_persona(context): logger.info( f"{colors.DARKCYAN} Finito di creare gli incarichi delle persone{colors.ENDC}" ) + + +def create_pdc(context): + portal_types = ["UnitaOrganizzativa", "Persona", "Event", "Venue"] # ? + MAPPINGS = { + "Persona": { + "telefono": "telefono", + "fax": "fax", + "email": "email", + "pec": "pec", + }, + "UnitaOrganizzativa": { + "telefono": "telefono", + "fax": "fax", + "email": "email", + "pec": "pec", + "web": "url", + }, + "Event": { + "telefono": "telefono", + "fax": "fax", + "email": "email", + "web": "url", + }, + "Venue": { + "telefono": "telefono", + "fax": "fax", + "email": "email", + "pec": "pec", + "web": "url", + }, + } + pc = api.portal.get_tool(name="portal_catalog") + wftool = api.portal.get_tool(name="portal_workflow") + portal = api.portal.get() + punti_contatto_id = "punti-di-contatto" + punti_contatto_title = "Punti di contatto" + if "punti-di-contatto" not in portal: + punti_contatto = api.content.create( + type="Document", + id=punti_contatto_id, + title=punti_contatto_title, + container=portal, + ) + wftool.doActionFor(punti_contatto, "publish") + logger.info( + f"{colors.GREEN} Creato cartella punti di contatto nella radice del portal{colors.ENDC}" # noqa + ) # noqa + else: + punti_contatto = portal[punti_contatto_id] + + for portal_type in portal_types: + brains = pc(**{"portal_type": portal_type}) + for brain in brains: + obj = brain.getObject() + mapping = MAPPINGS["portal_type"] + pdc = api.content.create( + type="PuntoDiContatto", + title=f"Punto di contatto per: {obj.title}", + container=punti_contatto, + ) + api.relation.create(source=obj, target=pdc, relationship="contact_info") + data = [] + for field in mapping: + field_value = getattr(obj, field, None) + if field_value: + continue + if type(field_value) != list: + # in some case we have a f*****g list + field_value = [ + field_value, + ] + for value in field_value: + data.append( + { + "pdc_type": mapping[field], + "pdc_value": field_value, + } + ) + pdc.value_punto_contatto = data + + +# TODO +# collegarsi + + +# occhio che nel summary della UO devono esserci le info del punto di contatto... +# se la UO ha più punti di contatto? +# From 8aa1a9529aa131cc57625a3f313644e87a4edfb1 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Wed, 11 Jan 2023 14:57:56 +0100 Subject: [PATCH 056/487] upgrade pdc --- .../contenttypes/upgrades/configure.zcml | 7 +- .../plone/contenttypes/upgrades/upgrades.py | 64 +++++++++++-------- 2 files changed, 44 insertions(+), 27 deletions(-) diff --git a/src/design/plone/contenttypes/upgrades/configure.zcml b/src/design/plone/contenttypes/upgrades/configure.zcml index 8a6ccc5c..85d1b7c3 100644 --- a/src/design/plone/contenttypes/upgrades/configure.zcml +++ b/src/design/plone/contenttypes/upgrades/configure.zcml @@ -604,6 +604,11 @@ source="6011" destination="7000" > + diff --git a/src/design/plone/contenttypes/upgrades/upgrades.py b/src/design/plone/contenttypes/upgrades/upgrades.py index e5fbe179..99e7a886 100644 --- a/src/design/plone/contenttypes/upgrades/upgrades.py +++ b/src/design/plone/contenttypes/upgrades/upgrades.py @@ -999,7 +999,7 @@ def migrate_pdc_and_incarico(context): "fax": "fax", "email": "email", "pec": "pec", - }, + }, # noqa "Incarico": { # HOW? Need taxonomies also # We could do: @@ -1028,7 +1028,7 @@ def migrate_pdc_and_incarico(context): "fax": "fax", "email": "email", "pec": "pec", - }, + }, # noqa }, # TODO: tbc "Venue": { @@ -1047,7 +1047,7 @@ def migrate_pdc_and_incarico(context): "fax": "fax", "email": "email", "pec": "pec", - }, + }, # noqa }, } @@ -1150,6 +1150,16 @@ class colors(object): YELLOW = "\033[93m" +def to_7000(context): + update_types(context) + update_registry(context) + update_catalog(context) + update_rolemap(context) + logger.info( + f"{colors.DARKCYAN} Upgraded types, registry, catalog and rolemap {colors.ENDC}" # noqa + ) + + def create_incarichi_folder(context): logger.info( f"{colors.DARKCYAN} Inizio a creare la cartella Incarichi nelle persone {colors.ENDC}" # noqa @@ -1265,7 +1275,8 @@ def create_incarico_for_persona(context): def create_pdc(context): - portal_types = ["UnitaOrganizzativa", "Persona", "Event", "Venue"] # ? + portal_types = ["UnitaOrganizzativa", "Persona", "Event", "Venue"] + portal_types = ["Persona"] MAPPINGS = { "Persona": { "telefono": "telefono", @@ -1309,25 +1320,22 @@ def create_pdc(context): wftool.doActionFor(punti_contatto, "publish") logger.info( f"{colors.GREEN} Creato cartella punti di contatto nella radice del portal{colors.ENDC}" # noqa - ) # noqa + ) else: punti_contatto = portal[punti_contatto_id] for portal_type in portal_types: brains = pc(**{"portal_type": portal_type}) + logger.info( + f"{colors.YELLOW} Stiamo per creare i PDC per {len(brains)} oggetti di tipo {portal_type}{colors.ENDC}" # noqa + ) for brain in brains: obj = brain.getObject() - mapping = MAPPINGS["portal_type"] - pdc = api.content.create( - type="PuntoDiContatto", - title=f"Punto di contatto per: {obj.title}", - container=punti_contatto, - ) - api.relation.create(source=obj, target=pdc, relationship="contact_info") + mapping = MAPPINGS[portal_type] data = [] for field in mapping: field_value = getattr(obj, field, None) - if field_value: + if not field_value: continue if type(field_value) != list: # in some case we have a f*****g list @@ -1335,19 +1343,23 @@ def create_pdc(context): field_value, ] for value in field_value: - data.append( - { - "pdc_type": mapping[field], - "pdc_value": field_value, - } - ) - pdc.value_punto_contatto = data - + data.append({"pdc_type": mapping[field], "pdc_value": value}) -# TODO -# collegarsi + if not data: + continue + try: + del obj.contact_info + except AttributeError: + pass -# occhio che nel summary della UO devono esserci le info del punto di contatto... -# se la UO ha più punti di contatto? -# + pdc = api.content.create( + type="PuntoDiContatto", + title=f"Punto di contatto per: {obj.title}", + container=punti_contatto, + ) + api.relation.create(source=obj, target=pdc, relationship="contact_info") + pdc.value_punto_contatto = data + logger.info( + f"{colors.GREEN} Creato il punto di contatto per {obj.title}({obj.absolute_url()}){colors.ENDC}" # noqa + ) From 3fe3bb050e22505b57d1ba22ddfe952c4f632e66 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Wed, 11 Jan 2023 15:13:17 +0100 Subject: [PATCH 057/487] [fix] fix tests --- test_plone60.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_plone60.cfg b/test_plone60.cfg index c2d687ba..f6841596 100644 --- a/test_plone60.cfg +++ b/test_plone60.cfg @@ -6,7 +6,7 @@ extends = https://raw.githubusercontent.com/RedTurtle/dist.design.plone/main/versions.cfg base.cfg -update-versions-file = test_plone52.cfg +update-versions-file = test_plone60.cfg [versions] From 432a060f1f2a6af2097658afd42b628eaaedf2d4 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Wed, 11 Jan 2023 15:18:08 +0100 Subject: [PATCH 058/487] [fix] fix tests --- constraints.txt | 2 +- constraints_plone52.txt | 3 --- constraints_plone60.txt | 3 +++ requirements.txt | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) delete mode 100644 constraints_plone52.txt create mode 100644 constraints_plone60.txt diff --git a/constraints.txt b/constraints.txt index 24cbf877..c1fb3a1b 100644 --- a/constraints.txt +++ b/constraints.txt @@ -1 +1 @@ --c constraints_plone52.txt +-c constraints_plone60.txt diff --git a/constraints_plone52.txt b/constraints_plone52.txt deleted file mode 100644 index d96fee01..00000000 --- a/constraints_plone52.txt +++ /dev/null @@ -1,3 +0,0 @@ --c https://dist.plone.org/release/5.2-latest/requirements.txt -# setuptools==40.2.0 -# zc.buildout==2.12.2 diff --git a/constraints_plone60.txt b/constraints_plone60.txt new file mode 100644 index 00000000..db7aa0fa --- /dev/null +++ b/constraints_plone60.txt @@ -0,0 +1,3 @@ +-c https://dist.plone.org/release/6.0-latest/requirements.txt +# setuptools==40.2.0 +# zc.buildout==2.12.2 diff --git a/requirements.txt b/requirements.txt index fa2f6147..cab798d0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ --c constraints_plone52.txt +-c constraints_plone60.txt setuptools zc.buildout From 57aa19ef2b6818283265c13338007124cca5b3be Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Wed, 11 Jan 2023 15:21:26 +0100 Subject: [PATCH 059/487] [fix] action --- .github/workflows/test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index adfbdcee..f14f596f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,8 +8,8 @@ jobs: strategy: max-parallel: 4 matrix: - python: ["3.7"] - plone: ["52"] + python: ["3.9"] + plone: ["60"] # exclude: # - python: "3.7" # plone: "51" From 44ac164f6b47d299bd589b4b4fa780d795fff672 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Wed, 11 Jan 2023 16:02:31 +0100 Subject: [PATCH 060/487] Update test_plone60.cfg --- test_plone60.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_plone60.cfg b/test_plone60.cfg index f6841596..4e0366f1 100644 --- a/test_plone60.cfg +++ b/test_plone60.cfg @@ -1,7 +1,7 @@ [buildout] extends = - https://raw.github.com/collective/buildout.plonetest/master/test-5.2.x.cfg + https://raw.github.com/collective/buildout.plonetest/master/test-6.0.x.cfg https://raw.githubusercontent.com/collective/buildout.plonetest/master/qa.cfg https://raw.githubusercontent.com/RedTurtle/dist.design.plone/main/versions.cfg base.cfg From fbfc605aa803bc35abbbffd59512562ef489cc15 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Wed, 11 Jan 2023 16:27:55 +0100 Subject: [PATCH 061/487] finishing test per upgrade pdc --- src/design/plone/contenttypes/upgrades/upgrades.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/design/plone/contenttypes/upgrades/upgrades.py b/src/design/plone/contenttypes/upgrades/upgrades.py index 99e7a886..6cdd16ce 100644 --- a/src/design/plone/contenttypes/upgrades/upgrades.py +++ b/src/design/plone/contenttypes/upgrades/upgrades.py @@ -1276,7 +1276,6 @@ def create_incarico_for_persona(context): def create_pdc(context): portal_types = ["UnitaOrganizzativa", "Persona", "Event", "Venue"] - portal_types = ["Persona"] MAPPINGS = { "Persona": { "telefono": "telefono", From 06e3adc3a7282c02c8721798560cfea896235365 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Wed, 11 Jan 2023 16:38:52 +0100 Subject: [PATCH 062/487] Update test_plone60.cfg --- test_plone60.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_plone60.cfg b/test_plone60.cfg index 4e0366f1..e3436ebc 100644 --- a/test_plone60.cfg +++ b/test_plone60.cfg @@ -3,7 +3,7 @@ extends = https://raw.github.com/collective/buildout.plonetest/master/test-6.0.x.cfg https://raw.githubusercontent.com/collective/buildout.plonetest/master/qa.cfg - https://raw.githubusercontent.com/RedTurtle/dist.design.plone/main/versions.cfg + https://raw.githubusercontent.com/RedTurtle/dist.design.plone/6.0/versions.cfg base.cfg update-versions-file = test_plone60.cfg From 13ad44ee7fb065a2809a5f9fb06454e2cb1adf16 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Wed, 11 Jan 2023 17:14:21 +0100 Subject: [PATCH 063/487] [fix] field tempi_e_scadenze --- .../plone/contenttypes/interfaces/servizio.py | 16 +++++----- .../restapi/deserializers/dxfields.py | 30 ++++++++++++------- .../restapi/deserializers/servizio.py | 1 + .../restapi/serializers/dxfields.py | 7 ++--- 4 files changed, 32 insertions(+), 22 deletions(-) diff --git a/src/design/plone/contenttypes/interfaces/servizio.py b/src/design/plone/contenttypes/interfaces/servizio.py index b685a248..c3028f67 100644 --- a/src/design/plone/contenttypes/interfaces/servizio.py +++ b/src/design/plone/contenttypes/interfaces/servizio.py @@ -1,8 +1,11 @@ # -*- coding: utf-8 -*- from collective.volto.blocksfield.field import BlocksField +from collective.z3cform.datagridfield.datagridfield import DataGridFieldFactory +from collective.z3cform.datagridfield.row import DictRow from design.plone.contenttypes import _ from design.plone.contenttypes.interfaces import IDesignPloneContentType from plone.app.dexterity import textindexer +from plone.app.z3cform.widget import DateFieldWidget from plone.app.z3cform.widget import RelatedItemsFieldWidget from plone.autoform import directives as form from plone.namedfile import field @@ -10,9 +13,6 @@ from z3c.relationfield.schema import RelationChoice from z3c.relationfield.schema import RelationList from zope import schema -from collective.z3cform.datagridfield.row import DictRow -from collective.z3cform.datagridfield.datagridfield import DataGridFieldFactory -from plone.app.z3cform.widget import DateFieldWidget class ITempiEScadenzeValueSchema(model.Schema): @@ -46,8 +46,7 @@ class ITempiEScadenzeValueSchema(model.Schema): title=_("interval_type_label", default="Tipo intervallo"), description=_( "interval_type_help", - default="Ad esempio: " - "ore, giorni, settimane, mesi.", + default="Ad esempio: " "ore, giorni, settimane, mesi.", ), required=False, default="", @@ -259,9 +258,10 @@ class IServizio(model.Schema, IDesignPloneContentType): value_type=DictRow(schema=ITempiEScadenzeValueSchema), description=_( "timeline_tempi_scadenze_help", - default="Timeline tempi e scadenze del servizio: indicare per ogni scadenza " - "un titolo descritttivo di tale scadenza e, opzionalmente, informazioni sulle" - " date o gli intervalli di tempo che intercorrono tra una fase e la successiva.", + default="Timeline tempi e scadenze del servizio: indicare per ogni " + "scadenza un titolo descritttivo di tale scadenza e, opzionalmente," + " informazioni sulle date o gli intervalli di tempo che " + "intercorrono tra una fase e la successiva.", ), required=False, ) diff --git a/src/design/plone/contenttypes/restapi/deserializers/dxfields.py b/src/design/plone/contenttypes/restapi/deserializers/dxfields.py index d95d713d..1edf89f2 100644 --- a/src/design/plone/contenttypes/restapi/deserializers/dxfields.py +++ b/src/design/plone/contenttypes/restapi/deserializers/dxfields.py @@ -1,21 +1,22 @@ # -*- coding: utf-8 -*- +from datetime import datetime from design.plone.contenttypes import _ from design.plone.contenttypes.interfaces import IDesignPloneContenttypesLayer +from design.plone.contenttypes.interfaces.servizio import IServizio from plone.dexterity.interfaces import IDexterityContent from plone.formwidget.geolocation.geolocation import Geolocation from plone.formwidget.geolocation.interfaces import IGeolocationField -from plone.restapi.deserializer.dxfields import DefaultFieldDeserializer, CollectionFieldDeserializer +from plone.restapi.deserializer.dxfields import CollectionFieldDeserializer +from plone.restapi.deserializer.dxfields import DefaultFieldDeserializer from plone.restapi.interfaces import IBlockFieldDeserializationTransformer from plone.restapi.interfaces import IFieldDeserializer +from zExceptions import BadRequest from zope.component import adapter from zope.component import subscribers from zope.i18n import translate from zope.interface import implementer -from zope.schema.interfaces import ISourceText -from datetime import datetime -from design.plone.contenttypes.interfaces.servizio import IServizio from zope.schema.interfaces import IList -from zExceptions import BadRequest +from zope.schema.interfaces import ISourceText import json @@ -91,24 +92,33 @@ class TimelineTempiEScadenzeFieldDeserializer(CollectionFieldDeserializer): field), I'll have to do some serializing magic in Servizio serializer. Also validate milestone field, frontend should take care of it, but you never know. """ + def __call__(self, value): if self.field.getName() != "timeline_tempi_scadenze" or not value: return super().__call__(value) + timeline = [] for item in value: if not item.get("milestone", None): - raise BadRequest({ - "error": "ValidationError", - "message": "Il campo {} è obbligatorio".format("Titolo della fase") - }) + raise BadRequest( + { + "error": "ValidationError", + "message": "Il campo {} è obbligatorio".format( + "Titolo della fase" + ), + } + ) + entry = { "milestone": item.get("milestone", ""), "milestone_description": item.get("milestone_description", ""), "interval_qt": item.get("interval_qt", ""), "interval_type": item.get("interval_type", ""), "data_scadenza": datetime.strptime( - item.get("data_scadenza") or "1969-01-01", "%Y-%m-%d" + item["data_scadenza"], "%Y-%m-%d" ).date() + if item.get("data_scadenza", None) + else None, # noqa } timeline.append(entry) diff --git a/src/design/plone/contenttypes/restapi/deserializers/servizio.py b/src/design/plone/contenttypes/restapi/deserializers/servizio.py index 09fdff14..9687d776 100644 --- a/src/design/plone/contenttypes/restapi/deserializers/servizio.py +++ b/src/design/plone/contenttypes/restapi/deserializers/servizio.py @@ -140,6 +140,7 @@ def __call__( if errors: raise BadRequest(errors) + return super(DeserializeServizioFromJson, self).__call__( validate_all=False, data=data, create=False ) diff --git a/src/design/plone/contenttypes/restapi/serializers/dxfields.py b/src/design/plone/contenttypes/restapi/serializers/dxfields.py index 159928f5..08fc4bdc 100644 --- a/src/design/plone/contenttypes/restapi/serializers/dxfields.py +++ b/src/design/plone/contenttypes/restapi/serializers/dxfields.py @@ -14,7 +14,8 @@ from zope.component import subscribers from zope.globalrequest import getRequest from zope.interface import implementer -from zope.schema.interfaces import ISourceText, IList +from zope.schema.interfaces import IList +from zope.schema.interfaces import ISourceText import json @@ -39,10 +40,8 @@ def __call__(self): value = super(TempiEScadenzeValueSerializer, self).__call__() patched_timeline = [] - if self.field.getName() == 'timeline_tempi_scadenze' and value: + if self.field.getName() == "timeline_tempi_scadenze" and value: for entry in value: - if entry.get("data_scadenza", "1969-01-01") == "1969-01-01": - entry["data_scadenza"] = "" patched_timeline.append(entry) return json_compatible(patched_timeline) return value From 4318b876350590fbbb0590ce1da1a137e7f42790 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Wed, 11 Jan 2023 17:20:17 +0100 Subject: [PATCH 064/487] [fix] fixed field canale_fisico --- src/design/plone/contenttypes/interfaces/servizio.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/design/plone/contenttypes/interfaces/servizio.py b/src/design/plone/contenttypes/interfaces/servizio.py index c3028f67..607f411c 100644 --- a/src/design/plone/contenttypes/interfaces/servizio.py +++ b/src/design/plone/contenttypes/interfaces/servizio.py @@ -410,6 +410,15 @@ class IServizio(model.Schema, IDesignPloneContentType): ) # custom widgets + form.widget( + "canale_fisico", + RelatedItemsFieldWidget, + vocabulary="plone.app.vocabularies.Catalog", + pattern_options={ + "maximumSelectionSize": 10, + "selectableTypes": ["UnitaOrganizzativa"], + }, + ) form.widget( "dove_rivolgersi", RelatedItemsFieldWidget, From 928e256865ed838f1ce47b1f1992a10d36db936b Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Wed, 11 Jan 2023 17:58:54 +0100 Subject: [PATCH 065/487] update summary serialization for UO --- .../restapi/serializers/configure.zcml | 3 ++- .../restapi/serializers/persona.py | 20 +++++++++++++++++++ .../restapi/serializers/summary.py | 15 ++++---------- .../serializers/unita_organizzativa.py | 5 +++-- 4 files changed, 29 insertions(+), 14 deletions(-) diff --git a/src/design/plone/contenttypes/restapi/serializers/configure.zcml b/src/design/plone/contenttypes/restapi/serializers/configure.zcml index 1fb1049d..2efefef4 100644 --- a/src/design/plone/contenttypes/restapi/serializers/configure.zcml +++ b/src/design/plone/contenttypes/restapi/serializers/configure.zcml @@ -6,13 +6,14 @@ - + + diff --git a/src/design/plone/contenttypes/restapi/serializers/persona.py b/src/design/plone/contenttypes/restapi/serializers/persona.py index 830606e1..2ea11119 100644 --- a/src/design/plone/contenttypes/restapi/serializers/persona.py +++ b/src/design/plone/contenttypes/restapi/serializers/persona.py @@ -1,7 +1,11 @@ # -*- coding: utf-8 -*- from .related_news_serializer import SerializeFolderToJson from Acquisition import aq_inner +from design.plone.contenttypes.interfaces import IDesignPloneContenttypesLayer from design.plone.contenttypes.interfaces.persona import IPersona +from design.plone.contenttypes.restapi.serializers.summary import ( + DefaultJSONSummarySerializer, +) from plone.restapi.interfaces import ISerializeToJson from plone.restapi.interfaces import ISerializeToJsonSummary from zc.relation.interfaces import ICatalog @@ -12,6 +16,7 @@ from zope.interface import implementer from zope.interface import Interface from zope.intid.interfaces import IIntIds +from zope.schema import getFieldsInOrder from zope.security import checkPermission @@ -56,3 +61,18 @@ def __call__(self, version=None, include_items=True): if assessore_di: result["assessore_di"] = assessore_di return result + + +@implementer(ISerializeToJsonSummary) +@adapter(IPersona, IDesignPloneContenttypesLayer) +class PersonaDefaultJSONSummarySerializer(DefaultJSONSummarySerializer): + def __call__(self, force_all_metadata=False): + res = super().__call__(force_all_metadata=force_all_metadata) + fields = dict(getFieldsInOrder(IPersona)) + field = fields["foto_persona"] + images_info_adapter = getMultiAdapter( + (field, self.context, IDesignPloneContenttypesLayer) + ) + if images_info_adapter: + res["foto_persona"] = images_info_adapter() + return res diff --git a/src/design/plone/contenttypes/restapi/serializers/summary.py b/src/design/plone/contenttypes/restapi/serializers/summary.py index 4abe6eed..dcbc4fa9 100644 --- a/src/design/plone/contenttypes/restapi/serializers/summary.py +++ b/src/design/plone/contenttypes/restapi/serializers/summary.py @@ -3,7 +3,7 @@ from collective.taxonomy.interfaces import ITaxonomy from design.plone.contenttypes.interfaces import IDesignPloneContenttypesLayer from design.plone.contenttypes.interfaces.incarico import IIncarico -from design.plone.contenttypes.interfaces.persona import IPersona +from design.plone.contenttypes.interfaces.punto_di_contatto import IPuntoDiContatto from plone import api from plone.restapi.interfaces import ISerializeToJsonSummary from plone.restapi.serializer.converters import json_compatible @@ -16,7 +16,6 @@ from zope.i18n import translate from zope.interface import implementer from zope.interface import Interface -from zope.schema import getFieldsInOrder import re @@ -150,15 +149,9 @@ def __call__(self, force_all_metadata=False): @implementer(ISerializeToJsonSummary) -@adapter(IPersona, IDesignPloneContenttypesLayer) -class PersonaDefaultJSONSummarySerializer(DefaultJSONSummarySerializer): +@adapter(IPuntoDiContatto, IDesignPloneContenttypesLayer) +class PuntoDiContattoDefaultJSONSummarySerializer(DefaultJSONSummarySerializer): def __call__(self, force_all_metadata=False): res = super().__call__(force_all_metadata=force_all_metadata) - fields = dict(getFieldsInOrder(IPersona)) - field = fields["foto_persona"] - images_info_adapter = getMultiAdapter( - (field, self.context, IDesignPloneContenttypesLayer) - ) - if images_info_adapter: - res["foto_persona"] = images_info_adapter() + res["value_punto_contatto"] = self.context.value_punto_contatto return res diff --git a/src/design/plone/contenttypes/restapi/serializers/unita_organizzativa.py b/src/design/plone/contenttypes/restapi/serializers/unita_organizzativa.py index 6cb03a36..70a2d283 100644 --- a/src/design/plone/contenttypes/restapi/serializers/unita_organizzativa.py +++ b/src/design/plone/contenttypes/restapi/serializers/unita_organizzativa.py @@ -118,13 +118,14 @@ def __call__(self, force_all_metadata=False): "address", "city", "zip_code", - "email", - "telefono", + # "email", + # "telefono", "nome_sede", "title", "quartiere", "circoscrizione", "street", + "contact_info", ] for field in fields: From 597c36a6578ddf16778ac09ac8eb5e677b6cad7b Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Wed, 11 Jan 2023 18:21:23 +0100 Subject: [PATCH 066/487] [fix] minor fix --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f14f596f..9a0ddf41 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,7 +8,7 @@ jobs: strategy: max-parallel: 4 matrix: - python: ["3.9"] + python: ["3.8"] plone: ["60"] # exclude: # - python: "3.7" From 7660187664a4726faa0effdb69bd870e8df22e89 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Thu, 12 Jan 2023 09:20:28 +0100 Subject: [PATCH 067/487] [fix] minor fix for buildout --- base.cfg | 2 -- test_plone60.cfg | 51 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/base.cfg b/base.cfg index e3a343d0..6cab78b7 100644 --- a/base.cfg +++ b/base.cfg @@ -112,8 +112,6 @@ mode = 755 [versions] # Don't use a released version of design.plone.contenttypes design.plone.contenttypes = -plone.namedfile = 5.4.0 -importlib-metadata = 1.0.0 [sources] #collective.volto.blocksfield = git https://github.com/collective/collective.volto.blocksfield.git pushurl=git@github.com:collective/collective.volto.blocksfield.git branch=main diff --git a/test_plone60.cfg b/test_plone60.cfg index e3436ebc..68afffe6 100644 --- a/test_plone60.cfg +++ b/test_plone60.cfg @@ -28,3 +28,54 @@ collective.purgebyid = 1.1.1 # flake8-debugger==3.2.1 # flake8-print==3.1.4 pycodestyle = 2.7.0 + +# Added by buildout at 2023-01-12 09:16:52.328614 +bleach = 5.0.1 +build = 0.9.0 +commonmark = 0.9.1 +i18ndude = 5.3.4 +keyring = 23.11.0 +pep517 = 0.13.0 +pkginfo = 1.8.3 +readme-renderer = 37.3 +requests-toolbelt = 0.10.1 +rfc3986 = 2.0.0 +rich = 12.6.0 +twine = 4.0.1 +zest.releaser = 7.2.0 + +# Required by: +# plone.recipe.codeanalysis==3.0.1 +check-manifest = 0.48 + +# Required by: +# eea.api.taxonomy==1.5 +collective.taxonomy = 3.0.0 + +# Required by: +# design.plone.contenttypes==6.0.0.dev0 +collective.z3cform.datagridfield = 2.0 + +# Required by: +# zest.releaser==7.2.0 +colorama = 0.4.6 + +# Required by: +# design.plone.contenttypes==6.0.0.dev0 +eea.api.taxonomy = 1.5 + +# Required by: +# keyring==23.11.0 +jaraco.classes = 3.2.3 + +# Required by: +# jaraco.classes==3.2.3 +more-itertools = 9.0.0 + +# Required by: +# check-manifest==0.48 +tomli = 2.0.1 + +# Required by: +# bleach==5.0.1 +webencodings = 0.5.1 From 5b74b1391b8375462f7a72d000b34f5e8ca12c24 Mon Sep 17 00:00:00 2001 From: Martina Bustacchini Date: Thu, 12 Jan 2023 09:26:55 +0100 Subject: [PATCH 068/487] fix: persona serializer foto_persona --- src/design/plone/contenttypes/restapi/serializers/summary.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/design/plone/contenttypes/restapi/serializers/summary.py b/src/design/plone/contenttypes/restapi/serializers/summary.py index 4abe6eed..fa01231f 100644 --- a/src/design/plone/contenttypes/restapi/serializers/summary.py +++ b/src/design/plone/contenttypes/restapi/serializers/summary.py @@ -160,5 +160,8 @@ def __call__(self, force_all_metadata=False): (field, self.context, IDesignPloneContenttypesLayer) ) if images_info_adapter: - res["foto_persona"] = images_info_adapter() + res["image_scales"] = { + "foto_persona": [images_info_adapter()], + } + res["image_field"] = "foto_persona" return res From 1bfab5fad6c11e537cbb8934b73a8a5531bb41da Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Thu, 12 Jan 2023 09:47:02 +0100 Subject: [PATCH 069/487] add new field to uo --- .../interfaces/unita_organizzativa.py | 30 +++++++++++++++++++ .../plone/contenttypes/upgrades/upgrades.py | 1 + 2 files changed, 31 insertions(+) diff --git a/src/design/plone/contenttypes/interfaces/unita_organizzativa.py b/src/design/plone/contenttypes/interfaces/unita_organizzativa.py index 33dfea62..f7e25505 100644 --- a/src/design/plone/contenttypes/interfaces/unita_organizzativa.py +++ b/src/design/plone/contenttypes/interfaces/unita_organizzativa.py @@ -125,7 +125,29 @@ class IUnitaOrganizzativa(model.Schema, IDesignPloneContentType): required=False, ) + documenti_pubblici = RelationList( + title=_("documenti_pubblici_label", default="Documenti pubblici"), + default=[], + description=_( + "documenti_pubblici_help", + default="Documenti pubblici importanti, collegati a questa Unità Organizzativa", # noqa + ), + value_type=RelationChoice( + title=_("Documenti pubblici"), vocabulary="plone.app.vocabularies.Catalog" + ), + required=False, + ) + #  custom widgets + form.widget( + "documenti_pubblici", + RelatedItemsFieldWidget, + vocabulary="plone.app.vocabularies.Catalog", + pattern_options={ + "maximumSelectionSize": 10, + "selectableTypes": ["Documento"], + }, + ) form.widget( "persone_struttura", RelatedItemsFieldWidget, @@ -203,7 +225,15 @@ class IUnitaOrganizzativa(model.Schema, IDesignPloneContentType): label=_("contatti_label", default="Contatti"), fields=["sede", "sedi_secondarie"], ) + + model.fieldset( + "correlati", + label=_("correlati_label", default="Contenuti collegati"), + fields=["documenti_pubblici"], + ) + form.order_after(sedi_secondarie="IContattiUnitaOrganizzativa.orario_pubblico") + form.order_after(documenti_pubblici="relatedItems") # form.order_after(contact_info="sedi_secondarie") # SearchableText indexers diff --git a/src/design/plone/contenttypes/upgrades/upgrades.py b/src/design/plone/contenttypes/upgrades/upgrades.py index 6cdd16ce..f2968d22 100644 --- a/src/design/plone/contenttypes/upgrades/upgrades.py +++ b/src/design/plone/contenttypes/upgrades/upgrades.py @@ -1348,6 +1348,7 @@ def create_pdc(context): continue try: + obj.old_contact_info = obj.contact_info del obj.contact_info except AttributeError: pass From dfdb312003e9672609e4cdb9bdad53107fad6648 Mon Sep 17 00:00:00 2001 From: Martina Bustacchini Date: Thu, 12 Jan 2023 10:04:47 +0100 Subject: [PATCH 070/487] fix pre merge conflicts --- .../restapi/serializers/configure.zcml | 2 +- .../restapi/serializers/summary.py | 29 +++++++++++++------ 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/src/design/plone/contenttypes/restapi/serializers/configure.zcml b/src/design/plone/contenttypes/restapi/serializers/configure.zcml index 9336011a..dbef8618 100644 --- a/src/design/plone/contenttypes/restapi/serializers/configure.zcml +++ b/src/design/plone/contenttypes/restapi/serializers/configure.zcml @@ -7,6 +7,7 @@ + @@ -24,5 +25,4 @@ - diff --git a/src/design/plone/contenttypes/restapi/serializers/summary.py b/src/design/plone/contenttypes/restapi/serializers/summary.py index fa01231f..1191b9c8 100644 --- a/src/design/plone/contenttypes/restapi/serializers/summary.py +++ b/src/design/plone/contenttypes/restapi/serializers/summary.py @@ -4,6 +4,7 @@ from design.plone.contenttypes.interfaces import IDesignPloneContenttypesLayer from design.plone.contenttypes.interfaces.incarico import IIncarico from design.plone.contenttypes.interfaces.persona import IPersona +from design.plone.contenttypes.interfaces.punto_di_contatto import IPuntoDiContatto from plone import api from plone.restapi.interfaces import ISerializeToJsonSummary from plone.restapi.serializer.converters import json_compatible @@ -149,19 +150,29 @@ def __call__(self, force_all_metadata=False): return res +@implementer(ISerializeToJsonSummary) +@adapter(IPuntoDiContatto, IDesignPloneContenttypesLayer) +class PuntoDiContattoDefaultJSONSummarySerializer(DefaultJSONSummarySerializer): + def __call__(self, force_all_metadata=False): + res = super().__call__(force_all_metadata=force_all_metadata) + res["value_punto_contatto"] = self.context.value_punto_contatto + return res + + @implementer(ISerializeToJsonSummary) @adapter(IPersona, IDesignPloneContenttypesLayer) class PersonaDefaultJSONSummarySerializer(DefaultJSONSummarySerializer): def __call__(self, force_all_metadata=False): res = super().__call__(force_all_metadata=force_all_metadata) fields = dict(getFieldsInOrder(IPersona)) - field = fields["foto_persona"] - images_info_adapter = getMultiAdapter( - (field, self.context, IDesignPloneContenttypesLayer) - ) - if images_info_adapter: - res["image_scales"] = { - "foto_persona": [images_info_adapter()], - } - res["image_field"] = "foto_persona" + field = fields.get("foto_persona", None) + if field: + images_info_adapter = getMultiAdapter( + (field, self.context, IDesignPloneContenttypesLayer) + ) + if images_info_adapter: + res["image_scales"] = { + "foto_persona": [images_info_adapter()], + } + res["image_field"] = "foto_persona" return res From c2a6cca5717e0449d69bc95134dcf21b4620f468 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Thu, 12 Jan 2023 10:56:15 +0100 Subject: [PATCH 071/487] fix problem with uo serialization --- .../restapi/serializers/punto_di_contatto.py | 24 ++++++++++++++----- .../serializers/unita_organizzativa.py | 6 ++++- .../plone/contenttypes/upgrades/upgrades.py | 10 ++++---- 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/src/design/plone/contenttypes/restapi/serializers/punto_di_contatto.py b/src/design/plone/contenttypes/restapi/serializers/punto_di_contatto.py index 37d433a7..adec3049 100644 --- a/src/design/plone/contenttypes/restapi/serializers/punto_di_contatto.py +++ b/src/design/plone/contenttypes/restapi/serializers/punto_di_contatto.py @@ -1,10 +1,10 @@ # -*- coding: utf-8 -*- from .related_news_serializer import SerializeFolderToJson from Acquisition import aq_inner +from design.plone.contenttypes.interfaces.punto_di_contatto import IPuntoDiContatto from design.plone.contenttypes.restapi.serializers.summary import ( DefaultJSONSummarySerializer, ) -from design.plone.contenttypes.interfaces.punto_di_contatto import IPuntoDiContatto from plone.dexterity.utils import iterSchemata from plone.restapi.interfaces import IFieldSerializer from plone.restapi.interfaces import ISerializeToJson @@ -62,7 +62,11 @@ def related_contents(self, field, portal_type): for rel in relations: obj = intids.queryObject(rel.from_id) - if obj is not None and checkPermission("zope2.View", obj) and getattr(obj, 'portal_type', None) == portal_type: + if ( + obj is not None + and checkPermission("zope2.View", obj) + and getattr(obj, "portal_type", None) == portal_type + ): summary = getMultiAdapter( (obj, getRequest()), ISerializeToJsonSummary )() @@ -73,10 +77,18 @@ def __call__(self, version=None, include_items=True): result = super(PuntoDiContattoSerializer, self).__call__( version=version, include_items=include_items ) - strutture_correlate = self.related_contents(field="contact_info", portal_type="UnitaOrganizzativa") - servizi_correlati = self.related_contents(field="contact_info", portal_type="Servizio") - luoghi_correlati = self.related_contents(field="contact_info", portal_type="Venue") - persone_correlate = self.related_contents(field="contact_info", portal_type="Persona") + strutture_correlate = self.related_contents( + field="contact_info", portal_type="UnitaOrganizzativa" + ) + servizi_correlati = self.related_contents( + field="contact_info", portal_type="Servizio" + ) + luoghi_correlati = self.related_contents( + field="contact_info", portal_type="Venue" + ) + persone_correlate = self.related_contents( + field="contact_info", portal_type="Persona" + ) if strutture_correlate: result["strutture_correlate"] = strutture_correlate diff --git a/src/design/plone/contenttypes/restapi/serializers/unita_organizzativa.py b/src/design/plone/contenttypes/restapi/serializers/unita_organizzativa.py index 70a2d283..fe23c272 100644 --- a/src/design/plone/contenttypes/restapi/serializers/unita_organizzativa.py +++ b/src/design/plone/contenttypes/restapi/serializers/unita_organizzativa.py @@ -8,6 +8,7 @@ from plone import api from plone.restapi.interfaces import ISerializeToJson from plone.restapi.interfaces import ISerializeToJsonSummary +from plone.restapi.serializer.converters import json_compatible from zc.relation.interfaces import ICatalog from zope.component import adapter from zope.component import getMultiAdapter @@ -129,7 +130,10 @@ def __call__(self, force_all_metadata=False): ] for field in fields: - data[field] = getattr(self.context, field, "") + if field == "contact_info": + data[field] = json_compatible(getattr(self.context, field, "")) + else: + data[field] = getattr(self.context, field, "") data["geolocation"] = self.getGeolocation() diff --git a/src/design/plone/contenttypes/upgrades/upgrades.py b/src/design/plone/contenttypes/upgrades/upgrades.py index 0cdfe330..17b1bb0d 100644 --- a/src/design/plone/contenttypes/upgrades/upgrades.py +++ b/src/design/plone/contenttypes/upgrades/upgrades.py @@ -994,7 +994,7 @@ def migrate_pdc_and_incarico(context): # "field name in original ct": "field name in new ct" type_mapping = { "Persona": { - 'PDC': { + "PDC": { "telefono": "telefono", "fax": "fax", "email": "email", @@ -1013,7 +1013,7 @@ def migrate_pdc_and_incarico(context): }, }, "UnitaOrganizzativa": { - 'PDC': { + "PDC": { "telefono": "telefono", "fax": "fax", "email": "email", @@ -1023,7 +1023,7 @@ def migrate_pdc_and_incarico(context): }, # TODO: tbc "Event": { - 'PDC': { + "PDC": { "telefono": "telefono", "fax": "fax", "email": "email", @@ -1032,7 +1032,7 @@ def migrate_pdc_and_incarico(context): }, # TODO: tbc "Venue": { - 'PDC': { + "PDC": { "riferimento_telefonico_struttura": "telefono", "riferimento_fax_struttura": "fax", "riferimento_mail_struttura": "email", @@ -1042,7 +1042,7 @@ def migrate_pdc_and_incarico(context): # TODO: tbc "Servizio": { # questi non sono presenti sul ct originale - 'PDC': { + "PDC": { "telefono": "telefono", "fax": "fax", "email": "email", From 6ae1ca96b4e0dcdfb1987b2170fda77f1059d4f8 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Thu, 12 Jan 2023 11:07:51 +0100 Subject: [PATCH 072/487] fix problem with uo summary serialization --- .../contenttypes/restapi/serializers/unita_organizzativa.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/design/plone/contenttypes/restapi/serializers/unita_organizzativa.py b/src/design/plone/contenttypes/restapi/serializers/unita_organizzativa.py index 70a2d283..fe23c272 100644 --- a/src/design/plone/contenttypes/restapi/serializers/unita_organizzativa.py +++ b/src/design/plone/contenttypes/restapi/serializers/unita_organizzativa.py @@ -8,6 +8,7 @@ from plone import api from plone.restapi.interfaces import ISerializeToJson from plone.restapi.interfaces import ISerializeToJsonSummary +from plone.restapi.serializer.converters import json_compatible from zc.relation.interfaces import ICatalog from zope.component import adapter from zope.component import getMultiAdapter @@ -129,7 +130,10 @@ def __call__(self, force_all_metadata=False): ] for field in fields: - data[field] = getattr(self.context, field, "") + if field == "contact_info": + data[field] = json_compatible(getattr(self.context, field, "")) + else: + data[field] = getattr(self.context, field, "") data["geolocation"] = self.getGeolocation() From ec7bc4fb31069025f8df3be29bee06a22cf39308 Mon Sep 17 00:00:00 2001 From: Martina Bustacchini Date: Thu, 12 Jan 2023 11:40:18 +0100 Subject: [PATCH 073/487] fix: configure, persona serializer and uo serializer --- .../restapi/serializers/configure.zcml | 1 - .../restapi/serializers/persona.py | 20 ------------------- .../serializers/unita_organizzativa.py | 4 ++-- 3 files changed, 2 insertions(+), 23 deletions(-) diff --git a/src/design/plone/contenttypes/restapi/serializers/configure.zcml b/src/design/plone/contenttypes/restapi/serializers/configure.zcml index 03ea7c27..dbef8618 100644 --- a/src/design/plone/contenttypes/restapi/serializers/configure.zcml +++ b/src/design/plone/contenttypes/restapi/serializers/configure.zcml @@ -14,7 +14,6 @@ - diff --git a/src/design/plone/contenttypes/restapi/serializers/persona.py b/src/design/plone/contenttypes/restapi/serializers/persona.py index 2ea11119..830606e1 100644 --- a/src/design/plone/contenttypes/restapi/serializers/persona.py +++ b/src/design/plone/contenttypes/restapi/serializers/persona.py @@ -1,11 +1,7 @@ # -*- coding: utf-8 -*- from .related_news_serializer import SerializeFolderToJson from Acquisition import aq_inner -from design.plone.contenttypes.interfaces import IDesignPloneContenttypesLayer from design.plone.contenttypes.interfaces.persona import IPersona -from design.plone.contenttypes.restapi.serializers.summary import ( - DefaultJSONSummarySerializer, -) from plone.restapi.interfaces import ISerializeToJson from plone.restapi.interfaces import ISerializeToJsonSummary from zc.relation.interfaces import ICatalog @@ -16,7 +12,6 @@ from zope.interface import implementer from zope.interface import Interface from zope.intid.interfaces import IIntIds -from zope.schema import getFieldsInOrder from zope.security import checkPermission @@ -61,18 +56,3 @@ def __call__(self, version=None, include_items=True): if assessore_di: result["assessore_di"] = assessore_di return result - - -@implementer(ISerializeToJsonSummary) -@adapter(IPersona, IDesignPloneContenttypesLayer) -class PersonaDefaultJSONSummarySerializer(DefaultJSONSummarySerializer): - def __call__(self, force_all_metadata=False): - res = super().__call__(force_all_metadata=force_all_metadata) - fields = dict(getFieldsInOrder(IPersona)) - field = fields["foto_persona"] - images_info_adapter = getMultiAdapter( - (field, self.context, IDesignPloneContenttypesLayer) - ) - if images_info_adapter: - res["foto_persona"] = images_info_adapter() - return res diff --git a/src/design/plone/contenttypes/restapi/serializers/unita_organizzativa.py b/src/design/plone/contenttypes/restapi/serializers/unita_organizzativa.py index fe23c272..ed53c45e 100644 --- a/src/design/plone/contenttypes/restapi/serializers/unita_organizzativa.py +++ b/src/design/plone/contenttypes/restapi/serializers/unita_organizzativa.py @@ -60,7 +60,7 @@ def getChildrenUo(self): for child in children: data = getMultiAdapter((child, self.request), ISerializeToJsonSummary)() data.update(self.getAdditionalInfos(context=child)) - res.append(data) + res.append(json_compatible(data)) return res def getParentUo(self): @@ -70,7 +70,7 @@ def getParentUo(self): data = getMultiAdapter((parent, self.request), ISerializeToJsonSummary)() data.update(self.getAdditionalInfos(context=parent)) - return data + return json_compatible(data) def getAdditionalInfos(self, context): return { From da52ac84fed3ae7a6e0d04048bd7161c79a9fee4 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Thu, 12 Jan 2023 13:14:22 +0100 Subject: [PATCH 074/487] [doc] update CHANGES + update setup.py --- CHANGES.rst | 7 +++++-- setup.py | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 6a851953..ccf10581 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -2,11 +2,14 @@ Changelog ========= -5.0.4 (unreleased) ------------------- +6.0.0a1 (unreleased) +-------------------- - Remove collective.dexteritytextindexer dependency (it's in core). [cekk] +- Adjustments to the pnrr. + [deodorhunter, lucabel, eikichi18] + 5.0.3 (2022-12-07) ------------------ diff --git a/setup.py b/setup.py index a5e6869a..58056d82 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.0.0.dev0", + version="6.0.0a1.dev0", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 68468ddf3cc1ad2a7ab684352bd1ba69c1021caf Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Thu, 12 Jan 2023 13:14:49 +0100 Subject: [PATCH 075/487] Preparing release 6.0.0a1 --- CHANGES.rst | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index ccf10581..2f311001 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -2,7 +2,7 @@ Changelog ========= -6.0.0a1 (unreleased) +6.0.0a1 (2023-01-12) -------------------- - Remove collective.dexteritytextindexer dependency (it's in core). diff --git a/setup.py b/setup.py index 58056d82..424cd1b9 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.0.0a1.dev0", + version="6.0.0a1", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 2b010a631fedfa292e1a6170f963e97d450b3897 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Thu, 12 Jan 2023 13:15:12 +0100 Subject: [PATCH 076/487] Back to development: 6.0.0a2 --- CHANGES.rst | 6 ++++++ setup.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 2f311001..0ba7104a 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -2,6 +2,12 @@ Changelog ========= +6.0.0a2 (unreleased) +-------------------- + +- Nothing changed yet. + + 6.0.0a1 (2023-01-12) -------------------- diff --git a/setup.py b/setup.py index 424cd1b9..d6161f75 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.0.0a1", + version="6.0.0a2.dev0", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 41fa91237229c2ed567656a6290d0e0d21f35840 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Thu, 12 Jan 2023 14:41:07 +0100 Subject: [PATCH 077/487] upgrade the upgrades steps --- .../profiles/default/metadata.xml | 2 +- .../serializers/unita_organizzativa.py | 10 +-- .../contenttypes/upgrades/configure.zcml | 4 +- .../plone/contenttypes/upgrades/upgrades.py | 70 +++++++++++++++---- 4 files changed, 65 insertions(+), 21 deletions(-) diff --git a/src/design/plone/contenttypes/profiles/default/metadata.xml b/src/design/plone/contenttypes/profiles/default/metadata.xml index 1994221a..b24e1f49 100644 --- a/src/design/plone/contenttypes/profiles/default/metadata.xml +++ b/src/design/plone/contenttypes/profiles/default/metadata.xml @@ -1,6 +1,6 @@ - 7000 + 7001 profile-redturtle.bandi:default profile-collective.venue:default diff --git a/src/design/plone/contenttypes/restapi/serializers/unita_organizzativa.py b/src/design/plone/contenttypes/restapi/serializers/unita_organizzativa.py index fe23c272..0201699f 100644 --- a/src/design/plone/contenttypes/restapi/serializers/unita_organizzativa.py +++ b/src/design/plone/contenttypes/restapi/serializers/unita_organizzativa.py @@ -102,10 +102,12 @@ def __call__(self, version=None, include_items=True): result = super(UOSerializer, self).__call__( version=version, include_items=include_items ) - result["servizi_offerti"] = self.get_services() - result["uo_parent"] = self.getParentUo() - result["uo_children"] = self.getChildrenUo() - result["prestazioni"] = self.getUOServiziDoveRivolgersi(result.get("UID", "")) + result["servizi_offerti"] = json_compatible(self.get_services()) + result["uo_parent"] = json_compatible(self.getParentUo()) + result["uo_children"] = json_compatible(self.getChildrenUo()) + result["prestazioni"] = json_compatible( + self.getUOServiziDoveRivolgersi(result.get("UID", "")) + ) return result diff --git a/src/design/plone/contenttypes/upgrades/configure.zcml b/src/design/plone/contenttypes/upgrades/configure.zcml index 85d1b7c3..f7ca83e8 100644 --- a/src/design/plone/contenttypes/upgrades/configure.zcml +++ b/src/design/plone/contenttypes/upgrades/configure.zcml @@ -602,12 +602,12 @@ 0 + ): + return True + pc = api.portal.get_tool(name="portal_catalog") wftool = api.portal.get_tool(name="portal_workflow") portal = api.portal.get() @@ -1347,11 +1386,14 @@ def create_pdc(context): if not data: continue - try: + if not migrated_contact_info(obj): obj.old_contact_info = obj.contact_info del obj.contact_info - except AttributeError: - pass + else: + logger.info( + f"{colors.RED} Esiste già un punto di contatto per {obj.title}({obj.absolute_url()}){colors.ENDC}" # noqa + ) + continue pdc = api.content.create( type="PuntoDiContatto", From dfe34a1b36bfdf3f01474c3a6db139025fff2728 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Thu, 12 Jan 2023 14:47:23 +0100 Subject: [PATCH 078/487] upgrade typo on version --- src/design/plone/contenttypes/upgrades/upgrades.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/design/plone/contenttypes/upgrades/upgrades.py b/src/design/plone/contenttypes/upgrades/upgrades.py index 81b16b5c..d66be0cc 100644 --- a/src/design/plone/contenttypes/upgrades/upgrades.py +++ b/src/design/plone/contenttypes/upgrades/upgrades.py @@ -1150,7 +1150,7 @@ class colors(object): YELLOW = "\033[93m" -def to_7000(context): +def to_7001(context): installer = get_installer(context=api.portal.get()) installer.install_product("eea.api.taxonomy") From f539a12b21f68ee5f4d76a9a5260b34a57a67cfa Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Thu, 12 Jan 2023 14:56:27 +0100 Subject: [PATCH 079/487] update incarico title in case of missing ruolo --- src/design/plone/contenttypes/upgrades/upgrades.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/design/plone/contenttypes/upgrades/upgrades.py b/src/design/plone/contenttypes/upgrades/upgrades.py index d66be0cc..690a454e 100644 --- a/src/design/plone/contenttypes/upgrades/upgrades.py +++ b/src/design/plone/contenttypes/upgrades/upgrades.py @@ -1243,7 +1243,7 @@ def create_incarico_for_persona(context): logger.info( f"{colors.RED} Attenzione: {persona.title} non ha un ruolo {colors.ENDC}" # noqa ) - incarico_title = persona.title + incarico_title = f"Incarico di {persona.title}" incarico = api.content.create( type="Incarico", title=incarico_title, container=incarichi_folder From bde3d0c5b78576db1863f3b97a838fb0d68f8a5c Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Thu, 12 Jan 2023 15:00:59 +0100 Subject: [PATCH 080/487] update incarico summary serializer --- .../contenttypes/restapi/serializers/summary.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/design/plone/contenttypes/restapi/serializers/summary.py b/src/design/plone/contenttypes/restapi/serializers/summary.py index dcbc4fa9..f3661e22 100644 --- a/src/design/plone/contenttypes/restapi/serializers/summary.py +++ b/src/design/plone/contenttypes/restapi/serializers/summary.py @@ -136,15 +136,22 @@ def __call__(self, force_all_metadata=False): taxonomy = getUtility(ITaxonomy, name="collective.taxonomy.tipologia_incarico") taxonomy_voc = taxonomy.makeVocabulary(self.request.get("LANGUAGE")) if "tipologia_incarico" not in res: - res["tipologia_incarico"] = taxonomy_voc.inv_data.get( - self.context.tipologia_incarico - ).replace(PATH_SEPARATOR, "") + if self.context.tipologia_incarico: + res["tipologia_incarico"] = taxonomy_voc.inv_data.get( + self.context.tipologia_incarico + ).replace(PATH_SEPARATOR, "") + else: + res["tipologia_incarico"] = json_compatible(None) if "data_inizio_incarico" not in res: res["data_inizio_incarico"] = json_compatible( self.context.data_inizio_incarico ) + else: + res["data_inizio_incarico"] = json_compatible(None) if "compensi" not in res: res["compensi"] = json_compatible(self.context.compensi) + else: + res["compensi"] = json_compatible([]) return res From 6a52f2234bf7551eb6a9712cbc895db6171803a6 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Thu, 12 Jan 2023 16:53:32 +0100 Subject: [PATCH 081/487] [doc] updated CHANGES --- CHANGES.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 0ba7104a..c610fc8f 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -5,7 +5,9 @@ Changelog 6.0.0a2 (unreleased) -------------------- -- Nothing changed yet. +- Fixed upgrade step +- minor fix + [lucabel] 6.0.0a1 (2023-01-12) From f0ff5638bcd82dae9077e2728e28433ded6dcaa8 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Thu, 12 Jan 2023 16:54:19 +0100 Subject: [PATCH 082/487] Preparing release 6.0.0a2 --- CHANGES.rst | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index c610fc8f..1dda541c 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -2,7 +2,7 @@ Changelog ========= -6.0.0a2 (unreleased) +6.0.0a2 (2023-01-12) -------------------- - Fixed upgrade step diff --git a/setup.py b/setup.py index d6161f75..63798dab 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.0.0a2.dev0", + version="6.0.0a2", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 63797413e8f723eb11233b00a4bad55fe49425ba Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Thu, 12 Jan 2023 16:54:42 +0100 Subject: [PATCH 083/487] Back to development: 6.0.0a3 --- CHANGES.rst | 6 ++++++ setup.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 1dda541c..34d3b1cc 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -2,6 +2,12 @@ Changelog ========= +6.0.0a3 (unreleased) +-------------------- + +- Nothing changed yet. + + 6.0.0a2 (2023-01-12) -------------------- diff --git a/setup.py b/setup.py index 63798dab..1558778f 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.0.0a2", + version="6.0.0a3.dev0", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 4d574d9b21efe71405121bec91556710f4d9afce Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Fri, 13 Jan 2023 09:52:25 +0100 Subject: [PATCH 084/487] [fix] fixed behavior name on Servizio --- .../plone/contenttypes/profiles/default/types/Servizio.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/design/plone/contenttypes/profiles/default/types/Servizio.xml b/src/design/plone/contenttypes/profiles/default/types/Servizio.xml index 65e7b976..fec732d7 100644 --- a/src/design/plone/contenttypes/profiles/default/types/Servizio.xml +++ b/src/design/plone/contenttypes/profiles/default/types/Servizio.xml @@ -61,7 +61,7 @@ - + From ea0c14f6bf15f39184353a29fde3260d667e2170 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Fri, 13 Jan 2023 16:04:14 +0100 Subject: [PATCH 085/487] update upgrades --- .../taxonomies/tipologia_documento.xml | 7 + .../taxonomies/tipologia_organizzazione.cfg | 1 + .../profiles/default/metadata.xml | 2 +- .../contenttypes/upgrades/configure.zcml | 16 ++ .../plone/contenttypes/upgrades/upgrades.py | 147 +++++++++++++++++- 5 files changed, 169 insertions(+), 4 deletions(-) diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_documento.xml b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_documento.xml index 990e806e..501f0afc 100644 --- a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_documento.xml +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_documento.xml @@ -59,4 +59,11 @@ Istanza + + dataset + + + Dataset + + diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_organizzazione.cfg b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_organizzazione.cfg index d651776a..11b1955f 100644 --- a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_organizzazione.cfg +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_organizzazione.cfg @@ -8,3 +8,4 @@ field_description = Selezione la tipologia dell'unità organizzativa field_prefix = taxonomy_fieldset = struttura is_required = true +is_single_select = true diff --git a/src/design/plone/contenttypes/profiles/default/metadata.xml b/src/design/plone/contenttypes/profiles/default/metadata.xml index b24e1f49..dd3d5a5b 100644 --- a/src/design/plone/contenttypes/profiles/default/metadata.xml +++ b/src/design/plone/contenttypes/profiles/default/metadata.xml @@ -1,6 +1,6 @@ - 7001 + 7002 profile-redturtle.bandi:default profile-collective.venue:default diff --git a/src/design/plone/contenttypes/upgrades/configure.zcml b/src/design/plone/contenttypes/upgrades/configure.zcml index f7ca83e8..b0923ca6 100644 --- a/src/design/plone/contenttypes/upgrades/configure.zcml +++ b/src/design/plone/contenttypes/upgrades/configure.zcml @@ -625,4 +625,20 @@ handler=".upgrades.create_pdc" /> + + + + diff --git a/src/design/plone/contenttypes/upgrades/upgrades.py b/src/design/plone/contenttypes/upgrades/upgrades.py index 690a454e..e6734256 100644 --- a/src/design/plone/contenttypes/upgrades/upgrades.py +++ b/src/design/plone/contenttypes/upgrades/upgrades.py @@ -1157,8 +1157,14 @@ def to_7001(context): logger.info( f"{colors.DARKCYAN} eea.api.taxonomy and collective.taxonomy installed {colors.ENDC}" # noqa ) - # no more available - # installer.install_product("design.plone.contentypes", profile="taxonomy") + # delete actual index from portal_catalog + for index in [ + "tipologia_notizia", + "tipologia_documento", + "tipologia_organizzazione", + ]: + api.portal.get_tool("portal_catalog").delIndex(index) + context.runImportStepFromProfile( "design.plone.contenttypes:taxonomy", "collective.taxonomy" ) @@ -1355,6 +1361,8 @@ def migrated_contact_info(source): title=punti_contatto_title, container=portal, ) + punti_contatto.exclude_from_nav = True + punti_contatto.reindexObject() wftool.doActionFor(punti_contatto, "publish") logger.info( f"{colors.GREEN} Creato cartella punti di contatto nella radice del portal{colors.ENDC}" # noqa @@ -1388,7 +1396,8 @@ def migrated_contact_info(source): if not migrated_contact_info(obj): obj.old_contact_info = obj.contact_info - del obj.contact_info + if obj.portal_type == "UnitaOrganizzativa": + del obj.contact_info else: logger.info( f"{colors.RED} Esiste già un punto di contatto per {obj.title}({obj.absolute_url()}){colors.ENDC}" # noqa @@ -1400,8 +1409,140 @@ def migrated_contact_info(source): title=f"Punto di contatto per: {obj.title}", container=punti_contatto, ) + api.relation.create(source=obj, target=pdc, relationship="contact_info") + pdc.value_punto_contatto = data logger.info( f"{colors.GREEN} Creato il punto di contatto per {obj.title}({obj.absolute_url()}){colors.ENDC}" # noqa ) + + +TYPE_TO_TAXONOMIES_MAPPING = { + "News Item": { + "tipologia_notizia": { + "it": { + "Avviso": "avviso", + "Comunicato stampa": "comunicato_stampa", + "Novit\u00e0": "notizia", + } + } + }, + "Documento": { + "tipologia_documento": { + "it": { + "Accordi tra enti": "accordo_tra_enti", + "Atti normativi": "atto_normativo", + "Dataset": "Dataset", + "Documenti (tecnici) di supporto": "documento_tecnico_di_supporto", + "Documenti albo pretorio": "documenti_albo_pretorio", + "Documenti attivit\u00e0 politica": "documento_attivita_politica", + "Documenti funzionamento interno": "documento_funzionamento_interno", + "Istanze": "istanza", + "Modulistica": "modulistica", + } + } + }, + "UnitaOrganizzativa": { + "tipologia_organizzazione": { + "it": { + "Politica": "struttura_politica", + "Amministrativa": "struttura_amministrativa", + "Altro": "altra_struttura", + } + } + }, +} + +TAXONOMIES_MAPPING = {} +for portal_type in TYPE_TO_TAXONOMIES_MAPPING: + for TAXONOMY in TYPE_TO_TAXONOMIES_MAPPING[portal_type]: + TAXONOMIES_MAPPING[TAXONOMY] = TYPE_TO_TAXONOMIES_MAPPING[portal_type][TAXONOMY] + + +def update_taxonomies(context): + # delete actual index from portal_catalog + logger.info( + f"{colors.DARKCYAN} Migrazione delle tassonomie dai vecchi ai nuovi valori {colors.ENDC}" # noqa + ) + pc = api.portal.get_tool("portal_catalog") + for portal_type in TYPE_TO_TAXONOMIES_MAPPING: + brains = pc(**{"portal_type": portal_type}) + logger.info( + f"{colors.DARKCYAN} Modifica delle tassonomie per {len(brains)} {portal_type}{colors.ENDC}" # noqa + ) + for brain in brains: + obj = brain.getObject() + obj_language = getattr(obj, "language", "it") + for taxonomy in TYPE_TO_TAXONOMIES_MAPPING[portal_type]: + old_value = getattr(obj, taxonomy) + if ( + old_value + and old_value + in TYPE_TO_TAXONOMIES_MAPPING[portal_type][taxonomy][obj_language] + ): + new_value = TYPE_TO_TAXONOMIES_MAPPING[portal_type][taxonomy][ + obj_language + ][old_value] + if taxonomy == "tipologia_documento": + new_value = [ + new_value, + ] + setattr(obj, taxonomy, new_value) + logger.info( + f"{colors.GREEN} Modifica della tassonomia '{taxonomy}' di {obj.title} da {old_value} a {new_value}{colors.ENDC}" # noqa + ) + + obj.reindexObject() + + +def update_taxonomies_on_blocks(context): + """ + Code from + https://github.com/RedTurtle/design.plone.contenttypes/pull/139/files#diff-330d75e9be6e5193ab4622582fe7031d05094784e08aa3ada201a4e3d1642632R33 + """ + # https://www.comune.novellara.re.it/novita/notizie/archivio-notizie + + logger.info( + f"{colors.DARKCYAN} Update dei blocchi listing basati sulle nuove tassonomie {colors.ENDC}" # noqa + ) + brains = api.portal.get_tool("portal_catalog")() + for index, brain in list(enumerate(brains)): + item = aq_base(brain.getObject()) + item_language = item.language or "it" + if not index % 500: + logger.info( + f"{colors.DARKCYAN} ({index}/{len(brains)}) Proseguo l'analisi delle pagine {colors.ENDC}" # noqa + ) + if getattr(item, "blocks", {}): + blocks = deepcopy(item.blocks) + + if blocks: + for block in blocks.values(): + if block.get("@type", "") == "listing": + for query in block.get("querystring", {}).get("query", []): + + if query["i"] in [ + "tipologia_notizia", + "tipologia_documento", + "tipologia_organizzazione", + ]: + new_values = [] + for v in query["v"]: + old_value = query["v"] + if ( + v + in TAXONOMIES_MAPPING[query["i"]][item_language] + ): + v = TAXONOMIES_MAPPING[query["i"]][ + item_language + ][v] + new_values.append(v) + query["v"] = new_values + logger.info( + f"{colors.GREEN} Modifica della query per '{query['i']}' di {item.title} da {old_value} a {query['v']}{colors.ENDC}" # noqa + ) + item.blocks = blocks + logger.info( + f"{colors.DARKCYAN} Terminato l'update dei blocchi {colors.ENDC}" # noqa + ) From 9193cc1fde761ccc39f235605e2aec95086fb6d0 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Fri, 13 Jan 2023 16:19:42 +0100 Subject: [PATCH 086/487] zpretty and black --- src/design/plone/contenttypes/indexers/configure.zcml | 2 +- src/design/plone/contenttypes/indexers/punto_di_contatto.py | 2 +- src/design/plone/contenttypes/interfaces/punto_di_contatto.py | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/design/plone/contenttypes/indexers/configure.zcml b/src/design/plone/contenttypes/indexers/configure.zcml index 0cff2790..ecd0b8fe 100644 --- a/src/design/plone/contenttypes/indexers/configure.zcml +++ b/src/design/plone/contenttypes/indexers/configure.zcml @@ -60,7 +60,7 @@ + /> diff --git a/src/design/plone/contenttypes/indexers/punto_di_contatto.py b/src/design/plone/contenttypes/indexers/punto_di_contatto.py index bda84a91..27184b6d 100644 --- a/src/design/plone/contenttypes/indexers/punto_di_contatto.py +++ b/src/design/plone/contenttypes/indexers/punto_di_contatto.py @@ -1,8 +1,8 @@ # -*- coding: utf-8 -*- from design.plone.contenttypes.interfaces.punto_di_contatto import IPuntoDiContatto from plone.app.dexterity.textindexer.interfaces import IDynamicTextIndexExtender -from zope.interface import implementer from zope.component import adapter +from zope.interface import implementer @implementer(IDynamicTextIndexExtender) diff --git a/src/design/plone/contenttypes/interfaces/punto_di_contatto.py b/src/design/plone/contenttypes/interfaces/punto_di_contatto.py index f4ebd8e6..4305ac2d 100644 --- a/src/design/plone/contenttypes/interfaces/punto_di_contatto.py +++ b/src/design/plone/contenttypes/interfaces/punto_di_contatto.py @@ -3,12 +3,12 @@ from collective.z3cform.datagridfield.row import DictRow from design.plone.contenttypes import _ from design.plone.contenttypes.interfaces import IDesignPloneContentType +from plone.app.z3cform.widget import RelatedItemsFieldWidget from plone.autoform import directives as form from plone.supermodel import model -from zope import schema -from plone.app.z3cform.widget import RelatedItemsFieldWidget from z3c.relationfield.schema import RelationChoice from z3c.relationfield.schema import RelationList +from zope import schema class IPDCValueSchema(model.Schema): From 866fce21abf9ee2d1bc4976aa66e0327e83b2890 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Fri, 13 Jan 2023 16:28:28 +0100 Subject: [PATCH 087/487] fix field description --- src/design/plone/contenttypes/interfaces/punto_di_contatto.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/design/plone/contenttypes/interfaces/punto_di_contatto.py b/src/design/plone/contenttypes/interfaces/punto_di_contatto.py index 4305ac2d..e119275c 100644 --- a/src/design/plone/contenttypes/interfaces/punto_di_contatto.py +++ b/src/design/plone/contenttypes/interfaces/punto_di_contatto.py @@ -55,7 +55,7 @@ class IPuntoDiContatto(model.Schema, IDesignPloneContentType): ), description=_( "persona_incarico_help", - default="Seleziona la/e persona/e che ha/hanno la carica e l'incarico.", + default="Se una persona è un punto di contatto di un'altra Tipologia", ), value_type=RelationChoice(vocabulary="plone.app.vocabularies.Catalog"), required=False, From f5e0de1be2e9f9b741deecd589ee883dd682adb1 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Fri, 13 Jan 2023 16:41:32 +0100 Subject: [PATCH 088/487] update changes --- CHANGES.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 34d3b1cc..27aa2d9f 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -5,7 +5,9 @@ Changelog 6.0.0a3 (unreleased) -------------------- -- Nothing changed yet. +- Update upgrade steps to change types information + according to new AGID AI + [lucabel] 6.0.0a2 (2023-01-12) From c88766ab1ddccaaf83d10020b7ef6dc4fafd6a6f Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Fri, 13 Jan 2023 16:42:45 +0100 Subject: [PATCH 089/487] Preparing release 6.0.0a3 --- CHANGES.rst | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 27aa2d9f..34d09051 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -2,7 +2,7 @@ Changelog ========= -6.0.0a3 (unreleased) +6.0.0a3 (2023-01-13) -------------------- - Update upgrade steps to change types information diff --git a/setup.py b/setup.py index 1558778f..7d8b3b54 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.0.0a3.dev0", + version="6.0.0a3", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 80d24ad8d6d1573a4564024e54fd495f74a81f54 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Fri, 13 Jan 2023 16:43:17 +0100 Subject: [PATCH 090/487] Back to development: 6.0.0a4 --- CHANGES.rst | 6 ++++++ setup.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 34d09051..c1c1ea49 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -2,6 +2,12 @@ Changelog ========= +6.0.0a4 (unreleased) +-------------------- + +- Nothing changed yet. + + 6.0.0a3 (2023-01-13) -------------------- diff --git a/setup.py b/setup.py index 7d8b3b54..f9c6ef19 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.0.0a3", + version="6.0.0a4.dev0", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 4dfb8863fc8ac55ea3f7f6d656081ed36c8087c2 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Tue, 17 Jan 2023 12:36:26 +0100 Subject: [PATCH 091/487] add image information to event summary --- .../restapi/serializers/configure.zcml | 1 + .../restapi/serializers/summary.py | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/src/design/plone/contenttypes/restapi/serializers/configure.zcml b/src/design/plone/contenttypes/restapi/serializers/configure.zcml index 0686004e..8ff7407f 100644 --- a/src/design/plone/contenttypes/restapi/serializers/configure.zcml +++ b/src/design/plone/contenttypes/restapi/serializers/configure.zcml @@ -8,6 +8,7 @@ + diff --git a/src/design/plone/contenttypes/restapi/serializers/summary.py b/src/design/plone/contenttypes/restapi/serializers/summary.py index e74210bf..cbacaac7 100644 --- a/src/design/plone/contenttypes/restapi/serializers/summary.py +++ b/src/design/plone/contenttypes/restapi/serializers/summary.py @@ -6,8 +6,10 @@ from design.plone.contenttypes.interfaces.persona import IPersona from design.plone.contenttypes.interfaces.punto_di_contatto import IPuntoDiContatto from plone import api +from plone.app.contenttypes.interfaces import IEvent from plone.restapi.interfaces import ISerializeToJsonSummary from plone.restapi.serializer.converters import json_compatible +from plone.volto.behaviors.preview import IPreview from redturtle.volto.restapi.serializer.summary import ( DefaultJSONSummarySerializer as BaseSerializer, ) @@ -183,3 +185,22 @@ def __call__(self, force_all_metadata=False): } res["image_field"] = "foto_persona" return res + + +@implementer(ISerializeToJsonSummary) +@adapter(IEvent, IDesignPloneContenttypesLayer) +class EventDefaultJSONSummarySerializer(DefaultJSONSummarySerializer): + def __call__(self, force_all_metadata=False): + res = super().__call__(force_all_metadata=force_all_metadata) + fields = dict(getFieldsInOrder(IPreview)) + field = fields.get("preview_image", None) + if field: + images_info_adapter = getMultiAdapter( + (field, self.context, IDesignPloneContenttypesLayer) + ) + if images_info_adapter: + res["image_scales"] = { + "preview_image": [images_info_adapter()], + } + res["image_field"] = "preview_image" + return res From 8835f54cbc12ea175e2fef08f8d8c4e4a802f329 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Tue, 17 Jan 2023 18:05:07 +0100 Subject: [PATCH 092/487] [dev] rimossi i campi evento_genitore e appuntamenti dalla behavior degli eventi --- .../plone/contenttypes/behaviors/evento.py | 42 ------------------- 1 file changed, 42 deletions(-) diff --git a/src/design/plone/contenttypes/behaviors/evento.py b/src/design/plone/contenttypes/behaviors/evento.py index a7b60da6..0c5eb0d9 100644 --- a/src/design/plone/contenttypes/behaviors/evento.py +++ b/src/design/plone/contenttypes/behaviors/evento.py @@ -125,31 +125,6 @@ class IEvento(model.Schema): ), ) - evento_genitore = RelationList( - title=_("evento_genitore_label", default="Evento genitore"), - required=False, - default=[], - value_type=RelationChoice(vocabulary="plone.app.vocabularies.Catalog"), - description=_( - "evento_genitore_help", - default="Un evento può essere parte di un altro evento definito come " - '"genitore" (ad es. "Mostra sul Rinascimento" è parte ' - "dell'evento \"Festival dell'Arte\")", - ), - ) - - appuntamenti = RelationList( - title=_("appuntamenti_label", default="Appuntamenti"), - required=False, - default=[], - value_type=RelationChoice(vocabulary="plone.app.vocabularies.Catalog"), - description=_( - "appuntamenti_help", - default="Link agli eventi figlio (solo se l'evento in questione è " - "evento genitore)", - ), - ) - parteciperanno = RelationList( title=_("parteciperanno_label", default="Parteciperanno (Persone)"), required=False, @@ -171,23 +146,6 @@ class IEvento(model.Schema): ) # custom widgets - form.widget( - "evento_genitore", - RelatedItemsFieldWidget, - vocabulary="plone.app.vocabularies.Catalog", - pattern_options={ - "maximumSelectionSize": 1, - "selectableTypes": ["Evento"], - }, - ) - form.widget( - "appuntamenti", - RelatedItemsFieldWidget, - vocabulary="plone.app.vocabularies.Catalog", - pattern_options={ - "selectableTypes": ["Evento"], - }, - ) form.widget( "parteciperanno", RelatedItemsFieldWidget, From a9f3eaffd45a79a937cff75ce37faf5e39fc5440 Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 18 Jan 2023 10:25:54 +0100 Subject: [PATCH 093/487] Fix datagrid field --- .../contenttypes/interfaces/punto_di_contatto.py | 1 + src/design/plone/contenttypes/interfaces/servizio.py | 1 + .../plone/contenttypes/restapi/types/adapters.py | 12 ------------ 3 files changed, 2 insertions(+), 12 deletions(-) diff --git a/src/design/plone/contenttypes/interfaces/punto_di_contatto.py b/src/design/plone/contenttypes/interfaces/punto_di_contatto.py index e119275c..84296528 100644 --- a/src/design/plone/contenttypes/interfaces/punto_di_contatto.py +++ b/src/design/plone/contenttypes/interfaces/punto_di_contatto.py @@ -65,6 +65,7 @@ class IPuntoDiContatto(model.Schema, IDesignPloneContentType): form.widget( "value_punto_contatto", DataGridFieldFactory, + frontendOptions={"widget": "data_grid"}, ) form.widget( diff --git a/src/design/plone/contenttypes/interfaces/servizio.py b/src/design/plone/contenttypes/interfaces/servizio.py index 607f411c..742ea2a3 100644 --- a/src/design/plone/contenttypes/interfaces/servizio.py +++ b/src/design/plone/contenttypes/interfaces/servizio.py @@ -472,6 +472,7 @@ class IServizio(model.Schema, IDesignPloneContentType): form.widget( "timeline_tempi_scadenze", DataGridFieldFactory, + frontendOptions={"widget": "data_grid"}, ) # custom fieldset and order diff --git a/src/design/plone/contenttypes/restapi/types/adapters.py b/src/design/plone/contenttypes/restapi/types/adapters.py index 9490b52f..70b4799a 100644 --- a/src/design/plone/contenttypes/restapi/types/adapters.py +++ b/src/design/plone/contenttypes/restapi/types/adapters.py @@ -1,8 +1,6 @@ # -*- coding: utf-8 -*- from collective.z3cform.datagridfield.interfaces import IRow from design.plone.contenttypes import _ -from design.plone.contenttypes.interfaces import IDesignPloneContenttypesLayer -from plone.restapi.types.adapters import ListJsonSchemaProvider from plone.restapi.types.adapters import ObjectJsonSchemaProvider from plone.restapi.types.interfaces import IJsonSchemaProvider from plone.restapi.types.utils import get_fieldsets @@ -14,7 +12,6 @@ from zope.interface import implementer from zope.interface import Interface from zope.schema.interfaces import IField -from zope.schema.interfaces import IList from zope.schema.interfaces import IVocabularyFactory @@ -49,15 +46,6 @@ def get_schema(self): return schema -@adapter(IList, Interface, IDesignPloneContenttypesLayer) -@implementer(IJsonSchemaProvider) -class DataGridFieldJsonSchemaProvider(ListJsonSchemaProvider): - def get_widget(self): - if self.field.getName() in DATAGRID_FIELDS: - return "data_grid" - return super().get_widget() - - @adapter(IRow, Interface, Interface) @implementer(IJsonSchemaProvider) class DataGridRowJsonSchemaProvider(ObjectJsonSchemaProvider): From 35e4c9e18b4b9e675ab28bc52c70a31eacee245d Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 18 Jan 2023 11:26:45 +0100 Subject: [PATCH 094/487] Remove adapter registration --- src/design/plone/contenttypes/restapi/types/configure.zcml | 1 - 1 file changed, 1 deletion(-) diff --git a/src/design/plone/contenttypes/restapi/types/configure.zcml b/src/design/plone/contenttypes/restapi/types/configure.zcml index b56c3e96..9adca258 100644 --- a/src/design/plone/contenttypes/restapi/types/configure.zcml +++ b/src/design/plone/contenttypes/restapi/types/configure.zcml @@ -8,7 +8,6 @@ factory=".adapters.LeadImageJsonSchemaProvider" name="ILeadImageBehavior.image" /> - From b005f7e6d00a818c1a71f105daf88f9103621cbb Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 15 Dec 2022 12:32:49 +0100 Subject: [PATCH 095/487] 35848 - Nel servizio, togliere il limite di 10 uffici selezionabili --- src/design/plone/contenttypes/interfaces/servizio.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/design/plone/contenttypes/interfaces/servizio.py b/src/design/plone/contenttypes/interfaces/servizio.py index 742ea2a3..801893f0 100644 --- a/src/design/plone/contenttypes/interfaces/servizio.py +++ b/src/design/plone/contenttypes/interfaces/servizio.py @@ -444,7 +444,6 @@ class IServizio(model.Schema, IDesignPloneContentType): RelatedItemsFieldWidget, vocabulary="plone.app.vocabularies.Catalog", pattern_options={ - "maximumSelectionSize": 10, "selectableTypes": ["UnitaOrganizzativa"], # "basePath": "/amministrazione/uffici", }, From 2967bb90a9ef0e703e0d53d53f7de7246c4d7bc2 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 15 Dec 2022 14:40:17 +0100 Subject: [PATCH 096/487] Update tests in accroding to this change --- src/design/plone/contenttypes/tests/test_ct_servizio.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/design/plone/contenttypes/tests/test_ct_servizio.py b/src/design/plone/contenttypes/tests/test_ct_servizio.py index 049c3c0d..61720655 100644 --- a/src/design/plone/contenttypes/tests/test_ct_servizio.py +++ b/src/design/plone/contenttypes/tests/test_ct_servizio.py @@ -22,7 +22,6 @@ "selectableTypes": ["Pagina Argomento"], }, "ufficio_responsabile": { - "maximumSelectionSize": 10, "selectableTypes": ["UnitaOrganizzativa"], }, "area": { From ac5f442b79951bd70ff8ecbd587396418ea1a6b2 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 15 Dec 2022 17:06:51 +0100 Subject: [PATCH 097/487] Changelog --- CHANGES.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index c1c1ea49..7191b3f4 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -5,7 +5,8 @@ Changelog 6.0.0a4 (unreleased) -------------------- -- Nothing changed yet. +- Remove selection limit in ufficio_responsabile field for Servizio. + [foxtrot-dfm1] 6.0.0a3 (2023-01-13) From 1545a34528f516c15e18d761f7deb2415c9f24dc Mon Sep 17 00:00:00 2001 From: Andrea Cecchi Date: Tue, 3 Jan 2023 09:00:28 +0100 Subject: [PATCH 098/487] new indexer/criteria for related arguments --- CHANGES.rst | 7 ++- .../plone/contenttypes/behaviors/argomenti.py | 12 +--- .../plone/contenttypes/indexers/common.py | 9 +++ .../contenttypes/indexers/configure.zcml | 4 ++ .../profiles/default/registry/criteria.xml | 27 ++++++++ .../contenttypes/upgrades/configure.zcml | 12 ++++ .../plone/contenttypes/upgrades/upgrades.py | 63 +++++++++++++++++++ .../vocabularies/argomenti_vocabulary.py | 16 +++++ .../contenttypes/vocabularies/configure.zcml | 6 ++ 9 files changed, 146 insertions(+), 10 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 7191b3f4..ec7be517 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -7,7 +7,12 @@ Changelog - Remove selection limit in ufficio_responsabile field for Servizio. [foxtrot-dfm1] - +- Add new indexer "tassonomia_argomenti_uid" that indexes related Argomenti UIDs. + [cekk] +- Change collection criteria to use new index. + [cekk] +- Upgrade-step to convert old blocks with new criteria. + [cekk] 6.0.0a3 (2023-01-13) -------------------- diff --git a/src/design/plone/contenttypes/behaviors/argomenti.py b/src/design/plone/contenttypes/behaviors/argomenti.py index 2f4de3df..52ab188b 100644 --- a/src/design/plone/contenttypes/behaviors/argomenti.py +++ b/src/design/plone/contenttypes/behaviors/argomenti.py @@ -189,25 +189,19 @@ def __init__(self, context): @implementer(IArgomentiDocumento) @adapter(IDocumento) -class ArgomentiDocumento(object): +class ArgomentiDocumento(Argomenti): """""" - def __init__(self, context): - self.context = context - @implementer(IArgomentiBando) @adapter(IBandoAgidSchema) -class ArgomentiBando(object): +class ArgomentiBando(Argomenti): """""" - def __init__(self, context): - self.context = context - @implementer(IArgomentiDocument) @adapter(IDocument) -class ArgomentiDocument(object): +class ArgomentiDocument(Argomenti): """""" def __init__(self, context): diff --git a/src/design/plone/contenttypes/indexers/common.py b/src/design/plone/contenttypes/indexers/common.py index 1e48bbbe..bf23ab58 100644 --- a/src/design/plone/contenttypes/indexers/common.py +++ b/src/design/plone/contenttypes/indexers/common.py @@ -12,6 +12,15 @@ def tassonomia_argomenti(context, **kw): ] +@indexer(IDexterityContent) +def tassonomia_argomenti_uid(context, **kw): + return [ + x.to_object.UID() + for x in getattr(context.aq_base, "tassonomia_argomenti", []) + if x.to_object + ] + + @indexer(IDexterityContent) def ufficio_responsabile(context, **kw): uffici = getattr(context.aq_base, "ufficio_responsabile", []) diff --git a/src/design/plone/contenttypes/indexers/configure.zcml b/src/design/plone/contenttypes/indexers/configure.zcml index ecd0b8fe..945d7a11 100644 --- a/src/design/plone/contenttypes/indexers/configure.zcml +++ b/src/design/plone/contenttypes/indexers/configure.zcml @@ -32,6 +32,10 @@ factory=".common.tassonomia_argomenti" name="tassonomia_argomenti" /> + + Metadata Metadata +======= + prefix="plone.app.querystring.field.tassonomia_argomenti_uid"> + Argomenti correlati + Argomenti correlati (con uid) + True + False + + plone.app.querystring.operation.selection.any + plone.app.querystring.operation.selection.all + + design.plone.vocabularies.argomenti_uid + Metadata + + + Tipologia documento + + True + False + + plone.app.querystring.operation.selection.any + plone.app.querystring.operation.selection.all + + design.plone.vocabularies.tipologie_documento + Metadata +>>>>>>> edd7357 (new indexer/criteria for related arguments) +======= + profile="design.plone.contenttypes:default" + source="5410" + destination="5500"> + + + +>>>>>>> edd7357 (new indexer/criteria for related arguments) diff --git a/src/design/plone/contenttypes/upgrades/upgrades.py b/src/design/plone/contenttypes/upgrades/upgrades.py index e6734256..b25d9d57 100644 --- a/src/design/plone/contenttypes/upgrades/upgrades.py +++ b/src/design/plone/contenttypes/upgrades/upgrades.py @@ -959,6 +959,7 @@ def to_5410(context): ) +<<<<<<< HEAD def to_6000(context): """ """ logger.info( @@ -1546,3 +1547,65 @@ def update_taxonomies_on_blocks(context): logger.info( f"{colors.DARKCYAN} Terminato l'update dei blocchi {colors.ENDC}" # noqa ) +======= +def to_5500(context): + update_registry(context) + update_catalog(context) + + argomenti_mapping = { + x.Title: x.UID for x in api.content.find(portal_type="Pagina Argomento") + } + + def fix_block(blocks, argomenti_mapping): + for block in blocks.values(): + if block.get("@type", "") == "listing": + for query in block.get("querystring", {}).get("query", []): + if query["i"] == "tassonomia_argomenti": + new_values = [] + for v in query["v"]: + uid = argomenti_mapping.get(v, "") + if uid: + new_values.append(uid) + query["i"] = "tassonomia_argomenti_uid" + query["v"] = new_values + logger.info(" - {}".format(brain.getURL())) + + pc = api.portal.get_tool(name="portal_catalog") + brains = pc() + tot = len(brains) + i = 0 + for brain in brains: + i += 1 + if i % 1000 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + item_obj = brain.getObject() + item = aq_base(brain.getObject()) + + # reindex argomenti indexes + if brain.tassonomia_argomenti: + item_obj.reindexObject( + idxs=["tassonomia_argomenti", "tassonomia_argomenti_uid"] + ) + + if getattr(item, "blocks", {}): + blocks = deepcopy(item.blocks) + if blocks: + fix_block(blocks, argomenti_mapping) + item.blocks = blocks + for schema in iterSchemata(item): + # fix blocks in blocksfields + for name, field in getFields(schema).items(): + if name == "blocks": + blocks = deepcopy(item.blocks) + if blocks: + fix_block(blocks, argomenti_mapping) + item.blocks = blocks + elif isinstance(field, BlocksField): + value = deepcopy(field.get(item)) + if not value: + continue + blocks = value.get("blocks", {}) + if blocks: + fix_block(blocks, argomenti_mapping) + setattr(item, name, value) +>>>>>>> edd7357 (new indexer/criteria for related arguments) diff --git a/src/design/plone/contenttypes/vocabularies/argomenti_vocabulary.py b/src/design/plone/contenttypes/vocabularies/argomenti_vocabulary.py index 61ff5e87..a07d25ff 100644 --- a/src/design/plone/contenttypes/vocabularies/argomenti_vocabulary.py +++ b/src/design/plone/contenttypes/vocabularies/argomenti_vocabulary.py @@ -22,4 +22,20 @@ def __call__(self, context): return SimpleVocabulary(terms) +@implementer(IVocabularyFactory) +class ArgomentiUIDVocabulary(object): + """ """ + + def __call__(self, context): + arguments = api.content.find( + portal_type="Pagina Argomento", sort_on="sortable_title" + ) + terms = [SimpleTerm(value="", token="", title="-- seleziona un valore --")] + for x in arguments: + terms.append(SimpleTerm(value=x.UID, token=x.UID, title=x.Title)) + + return SimpleVocabulary(terms) + + ArgomentiVocabularyFactory = ArgomentiVocabulary() +ArgomentiUIDVocabularyFactory = ArgomentiUIDVocabulary() diff --git a/src/design/plone/contenttypes/vocabularies/configure.zcml b/src/design/plone/contenttypes/vocabularies/configure.zcml index 2115dfb7..3550dc13 100644 --- a/src/design/plone/contenttypes/vocabularies/configure.zcml +++ b/src/design/plone/contenttypes/vocabularies/configure.zcml @@ -39,6 +39,12 @@ component=".argomenti_vocabulary.ArgomentiVocabularyFactory" /> + + + Date: Tue, 3 Jan 2023 09:06:36 +0100 Subject: [PATCH 099/487] zpretty --- .../plone/contenttypes/indexers/configure.zcml | 3 ++- .../plone/contenttypes/upgrades/configure.zcml | 12 ------------ 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/src/design/plone/contenttypes/indexers/configure.zcml b/src/design/plone/contenttypes/indexers/configure.zcml index 945d7a11..ec1b51ec 100644 --- a/src/design/plone/contenttypes/indexers/configure.zcml +++ b/src/design/plone/contenttypes/indexers/configure.zcml @@ -34,7 +34,8 @@ /> + name="tassonomia_argomenti_uid" + /> -======= - profile="design.plone.contenttypes:default" - source="5410" - destination="5500"> - - - ->>>>>>> edd7357 (new indexer/criteria for related arguments) From 90cb737ba3b38632d9d8dd5d97304dffc0b84675 Mon Sep 17 00:00:00 2001 From: Andrea Cecchi Date: Tue, 3 Jan 2023 10:13:42 +0100 Subject: [PATCH 100/487] Preparing release 5.1.0 --- CHANGES.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGES.rst b/CHANGES.rst index ec7be517..083cdb1a 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,6 +4,8 @@ Changelog 6.0.0a4 (unreleased) -------------------- +5.1.0 (2023-01-03) +------------------ - Remove selection limit in ufficio_responsabile field for Servizio. [foxtrot-dfm1] From f6785d7ffdc28c44b857466f3ca4c85223409d86 Mon Sep 17 00:00:00 2001 From: Andrea Cecchi Date: Tue, 3 Jan 2023 10:14:04 +0100 Subject: [PATCH 101/487] Back to development: 5.1.1 --- CHANGES.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGES.rst b/CHANGES.rst index 083cdb1a..3c1108b4 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,6 +4,12 @@ Changelog 6.0.0a4 (unreleased) -------------------- +5.1.1 (unreleased) +------------------ + +- Nothing changed yet. + + 5.1.0 (2023-01-03) ------------------ From 7dced471bb641c7bcd839ca5aa8fe938bfe0854d Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 3 Jan 2023 17:27:26 +0100 Subject: [PATCH 102/487] New view `move_news_items` (#36669) --- CHANGES.rst | 3 +- .../plone/contenttypes/browser/configure.zcml | 10 +++ .../browser/move_content/__init__.py | 0 .../browser/move_content/configure.zcml | 16 ++++ .../browser/move_content/move_news_items.py | 79 ++++++++++++++++++ .../move_content/templates/move_news_items.pt | 82 +++++++++++++++++++ .../browser/static/js/move_content.js | 15 ++++ .../tests/test_move_news_items_view.py | 79 ++++++++++++++++++ 8 files changed, 283 insertions(+), 1 deletion(-) create mode 100644 src/design/plone/contenttypes/browser/move_content/__init__.py create mode 100644 src/design/plone/contenttypes/browser/move_content/configure.zcml create mode 100644 src/design/plone/contenttypes/browser/move_content/move_news_items.py create mode 100644 src/design/plone/contenttypes/browser/move_content/templates/move_news_items.pt create mode 100644 src/design/plone/contenttypes/browser/static/js/move_content.js create mode 100644 src/design/plone/contenttypes/tests/test_move_news_items_view.py diff --git a/CHANGES.rst b/CHANGES.rst index 3c1108b4..1198a995 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -7,7 +7,8 @@ Changelog 5.1.1 (unreleased) ------------------ -- Nothing changed yet. +- New view `move_news_item`. + [foxtrot-dfm1] 5.1.0 (2023-01-03) diff --git a/src/design/plone/contenttypes/browser/configure.zcml b/src/design/plone/contenttypes/browser/configure.zcml index 166f644a..6475299d 100644 --- a/src/design/plone/contenttypes/browser/configure.zcml +++ b/src/design/plone/contenttypes/browser/configure.zcml @@ -10,6 +10,16 @@ package="z3c.jbot" file="meta.zcml" /> + + + + + + + + + + diff --git a/src/design/plone/contenttypes/browser/move_content/move_news_items.py b/src/design/plone/contenttypes/browser/move_content/move_news_items.py new file mode 100644 index 00000000..eb99a9ce --- /dev/null +++ b/src/design/plone/contenttypes/browser/move_content/move_news_items.py @@ -0,0 +1,79 @@ +from zope.schema.interfaces import IVocabularyFactory +from zope.component import getUtility +from plone import api +from plone.memoize import ram +from Products.Five import BrowserView + +from plone.app.contenttypes import _ + +import time +import logging +import pkg_resources + + +JS_TEMPLATE = ( + "{portal_url}/++plone++design.plone.contenttypes/js/{name}.js?v={version}" # noqa +) + +logger = logging.getLogger(__name__) + + +class View(BrowserView): + def __call__(self, *args, **kwargs): + self.move_data() + return super().__call__(*args, **kwargs) + + def move_data(self): + if self.request.form.get("move", ""): + path = self.request.form.get("to_path") + if path: + move_to = api.content.get(path) + if not move_to: + self.context.plone_utils.addPortalMessage( + _("Indicated path is not valid"), "error" + ) + return + + for item_uid in [i for i, j in self.request.form.items() if j == "on"]: + item = api.content.get(UID=item_uid) + if item: + try: + api.content.move(item, move_to) + except Exception as e: + logger.error(f"Couldn'move items due to {e}") + self.context.plone_utils.addPortalMessage( + _("Items move was failed"), "error" + ) + return + + self.context.plone_utils.addPortalMessage( + _("Items moved with success"), "info" + ) + + def news_results(self): + news_type = self.request.form.get("news_type", "") + path = self.request.form.get("path", "") + query = {} + + if news_type: + query["tipologia_notizia"] = news_type + if path: + query["path"] = path + + return api.portal.get_tool("portal_catalog")(**query) + + def news_types(self): + return getUtility( + IVocabularyFactory, "design.plone.vocabularies.tipologie_notizia" + )(self.context) + + @ram.cache(lambda *args: time.time() // (60 * 60)) + def get_version(self): + return pkg_resources.get_distribution("design.plone.contenttypes").version + + def get_resource_js(self, name="move_content"): + return JS_TEMPLATE.format( + portal_url=api.portal.get().absolute_url(), + name=name, + version=self.get_version(), + ) diff --git a/src/design/plone/contenttypes/browser/move_content/templates/move_news_items.pt b/src/design/plone/contenttypes/browser/move_content/templates/move_news_items.pt new file mode 100644 index 00000000..8d388a9f --- /dev/null +++ b/src/design/plone/contenttypes/browser/move_content/templates/move_news_items.pt @@ -0,0 +1,82 @@ + + + + +

Move News Items

+
+ + + +
+
+
+ +
+ Find news with this News Type +
+
+ +
+ Find news with the indicated Path +
+ +
+
+ +
+
+
+
+
+
+

Found ${tot_results} items

+
    +
  • +
    + +

    Select all

    +
    +
  • +
  • +
    + +
    +

    Contained by ${python: '/'.join(item.getPath().split('/')[:-1])}

    +
    +
  • +
+
+ +
+ All the selected items will be moved to indicated path +
+ +
+
+
+ +
+
+
+ +
+ + + diff --git a/src/design/plone/contenttypes/browser/static/js/move_content.js b/src/design/plone/contenttypes/browser/static/js/move_content.js new file mode 100644 index 00000000..ea49dfb6 --- /dev/null +++ b/src/design/plone/contenttypes/browser/static/js/move_content.js @@ -0,0 +1,15 @@ +$('#select_all').click(function(event){ + if(this.checked){ + $('form :checkbox').each( + function(){ + this.checked = true; + } + ) + } else { + $('form :checkbox').each( + function(){ + this.checked = false; + } + ) + } +}); diff --git a/src/design/plone/contenttypes/tests/test_move_news_items_view.py b/src/design/plone/contenttypes/tests/test_move_news_items_view.py new file mode 100644 index 00000000..16786d8b --- /dev/null +++ b/src/design/plone/contenttypes/tests/test_move_news_items_view.py @@ -0,0 +1,79 @@ +from plone.app.testing import setRoles +from plone.app.testing import TEST_USER_ID +from plone import api + +from design.plone.contenttypes.testing import ( + DESIGN_PLONE_CONTENTTYPES_INTEGRATION_TESTING, +) + +import unittest + + +class MoveNewsItemView(unittest.TestCase): + + layer = DESIGN_PLONE_CONTENTTYPES_INTEGRATION_TESTING + + def setUp(self): + self.portal = self.layer["portal"] + self.request = self.layer["request"] + self.view = api.content.get_view( + "move_news_items", context=self.portal, request=self.request + ) + + setRoles(self.portal, TEST_USER_ID, ["Manager"]) + + self.news_container = api.content.create( + type="Folder", + title="News container", + container=self.portal, + ) + self.news_item = api.content.create( + type="News Item", + title="news item", + tipologia_notizia="Notizia", + container=self.portal, + ) + self.news_item1 = api.content.create( + type="News Item", + title="news item1", + tipologia_notizia="Notizia", + container=self.news_container, + ) + + def test_news_result(self): + self.view.request.form["news_type"] = "Notizia" + + result = self.view.news_results() + + self.assertIn(self.news_item.UID(), [i.UID for i in result]) + self.assertIn(self.news_item1.UID(), [i.UID for i in result]) + + def test_move_data(self): + self.view.request.form[self.news_item.UID()] = "on" + self.view.request.form[self.news_item1.UID()] = "on" + self.view.request.form["move"] = "true" + self.view.request.form["to_path"] = "/".join( + self.news_container.getPhysicalPath() + ) + + self.view.move_data() + + self.assertIn(self.news_item, self.news_container.listFolderContents()) + self.assertIn(self.news_item1, self.news_container.listFolderContents()) + + def test_bad_data_endurance(self): + """Test instatnce endurance to bad data""" + bad_uid = "bad_uid" + bad_path = "bad_path" + self.view.request.form["move"] = "true" + + self.view.request.form["bad_uid"] = "on" + + self.view.move_data() + + self.view.request.form.pop(bad_uid) + + self.view.request.form[self.news_item.UID()] = "on" + self.view.request.form["to_path"] = bad_path + + self.view.move_data() From 81c87cf94a94bbbf5f019adae11096479d404e74 Mon Sep 17 00:00:00 2001 From: Roman Date: Tue, 3 Jan 2023 18:07:17 +0100 Subject: [PATCH 103/487] Add locales --- .../move_content/templates/move_news_items.pt | 4 +- .../LC_MESSAGES/design.plone.contenttypes.po | 2640 +++++++++++++++++ .../locales/design.plone.contenttypes.pot | 80 +- .../LC_MESSAGES/design.plone.contenttypes.po | 74 +- .../LC_MESSAGES/design.plone.contenttypes.po | 74 +- 5 files changed, 2807 insertions(+), 65 deletions(-) create mode 100644 src/design/plone/contenttypes/locales/__pycache__/LC_MESSAGES/design.plone.contenttypes.po diff --git a/src/design/plone/contenttypes/browser/move_content/templates/move_news_items.pt b/src/design/plone/contenttypes/browser/move_content/templates/move_news_items.pt index 8d388a9f..e4f8d5cf 100644 --- a/src/design/plone/contenttypes/browser/move_content/templates/move_news_items.pt +++ b/src/design/plone/contenttypes/browser/move_content/templates/move_news_items.pt @@ -43,7 +43,7 @@

Found ${tot_results} items

    -
  • +
  • Select all

    @@ -53,7 +53,7 @@

    -

    Contained by ${python: '/'.join(item.getPath().split('/')[:-1])}

    +

    Contained by ${python: '/'.join(item.getPath().split('/')[:-1])}

diff --git a/src/design/plone/contenttypes/locales/__pycache__/LC_MESSAGES/design.plone.contenttypes.po b/src/design/plone/contenttypes/locales/__pycache__/LC_MESSAGES/design.plone.contenttypes.po new file mode 100644 index 00000000..b2dbacdf --- /dev/null +++ b/src/design/plone/contenttypes/locales/__pycache__/LC_MESSAGES/design.plone.contenttypes.po @@ -0,0 +1,2640 @@ +# --- PLEASE EDIT THE LINES BELOW CORRECTLY --- +# Language translations for PACKAGE package. +# Roman Kysil , 2023. +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2023-01-03 17:03+0000\n" +"PO-Revision-Date: 2023-01-03 18:01+0100\n" +"Last-Translator: Roman Kysil \n" +"Language-Team: Language\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0\n" +"Language-Code: en\n" +"Language-Name: English\n" +"Preferred-Encodings: utf-8 latin1\n" +"Domain: design.plone.contenttypes\n" +"Language: __pycache__\n" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:32 +msgid "Abitazione" +msgstr "" + +#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:36 +msgid "Accesso al trasporto pubblico" +msgstr "" + +#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:59 +msgid "Accesso luoghi della cultura" +msgstr "" + +#: design/plone/contenttypes/vocabularies/lista_azioni_pratica.py:33 +msgid "Accettare" +msgstr "" + +#: design/plone/contenttypes/vocabularies/document_types_vocabulary.py:34 +msgid "Accordo tra enti" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:52 +msgid "Acqua" +msgstr "" + +#: design/plone/contenttypes/behaviors/configure.zcml:194 +msgid "Address Event" +msgstr "" + +#: design/plone/contenttypes/behaviors/configure.zcml:178 +msgid "Address UO" +msgstr "" + +#: design/plone/contenttypes/behaviors/configure.zcml:186 +msgid "Address Venue" +msgstr "" + +#: design/plone/contenttypes/behaviors/configure.zcml:19 +msgid "Adds fields." +msgstr "" + +#: design/plone/contenttypes/vocabularies/dataset.py:28 +msgid "Agricoltura, pesca, silvicoltura e prodotti alimentari" +msgstr "" + +#: design/plone/contenttypes/vocabularies/dataset.py:36 +msgid "Ambiente" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:33 +msgid "Animale domestico" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:25 +msgid "Anziano" +msgstr "" + +#: design/plone/contenttypes/interfaces/bando.py:134 +#: design/plone/contenttypes/interfaces/documento.py:67 +#: design/plone/contenttypes/interfaces/servizio.py:239 +msgid "Area" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:50 +msgid "Area di parcheggio" +msgstr "" + +#: design/plone/contenttypes/behaviors/configure.zcml:49 +msgid "Argomenti" +msgstr "" + +#: design/plone/contenttypes/behaviors/configure.zcml:76 +msgid "Argomenti Bando" +msgstr "" + +#: design/plone/contenttypes/behaviors/configure.zcml:58 +msgid "Argomenti Document" +msgstr "" + +#: design/plone/contenttypes/behaviors/configure.zcml:67 +msgid "Argomenti Documento" +msgstr "" + +#: design/plone/contenttypes/behaviors/argomenti.py:28 +msgid "Argomenti correlati" +msgstr "" + +#: design/plone/contenttypes/profiles/default/types/Pagina_Argomento.xml +msgid "Argomento" +msgstr "" + +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:73 +msgid "Assessore di riferimento" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:30 +msgid "Associazione" +msgstr "" + +#: design/plone/contenttypes/vocabularies/lista_azioni_pratica.py:29 +msgid "Attivare" +msgstr "" + +#: design/plone/contenttypes/vocabularies/document_types_vocabulary.py:33 +msgid "Atto normativo" +msgstr "" + +#: design/plone/contenttypes/interfaces/documento_personale.py:86 +msgid "Autore" +msgstr "" + +#: design/plone/contenttypes/vocabularies/lista_azioni_pratica.py:30 +msgid "Autorizzare" +msgstr "" + +#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:65 +msgid "Avvio impresa" +msgstr "" + +#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:66 +msgid "Avvio nuova attività professionale" +msgstr "" + +#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:69 +msgid "Avvio/registrazione filiale" +msgstr "" + +#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:78 +msgid "Bancarotta" +msgstr "" + +#: design/plone/contenttypes/behaviors/configure.zcml:194 +msgid "Behavior address per Event." +msgstr "" + +#: design/plone/contenttypes/behaviors/configure.zcml:178 +msgid "Behavior address per UO." +msgstr "" + +#: design/plone/contenttypes/behaviors/configure.zcml:186 +msgid "Behavior address per Venue." +msgstr "" + +#: design/plone/contenttypes/behaviors/configure.zcml:202 +msgid "Behavior contatti per UO." +msgstr "" + +#: design/plone/contenttypes/behaviors/configure.zcml:210 +msgid "Behavior contatti per Venue." +msgstr "" + +#: design/plone/contenttypes/behaviors/configure.zcml:234 +msgid "Behavior geolocatable per Event." +msgstr "" + +#: design/plone/contenttypes/behaviors/configure.zcml:218 +msgid "Behavior geolocatable per UO." +msgstr "" + +#: design/plone/contenttypes/behaviors/configure.zcml:226 +msgid "Behavior geolocatable per Venue." +msgstr "" + +#: design/plone/contenttypes/controlpanels/geolocation_defaults.py:18 +msgid "CAP" +msgstr "" + +#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:43 +msgid "Cambio di residenza/domicilio" +msgstr "" + +#: design/plone/contenttypes/behaviors/configure.zcml:261 +msgid "Campi aggiuntivi per la sezione amministrazione trasparente." +msgstr "" + +#: design/plone/contenttypes/behaviors/configure.zcml:270 +msgid "Campo per le note di aggiornamento." +msgstr "" + +#: design/plone/contenttypes/vocabularies/mockup.py:26 +msgid "Canon 5D IV" +msgstr "" + +#: design/plone/contenttypes/profiles/default/types/CartellaModulistica.xml +msgid "Cartella Modulistica" +msgstr "" + +#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:75 +msgid "Chiusura filiale" +msgstr "" + +#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:74 +msgid "Chiusura impresa e attività professionale" +msgstr "" + +#: design/plone/contenttypes/controlpanels/geolocation_defaults.py:23 +msgid "Città" +msgstr "" + +#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:39 +msgid "Compravendita/affitto casa/edifici/terreni, costruzione o ristrutturazione casa/edificio " +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:36 +msgid "Comunicazione" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:41 +msgid "Condizioni e organizzazione del lavoro" +msgstr "" + +#: design/plone/contenttypes/browser/move_content/templates/move_news_items.pt:56 +msgid "Contained by" +msgstr "" + +#: design/plone/contenttypes/behaviors/configure.zcml:202 +msgid "Contatti" +msgstr "" + +#: design/plone/contenttypes/controlpanels/geolocation_defaults.py:33 +msgid "Coordinate" +msgstr "" + +#: design/plone/contenttypes/behaviors/argomenti.py:42 +msgid "Correlato in evidenza" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:47 +msgid "Cultura" +msgstr "" + +#: design/plone/contenttypes/interfaces/documento_personale.py:130 +#: design/plone/contenttypes/profiles/default/types/Dataset.xml +msgid "Dataset" +msgstr "" + +#: design/plone/contenttypes/interfaces/documento_personale.py:134 +msgid "Dataset collegato" +msgstr "" + +#: design/plone/contenttypes/behaviors/configure.zcml:104 +msgid "Dataset correlati" +msgstr "" + +#: design/plone/contenttypes/vocabularies/lista_azioni_pratica.py:31 +msgid "Delegare" +msgstr "" + +#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:52 +msgid "Denuncia crimini" +msgstr "" + +#: design/plone/contenttypes/behaviors/configure.zcml:143 +msgid "Descrizione estesa" +msgstr "" + +#: design/plone/contenttypes/behaviors/configure.zcml:160 +msgid "Descrizione estesa documento" +msgstr "" + +#: design/plone/contenttypes/behaviors/configure.zcml:152 +msgid "Descrizione estesa servizio" +msgstr "" + +#: design/plone/contenttypes/configure.zcml:36 +msgid "Design Plone: Content-types" +msgstr "" + +#: design/plone/contenttypes/configure.zcml:45 +msgid "Design Plone: Content-types (uninstall)" +msgstr "" + +#: design/plone/contenttypes/configure.zcml:52 +msgid "Design Plone: Content-types to 3000" +msgstr "" + +#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:55 +msgid "Dichiarazione dei redditi, versamento e riscossione tributi/imposte e contributi" +msgstr "" + +#: design/plone/contenttypes/behaviors/trasparenza.py:145 +msgid "Dirigente" +msgstr "" + +#: design/plone/contenttypes/vocabularies/document_types_vocabulary.py:27 +msgid "Documenti albo pretorio" +msgstr "" + +#: design/plone/contenttypes/interfaces/servizio.py:252 +#: design/plone/contenttypes/profiles/default/types/Documento.xml +msgid "Documento" +msgstr "" + +#: design/plone/contenttypes/vocabularies/document_types_vocabulary.py:41 +msgid "Documento (tecnico) di supporto" +msgstr "" + +#: design/plone/contenttypes/profiles/default/types/Documento_Personale.xml +msgid "Documento Personale" +msgstr "" + +#: design/plone/contenttypes/vocabularies/document_types_vocabulary.py:37 +msgid "Documento attivita politica" +msgstr "" + +#: design/plone/contenttypes/vocabularies/document_types_vocabulary.py:31 +msgid "Documento funzionamento interno" +msgstr "" + +#: design/plone/contenttypes/vocabularies/dataset.py:30 +msgid "Economia e Finanze" +msgstr "" + +#: design/plone/contenttypes/profiles/default/types/CartellaModulistica.xml +#: design/plone/contenttypes/profiles/default/types/Dataset.xml +#: design/plone/contenttypes/profiles/default/types/Documento.xml +msgid "Edit" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:45 +msgid "Elezione" +msgstr "" + +#: design/plone/contenttypes/vocabularies/dataset.py:35 +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:61 +msgid "Energia" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:28 +msgid "Famiglia" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:26 +msgid "Fanciullo" +msgstr "" + +#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:70 +msgid "Finanziamento impresa" +msgstr "" + +#: design/plone/contenttypes/configure.zcml:52 +msgid "Fix control panel of design.plone.contenttypes add-on." +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:38 +msgid "Formazione professionale" +msgstr "" + +#: design/plone/contenttypes/behaviors/configure.zcml:218 +msgid "Geolocatable" +msgstr "" + +#: design/plone/contenttypes/controlpanels/geolocation_defaults.py:43 +#: design/plone/contenttypes/profiles/default/controlpanel.xml +msgid "Geolocation default" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:53 +msgid "Gestione dei rifiuti" +msgstr "" + +#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:71 +msgid "Gestione personale" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:27 +msgid "Giovane" +msgstr "" + +#: design/plone/contenttypes/vocabularies/mockup.py:30 +msgid "Giovanni" +msgstr "" + +#: design/plone/contenttypes/vocabularies/dataset.py:42 +msgid "Giustizia, sistema giuridico e sicurezza pubblica" +msgstr "" + +#: design/plone/contenttypes/vocabularies/dataset.py:37 +msgid "Governo e settore pubblico" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:48 +msgid "Immigrazione" +msgstr "" + +#: design/plone/contenttypes/controlpanels/settings.py:154 +#: design/plone/contenttypes/profiles/default/controlpanel.xml +msgid "Impostazioni Design Plone" +msgstr "" + +#: design/plone/contenttypes/browser/move_content/move_news_items.py:33 +msgid "Indicated path is not valid" +msgstr "" + +#: design/plone/contenttypes/behaviors/configure.zcml:170 +msgid "Info per la testata" +msgstr "" + +#: design/plone/contenttypes/vocabularies/lista_azioni_pratica.py:32 +msgid "Informare" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:64 +msgid "Informatica e trattamento dei dati" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:49 +msgid "Inquinamento" +msgstr "" + +#: design/plone/contenttypes/configure.zcml:36 +msgid "Installs the design.plone.contenttypes add-on." +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:34 +msgid "Integrazione sociale" +msgstr "" + +#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:28 +msgid "Invalidità" +msgstr "" + +#: design/plone/contenttypes/vocabularies/lista_azioni_pratica.py:26 +msgid "Iscriversi" +msgstr "" + +#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:26 +msgid "Iscrizione scuola/università e/o richiesta borsa di studio" +msgstr "" + +#: design/plone/contenttypes/vocabularies/document_types_vocabulary.py:43 +msgid "Istanza" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:31 +msgid "Istruzione" +msgstr "" + +#: design/plone/contenttypes/vocabularies/dataset.py:33 +msgid "Istruzione, cultura e sport" +msgstr "" + +#: design/plone/contenttypes/browser/move_content/move_news_items.py:45 +msgid "Items move was failed" +msgstr "" + +#: design/plone/contenttypes/browser/move_content/move_news_items.py:50 +msgid "Items moved with success" +msgstr "" + +#: design/plone/contenttypes/vocabularies/lista_azioni_pratica.py:28 +msgid "Leggere" +msgstr "" + +#: design/plone/contenttypes/behaviors/configure.zcml:85 +msgid "Luoghi correlati" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:44 +msgid "Matrimonio" +msgstr "" + +#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:49 +msgid "Matrimonio e/o cambio stato civile" +msgstr "" + +#: design/plone/contenttypes/profiles/default/types/Messaggio.xml +msgid "Messaggio" +msgstr "" + +#: design/plone/contenttypes/behaviors/configure.zcml:29 +msgid "Metadati evento" +msgstr "" + +#: design/plone/contenttypes/behaviors/configure.zcml:19 +msgid "Metadati luogo" +msgstr "" + +#: design/plone/contenttypes/behaviors/configure.zcml:39 +msgid "Metadati news" +msgstr "" + +#: design/plone/contenttypes/vocabularies/document_types_vocabulary.py:28 +msgid "Modulistica" +msgstr "" + +#: design/plone/contenttypes/profiles/default/types/Modulo.xml +msgid "Modulo" +msgstr "" + +#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:50 +msgid "Morte ed eredità" +msgstr "" + +#: design/plone/contenttypes/behaviors/configure.zcml:252 +msgid "Mostra la data di modifica." +msgstr "" + +#: design/plone/contenttypes/browser/move_content/templates/move_news_items.pt:69 +msgid "Move" +msgstr "" + +#: design/plone/contenttypes/browser/move_content/templates/move_news_items.pt:11 +msgid "Move News Items" +msgstr "" + +#: design/plone/contenttypes/behaviors/configure.zcml:243 +msgid "Multi File" +msgstr "" + +#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:48 +msgid "Nascita di un bambino, richiesta adozioni" +msgstr "" + +#: design/plone/contenttypes/controlpanels/geolocation_defaults.py:28 +msgid "Nazione" +msgstr "" + +#. Default: "Nome e cognome" +#: design/plone/contenttypes/restapi/services/types/get.py:152 +msgid "Nome e Cognome" +msgstr "" + +#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:73 +msgid "Notifiche autorità" +msgstr "" + +#: design/plone/contenttypes/interfaces/persona.py:48 +msgid "Organizzazione di riferimento" +msgstr "" + +#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:72 +msgid "Pagamento tasse, iva e dogane" +msgstr "" + +#: design/plone/contenttypes/vocabularies/lista_azioni_pratica.py:25 +msgid "Pagare" +msgstr "" + +#: design/plone/contenttypes/vocabularies/mockup.py:29 +msgid "Paperino" +msgstr "" + +#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:81 +msgid "Partecipazione ad appalti pubblici nazionali e trasfrontalieri" +msgstr "" + +#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:33 +msgid "Pensionamento" +msgstr "" + +#: design/plone/contenttypes/profiles/default/types/Persona.xml +msgid "Persona" +msgstr "" + +#: design/plone/contenttypes/behaviors/evento.py:50 +msgid "Persona dell'amministrazione" +msgstr "" + +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:92 +msgid "Persone della struttura" +msgstr "" + +#: design/plone/contenttypes/vocabularies/mockup.py:27 +msgid "Pippo" +msgstr "" + +#: design/plone/contenttypes/vocabularies/mockup.py:28 +msgid "Pluto" +msgstr "" + +#: design/plone/contenttypes/vocabularies/dataset.py:45 +msgid "Popolazione e società" +msgstr "" + +#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:60 +msgid "Possesso, cura, smarrimento animale da compagnia" +msgstr "" + +#: design/plone/contenttypes/profiles/default/types/Pratica.xml +msgid "Pratica" +msgstr "" + +#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:51 +msgid "Prenotazione e disdetta visite/esami" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:35 +msgid "Protezione sociale" +msgstr "" + +#: design/plone/contenttypes/vocabularies/dataset.py:44 +msgid "Regioni e città" +msgstr "" + +#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:68 +msgid "Registrazione impresa transfrontalier" +msgstr "" + +#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:35 +msgid "Registrazione/possesso veicolo" +msgstr "" + +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:45 +msgid "Responsabile" +msgstr "" + +#: design/plone/contenttypes/behaviors/trasparenza.py:129 +msgid "Responsabile procedimento" +msgstr "" + +#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:31 +msgid "Ricerca di lavoro, avvio nuovo lavoro, disoccupazione" +msgstr "" + +#: design/plone/contenttypes/profiles/default/types/RicevutaPagamento.xml +msgid "RicevutaPagamento" +msgstr "" + +#: design/plone/contenttypes/vocabularies/lista_azioni_pratica.py:27 +msgid "Richiedere" +msgstr "" + +#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:67 +msgid "Richiesta licenze/permessi/certificati" +msgstr "" + +#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:34 +msgid "Richiesta o rinnovo patente" +msgstr "" + +#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:46 +msgid "Richiesta passaporto, visto e assistenza viaggi internazionali" +msgstr "" + +#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:76 +msgid "Ristrutturazione impresa" +msgstr "" + +#: design/plone/contenttypes/vocabularies/dataset.py:38 +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:54 +msgid "Salute" +msgstr "" + +#: design/plone/contenttypes/vocabularies/dataset.py:46 +msgid "Scienza e tecnologia" +msgstr "" + +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:114 +msgid "Sede" +msgstr "" + +#: design/plone/contenttypes/behaviors/configure.zcml:114 +msgid "Servizi correlati" +msgstr "" + +#: design/plone/contenttypes/profiles/default/types/Servizio.xml +msgid "Servizio" +msgstr "" + +#: design/plone/contenttypes/interfaces/documento_personale.py:101 +msgid "Servizio collegato" +msgstr "" + +#: design/plone/contenttypes/behaviors/configure.zcml:252 +msgid "Show modified" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:56 +msgid "Sicurezza internazionale" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:55 +msgid "Sicurezza pubblica" +msgstr "" + +#: design/plone/contenttypes/vocabularies/mockup.py:25 +msgid "Sony Aplha 7R III" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:57 +msgid "Spazio verde" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:58 +msgid "Sport" +msgstr "" + +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:37 +msgid "Struttura" +msgstr "" + +#: design/plone/contenttypes/behaviors/strutture_correlate.py:20 +msgid "Struttura politica coinvolta" +msgstr "" + +#: design/plone/contenttypes/behaviors/luogo.py:74 +msgid "Struttura responsabile" +msgstr "" + +#: design/plone/contenttypes/behaviors/configure.zcml:124 +msgid "Strutture correlate" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:29 +msgid "Studente" +msgstr "" + +#: design/plone/contenttypes/behaviors/configure.zcml:49 +msgid "Tassonomia argomenti" +msgstr "" + +#: design/plone/contenttypes/behaviors/configure.zcml:58 +msgid "Tassonomia argomenti per i Document" +msgstr "" + +#: design/plone/contenttypes/vocabularies/dataset.py:39 +msgid "Tematiche internazionali" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:46 +msgid "Tempo libero" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:51 +msgid "Traffico urbano" +msgstr "" + +#: design/plone/contenttypes/behaviors/configure.zcml:261 +msgid "Trasparenza" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:43 +msgid "Trasporto" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:59 +msgid "Trasporto stradale" +msgstr "" + +#: design/plone/contenttypes/behaviors/configure.zcml:243 +msgid "Tre campi file aggiuntivi." +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:60 +msgid "Turismo" +msgstr "" + +#: design/plone/contenttypes/interfaces/bando.py:117 +#: design/plone/contenttypes/interfaces/documento.py:50 +#: design/plone/contenttypes/interfaces/servizio.py:225 +msgid "Ufficio responsabile" +msgstr "" + +#: design/plone/contenttypes/behaviors/configure.zcml:134 +msgid "Ulteriori campi aiuto testuali" +msgstr "" + +#: design/plone/contenttypes/profiles/default/types/Modulo.xml +msgid "Un modulo compilabile." +msgstr "" + +#: design/plone/contenttypes/configure.zcml:45 +msgid "Uninstalls the design.plone.contenttypes add-on." +msgstr "" + +#: design/plone/contenttypes/profiles/default/types/UnitaOrganizzativa.xml +msgid "Unita Organizzativa" +msgstr "" + +#: design/plone/contenttypes/interfaces/pagina_argomento.py:45 +msgid "Unità amministrative responsabili" +msgstr "" + +#: design/plone/contenttypes/behaviors/configure.zcml:270 +msgid "Update note" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:37 +msgid "Urbanistica ed edilizia" +msgstr "" + +#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:77 +msgid "Vendita impresa" +msgstr "" + +#: design/plone/contenttypes/controlpanels/geolocation_defaults.py:13 +msgid "Via" +msgstr "" + +#: design/plone/contenttypes/profiles/default/types/CartellaModulistica.xml +#: design/plone/contenttypes/profiles/default/types/Dataset.xml +#: design/plone/contenttypes/profiles/default/types/Documento.xml +msgid "View" +msgstr "" + +#. Default: "A chi si rivolge questo servizio e chi può usufruirne." +#: design/plone/contenttypes/interfaces/servizio.py:53 +msgid "a_chi_si_rivolge_help" +msgstr "" + +#. Default: "A chi si rivolge" +#: design/plone/contenttypes/interfaces/servizio.py:51 +msgid "a_chi_si_rivolge_label" +msgstr "" + +#. Default: "Seleziona l'ufficio di comunicazione responsabile di questa notizia/comunicato stampa." +#: design/plone/contenttypes/behaviors/news_additional_fields.py:47 +msgid "a_cura_di_help" +msgstr "" + +#. Default: "A cura di" +#: design/plone/contenttypes/behaviors/news_additional_fields.py:46 +msgid "a_cura_di_label" +msgstr "" + +#. Default: "Seleziona una lista di persone dell'amministrazione citate in questa notizia/comunicato stampa. Questa informazione verrà mostrata nella sezione \"A cura di\"." +#: design/plone/contenttypes/behaviors/news_additional_fields.py:59 +msgid "a_cura_di_persone_help" +msgstr "" + +#. Default: "Persone" +#: design/plone/contenttypes/behaviors/news_additional_fields.py:58 +msgid "a_cura_di_persone_label" +msgstr "" + +#. Default: "Accedere al servizio" +#: design/plone/contenttypes/interfaces/servizio.py:370 +msgid "accedi_al_servizio_label" +msgstr "" + +#. Default: "Modalità di accesso" +#: design/plone/contenttypes/behaviors/luogo.py:171 +msgid "accesso_label" +msgstr "" + +#. Default: "Allegato" +#: design/plone/contenttypes/interfaces/ricevuta_pagamento.py:56 +msgid "allegato" +msgstr "" + +#. Default: "Indicare, se esistono, altre modalità di invio." +#: design/plone/contenttypes/behaviors/trasparenza.py:189 +msgid "altre_modalita_invio_help" +msgstr "" + +#. Default: "Altre modalità di invio" +#: design/plone/contenttypes/behaviors/trasparenza.py:185 +msgid "altre_modalita_invio_label" +msgstr "" + +#. Default: "Seleziona la lista dei documenti di supporto collegati a questo servizio." +#: design/plone/contenttypes/interfaces/servizio.py:246 +msgid "altri_documenti_help" +msgstr "" + +#. Default: "Date and time of the opening of the announcement. Use this field if you want to set a specific opening date. If not set, the announcement will be open immediately." +#: design/plone/contenttypes/interfaces/bando.py:56 +msgid "apertura_bando_help" +msgstr "" + +#. Default: "Opening date" +#: design/plone/contenttypes/interfaces/bando.py:55 +msgid "apertura_bando_label" +msgstr "" + +#. Default: "Area" +#: design/plone/contenttypes/interfaces/servizio.py:231 +msgid "area" +msgstr "" + +#. Default: "Seleziona l'area da cui dipende questo servizio." +#: design/plone/contenttypes/interfaces/servizio.py:234 +msgid "area_help" +msgstr "" + +#. Default: "Area responsabile" +#: design/plone/contenttypes/interfaces/documento_personale.py:73 +msgid "area_responsabile_documento_personale" +msgstr "" + +#. Default: "Seleziona l'area amministrativa responsabile del documento." +#: design/plone/contenttypes/interfaces/bando.py:127 +#: design/plone/contenttypes/interfaces/documento.py:60 +msgid "area_responsabile_help" +msgstr "" + +#. Default: "Area responsabile del documento" +#: design/plone/contenttypes/interfaces/bando.py:123 +#: design/plone/contenttypes/interfaces/documento.py:56 +msgid "area_responsabile_label" +msgstr "" + +#. Default: "Argomenti utenti" +#: design/plone/contenttypes/interfaces/documento_personale.py:42 +msgid "argomenti_utenti" +msgstr "" + +#. Default: "Inserire l'assessore di riferimento della struttura, se esiste." +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:76 +msgid "assessore_riferimento_help" +msgstr "" + +#. Default: "Indicare, se la esistono, atti e documenti a corredo dell'istanza." +#: design/plone/contenttypes/behaviors/trasparenza.py:200 +msgid "atti_documenti_corredo_help" +msgstr "" + +#. Default: "Atti e documenti a corredo dell'istanza" +#: design/plone/contenttypes/behaviors/trasparenza.py:196 +msgid "atti_documenti_corredo_label" +msgstr "" + +#. Default: "Inserire un file contenente l'atto di nomina della persona." +#: design/plone/contenttypes/interfaces/persona.py:160 +msgid "atto_nomina_help" +msgstr "" + +#. Default: "Atto di nomina" +#: design/plone/contenttypes/interfaces/persona.py:158 +msgid "atto_nomina_label" +msgstr "" + +#. Default: "Autenticazione" +#: design/plone/contenttypes/interfaces/servizio.py:121 +msgid "autenticazione" +msgstr "" + +#. Default: "Indicare, se previste, le modalità di autenticazione necessarie per poter accedere al servizio." +#: design/plone/contenttypes/interfaces/servizio.py:122 +msgid "autenticazione_help" +msgstr "" + +#. Default: "Seleziona una lista di autori che hanno pubblicato il documento. Possono essere Persone o Unità Organizzative." +#: design/plone/contenttypes/interfaces/documento.py:76 +msgid "autori_help" +msgstr "" + +#. Default: "Autore/i" +#: design/plone/contenttypes/interfaces/documento.py:72 +msgid "autori_label" +msgstr "" + +#. Default: "Azioni" +#: design/plone/contenttypes/interfaces/messaggio.py:28 +msgid "azioni_pratica" +msgstr "" + +#. Default: "Azioni richieste" +#: design/plone/contenttypes/interfaces/messaggio.py:22 +msgid "azioni_richieste" +msgstr "" + +#. Default: "Azioni utente" +#: design/plone/contenttypes/interfaces/pratica.py:47 +msgid "azioni_utente" +msgstr "" + +#. Default: "Solo per persona politica: testo descrittivo che riporta la biografia della persona." +#: design/plone/contenttypes/interfaces/persona.py:107 +msgid "biografia_help" +msgstr "" + +#. Default: "Biografia" +#: design/plone/contenttypes/interfaces/persona.py:106 +msgid "biografia_label" +msgstr "" + +#. Default: "Canale digitale" +#: design/plone/contenttypes/interfaces/servizio.py:111 +msgid "canale_digitale" +msgstr "" + +#. Default: "Collegamento con l'eventuale canale digitale di attivazione del servizio." +#: design/plone/contenttypes/interfaces/servizio.py:112 +msgid "canale_digitale_help" +msgstr "" + +#. Default: "Canale digitale servizio collegato" +#: design/plone/contenttypes/interfaces/documento_personale.py:108 +msgid "canale_digitale_servizio" +msgstr "" + +#. Default: "Casi particolari" +#: design/plone/contenttypes/interfaces/servizio.py:205 +msgid "casi_particolari" +msgstr "" + +#. Default: "Descrizione degli evetuali casi particolari riferiti alla fruibilità di questo servizio." +#: design/plone/contenttypes/interfaces/servizio.py:207 +msgid "casi_particolari_help" +msgstr "" + +#. Default: "Casi particolari" +#: design/plone/contenttypes/interfaces/servizio.py:401 +msgid "casi_particolari_label" +msgstr "" + +#. Default: "Descrizione di chi può presentare domanda per usufruire del servizio e delle diverse casistiche." +#: design/plone/contenttypes/interfaces/servizio.py:62 +msgid "chi_puo_presentare_help" +msgstr "" + +#. Default: "Chi può presentare" +#: design/plone/contenttypes/interfaces/servizio.py:60 +msgid "chi_puo_presentare_label" +msgstr "" + +#. Default: "Circoscrizione" +#: design/plone/contenttypes/behaviors/address.py:37 +msgid "circoscrizione" +msgstr "" + +#. Default: "Codice dell'ente erogatore (ipa)" +#: design/plone/contenttypes/interfaces/servizio.py:268 +msgid "codice_ipa" +msgstr "" + +#. Default: "Specificare il nome dell’organizzazione, come indicato nell’Indice della Pubblica Amministrazione (IPA), che esercita uno specifico ruolo sul Servizio." +#: design/plone/contenttypes/interfaces/servizio.py:270 +msgid "codice_ipa_help" +msgstr "" + +#. Default: "Come si fa" +#: design/plone/contenttypes/interfaces/servizio.py:80 +msgid "come_si_fa" +msgstr "" + +#. Default: "Descrizione della procedura da seguire per poter usufruire del servizio." +#: design/plone/contenttypes/interfaces/servizio.py:82 +msgid "come_si_fa_help" +msgstr "" + +#. Default: "Descrizione del ruolo e dei compiti della persona." +#: design/plone/contenttypes/interfaces/persona.py:69 +msgid "competenze_help" +msgstr "" + +#. Default: "Competenze" +#: design/plone/contenttypes/interfaces/persona.py:68 +msgid "competenze_label" +msgstr "" + +#. Default: "Informazioni di contatto generiche" +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:137 +msgid "contact_info_label" +msgstr "" + +#. Default: "Contatti" +#: design/plone/contenttypes/interfaces/pratica.py:44 +msgid "contatti" +msgstr "" + +#. Default: "Contatti" +#: design/plone/contenttypes/behaviors/address.py:52 +#: design/plone/contenttypes/behaviors/contatti.py:76 +#: design/plone/contenttypes/behaviors/evento.py:215 +msgid "contatti_label" +msgstr "" + +#. Default: "Contenuto" +#: design/plone/contenttypes/interfaces/pratica.py:42 +msgid "contenuto" +msgstr "" + +#. Default: "Indicare se il servizio si riferisce ad una particolare area geografica o all'intero territorio di riferimento." +#: design/plone/contenttypes/interfaces/servizio.py:72 +msgid "copertura_geografica_help" +msgstr "" + +#. Default: "Copertura geografica" +#: design/plone/contenttypes/interfaces/servizio.py:70 +msgid "copertura_geografica_label" +msgstr "" + +#. Default: "Contenuti collegati" +#: design/plone/contenttypes/behaviors/argomenti.py:74 +#: design/plone/contenttypes/behaviors/dataset_correlati.py:40 +#: design/plone/contenttypes/behaviors/servizi_correlati.py:43 +msgid "correlati_label" +msgstr "" + +#. Default: "Seleziona un correlato da mettere in evidenza per questo contenuto." +#: design/plone/contenttypes/behaviors/argomenti.py:36 +msgid "correlato_in_evidenza_help" +msgstr "" + +#. Default: "Correlato in evidenza" +#: design/plone/contenttypes/behaviors/argomenti.py:35 +msgid "correlato_in_evidenza_label" +msgstr "" + +#. Default: "Cosa fa" +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:206 +msgid "cosa_fa_label" +msgstr "" + +#. Default: "Cosa serve" +#: design/plone/contenttypes/interfaces/servizio.py:177 +msgid "cosa_serve" +msgstr "" + +#. Default: "Descrizione delle istruzioni per usufruire del servizio." +#: design/plone/contenttypes/interfaces/servizio.py:179 +msgid "cosa_serve_help" +msgstr "" + +#. Default: "Cosa serve" +#: design/plone/contenttypes/interfaces/servizio.py:384 +msgid "cosa_serve_label" +msgstr "" + +#. Default: "Cosa si ottiene" +#: design/plone/contenttypes/interfaces/servizio.py:90 +msgid "cosa_si_ottiene" +msgstr "" + +#. Default: "Indicare cosa si può ottenere dal servizio, ad esempio 'carta di identità elettronica', 'certificato di residenza'." +#: design/plone/contenttypes/interfaces/servizio.py:91 +msgid "cosa_si_ottiene_help" +msgstr "" + +#. Default: "Cos'è" +#: design/plone/contenttypes/behaviors/descrizione_estesa.py:40 +#: design/plone/contenttypes/behaviors/evento.py:200 +msgid "cose_label" +msgstr "" + +#. Default: "Costi" +#: design/plone/contenttypes/interfaces/servizio.py:186 +msgid "costi" +msgstr "" + +#. Default: "Costi e vincoli" +#: design/plone/contenttypes/interfaces/servizio.py:389 +msgid "costi_e_vincoli_label" +msgstr "" + +#. Default: "Descrizione delle condizioni e dei termini economici per completare la procedura di richiesta del servizio." +#: design/plone/contenttypes/interfaces/servizio.py:188 +msgid "costi_help" +msgstr "" + +#. Default: "Costi" +#: design/plone/contenttypes/behaviors/evento.py:212 +msgid "costi_label" +msgstr "" + +#. Default: "Allega un file contenente il curriculum vitae della persona. Se ha più file da allegare, utilizza questo campo per quello principale e gli altri mettili dentro alla cartella \"Curriculum vitae\" che troverai dentro alla Persona." +#: design/plone/contenttypes/interfaces/persona.py:149 +msgid "curriculum_vitae_help" +msgstr "" + +#. Default: "Curriculum vitae" +#: design/plone/contenttypes/interfaces/persona.py:147 +msgid "curriculum_vitae_label" +msgstr "" + +#. Default: "Risultati indagini di customer satisfaction." +#: design/plone/contenttypes/behaviors/trasparenza.py:254 +msgid "customer_satisfaction_help" +msgstr "" + +#. Default: "Risultati indagini di customer satisfaction" +#: design/plone/contenttypes/behaviors/trasparenza.py:249 +msgid "customer_satisfaction_label" +msgstr "" + +#. Default: "Data di conclusione dell'incarico." +#: design/plone/contenttypes/interfaces/persona.py:60 +msgid "data_conclusione_incarico_help" +msgstr "" + +#. Default: "Data conclusione incarico" +#: design/plone/contenttypes/interfaces/persona.py:56 +msgid "data_conclusione_incarico_label" +msgstr "" + +#. Default: "Data e fasi intermedie" +#: design/plone/contenttypes/interfaces/documento_personale.py:120 +msgid "data_e_fasi_intermedie" +msgstr "" + +#. Default: "Data di inizio" +#: design/plone/contenttypes/interfaces/documento_personale.py:116 +msgid "data_inizio" +msgstr "" + +#. Default: "Solo per persona politica: specificare la data di insediamento." +#: design/plone/contenttypes/interfaces/persona.py:97 +msgid "data_insediamento_help" +msgstr "" + +#. Default: "Data insediamento" +#: design/plone/contenttypes/interfaces/persona.py:96 +msgid "data_insediamento_label" +msgstr "" + +#. Default: "Data del messaggio" +#: design/plone/contenttypes/interfaces/messaggio.py:12 +msgid "data_messaggio" +msgstr "" + +#. Default: "Data pagamento" +#: design/plone/contenttypes/interfaces/ricevuta_pagamento.py:21 +msgid "data_pagamento" +msgstr "" + +#. Default: "Data del protocollo" +#: design/plone/contenttypes/interfaces/documento_personale.py:19 +msgid "data_protocollo" +msgstr "" + +#. Default: "Data di scadenza della procedura" +#: design/plone/contenttypes/interfaces/messaggio.py:40 +msgid "data_scadenza_procedura" +msgstr "" + +#. Default: "Dataset" +#: design/plone/contenttypes/interfaces/dataset.py:27 +msgid "dataset" +msgstr "" + +#. Default: "Seleziona una lista di schede dataset collegate a questo contenuto." +#: design/plone/contenttypes/behaviors/dataset_correlati.py:19 +msgid "dataset_correlati_help" +msgstr "" + +#. Default: "Dataset correlati" +#: design/plone/contenttypes/behaviors/dataset_correlati.py:18 +msgid "dataset_correlati_label" +msgstr "" + +#. Default: "Date e orari" +#: design/plone/contenttypes/behaviors/evento.py:209 +#: design/plone/contenttypes/schema_overrides.py:34 +msgid "date_e_orari_label" +msgstr "" + +#. Default: "Inserisci la decorrenza termine del procedimento." +#: design/plone/contenttypes/behaviors/trasparenza.py:69 +msgid "decorrenza_termini_help" +msgstr "" + +#. Default: "Decorrenza termine del procedimento" +#: design/plone/contenttypes/behaviors/trasparenza.py:64 +msgid "decorrenza_termini_label" +msgstr "" + +#. Default: "Elenco delle deleghe a capo della persona." +#: design/plone/contenttypes/interfaces/persona.py:77 +msgid "deleghe_help" +msgstr "" + +#. Default: "Deleghe" +#: design/plone/contenttypes/interfaces/persona.py:76 +msgid "deleghe_label" +msgstr "" + +#. Default: "Descrizione completa" +#: design/plone/contenttypes/behaviors/luogo.py:23 +msgid "descrizione_completa" +msgstr "" + +#. Default: "Descrizione destinatari" +#: design/plone/contenttypes/behaviors/evento.py:38 +msgid "descrizione_destinatari" +msgstr "" + +#. Default: "Descrizione dei principali interlocutori dell'evento." +#: design/plone/contenttypes/behaviors/evento.py:40 +msgid "descrizione_destinatari_help" +msgstr "" + +#. Default: "Descrizione estesa" +#: design/plone/contenttypes/behaviors/descrizione_estesa.py:16 +#: design/plone/contenttypes/behaviors/evento.py:30 +#: design/plone/contenttypes/behaviors/news_additional_fields.py:19 +msgid "descrizione_estesa" +msgstr "" + +#. Default: "Descrizione dettagliata e completa." +#: design/plone/contenttypes/behaviors/descrizione_estesa.py:18 +#: design/plone/contenttypes/behaviors/evento.py:32 +#: design/plone/contenttypes/behaviors/news_additional_fields.py:21 +msgid "descrizione_estesa_help" +msgstr "" + +#. Default: "Descrizione" +#: design/plone/contenttypes/behaviors/descrizione_estesa.py:51 +#: design/plone/contenttypes/behaviors/luogo.py:166 +#: design/plone/contenttypes/interfaces/documento.py:162 +msgid "descrizione_label" +msgstr "" + +#. Default: "Inserisci eventuale testo descrittivo del procedimento." +#: design/plone/contenttypes/behaviors/trasparenza.py:37 +msgid "descrizione_procedimento_help" +msgstr "" + +#. Default: "Descrizione del procedimento" +#: design/plone/contenttypes/behaviors/trasparenza.py:32 +msgid "descrizione_procedimento_label" +msgstr "" + +#. Default: "Dirigente" +#: design/plone/contenttypes/behaviors/trasparenza.py:136 +msgid "dirigente" +msgstr "" + +#. Default: "Indicare il dirigente." +#: design/plone/contenttypes/behaviors/trasparenza.py:140 +msgid "dirigente_help" +msgstr "" + +#. Default: "Distribuzione" +#: design/plone/contenttypes/interfaces/dataset.py:22 +msgid "distribuzione" +msgstr "" + +#. Default: "Documenti allegati" +#: design/plone/contenttypes/interfaces/messaggio.py:56 +msgid "documenti_allegati" +msgstr "" + +#. Default: "Seleziona una serie di altri contenuti di tipo Documento che vanno allegati a questo." +#: design/plone/contenttypes/interfaces/documento.py:113 +msgid "documenti_allegati_help" +msgstr "" + +#. Default: "Documenti allegati" +#: design/plone/contenttypes/interfaces/documento.py:109 +msgid "documenti_allegati_label" +msgstr "" + +#. Default: "Documenti" +#: design/plone/contenttypes/interfaces/persona.py:199 +#: design/plone/contenttypes/interfaces/servizio.py:412 +msgid "documenti_label" +msgstr "" + +#. Default: "Dove" +#: design/plone/contenttypes/behaviors/address.py:71 +#: design/plone/contenttypes/behaviors/geolocation.py:29 +msgid "dove_label" +msgstr "" + +#. Default: "Dove rivolgersi: informazioni aggiuntive" +#: design/plone/contenttypes/interfaces/servizio.py:143 +msgid "dove_rivolgersi_extra" +msgstr "" + +#. Default: "Indicare eventuali informazioni aggiuntive riguardo al dove rivolgersi per questo servizio." +#: design/plone/contenttypes/interfaces/servizio.py:147 +msgid "dove_rivolgersi_extra_help" +msgstr "" + +#. Default: "Seleziona una lista delle sedi e dei luoghi in cui è presente questo servizio." +#: design/plone/contenttypes/interfaces/servizio.py:135 +msgid "dove_rivolgersi_help" +msgstr "" + +#. Default: "Elementi di interesse" +#: design/plone/contenttypes/behaviors/luogo.py:44 +msgid "elementi_di_interesse" +msgstr "" + +#. Default: "Indicare un indirizzo mail per poter contattare gli organizzatori." +#: design/plone/contenttypes/behaviors/evento.py:128 +msgid "email_event_help" +msgstr "" + +#. Default: "E-mail" +#: design/plone/contenttypes/behaviors/evento.py:127 +msgid "email_event_label" +msgstr "" + +#. Default: "Indicare un indirizzo mail per poter contattare i referenti." +#: design/plone/contenttypes/behaviors/contatti.py:35 +msgid "email_help" +msgstr "" + +#. Default: "E-mail" +#: design/plone/contenttypes/behaviors/contatti.py:34 +msgid "email_label" +msgstr "" + +#. Default: "Contatto mail della persona. E' possibile inserire più di un indirizzo. Premendo \"Invio\" o \"tab\" si può passare al successivo da inserire." +#: design/plone/contenttypes/interfaces/persona.py:135 +msgid "email_persona_help" +msgstr "" + +#. Default: "Indirizzo email" +#: design/plone/contenttypes/interfaces/persona.py:134 +msgid "email_persona_label" +msgstr "" + +#. Default: "Esito" +#: design/plone/contenttypes/interfaces/ricevuta_pagamento.py:51 +msgid "esito" +msgstr "" + +#. Default: "Fax" +#: design/plone/contenttypes/behaviors/evento.py:113 +msgid "fax_event_help" +msgstr "" + +#. Default: "Indicare un numero di fax." +#: design/plone/contenttypes/behaviors/evento.py:114 +msgid "fax_event_label" +msgstr "" + +#. Default: "Indicare un numero di fax." +#: design/plone/contenttypes/behaviors/contatti.py:29 +msgid "fax_help" +msgstr "" + +#. Default: "Fax" +#: design/plone/contenttypes/behaviors/contatti.py:28 +msgid "fax_label" +msgstr "" + +#. Default: "Indicare un numero di fax." +#: design/plone/contenttypes/interfaces/persona.py:130 +msgid "fax_persona_help" +msgstr "" + +#. Default: "Fax" +#: design/plone/contenttypes/interfaces/persona.py:129 +msgid "fax_persona_label" +msgstr "" + +#. Default: "Inserisci il file correlato di questo pocedimento." +#: design/plone/contenttypes/behaviors/trasparenza.py:44 +msgid "file_correlato_help" +msgstr "" + +#. Default: "File correlato" +#: design/plone/contenttypes/behaviors/trasparenza.py:43 +msgid "file_correlato_label" +msgstr "" + +#. Default: "Inserisci il file principale di questo contenuto." +#: design/plone/contenttypes/behaviors/multi_file.py:16 +msgid "file_principale_help" +msgstr "" + +#. Default: "File principale" +#: design/plone/contenttypes/behaviors/multi_file.py:15 +msgid "file_principale_label" +msgstr "" + +#. Default: "Inserisci la fine termine del procedimento." +#: design/plone/contenttypes/behaviors/trasparenza.py:80 +msgid "fine_termine_help" +msgstr "" + +#. Default: "Fine termine del procedimento" +#: design/plone/contenttypes/behaviors/trasparenza.py:75 +msgid "fine_termine_label" +msgstr "" + +#. Default: "Inserisci un eventuale formato alternativo del file principale." +#: design/plone/contenttypes/behaviors/multi_file.py:25 +msgid "formato_alternativo_1_help" +msgstr "" + +#. Default: "Formato alternativo 1" +#: design/plone/contenttypes/behaviors/multi_file.py:24 +msgid "formato_alternativo_1_label" +msgstr "" + +#. Default: "Inserisci un eventuale formato alternativo del file principale." +#: design/plone/contenttypes/behaviors/multi_file.py:35 +msgid "formato_alternativo_2_help" +msgstr "" + +#. Default: "Formato alternativo 2" +#: design/plone/contenttypes/behaviors/multi_file.py:34 +msgid "formato_alternativo_2_label" +msgstr "" + +#. Default: "Foto da mostrare della persona. La dimensione suggerita è 180x100 px." +#: design/plone/contenttypes/interfaces/persona.py:21 +msgid "foto_persona_help" +msgstr "" + +#. Default: "Foto della persona" +#: design/plone/contenttypes/interfaces/persona.py:19 +msgid "foto_persona_label" +msgstr "" + +#. Default: "Frequenza di aggiornamento" +#: design/plone/contenttypes/interfaces/dataset.py:32 +msgid "frequenza_aggiornamento" +msgstr "" + +#. Default: "Invalid geolocation data: ${value}. Provide latitude and longitude coordinates." +#: design/plone/contenttypes/restapi/deserializers/dxfields.py:28 +msgid "geolocation_field_validator_label" +msgstr "" + +#: design/plone/contenttypes/behaviors/address.py:38 +msgid "help_circoscrizione" +msgstr "" + +#. Default: "Indicare una descrizione completa, inserendo tutte le informazioni rilevanti relative al luogo" +#: design/plone/contenttypes/behaviors/luogo.py:24 +msgid "help_descrizione_completa" +msgstr "" + +#. Default: "Indicare eventuali elementi di interesse per il cittadino." +#: design/plone/contenttypes/behaviors/luogo.py:45 +msgid "help_elementi_di_interesse" +msgstr "" + +#. Default: "Indicare tutte le informazioni relative alla modalità di accesso al luogo" +#: design/plone/contenttypes/behaviors/luogo.py:54 +msgid "help_modalita_accesso" +msgstr "" + +#. Default: "Indicare, se esiste, un nome alternativo per il luogo; questo sarà mostrato affianco al titolo della scheda" +#: design/plone/contenttypes/behaviors/luogo.py:34 +msgid "help_nome_alternativo" +msgstr "" + +#. Default: "Inserisci il nome della sede, se non è presente tra i Luoghi del sito." +#: design/plone/contenttypes/behaviors/address.py:17 +msgid "help_nome_sede" +msgstr "" + +#: design/plone/contenttypes/behaviors/address.py:32 +msgid "help_quartiere" +msgstr "" + +#. Default: "Indicare un numero di fax della struttura responsabile." +#: design/plone/contenttypes/behaviors/luogo.py:108 +msgid "help_riferimento_fax_struttura" +msgstr "" + +#. Default: "Indicare un indirizzo mail per poter contattare i referenti della struttura responsabile." +#: design/plone/contenttypes/behaviors/luogo.py:119 +msgid "help_riferimento_mail_struttura" +msgstr "" + +#. Default: "Indicare un indirizzo pec per poter contattare i referenti della struttura responsabile." +#: design/plone/contenttypes/behaviors/luogo.py:132 +msgid "help_riferimento_pec_struttura" +msgstr "" + +#. Default: "Indicare il riferimento telefonico per poter contattare i referenti della struttura responsabile." +#: design/plone/contenttypes/behaviors/luogo.py:96 +msgid "help_riferimento_telefonico_struttura" +msgstr "" + +#. Default: "Inserisci una nota per indicare che il contenuto corrente è stato aggiornato.Questo testo può essere visualizzato nei blocchi elenco con determinati layout per informare gli utenti che un determinato contenuto è stato aggiornato. Ad esempio se in un bando sono stati aggiunti dei documenti." +#: design/plone/contenttypes/behaviors/update_note.py:17 +msgid "help_update_note" +msgstr "" + +#. Default: "Icona" +#: design/plone/contenttypes/interfaces/pagina_argomento.py:27 +msgid "icona" +msgstr "" + +#. Default: "Puoi selezionare un’icona fra quelle proposte nel menu a tendina oppure puoi scrivere/incollare nel campo di testo il nome di un’icona di fontawsome 5" +#: design/plone/contenttypes/interfaces/pagina_argomento.py:28 +msgid "icona_help" +msgstr "" + +#. Default: "Identificativo" +#: design/plone/contenttypes/interfaces/servizio.py:290 +msgid "identificativo" +msgstr "" + +#. Default: "Un numero identificativo del documento." +#: design/plone/contenttypes/interfaces/documento.py:21 +msgid "identificativo_documento_help" +msgstr "" + +#. Default: "Identificativo del documento." +#: design/plone/contenttypes/interfaces/documento.py:17 +msgid "identificativo_documento_label" +msgstr "" + +#. Default: "Eventuale codice identificativo del servizio." +#: design/plone/contenttypes/interfaces/servizio.py:292 +msgid "identificativo_help" +msgstr "" + +#. Default: "La dimensione dell'immagine dovrebbe essere di ${size} px" +#: design/plone/contenttypes/restapi/types/adapters.py:31 +msgid "image_size_help" +msgstr "" + +#. Default: "Immagine" +#: design/plone/contenttypes/interfaces/documento_personale.py:23 +msgid "immagine" +msgstr "" + +#. Default: "Importo pagato" +#: design/plone/contenttypes/interfaces/ricevuta_pagamento.py:25 +msgid "importo_pagato" +msgstr "" + +#. Default: "Inserisci eventuale testo informativo che verrà mostrato in testata." +#: design/plone/contenttypes/behaviors/info_testata.py:23 +msgid "info_testata_help" +msgstr "" + +#. Default: "Informazioni aggiuntive per la testata" +#: design/plone/contenttypes/behaviors/info_testata.py:18 +msgid "info_testata_label" +msgstr "" + +#. Default: "Ulteriori informazioni" +#: design/plone/contenttypes/interfaces/documento_personale.py:140 +msgid "informazioni" +msgstr "" + +#. Default: "Ulteriori informazioni" +#: design/plone/contenttypes/behaviors/additional_help_infos.py:28 +#: design/plone/contenttypes/behaviors/evento.py:229 +#: design/plone/contenttypes/behaviors/strutture_correlate.py:42 +msgid "informazioni_label" +msgstr "" + +#. Default: "Se un content-type deve avere una dimensione della leadimage particolare, indicarle qui. Inserire le dimensioni nella forma di esempio PortalType|900x900" +#: design/plone/contenttypes/controlpanels/settings.py:110 +msgid "lead_image_dimension_help" +msgstr "" + +#. Default: "Dimensioni lead image" +#: design/plone/contenttypes/controlpanels/settings.py:106 +msgid "lead_image_dimension_label" +msgstr "" + +#. Default: "Servizi o uffici di riferimento" +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:27 +msgid "legami_altre_strutture_label" +msgstr "" + +#. Default: "Selezionare la lista di strutture e/o uffici collegati a questa unità organizzativa." +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:31 +msgid "legami_con_altre_strutture_help" +msgstr "" + +#. Default: "Licenza" +#: design/plone/contenttypes/interfaces/dataset.py:25 +msgid "licenza" +msgstr "" + +#. Default: "Licenza di distribuzione" +#: design/plone/contenttypes/interfaces/documento_personale.py:92 +msgid "licenza_distribuzione" +msgstr "" + +#. Default: "La licenza con il quale viene distribuito questo documento." +#: design/plone/contenttypes/interfaces/documento.py:88 +msgid "licenza_distribuzione_help" +msgstr "" + +#. Default: "Licenza di distribuzione" +#: design/plone/contenttypes/interfaces/documento.py:87 +msgid "licenza_distribuzione_label" +msgstr "" + +#. Default: "Link a siti esterni" +#: design/plone/contenttypes/interfaces/servizio.py:258 +msgid "link_siti_esterni" +msgstr "" + +#. Default: "Eventuali collegamenti a pagine web, siti, servizi esterni all'ambito Comunale utili all'erogazione del servizio." +#: design/plone/contenttypes/interfaces/servizio.py:260 +msgid "link_siti_esterni_help" +msgstr "" + +#. Default: "Link utili" +#: design/plone/contenttypes/interfaces/servizio.py:417 +msgid "link_utili_label" +msgstr "" + +#. Default: "Seleziona una lista di luoghi citati. Se il luogo dell'evento non è presente sul sito, inserisci le sue informazioni nei campi seguenti." +#: design/plone/contenttypes/behaviors/luoghi_correlati.py:52 +msgid "luoghi_correlati_event_help" +msgstr "" + +#. Default: "Seleziona una lista di luoghi citati." +#: design/plone/contenttypes/behaviors/luoghi_correlati.py:18 +#: design/plone/contenttypes/behaviors/news_additional_fields.py:72 +msgid "luoghi_correlati_help" +msgstr "" + +#. Default: "Luoghi correlati" +#: design/plone/contenttypes/behaviors/luoghi_correlati.py:17 +#: design/plone/contenttypes/behaviors/news_additional_fields.py:71 +msgid "luoghi_correlati_label" +msgstr "" + +#. Default: "Luogo" +#: design/plone/contenttypes/behaviors/address.py:89 +#: design/plone/contenttypes/behaviors/geolocation.py:38 +#: design/plone/contenttypes/behaviors/luoghi_correlati.py:74 +msgid "luogo_label" +msgstr "" + +#. Default: "Modalita' di accesso" +#: design/plone/contenttypes/behaviors/luogo.py:53 +msgid "modalita_accesso" +msgstr "" + +#. Default: "Indicare la modalità di avvio del procedimento." +#: design/plone/contenttypes/behaviors/trasparenza.py:25 +msgid "modalita_avvio_help" +msgstr "" + +#. Default: "Modalita di avvio" +#: design/plone/contenttypes/behaviors/trasparenza.py:24 +msgid "modalita_avvio_label" +msgstr "" + +#. Default: "Modalità pagamento" +#: design/plone/contenttypes/interfaces/ricevuta_pagamento.py:29 +msgid "modalita_pagamento" +msgstr "" + +#. Default: "Indicare le modalità per richiedere informazioni riguardo a questo procedimento." +#: design/plone/contenttypes/behaviors/trasparenza.py:168 +msgid "modalita_richiesta_informazioni_help" +msgstr "" + +#. Default: "Modalità per richiedere informazioni" +#: design/plone/contenttypes/behaviors/trasparenza.py:163 +msgid "modalita_richiesta_informazioni_label" +msgstr "" + +#. Default: "Seleziona se mostrare o meno i bottoni con i link per la condivisione sui vari social, mail e stampa." +#: design/plone/contenttypes/behaviors/info_testata.py:44 +msgid "mostra_bottoni_condivisione_help" +msgstr "" + +#. Default: "Mostra i bottoni per la condivisione sui social" +#: design/plone/contenttypes/behaviors/info_testata.py:38 +msgid "mostra_bottoni_condivisione_label" +msgstr "" + +#. Default: "Seleziona se mostrare o meno la navigazione laterale nella testata." +#: design/plone/contenttypes/behaviors/info_testata.py:54 +msgid "mostra_navigazione_help" +msgstr "" + +#. Default: "Mostra la navigazione" +#: design/plone/contenttypes/behaviors/info_testata.py:51 +msgid "mostra_navigazione_label" +msgstr "" + +#. Default: "Descrizione del motivo per cui il servizio non è attivo." +#: design/plone/contenttypes/interfaces/servizio.py:44 +msgid "motivo_stato_servizio_help" +msgstr "" + +#. Default: "Motivo dello stato del servizio nel caso non sia attivo" +#: design/plone/contenttypes/interfaces/servizio.py:39 +msgid "motivo_stato_servizio_label" +msgstr "" + +#. Default: "Nome alternativo" +#: design/plone/contenttypes/behaviors/luogo.py:33 +msgid "nome_alternativo" +msgstr "" + +#. Default: "Nome sede" +#: design/plone/contenttypes/behaviors/address.py:16 +msgid "nome_sede" +msgstr "" + +#. Default: "Seleziona una lista di notizie correlate a questa." +#: design/plone/contenttypes/behaviors/news_additional_fields.py:83 +msgid "notizie_correlate_help" +msgstr "" + +#. Default: "Notizie correlate" +#: design/plone/contenttypes/behaviors/news_additional_fields.py:82 +msgid "notizie_correlate_label" +msgstr "" + +#. Default: "Numero progressivo del comunicato stampa" +#: design/plone/contenttypes/behaviors/news_additional_fields.py:38 +msgid "numero_progressivo_cs_label" +msgstr "" + +#. Default: "Numero protocollo" +#: design/plone/contenttypes/interfaces/pratica.py:12 +#: design/plone/contenttypes/interfaces/ricevuta_pagamento.py:12 +msgid "numero_protocollo" +msgstr "" + +#. Default: "Oggetto" +#: design/plone/contenttypes/interfaces/documento_personale.py:48 +msgid "oggetto" +msgstr "" + +#. Default: "Informazioni sugli orari" +#: design/plone/contenttypes/behaviors/evento.py:62 +msgid "orari" +msgstr "" + +#. Default: "Informazioni sugli orari di svolgimento dell'evento." +#: design/plone/contenttypes/behaviors/evento.py:64 +msgid "orari_help" +msgstr "" + +#. Default: "Orari di apertura" +#: design/plone/contenttypes/behaviors/contatti.py:86 +msgid "orari_label" +msgstr "" + +#. Default: "Indicare eventuali orari di accesso al pubblico" +#: design/plone/contenttypes/behaviors/contatti.py:59 +msgid "orario_pubblico_help" +msgstr "" + +#. Default: "Orario per il pubblico" +#: design/plone/contenttypes/behaviors/contatti.py:58 +msgid "orario_pubblico_label" +msgstr "" + +#. Default: "Se l'evento non è organizzato direttamente dal comune oppure ha anche un organizzatore esterno, indicare il nome del contatto." +#: design/plone/contenttypes/behaviors/evento.py:97 +msgid "organizzato_da_esterno_help" +msgstr "" + +#. Default: "Organizzatore" +#: design/plone/contenttypes/behaviors/evento.py:95 +msgid "organizzato_da_esterno_label" +msgstr "" + +#. Default: "Se l'evento è organizzato direttamente dal comune, indicare l'ufficio/ente organizzatore. I dati di contatto verranno presi direttamente dall'ufficio selezionato. Se l'evento non è organizzato direttamente dal comune, o si vogliono sovrascrivere alcuni dati di contatto, utilizzare i seguenti campi." +#: design/plone/contenttypes/behaviors/evento.py:84 +msgid "organizzato_da_interno_help" +msgstr "" + +#. Default: "Organizzato da" +#: design/plone/contenttypes/behaviors/evento.py:80 +msgid "organizzato_da_interno_label" +msgstr "" + +#. Default: "Seleziona una lista di organizzazioni a cui la persona appartiene." +#: design/plone/contenttypes/interfaces/persona.py:42 +msgid "organizzazione_riferimento_help" +msgstr "" + +#. Default: "Organizzazione di riferimento" +#: design/plone/contenttypes/interfaces/persona.py:38 +msgid "organizzazione_riferimento_label" +msgstr "" + +#. Default: "Organo competente del provvedimento finale." +#: design/plone/contenttypes/behaviors/trasparenza.py:157 +msgid "organo_competente_provvedimento_finale_help" +msgstr "" + +#. Default: "Organo competente del provvedimento finale" +#: design/plone/contenttypes/behaviors/trasparenza.py:152 +msgid "organo_competente_provvedimento_finale_label" +msgstr "" + +#. Default: "Indicare le informazioni riguardanti i pagamenti previsti e modalità di pagamento." +#: design/plone/contenttypes/behaviors/trasparenza.py:222 +msgid "pagamenti_help" +msgstr "" + +#. Default: "Pagamenti previsti e modalità" +#: design/plone/contenttypes/behaviors/trasparenza.py:218 +msgid "pagamenti_label" +msgstr "" + +#. Default: "Indicare l'ente che supporta l'evento, se presente." +#: design/plone/contenttypes/behaviors/evento.py:160 +msgid "patrocinato_da_help" +msgstr "" + +#. Default: "Patrocinato da" +#: design/plone/contenttypes/behaviors/evento.py:158 +msgid "patrocinato_da_label" +msgstr "" + +#. Default: "Indicare un indirizzo pec per poter contattare i referenti." +#: design/plone/contenttypes/behaviors/contatti.py:44 +msgid "pec_help" +msgstr "" + +#. Default: "Pec" +#: design/plone/contenttypes/behaviors/contatti.py:43 +msgid "pec_label" +msgstr "" + +#. Default: "Elenco delle persone dell'amministrazione che parteciperanno all'evento." +#: design/plone/contenttypes/behaviors/evento.py:53 +msgid "persone_amministrazione_help" +msgstr "" + +#. Default: "Persone" +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:221 +msgid "persone_label" +msgstr "" + +#. Default: "Seleziona la lista delle persone che compongono la struttura." +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:95 +msgid "persone_struttura_help" +msgstr "" + +#. Default: "Persone che compongono la struttura" +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:87 +msgid "persone_struttura_label" +msgstr "" + +#. Default: "Pratica associata" +#: design/plone/contenttypes/interfaces/documento_personale.py:26 +#: design/plone/contenttypes/interfaces/messaggio.py:35 +msgid "pratica_associata" +msgstr "" + +#. Default: "Pratica associata al pagamento" +#: design/plone/contenttypes/interfaces/ricevuta_pagamento.py:43 +msgid "pratica_associata_ricevuta" +msgstr "" + +#. Default: "Prenota un appuntamento" +#: design/plone/contenttypes/interfaces/servizio.py:156 +msgid "prenota_appuntamento" +msgstr "" + +#. Default: "Se è possibile prenotare un'appuntamento, indicare le informazioni necessarie e il collegamento al servizio di prenotazione appuntamenti del Comune." +#: design/plone/contenttypes/interfaces/servizio.py:157 +msgid "prenota_appuntamento_help" +msgstr "" + +#. Default: "Prezzo" +#: design/plone/contenttypes/behaviors/evento.py:71 +msgid "prezzo" +msgstr "" + +#. Default: "Indicare il prezzo dell'evento, se presente, specificando se esistono formati diversi." +#: design/plone/contenttypes/behaviors/evento.py:73 +msgid "prezzo_help" +msgstr "" + +#. Default: "Indicare, se la procedura è informatizzata online, il riferimento." +#: design/plone/contenttypes/behaviors/trasparenza.py:178 +msgid "procedura_online_help" +msgstr "" + +#. Default: "Procedura informatizzata online" +#: design/plone/contenttypes/behaviors/trasparenza.py:174 +msgid "procedura_online_label" +msgstr "" + +#. Default: "Procedure collegate all'esito" +#: design/plone/contenttypes/interfaces/servizio.py:100 +msgid "procedure_collegate" +msgstr "" + +#. Default: "Indicare cosa deve fare l'utente del servizio per conoscere l'esito della procedura, e dove eventualmente poter ritirare l'esito." +#: design/plone/contenttypes/interfaces/servizio.py:102 +msgid "procedure_collegate_help" +msgstr "" + +#. Default: "Protocollo" +#: design/plone/contenttypes/interfaces/documento_personale.py:15 +msgid "protocollo" +msgstr "" + +#. Default: "Eventuale provvedimento finale del procedimento." +#: design/plone/contenttypes/behaviors/trasparenza.py:114 +msgid "provvedimento_finale_help" +msgstr "" + +#. Default: "Provvedimento del procedimento" +#: design/plone/contenttypes/behaviors/trasparenza.py:109 +msgid "provvedimento_finale_label" +msgstr "" + +#. Default: "Quartiere" +#: design/plone/contenttypes/behaviors/address.py:31 +msgid "quartiere" +msgstr "" + +#. Default: "Reperibilità organizzatore" +#: design/plone/contenttypes/behaviors/evento.py:118 +msgid "reperibilita" +msgstr "" + +#. Default: "Indicare gli orari in cui l'organizzatore è telefonicamente reperibile." +#: design/plone/contenttypes/behaviors/evento.py:120 +msgid "reperibilita_help" +msgstr "" + +#. Default: "Indicare dove è possibile reperre la modulistica per il procedimento." +#: design/plone/contenttypes/behaviors/trasparenza.py:211 +msgid "reperimento_modulistica_help" +msgstr "" + +#. Default: "Dove reperire la modulistica" +#: design/plone/contenttypes/behaviors/trasparenza.py:207 +msgid "reperimento_modulistica_label" +msgstr "" + +#. Default: "Selezionare il/i responsabile/i della struttura." +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:48 +msgid "responsabile_help" +msgstr "" + +#. Default: "Responsabile" +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:43 +msgid "responsabile_label" +msgstr "" + +#. Default: "Responsabile del procedimento" +#: design/plone/contenttypes/behaviors/trasparenza.py:120 +msgid "responsabile_procedimento" +msgstr "" + +#. Default: "Indicare il responsabile del procedimento." +#: design/plone/contenttypes/behaviors/trasparenza.py:124 +msgid "responsabile_procedimento_help" +msgstr "" + +#. Default: "Seleziona se mostrare o meno il campo di ricerca in testata." +#: design/plone/contenttypes/behaviors/info_testata.py:32 +msgid "ricerca_in_testata_help" +msgstr "" + +#. Default: "Ricerca in testata" +#: design/plone/contenttypes/behaviors/info_testata.py:29 +msgid "ricerca_in_testata_label" +msgstr "" + +#. Default: "Ulteriori informazioni non previste negli altri campi; si può trattare di contatti o note informative la cui conoscenza è indispensabile per la partecipazione al bando" +#: design/plone/contenttypes/interfaces/bando.py:96 +msgid "riferimenti_bando_agid_help" +msgstr "" + +#. Default: "Ulteriori informazioni" +#: design/plone/contenttypes/interfaces/bando.py:95 +msgid "riferimenti_bando_agid_label" +msgstr "" + +#. Default: "Riferimenti normativi" +#: design/plone/contenttypes/interfaces/documento_personale.py:145 +msgid "riferimenti_normativi" +msgstr "" + +#. Default: "Inserisici del testo di dettaglio per eventuali riferimenti normativi utili a questo documento." +#: design/plone/contenttypes/interfaces/documento.py:100 +msgid "riferimenti_normativi_documento_help" +msgstr "" + +#. Default: "Riferimenti normativi" +#: design/plone/contenttypes/interfaces/documento.py:96 +msgid "riferimenti_normativi_documento_label" +msgstr "" + +#. Default: "Indicare eventuali riferimenti normativi." +#: design/plone/contenttypes/behaviors/trasparenza.py:265 +msgid "riferimenti_normativi_help" +msgstr "" + +#. Default: "Riferimenti normativi" +#: design/plone/contenttypes/behaviors/trasparenza.py:260 +msgid "riferimenti_normativi_label" +msgstr "" + +#. Default: "Fax della struttura responsabile" +#: design/plone/contenttypes/behaviors/luogo.py:104 +msgid "riferimento_fax_struttura" +msgstr "" + +#. Default: "E-mail struttura responsabile" +#: design/plone/contenttypes/behaviors/luogo.py:115 +msgid "riferimento_mail_struttura" +msgstr "" + +#. Default: "Pec della struttura responsabile" +#: design/plone/contenttypes/behaviors/luogo.py:128 +msgid "riferimento_pec_struttura" +msgstr "" + +#. Default: "Telefono della struttura responsabile" +#: design/plone/contenttypes/behaviors/luogo.py:92 +msgid "riferimento_telefonico_struttura" +msgstr "" + +#. Default: "Inserisci i valori utilizzabili per il ruolo di una Persona. Se il sito è multilingua, puoi inserire valori diversi a seconda delle lingue del sito." +#: design/plone/contenttypes/controlpanels/settings.py:84 +msgid "ruoli_persona_help" +msgstr "" + +#. Default: "Ruoli Persona" +#: design/plone/contenttypes/controlpanels/settings.py:83 +msgid "ruoli_persona_label" +msgstr "" + +#. Default: "Seleziona il ruolo della persona tra quelli disponibili." +#: design/plone/contenttypes/interfaces/persona.py:29 +msgid "ruolo_help" +msgstr "" + +#. Default: "Ruolo" +#: design/plone/contenttypes/interfaces/persona.py:28 +msgid "ruolo_label" +msgstr "" + +#. Default: "Data entro la quale sarà possibile far pervenire domande e richieste di chiarimento a chi eroga il bando" +#: design/plone/contenttypes/interfaces/bando.py:69 +msgid "scadenza_domande_bando_help" +msgstr "" + +#. Default: "Termine per le richieste di chiarimenti" +#: design/plone/contenttypes/interfaces/bando.py:65 +msgid "scadenza_domande_bando_label" +msgstr "" + +#. Default: "Inserire una lista di sezioni per la ricerca." +#: design/plone/contenttypes/controlpanels/settings.py:129 +msgid "search_sections_help" +msgstr "" + +#. Default: "Sezioni ricerca" +#: design/plone/contenttypes/controlpanels/settings.py:128 +msgid "search_sections_label" +msgstr "" + +#. Default: "Seleziona il Luogo in cui questa struttura ha sede. Se non è presente un contenuto di tipo Luogo a cui far riferimento, puoi compilare i campi seguenti. Se selezioni un Luogo, puoi usare comunque i campi seguenti per sovrascrivere alcune informazioni." +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:105 +msgid "sede_help" +msgstr "" + +#. Default: "Sede principale" +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:103 +msgid "sede_label" +msgstr "" + +#. Default: "Seleziona una lista di eventuali contenuti di tipo Luogo che sono sedi secondarie di questa struttura. Per queste sedi non sarà possibile sovrascrivere i dati. Nel caso servano informazioni diverse, è possibile usare il campo sottostante." +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:122 +msgid "sedi_secondarie_help" +msgstr "" + +#. Default: "Sedi secondarie" +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:120 +msgid "sedi_secondarie_label" +msgstr "" + +#. Default: "Seleziona la lista dei servizi collegati a questo." +#: design/plone/contenttypes/interfaces/servizio.py:300 +msgid "servizi_collegati_help" +msgstr "" + +#. Default: "Servizi collegati" +#: design/plone/contenttypes/interfaces/servizio.py:299 +msgid "servizi_collegati_label" +msgstr "" + +#. Default: "Questi servizi non verranno mostrati nel contenuto, ma permetteranno di vedere questo contenuto associato quando si visita il servizio" +#: design/plone/contenttypes/behaviors/servizi_correlati.py:19 +msgid "servizi_correlati_description" +msgstr "" + +#. Default: "Servizi correlati" +#: design/plone/contenttypes/behaviors/servizi_correlati.py:18 +msgid "servizi_correlati_label" +msgstr "" + +#. Default: "Servizio che genera il documento" +#: design/plone/contenttypes/interfaces/documento_personale.py:31 +msgid "servizio_origine" +msgstr "" + +#. Default: "Servizio che origina la pratica" +#: design/plone/contenttypes/interfaces/pratica.py:32 +msgid "servizio_origine_pratica" +msgstr "" + +#. Default: "Servizio che origina la pratica" +#: design/plone/contenttypes/interfaces/ricevuta_pagamento.py:35 +msgid "servizio_origine_ricevuta" +msgstr "" + +#. Default: "Settore merceologico" +#: design/plone/contenttypes/interfaces/servizio.py:280 +msgid "settore_merceologico" +msgstr "" + +#. Default: "Classificazione del servizio basata su catalogo dei servizi (Classificazione NACE)." +#: design/plone/contenttypes/interfaces/servizio.py:282 +msgid "settore_merceologico_help" +msgstr "" + +#. Default: "Questo è il valore di default per decidere se mostrare o meno la data di modifica nei contenuti che hanno la behavior abilitata. E' poi possibile sovrascrivere il default nei singoli contenuti (nel tab \"Impostazioni\")." +#: design/plone/contenttypes/controlpanels/settings.py:139 +msgid "show_modified_default_help" +msgstr "" + +#. Default: "Mostra la data di modifica" +#: design/plone/contenttypes/controlpanels/settings.py:138 +msgid "show_modified_default_label" +msgstr "" + +#. Default: "Se attivo, verrà mostrata la data di ultima modifica in visualizzazione del contenuto." +#: design/plone/contenttypes/behaviors/show_modified.py:24 +msgid "show_modified_help" +msgstr "" + +#. Default: "Mostra la data di ultima modifica" +#: design/plone/contenttypes/behaviors/show_modified.py:23 +msgid "show_modified_label" +msgstr "" + +#. Default: "Indicare se il procedimento prevede il silenzio assenso o la dichiarazione dell'interessato sostitutiva del provvedimento finale." +#: design/plone/contenttypes/behaviors/trasparenza.py:103 +msgid "silenzio_assenso_help" +msgstr "" + +#. Default: "Silenzio assenso/Dichiarazione dell'interessato sostitutiva del provvedimento finale" +#: design/plone/contenttypes/behaviors/trasparenza.py:97 +msgid "silenzio_assenso_label" +msgstr "" + +#. Default: "Inserisci eventuali soggetti esterni, nonché, strutture interne coinvolte nel procedimento." +#: design/plone/contenttypes/behaviors/trasparenza.py:57 +msgid "soggetti_eserni_help" +msgstr "" + +#. Default: "Soggetti esterni, nonché, strutture interne coinvolte nel procedimento" +#: design/plone/contenttypes/behaviors/trasparenza.py:52 +msgid "soggetti_eserni_label" +msgstr "" + +#. Default: "Indica un eventuale sottotitolo/titolo alternativo." +#: design/plone/contenttypes/behaviors/evento.py:23 +#: design/plone/contenttypes/interfaces/servizio.py:19 +msgid "sottotitolo_help" +msgstr "" + +#. Default: "Sottotitolo" +#: design/plone/contenttypes/behaviors/evento.py:22 +#: design/plone/contenttypes/interfaces/servizio.py:18 +msgid "sottotitolo_label" +msgstr "" + +#. Default: "Stampa ricevuta" +#: design/plone/contenttypes/interfaces/ricevuta_pagamento.py:17 +msgid "stampa_ricevuta" +msgstr "" + +#. Default: "Stato della pratica" +#: design/plone/contenttypes/interfaces/pratica.py:26 +msgid "stato_pratica" +msgstr "" + +#. Default: "Indica se il servizio è effettivamente fruibile." +#: design/plone/contenttypes/interfaces/servizio.py:32 +msgid "stato_servizio_help" +msgstr "" + +#. Default: "Servizio non attivo" +#: design/plone/contenttypes/interfaces/servizio.py:30 +msgid "stato_servizio_label" +msgstr "" + +#. Default: "Indicare gli eventuali strumenti di tutela." +#: design/plone/contenttypes/behaviors/trasparenza.py:230 +msgid "strumenti_tutela_help" +msgstr "" + +#. Default: "Strumenti di tutela" +#: design/plone/contenttypes/behaviors/trasparenza.py:229 +msgid "strumenti_tutela_label" +msgstr "" + +#. Default: "Struttura" +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:211 +msgid "struttura_label" +msgstr "" + +#. Default: "Struttura responsabile" +#: design/plone/contenttypes/behaviors/luogo.py:82 +msgid "struttura_responsabile" +msgstr "" + +#. Default: "Struttura responsabile del luogo." +#: design/plone/contenttypes/behaviors/luogo.py:63 +msgid "struttura_responsabile_correlati" +msgstr "" + +#. Default: "Indicare la struttura responsabile del luogo qualora sia fra unità organizzative del comune inserite nel sito; altrimenti compilare i campi testuali relativi alla struttura responsabile" +#: design/plone/contenttypes/behaviors/luogo.py:67 +msgid "struttura_responsabile_correlati_help" +msgstr "" + +#. Default: "Nome/link al sito web della struttura che gestisce il luogo, se questa non è comunale." +#: design/plone/contenttypes/behaviors/luogo.py:84 +msgid "struttura_responsabile_help" +msgstr "" + +#. Default: "Seleziona la lista delle strutture politiche coinvolte." +#: design/plone/contenttypes/behaviors/strutture_correlate.py:25 +msgid "strutture_politiche_help" +msgstr "" + +#. Default: "Indicare gli uffici/enti che supportano l'evento." +#: design/plone/contenttypes/behaviors/evento.py:149 +msgid "supportato_da_help" +msgstr "" + +#. Default: "Evento supportato da" +#: design/plone/contenttypes/behaviors/evento.py:145 +msgid "supportato_da_label" +msgstr "" + +#. Default: "Seleziona una lista di argomenti d'interesse per questo contenuto." +#: design/plone/contenttypes/behaviors/argomenti.py:22 +msgid "tassonomia_argomenti_help" +msgstr "" + +#. Default: "Tassonomia argomenti" +#: design/plone/contenttypes/behaviors/argomenti.py:21 +msgid "tassonomia_argomenti_label" +msgstr "" + +#. Default: "Telefono" +#: design/plone/contenttypes/behaviors/evento.py:104 +msgid "telefono_event_help" +msgstr "" + +#. Default: "Indicare un riferimento telefonico per poter contattare gli organizzatori." +#: design/plone/contenttypes/behaviors/evento.py:105 +msgid "telefono_event_label" +msgstr "" + +#. Default: "Indicare un riferimento telefonico per poter contattare i referenti." +#: design/plone/contenttypes/behaviors/contatti.py:19 +msgid "telefono_help" +msgstr "" + +#. Default: "Telefono" +#: design/plone/contenttypes/behaviors/contatti.py:18 +msgid "telefono_label" +msgstr "" + +#. Default: "Contatto telefonico della persona. E' possibile inserire più di un numero. Premendo \"Invio\" o \"tab\" si può passare al successivo da inserire." +#: design/plone/contenttypes/interfaces/persona.py:117 +msgid "telefono_persona_help" +msgstr "" + +#. Default: "Numero di telefono" +#: design/plone/contenttypes/interfaces/persona.py:116 +msgid "telefono_persona_label" +msgstr "" + +#. Default: "Temi" +#: design/plone/contenttypes/interfaces/dataset.py:14 +msgid "temi" +msgstr "" + +#. Default: "Tempi e scadenze" +#: design/plone/contenttypes/interfaces/servizio.py:167 +msgid "tempi_e_scadenze" +msgstr "" + +#. Default: "Descrivere le informazioni dettagliate riguardo eventuali tempi e scadenze di questo servizio." +#: design/plone/contenttypes/interfaces/servizio.py:169 +msgid "tempi_e_scadenze_help" +msgstr "" + +#. Default: "Tempi e scadenze" +#: design/plone/contenttypes/interfaces/servizio.py:395 +msgid "tempi_e_scadenze_label" +msgstr "" + +#. Default: "Inserisci il tempo medio del procedimento." +#: design/plone/contenttypes/behaviors/trasparenza.py:91 +msgid "tempo_medio_help" +msgstr "" + +#. Default: "Tempo medio del procedimento" +#: design/plone/contenttypes/behaviors/trasparenza.py:86 +msgid "tempo_medio_label" +msgstr "" + +#. Default: "Testata" +#: design/plone/contenttypes/behaviors/argomenti.py:104 +#: design/plone/contenttypes/behaviors/info_testata.py:62 +msgid "testata_fieldset_label" +msgstr "" + +#: design/plone/contenttypes/interfaces/bando.py:28 +msgid "text_help" +msgstr "" + +#. Default: "Testo" +#: design/plone/contenttypes/interfaces/bando.py:27 +msgid "text_label" +msgstr "" + +#. Default: "Tipologia documento" +#: design/plone/contenttypes/interfaces/messaggio.py:49 +msgid "tipologia_documento" +msgstr "" + +#. Default: "Seleziona la tipologia del documento." +#: design/plone/contenttypes/interfaces/documento.py:30 +msgid "tipologia_documento_help" +msgstr "" + +#. Default: "Tipologia del documento" +#: design/plone/contenttypes/interfaces/documento.py:29 +msgid "tipologia_documento_label" +msgstr "" + +#. Default: "Seleziona la tipologia della notizia." +#: design/plone/contenttypes/behaviors/news_additional_fields.py:29 +msgid "tipologia_notizia_help" +msgstr "" + +#. Default: "Tipologia notizia" +#: design/plone/contenttypes/behaviors/news_additional_fields.py:28 +msgid "tipologia_notizia_label" +msgstr "" + +#. Default: "Specificare la tipologia di organizzazione: politica, amminsitrativa o di altro tipo." +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:60 +msgid "tipologia_organizzazione_help" +msgstr "" + +#. Default: "Tipologia organizzazione" +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:57 +msgid "tipologia_organizzazione_label" +msgstr "" + +#. Default: "Seleziona la tipologia di persona: politica, amministrativa o di altro tipo." +#: design/plone/contenttypes/interfaces/persona.py:86 +msgid "tipologia_persona_help" +msgstr "" + +#. Default: "Tipologia persona" +#: design/plone/contenttypes/interfaces/persona.py:85 +msgid "tipologia_persona_label" +msgstr "" + +#. Default: "Inserisci i valori utilizzabili per le tipologie di un Documento. Se il sito è multilingua, puoi inserire valori diversi a seconda delle lingue del sito." +#: design/plone/contenttypes/controlpanels/settings.py:46 +msgid "tipologie_documento_help" +msgstr "" + +#. Default: "Tipologie Documento" +#: design/plone/contenttypes/controlpanels/settings.py:45 +msgid "tipologie_documento_label" +msgstr "" + +#. Default: "Inserisci i valori utilizzabili per le tipologie di una Notizia. Se il sito è multilingua, puoi inserire valori diversi a seconda delle lingue del sito." +#: design/plone/contenttypes/controlpanels/settings.py:19 +msgid "tipologie_notizia_help" +msgstr "" + +#. Default: "Tipologie Notizia" +#: design/plone/contenttypes/controlpanels/settings.py:18 +msgid "tipologie_notizia_label" +msgstr "" + +#. Default: "Inserisci i valori utilizzabili per le tipologie di una Persona. Se il sito è multilingua, puoi inserire valori diversi a seconda delle lingue del sito." +#: design/plone/contenttypes/controlpanels/settings.py:72 +msgid "tipologie_persona_help" +msgstr "" + +#. Default: "Tipologie Persona" +#: design/plone/contenttypes/controlpanels/settings.py:71 +msgid "tipologie_persona_label" +msgstr "" + +#. Default: "Inserisci i valori utilizzabili per le tipologie di un' Unità Organizzativa. Se il sito è multilingua, puoi inserire valori diversi a seconda delle lingue del sito." +#: design/plone/contenttypes/controlpanels/settings.py:34 +msgid "tipologie_unita_organizzativa_help" +msgstr "" + +#. Default: "Tipologie Unità Organizzativa" +#: design/plone/contenttypes/controlpanels/settings.py:30 +msgid "tipologie_unita_organizzativa_label" +msgstr "" + +#. Default: "Titolare" +#: design/plone/contenttypes/interfaces/dataset.py:29 +msgid "titolare" +msgstr "" + +#. Default: "Eventuale titolare del potere sostitutivo." +#: design/plone/contenttypes/behaviors/trasparenza.py:243 +msgid "titolare_potere_sostitutivo_help" +msgstr "" + +#. Default: "Titolare del potere sostitutivo" +#: design/plone/contenttypes/behaviors/trasparenza.py:238 +msgid "titolare_potere_sostitutivo_label" +msgstr "" + +#. Default: "Trasparenza" +#: design/plone/contenttypes/behaviors/trasparenza.py:292 +msgid "trasparenza_fieldset_label" +msgstr "" + +#. Default: "Seleziona l'ufficio responsabile di questo bando." +#: design/plone/contenttypes/interfaces/bando.py:110 +msgid "ufficio_responsabile_bando_help" +msgstr "" + +#. Default: "Ufficio responsabile del bando" +#: design/plone/contenttypes/interfaces/bando.py:106 +msgid "ufficio_responsabile_bando_label" +msgstr "" + +#. Default: "Seleziona l'ufficio responsabile di questo documento." +#: design/plone/contenttypes/interfaces/documento.py:43 +msgid "ufficio_responsabile_documento_help" +msgstr "" + +#. Default: "Ufficio responsabile del documento" +#: design/plone/contenttypes/interfaces/documento.py:39 +msgid "ufficio_responsabile_documento_label" +msgstr "" + +#. Default: "Ufficio responsabile" +#: design/plone/contenttypes/interfaces/documento_personale.py:62 +msgid "ufficio_responsabile_documento_personale" +msgstr "" + +#. Default: "Uffici responsabili" +#: design/plone/contenttypes/interfaces/servizio.py:216 +msgid "ufficio_responsabile_erogazione" +msgstr "" + +#. Default: "Seleziona gli uffici responsabili dell'erogazione di questo servizio." +#: design/plone/contenttypes/interfaces/servizio.py:217 +msgid "ufficio_responsabile_help" +msgstr "" + +#. Default: "Ufficio di riferimento" +#: design/plone/contenttypes/interfaces/pratica.py:17 +msgid "ufficio_riferimento" +msgstr "" + +#. Default: "Ulteriori informazioni" +#: design/plone/contenttypes/behaviors/additional_help_infos.py:18 +#: design/plone/contenttypes/interfaces/pagina_argomento.py:18 +msgid "ulteriori_informazioni" +msgstr "" + +#. Default: "Ulteriori informazioni non contemplate dai campi precedenti." +#: design/plone/contenttypes/behaviors/additional_help_infos.py:19 +#: design/plone/contenttypes/interfaces/pagina_argomento.py:19 +msgid "ulteriori_informazioni_help" +msgstr "" + +#. Default: "Unità amministrative responsabili" +#: design/plone/contenttypes/interfaces/pagina_argomento.py:38 +msgid "unita_amministrative_responsabili" +msgstr "" + +#. Default: "Seleziona la lista delle unità amministrative responsabili di questo argomento." +#: design/plone/contenttypes/interfaces/pagina_argomento.py:48 +msgid "unita_amministrative_responsabili_help" +msgstr "" + +#. Default: "Descrizione dei compiti assegnati alla struttura." +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:19 +msgid "uo_competenze_help" +msgstr "" + +#. Default: "Competenze" +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:18 +msgid "uo_competenze_label" +msgstr "" + +#. Default: "Inserisci eventuali informazioni di contatto aggiuntive non contemplate nei campi precedenti. Utilizza questo campo se ci sono dei contatti aggiuntivi rispetto ai contatti della sede principale. Se inserisci un collegamento con un indirizzo email, aggiungi \"mailto:\" prima dell'indirizzo, per farlo aprire direttamente nel client di posta." +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:139 +msgid "uo_contact_info_description" +msgstr "" + +#. Default: "Note di aggiornamento" +#: design/plone/contenttypes/behaviors/update_note.py:16 +msgid "update_note_label" +msgstr "" + +#. Default: "Vincoli" +#: design/plone/contenttypes/interfaces/servizio.py:196 +msgid "vincoli" +msgstr "" + +#. Default: "Descrizione degli eventuali vincoli presenti." +#: design/plone/contenttypes/interfaces/servizio.py:198 +msgid "vincoli_help" +msgstr "" + +#. Default: "Indicare un indirizzo web di riferimento a questo evento." +#: design/plone/contenttypes/behaviors/evento.py:138 +msgid "web_event_help" +msgstr "" + +#. Default: "Sito web" +#: design/plone/contenttypes/behaviors/evento.py:137 +msgid "web_event_label" +msgstr "" + +#. Default: "Indicare un indirizzo web di riferimento." +#: design/plone/contenttypes/behaviors/contatti.py:53 +msgid "web_help" +msgstr "" + +#. Default: "Sito web" +#: design/plone/contenttypes/behaviors/contatti.py:52 +msgid "web_label" +msgstr "" diff --git a/src/design/plone/contenttypes/locales/design.plone.contenttypes.pot b/src/design/plone/contenttypes/locales/design.plone.contenttypes.pot index fc8b9161..6dbc95b9 100644 --- a/src/design/plone/contenttypes/locales/design.plone.contenttypes.pot +++ b/src/design/plone/contenttypes/locales/design.plone.contenttypes.pot @@ -1,10 +1,10 @@ -# --- PLEASE EDIT THE LINES BELOW CORRECTLY --- -# SOME DESCRIPTIVE TITLE. -# FIRST AUTHOR , YEAR. +#--- PLEASE EDIT THE LINES BELOW CORRECTLY --- +#SOME DESCRIPTIVE TITLE. +#FIRST AUTHOR , YEAR. msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2022-04-21 09:38+0000\n" +"POT-Creation-Date: 2023-01-03 17:03+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI +ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -73,7 +73,7 @@ msgstr "" msgid "Anziano" msgstr "" -#: design/plone/contenttypes/interfaces/bando.py:123 +#: design/plone/contenttypes/interfaces/bando.py:134 #: design/plone/contenttypes/interfaces/documento.py:67 #: design/plone/contenttypes/interfaces/servizio.py:239 msgid "Area" @@ -227,6 +227,10 @@ msgstr "" msgid "Condizioni e organizzazione del lavoro" msgstr "" +#: design/plone/contenttypes/browser/move_content/templates/move_news_items.pt:56 +msgid "Contained by" +msgstr "" + #: design/plone/contenttypes/behaviors/configure.zcml:202 msgid "Contatti" msgstr "" @@ -402,6 +406,10 @@ msgstr "" msgid "Impostazioni Design Plone" msgstr "" +#: design/plone/contenttypes/browser/move_content/move_news_items.py:33 +msgid "Indicated path is not valid" +msgstr "" + #: design/plone/contenttypes/behaviors/configure.zcml:170 msgid "Info per la testata" msgstr "" @@ -450,6 +458,14 @@ msgstr "" msgid "Istruzione, cultura e sport" msgstr "" +#: design/plone/contenttypes/browser/move_content/move_news_items.py:45 +msgid "Items move was failed" +msgstr "" + +#: design/plone/contenttypes/browser/move_content/move_news_items.py:50 +msgid "Items moved with success" +msgstr "" + #: design/plone/contenttypes/vocabularies/lista_azioni_pratica.py:28 msgid "Leggere" msgstr "" @@ -498,6 +514,14 @@ msgstr "" msgid "Mostra la data di modifica." msgstr "" +#: design/plone/contenttypes/browser/move_content/templates/move_news_items.pt:69 +msgid "Move" +msgstr "" + +#: design/plone/contenttypes/browser/move_content/templates/move_news_items.pt:11 +msgid "Move News Items" +msgstr "" + #: design/plone/contenttypes/behaviors/configure.zcml:243 msgid "Multi File" msgstr "" @@ -740,7 +764,7 @@ msgstr "" msgid "Turismo" msgstr "" -#: design/plone/contenttypes/interfaces/bando.py:106 +#: design/plone/contenttypes/interfaces/bando.py:117 #: design/plone/contenttypes/interfaces/documento.py:50 #: design/plone/contenttypes/interfaces/servizio.py:225 msgid "Ufficio responsabile" @@ -819,7 +843,7 @@ msgid "a_cura_di_persone_label" msgstr "" #. Default: "Accedere al servizio" -#: design/plone/contenttypes/interfaces/servizio.py:371 +#: design/plone/contenttypes/interfaces/servizio.py:370 msgid "accedi_al_servizio_label" msgstr "" @@ -848,6 +872,16 @@ msgstr "" msgid "altri_documenti_help" msgstr "" +#. Default: "Date and time of the opening of the announcement. Use this field if you want to set a specific opening date. If not set, the announcement will be open immediately." +#: design/plone/contenttypes/interfaces/bando.py:56 +msgid "apertura_bando_help" +msgstr "" + +#. Default: "Opening date" +#: design/plone/contenttypes/interfaces/bando.py:55 +msgid "apertura_bando_label" +msgstr "" + #. Default: "Area" #: design/plone/contenttypes/interfaces/servizio.py:231 msgid "area" @@ -864,13 +898,13 @@ msgid "area_responsabile_documento_personale" msgstr "" #. Default: "Seleziona l'area amministrativa responsabile del documento." -#: design/plone/contenttypes/interfaces/bando.py:116 +#: design/plone/contenttypes/interfaces/bando.py:127 #: design/plone/contenttypes/interfaces/documento.py:60 msgid "area_responsabile_help" msgstr "" #. Default: "Area responsabile del documento" -#: design/plone/contenttypes/interfaces/bando.py:112 +#: design/plone/contenttypes/interfaces/bando.py:123 #: design/plone/contenttypes/interfaces/documento.py:56 msgid "area_responsabile_label" msgstr "" @@ -976,7 +1010,7 @@ msgid "casi_particolari_help" msgstr "" #. Default: "Casi particolari" -#: design/plone/contenttypes/interfaces/servizio.py:402 +#: design/plone/contenttypes/interfaces/servizio.py:401 msgid "casi_particolari_label" msgstr "" @@ -1090,7 +1124,7 @@ msgid "cosa_serve_help" msgstr "" #. Default: "Cosa serve" -#: design/plone/contenttypes/interfaces/servizio.py:385 +#: design/plone/contenttypes/interfaces/servizio.py:384 msgid "cosa_serve_label" msgstr "" @@ -1116,7 +1150,7 @@ msgid "costi" msgstr "" #. Default: "Costi e vincoli" -#: design/plone/contenttypes/interfaces/servizio.py:390 +#: design/plone/contenttypes/interfaces/servizio.py:389 msgid "costi_e_vincoli_label" msgstr "" @@ -1319,7 +1353,7 @@ msgstr "" #. Default: "Documenti" #: design/plone/contenttypes/interfaces/persona.py:199 -#: design/plone/contenttypes/interfaces/servizio.py:413 +#: design/plone/contenttypes/interfaces/servizio.py:412 msgid "documenti_label" msgstr "" @@ -1660,7 +1694,7 @@ msgid "link_siti_esterni_help" msgstr "" #. Default: "Link utili" -#: design/plone/contenttypes/interfaces/servizio.py:418 +#: design/plone/contenttypes/interfaces/servizio.py:417 msgid "link_utili_label" msgstr "" @@ -2021,12 +2055,12 @@ msgid "ricerca_in_testata_label" msgstr "" #. Default: "Ulteriori informazioni non previste negli altri campi; si può trattare di contatti o note informative la cui conoscenza è indispensabile per la partecipazione al bando" -#: design/plone/contenttypes/interfaces/bando.py:85 +#: design/plone/contenttypes/interfaces/bando.py:96 msgid "riferimenti_bando_agid_help" msgstr "" #. Default: "Ulteriori informazioni" -#: design/plone/contenttypes/interfaces/bando.py:84 +#: design/plone/contenttypes/interfaces/bando.py:95 msgid "riferimenti_bando_agid_label" msgstr "" @@ -2096,12 +2130,12 @@ msgid "ruolo_label" msgstr "" #. Default: "Data entro la quale sarà possibile far pervenire domande e richieste di chiarimento a chi eroga il bando" -#: design/plone/contenttypes/interfaces/bando.py:58 +#: design/plone/contenttypes/interfaces/bando.py:69 msgid "scadenza_domande_bando_help" msgstr "" #. Default: "Termine per le richieste di chiarimenti" -#: design/plone/contenttypes/interfaces/bando.py:54 +#: design/plone/contenttypes/interfaces/bando.py:65 msgid "scadenza_domande_bando_label" msgstr "" @@ -2358,7 +2392,7 @@ msgid "tempi_e_scadenze_help" msgstr "" #. Default: "Tempi e scadenze" -#: design/plone/contenttypes/interfaces/servizio.py:396 +#: design/plone/contenttypes/interfaces/servizio.py:395 msgid "tempi_e_scadenze_label" msgstr "" @@ -2378,12 +2412,12 @@ msgstr "" msgid "testata_fieldset_label" msgstr "" -#: design/plone/contenttypes/interfaces/bando.py:27 +#: design/plone/contenttypes/interfaces/bando.py:28 msgid "text_help" msgstr "" #. Default: "Testo" -#: design/plone/contenttypes/interfaces/bando.py:26 +#: design/plone/contenttypes/interfaces/bando.py:27 msgid "text_label" msgstr "" @@ -2493,12 +2527,12 @@ msgid "trasparenza_fieldset_label" msgstr "" #. Default: "Seleziona l'ufficio responsabile di questo bando." -#: design/plone/contenttypes/interfaces/bando.py:99 +#: design/plone/contenttypes/interfaces/bando.py:110 msgid "ufficio_responsabile_bando_help" msgstr "" #. Default: "Ufficio responsabile del bando" -#: design/plone/contenttypes/interfaces/bando.py:95 +#: design/plone/contenttypes/interfaces/bando.py:106 msgid "ufficio_responsabile_bando_label" msgstr "" diff --git a/src/design/plone/contenttypes/locales/en/LC_MESSAGES/design.plone.contenttypes.po b/src/design/plone/contenttypes/locales/en/LC_MESSAGES/design.plone.contenttypes.po index c8852dbd..5277394d 100644 --- a/src/design/plone/contenttypes/locales/en/LC_MESSAGES/design.plone.contenttypes.po +++ b/src/design/plone/contenttypes/locales/en/LC_MESSAGES/design.plone.contenttypes.po @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2022-04-21 09:38+0000\n" +"POT-Creation-Date: 2023-01-03 17:03+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI +ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -70,7 +70,7 @@ msgstr "" msgid "Anziano" msgstr "" -#: design/plone/contenttypes/interfaces/bando.py:123 +#: design/plone/contenttypes/interfaces/bando.py:134 #: design/plone/contenttypes/interfaces/documento.py:67 #: design/plone/contenttypes/interfaces/servizio.py:239 msgid "Area" @@ -224,6 +224,10 @@ msgstr "" msgid "Condizioni e organizzazione del lavoro" msgstr "" +#: design/plone/contenttypes/browser/move_content/templates/move_news_items.pt:56 +msgid "Contained by" +msgstr "" + #: design/plone/contenttypes/behaviors/configure.zcml:202 msgid "Contatti" msgstr "" @@ -399,6 +403,10 @@ msgstr "" msgid "Impostazioni Design Plone" msgstr "" +#: design/plone/contenttypes/browser/move_content/move_news_items.py:33 +msgid "Indicated path is not valid" +msgstr "" + #: design/plone/contenttypes/behaviors/configure.zcml:170 msgid "Info per la testata" msgstr "" @@ -447,6 +455,14 @@ msgstr "" msgid "Istruzione, cultura e sport" msgstr "" +#: design/plone/contenttypes/browser/move_content/move_news_items.py:45 +msgid "Items move was failed" +msgstr "" + +#: design/plone/contenttypes/browser/move_content/move_news_items.py:50 +msgid "Items moved with success" +msgstr "" + #: design/plone/contenttypes/vocabularies/lista_azioni_pratica.py:28 msgid "Leggere" msgstr "" @@ -495,6 +511,14 @@ msgstr "" msgid "Mostra la data di modifica." msgstr "" +#: design/plone/contenttypes/browser/move_content/templates/move_news_items.pt:69 +msgid "Move" +msgstr "" + +#: design/plone/contenttypes/browser/move_content/templates/move_news_items.pt:11 +msgid "Move News Items" +msgstr "" + #: design/plone/contenttypes/behaviors/configure.zcml:243 msgid "Multi File" msgstr "" @@ -737,7 +761,7 @@ msgstr "" msgid "Turismo" msgstr "" -#: design/plone/contenttypes/interfaces/bando.py:106 +#: design/plone/contenttypes/interfaces/bando.py:117 #: design/plone/contenttypes/interfaces/documento.py:50 #: design/plone/contenttypes/interfaces/servizio.py:225 msgid "Ufficio responsabile" @@ -816,7 +840,7 @@ msgid "a_cura_di_persone_label" msgstr "" #. Default: "Accedere al servizio" -#: design/plone/contenttypes/interfaces/servizio.py:371 +#: design/plone/contenttypes/interfaces/servizio.py:370 msgid "accedi_al_servizio_label" msgstr "" @@ -845,6 +869,16 @@ msgstr "" msgid "altri_documenti_help" msgstr "" +#. Default: "Date and time of the opening of the announcement. Use this field if you want to set a specific opening date. If not set, the announcement will be open immediately." +#: design/plone/contenttypes/interfaces/bando.py:56 +msgid "apertura_bando_help" +msgstr "" + +#. Default: "Opening date" +#: design/plone/contenttypes/interfaces/bando.py:55 +msgid "apertura_bando_label" +msgstr "" + #. Default: "Area" #: design/plone/contenttypes/interfaces/servizio.py:231 msgid "area" @@ -861,13 +895,13 @@ msgid "area_responsabile_documento_personale" msgstr "" #. Default: "Seleziona l'area amministrativa responsabile del documento." -#: design/plone/contenttypes/interfaces/bando.py:116 +#: design/plone/contenttypes/interfaces/bando.py:127 #: design/plone/contenttypes/interfaces/documento.py:60 msgid "area_responsabile_help" msgstr "" #. Default: "Area responsabile del documento" -#: design/plone/contenttypes/interfaces/bando.py:112 +#: design/plone/contenttypes/interfaces/bando.py:123 #: design/plone/contenttypes/interfaces/documento.py:56 msgid "area_responsabile_label" msgstr "" @@ -973,7 +1007,7 @@ msgid "casi_particolari_help" msgstr "" #. Default: "Casi particolari" -#: design/plone/contenttypes/interfaces/servizio.py:402 +#: design/plone/contenttypes/interfaces/servizio.py:401 msgid "casi_particolari_label" msgstr "" @@ -1087,7 +1121,7 @@ msgid "cosa_serve_help" msgstr "" #. Default: "Cosa serve" -#: design/plone/contenttypes/interfaces/servizio.py:385 +#: design/plone/contenttypes/interfaces/servizio.py:384 msgid "cosa_serve_label" msgstr "" @@ -1113,7 +1147,7 @@ msgid "costi" msgstr "" #. Default: "Costi e vincoli" -#: design/plone/contenttypes/interfaces/servizio.py:390 +#: design/plone/contenttypes/interfaces/servizio.py:389 msgid "costi_e_vincoli_label" msgstr "" @@ -1316,7 +1350,7 @@ msgstr "" #. Default: "Documenti" #: design/plone/contenttypes/interfaces/persona.py:199 -#: design/plone/contenttypes/interfaces/servizio.py:413 +#: design/plone/contenttypes/interfaces/servizio.py:412 msgid "documenti_label" msgstr "" @@ -1659,7 +1693,7 @@ msgid "link_siti_esterni_help" msgstr "" #. Default: "Link utili" -#: design/plone/contenttypes/interfaces/servizio.py:418 +#: design/plone/contenttypes/interfaces/servizio.py:417 msgid "link_utili_label" msgstr "" @@ -2020,12 +2054,12 @@ msgid "ricerca_in_testata_label" msgstr "" #. Default: "Ulteriori informazioni non previste negli altri campi; si può trattare di contatti o note informative la cui conoscenza è indispensabile per la partecipazione al bando" -#: design/plone/contenttypes/interfaces/bando.py:85 +#: design/plone/contenttypes/interfaces/bando.py:96 msgid "riferimenti_bando_agid_help" msgstr "" #. Default: "Ulteriori informazioni" -#: design/plone/contenttypes/interfaces/bando.py:84 +#: design/plone/contenttypes/interfaces/bando.py:95 msgid "riferimenti_bando_agid_label" msgstr "" @@ -2095,12 +2129,12 @@ msgid "ruolo_label" msgstr "" #. Default: "Data entro la quale sarà possibile far pervenire domande e richieste di chiarimento a chi eroga il bando" -#: design/plone/contenttypes/interfaces/bando.py:58 +#: design/plone/contenttypes/interfaces/bando.py:69 msgid "scadenza_domande_bando_help" msgstr "" #. Default: "Termine per le richieste di chiarimenti" -#: design/plone/contenttypes/interfaces/bando.py:54 +#: design/plone/contenttypes/interfaces/bando.py:65 msgid "scadenza_domande_bando_label" msgstr "" @@ -2357,7 +2391,7 @@ msgid "tempi_e_scadenze_help" msgstr "" #. Default: "Tempi e scadenze" -#: design/plone/contenttypes/interfaces/servizio.py:396 +#: design/plone/contenttypes/interfaces/servizio.py:395 msgid "tempi_e_scadenze_label" msgstr "" @@ -2377,12 +2411,12 @@ msgstr "" msgid "testata_fieldset_label" msgstr "" -#: design/plone/contenttypes/interfaces/bando.py:27 +#: design/plone/contenttypes/interfaces/bando.py:28 msgid "text_help" msgstr "" #. Default: "Testo" -#: design/plone/contenttypes/interfaces/bando.py:26 +#: design/plone/contenttypes/interfaces/bando.py:27 msgid "text_label" msgstr "" @@ -2492,12 +2526,12 @@ msgid "trasparenza_fieldset_label" msgstr "" #. Default: "Seleziona l'ufficio responsabile di questo bando." -#: design/plone/contenttypes/interfaces/bando.py:99 +#: design/plone/contenttypes/interfaces/bando.py:110 msgid "ufficio_responsabile_bando_help" msgstr "" #. Default: "Ufficio responsabile del bando" -#: design/plone/contenttypes/interfaces/bando.py:95 +#: design/plone/contenttypes/interfaces/bando.py:106 msgid "ufficio_responsabile_bando_label" msgstr "" diff --git a/src/design/plone/contenttypes/locales/it/LC_MESSAGES/design.plone.contenttypes.po b/src/design/plone/contenttypes/locales/it/LC_MESSAGES/design.plone.contenttypes.po index c8852dbd..a026e4a8 100644 --- a/src/design/plone/contenttypes/locales/it/LC_MESSAGES/design.plone.contenttypes.po +++ b/src/design/plone/contenttypes/locales/it/LC_MESSAGES/design.plone.contenttypes.po @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2022-04-21 09:38+0000\n" +"POT-Creation-Date: 2023-01-03 17:03+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI +ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -70,7 +70,7 @@ msgstr "" msgid "Anziano" msgstr "" -#: design/plone/contenttypes/interfaces/bando.py:123 +#: design/plone/contenttypes/interfaces/bando.py:134 #: design/plone/contenttypes/interfaces/documento.py:67 #: design/plone/contenttypes/interfaces/servizio.py:239 msgid "Area" @@ -224,6 +224,10 @@ msgstr "" msgid "Condizioni e organizzazione del lavoro" msgstr "" +#: design/plone/contenttypes/browser/move_content/templates/move_news_items.pt:56 +msgid "Contained by" +msgstr "Contenuto da" + #: design/plone/contenttypes/behaviors/configure.zcml:202 msgid "Contatti" msgstr "" @@ -399,6 +403,10 @@ msgstr "" msgid "Impostazioni Design Plone" msgstr "" +#: design/plone/contenttypes/browser/move_content/move_news_items.py:33 +msgid "Indicated path is not valid" +msgstr "Path indicato non è valido" + #: design/plone/contenttypes/behaviors/configure.zcml:170 msgid "Info per la testata" msgstr "" @@ -447,6 +455,14 @@ msgstr "" msgid "Istruzione, cultura e sport" msgstr "" +#: design/plone/contenttypes/browser/move_content/move_news_items.py:45 +msgid "Items move was failed" +msgstr "Spostamento dei dati è fallito" + +#: design/plone/contenttypes/browser/move_content/move_news_items.py:50 +msgid "Items moved with success" +msgstr "Gli elementi sono stati spostati con sucesso" + #: design/plone/contenttypes/vocabularies/lista_azioni_pratica.py:28 msgid "Leggere" msgstr "" @@ -495,6 +511,14 @@ msgstr "" msgid "Mostra la data di modifica." msgstr "" +#: design/plone/contenttypes/browser/move_content/templates/move_news_items.pt:69 +msgid "Move" +msgstr "Sposta" + +#: design/plone/contenttypes/browser/move_content/templates/move_news_items.pt:11 +msgid "Move News Items" +msgstr "Sposta le notizie" + #: design/plone/contenttypes/behaviors/configure.zcml:243 msgid "Multi File" msgstr "" @@ -737,7 +761,7 @@ msgstr "" msgid "Turismo" msgstr "" -#: design/plone/contenttypes/interfaces/bando.py:106 +#: design/plone/contenttypes/interfaces/bando.py:117 #: design/plone/contenttypes/interfaces/documento.py:50 #: design/plone/contenttypes/interfaces/servizio.py:225 msgid "Ufficio responsabile" @@ -816,7 +840,7 @@ msgid "a_cura_di_persone_label" msgstr "" #. Default: "Accedere al servizio" -#: design/plone/contenttypes/interfaces/servizio.py:371 +#: design/plone/contenttypes/interfaces/servizio.py:370 msgid "accedi_al_servizio_label" msgstr "" @@ -845,6 +869,16 @@ msgstr "" msgid "altri_documenti_help" msgstr "" +#. Default: "Date and time of the opening of the announcement. Use this field if you want to set a specific opening date. If not set, the announcement will be open immediately." +#: design/plone/contenttypes/interfaces/bando.py:56 +msgid "apertura_bando_help" +msgstr "" + +#. Default: "Opening date" +#: design/plone/contenttypes/interfaces/bando.py:55 +msgid "apertura_bando_label" +msgstr "" + #. Default: "Area" #: design/plone/contenttypes/interfaces/servizio.py:231 msgid "area" @@ -861,13 +895,13 @@ msgid "area_responsabile_documento_personale" msgstr "" #. Default: "Seleziona l'area amministrativa responsabile del documento." -#: design/plone/contenttypes/interfaces/bando.py:116 +#: design/plone/contenttypes/interfaces/bando.py:127 #: design/plone/contenttypes/interfaces/documento.py:60 msgid "area_responsabile_help" msgstr "" #. Default: "Area responsabile del documento" -#: design/plone/contenttypes/interfaces/bando.py:112 +#: design/plone/contenttypes/interfaces/bando.py:123 #: design/plone/contenttypes/interfaces/documento.py:56 msgid "area_responsabile_label" msgstr "" @@ -973,7 +1007,7 @@ msgid "casi_particolari_help" msgstr "" #. Default: "Casi particolari" -#: design/plone/contenttypes/interfaces/servizio.py:402 +#: design/plone/contenttypes/interfaces/servizio.py:401 msgid "casi_particolari_label" msgstr "" @@ -1087,7 +1121,7 @@ msgid "cosa_serve_help" msgstr "" #. Default: "Cosa serve" -#: design/plone/contenttypes/interfaces/servizio.py:385 +#: design/plone/contenttypes/interfaces/servizio.py:384 msgid "cosa_serve_label" msgstr "" @@ -1113,7 +1147,7 @@ msgid "costi" msgstr "" #. Default: "Costi e vincoli" -#: design/plone/contenttypes/interfaces/servizio.py:390 +#: design/plone/contenttypes/interfaces/servizio.py:389 msgid "costi_e_vincoli_label" msgstr "" @@ -1316,7 +1350,7 @@ msgstr "" #. Default: "Documenti" #: design/plone/contenttypes/interfaces/persona.py:199 -#: design/plone/contenttypes/interfaces/servizio.py:413 +#: design/plone/contenttypes/interfaces/servizio.py:412 msgid "documenti_label" msgstr "" @@ -1659,7 +1693,7 @@ msgid "link_siti_esterni_help" msgstr "" #. Default: "Link utili" -#: design/plone/contenttypes/interfaces/servizio.py:418 +#: design/plone/contenttypes/interfaces/servizio.py:417 msgid "link_utili_label" msgstr "" @@ -2020,12 +2054,12 @@ msgid "ricerca_in_testata_label" msgstr "" #. Default: "Ulteriori informazioni non previste negli altri campi; si può trattare di contatti o note informative la cui conoscenza è indispensabile per la partecipazione al bando" -#: design/plone/contenttypes/interfaces/bando.py:85 +#: design/plone/contenttypes/interfaces/bando.py:96 msgid "riferimenti_bando_agid_help" msgstr "" #. Default: "Ulteriori informazioni" -#: design/plone/contenttypes/interfaces/bando.py:84 +#: design/plone/contenttypes/interfaces/bando.py:95 msgid "riferimenti_bando_agid_label" msgstr "" @@ -2095,12 +2129,12 @@ msgid "ruolo_label" msgstr "" #. Default: "Data entro la quale sarà possibile far pervenire domande e richieste di chiarimento a chi eroga il bando" -#: design/plone/contenttypes/interfaces/bando.py:58 +#: design/plone/contenttypes/interfaces/bando.py:69 msgid "scadenza_domande_bando_help" msgstr "" #. Default: "Termine per le richieste di chiarimenti" -#: design/plone/contenttypes/interfaces/bando.py:54 +#: design/plone/contenttypes/interfaces/bando.py:65 msgid "scadenza_domande_bando_label" msgstr "" @@ -2357,7 +2391,7 @@ msgid "tempi_e_scadenze_help" msgstr "" #. Default: "Tempi e scadenze" -#: design/plone/contenttypes/interfaces/servizio.py:396 +#: design/plone/contenttypes/interfaces/servizio.py:395 msgid "tempi_e_scadenze_label" msgstr "" @@ -2377,12 +2411,12 @@ msgstr "" msgid "testata_fieldset_label" msgstr "" -#: design/plone/contenttypes/interfaces/bando.py:27 +#: design/plone/contenttypes/interfaces/bando.py:28 msgid "text_help" msgstr "" #. Default: "Testo" -#: design/plone/contenttypes/interfaces/bando.py:26 +#: design/plone/contenttypes/interfaces/bando.py:27 msgid "text_label" msgstr "" @@ -2492,12 +2526,12 @@ msgid "trasparenza_fieldset_label" msgstr "" #. Default: "Seleziona l'ufficio responsabile di questo bando." -#: design/plone/contenttypes/interfaces/bando.py:99 +#: design/plone/contenttypes/interfaces/bando.py:110 msgid "ufficio_responsabile_bando_help" msgstr "" #. Default: "Ufficio responsabile del bando" -#: design/plone/contenttypes/interfaces/bando.py:95 +#: design/plone/contenttypes/interfaces/bando.py:106 msgid "ufficio_responsabile_bando_label" msgstr "" From 713b28ed50185fa97ce5bc8720375d98b0feae2d Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 4 Jan 2023 10:16:57 +0100 Subject: [PATCH 104/487] Update changes --- CHANGES.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 1198a995..2f2c0575 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -7,7 +7,7 @@ Changelog 5.1.1 (unreleased) ------------------ -- New view `move_news_item`. +- New view 'move_news_items'. [foxtrot-dfm1] From 2d1d56b295840d6f6a006f0108757081d9c1a36b Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 5 Jan 2023 11:10:14 +0100 Subject: [PATCH 105/487] Update locales --- .../move_content/templates/move_news_items.pt | 12 ++++----- .../LC_MESSAGES/design.plone.contenttypes.po | 26 ++++++++++++++++++- .../locales/design.plone.contenttypes.pot | 26 ++++++++++++++++++- .../LC_MESSAGES/design.plone.contenttypes.po | 26 ++++++++++++++++++- .../LC_MESSAGES/design.plone.contenttypes.po | 26 ++++++++++++++++++- 5 files changed, 106 insertions(+), 10 deletions(-) diff --git a/src/design/plone/contenttypes/browser/move_content/templates/move_news_items.pt b/src/design/plone/contenttypes/browser/move_content/templates/move_news_items.pt index e4f8d5cf..77858173 100644 --- a/src/design/plone/contenttypes/browser/move_content/templates/move_news_items.pt +++ b/src/design/plone/contenttypes/browser/move_content/templates/move_news_items.pt @@ -16,15 +16,15 @@
- -
+ +
Find news with this News Type

- -
+ +
Find news with the indicated Path
@@ -58,8 +58,8 @@
- -
+ +
All the selected items will be moved to indicated path
diff --git a/src/design/plone/contenttypes/locales/__pycache__/LC_MESSAGES/design.plone.contenttypes.po b/src/design/plone/contenttypes/locales/__pycache__/LC_MESSAGES/design.plone.contenttypes.po index b2dbacdf..d2445295 100644 --- a/src/design/plone/contenttypes/locales/__pycache__/LC_MESSAGES/design.plone.contenttypes.po +++ b/src/design/plone/contenttypes/locales/__pycache__/LC_MESSAGES/design.plone.contenttypes.po @@ -4,7 +4,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2023-01-03 17:03+0000\n" +"POT-Creation-Date: 2023-01-05 10:06+0000\n" "PO-Revision-Date: 2023-01-03 18:01+0100\n" "Last-Translator: Roman Kysil \n" "Language-Team: Language\n" @@ -62,6 +62,10 @@ msgstr "" msgid "Agricoltura, pesca, silvicoltura e prodotti alimentari" msgstr "" +#: design/plone/contenttypes/browser/move_content/templates/move_news_items.pt:62 +msgid "All the selected items will be moved to indicated path" +msgstr "" + #: design/plone/contenttypes/vocabularies/dataset.py:36 msgid "Ambiente" msgstr "" @@ -357,6 +361,14 @@ msgstr "" msgid "Finanziamento impresa" msgstr "" +#: design/plone/contenttypes/browser/move_content/templates/move_news_items.pt:27 +msgid "Find news with the indicated Path" +msgstr "" + +#: design/plone/contenttypes/browser/move_content/templates/move_news_items.pt:20 +msgid "Find news with this News Type" +msgstr "" + #: design/plone/contenttypes/configure.zcml:52 msgid "Fix control panel of design.plone.contenttypes add-on." msgstr "" @@ -523,6 +535,10 @@ msgstr "" msgid "Move News Items" msgstr "" +#: design/plone/contenttypes/browser/move_content/templates/move_news_items.pt:61 +msgid "Move to Path" +msgstr "" + #: design/plone/contenttypes/behaviors/configure.zcml:243 msgid "Multi File" msgstr "" @@ -535,6 +551,10 @@ msgstr "" msgid "Nazione" msgstr "" +#: design/plone/contenttypes/browser/move_content/templates/move_news_items.pt:19 +msgid "News Type" +msgstr "" + #. Default: "Nome e cognome" #: design/plone/contenttypes/restapi/services/types/get.py:152 msgid "Nome e Cognome" @@ -665,6 +685,10 @@ msgstr "" msgid "Scienza e tecnologia" msgstr "" +#: design/plone/contenttypes/browser/move_content/templates/move_news_items.pt:26 +msgid "Search Path" +msgstr "" + #: design/plone/contenttypes/interfaces/unita_organizzativa.py:114 msgid "Sede" msgstr "" diff --git a/src/design/plone/contenttypes/locales/design.plone.contenttypes.pot b/src/design/plone/contenttypes/locales/design.plone.contenttypes.pot index 6dbc95b9..55b97a7f 100644 --- a/src/design/plone/contenttypes/locales/design.plone.contenttypes.pot +++ b/src/design/plone/contenttypes/locales/design.plone.contenttypes.pot @@ -4,7 +4,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2023-01-03 17:03+0000\n" +"POT-Creation-Date: 2023-01-05 10:07+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI +ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -61,6 +61,10 @@ msgstr "" msgid "Agricoltura, pesca, silvicoltura e prodotti alimentari" msgstr "" +#: design/plone/contenttypes/browser/move_content/templates/move_news_items.pt:62 +msgid "All the selected items will be moved to indicated path" +msgstr "" + #: design/plone/contenttypes/vocabularies/dataset.py:36 msgid "Ambiente" msgstr "" @@ -356,6 +360,14 @@ msgstr "" msgid "Finanziamento impresa" msgstr "" +#: design/plone/contenttypes/browser/move_content/templates/move_news_items.pt:27 +msgid "Find news with the indicated Path" +msgstr "" + +#: design/plone/contenttypes/browser/move_content/templates/move_news_items.pt:20 +msgid "Find news with this News Type" +msgstr "" + #: design/plone/contenttypes/configure.zcml:52 msgid "Fix control panel of design.plone.contenttypes add-on." msgstr "" @@ -522,6 +534,10 @@ msgstr "" msgid "Move News Items" msgstr "" +#: design/plone/contenttypes/browser/move_content/templates/move_news_items.pt:61 +msgid "Move to Path" +msgstr "" + #: design/plone/contenttypes/behaviors/configure.zcml:243 msgid "Multi File" msgstr "" @@ -534,6 +550,10 @@ msgstr "" msgid "Nazione" msgstr "" +#: design/plone/contenttypes/browser/move_content/templates/move_news_items.pt:19 +msgid "News Type" +msgstr "" + #. Default: "Nome e cognome" #: design/plone/contenttypes/restapi/services/types/get.py:152 msgid "Nome e Cognome" @@ -664,6 +684,10 @@ msgstr "" msgid "Scienza e tecnologia" msgstr "" +#: design/plone/contenttypes/browser/move_content/templates/move_news_items.pt:26 +msgid "Search Path" +msgstr "" + #: design/plone/contenttypes/interfaces/unita_organizzativa.py:114 msgid "Sede" msgstr "" diff --git a/src/design/plone/contenttypes/locales/en/LC_MESSAGES/design.plone.contenttypes.po b/src/design/plone/contenttypes/locales/en/LC_MESSAGES/design.plone.contenttypes.po index 5277394d..693760ca 100644 --- a/src/design/plone/contenttypes/locales/en/LC_MESSAGES/design.plone.contenttypes.po +++ b/src/design/plone/contenttypes/locales/en/LC_MESSAGES/design.plone.contenttypes.po @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2023-01-03 17:03+0000\n" +"POT-Creation-Date: 2023-01-05 10:06+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI +ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -58,6 +58,10 @@ msgstr "" msgid "Agricoltura, pesca, silvicoltura e prodotti alimentari" msgstr "" +#: design/plone/contenttypes/browser/move_content/templates/move_news_items.pt:62 +msgid "All the selected items will be moved to indicated path" +msgstr "" + #: design/plone/contenttypes/vocabularies/dataset.py:36 msgid "Ambiente" msgstr "" @@ -353,6 +357,14 @@ msgstr "" msgid "Finanziamento impresa" msgstr "" +#: design/plone/contenttypes/browser/move_content/templates/move_news_items.pt:27 +msgid "Find news with the indicated Path" +msgstr "" + +#: design/plone/contenttypes/browser/move_content/templates/move_news_items.pt:20 +msgid "Find news with this News Type" +msgstr "" + #: design/plone/contenttypes/configure.zcml:52 msgid "Fix control panel of design.plone.contenttypes add-on." msgstr "" @@ -519,6 +531,10 @@ msgstr "" msgid "Move News Items" msgstr "" +#: design/plone/contenttypes/browser/move_content/templates/move_news_items.pt:61 +msgid "Move to Path" +msgstr "" + #: design/plone/contenttypes/behaviors/configure.zcml:243 msgid "Multi File" msgstr "" @@ -531,6 +547,10 @@ msgstr "" msgid "Nazione" msgstr "" +#: design/plone/contenttypes/browser/move_content/templates/move_news_items.pt:19 +msgid "News Type" +msgstr "" + #. Default: "Nome e cognome" #: design/plone/contenttypes/restapi/services/types/get.py:152 msgid "Nome e Cognome" @@ -661,6 +681,10 @@ msgstr "" msgid "Scienza e tecnologia" msgstr "" +#: design/plone/contenttypes/browser/move_content/templates/move_news_items.pt:26 +msgid "Search Path" +msgstr "" + #: design/plone/contenttypes/interfaces/unita_organizzativa.py:114 msgid "Sede" msgstr "" diff --git a/src/design/plone/contenttypes/locales/it/LC_MESSAGES/design.plone.contenttypes.po b/src/design/plone/contenttypes/locales/it/LC_MESSAGES/design.plone.contenttypes.po index a026e4a8..fafa0aaa 100644 --- a/src/design/plone/contenttypes/locales/it/LC_MESSAGES/design.plone.contenttypes.po +++ b/src/design/plone/contenttypes/locales/it/LC_MESSAGES/design.plone.contenttypes.po @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2023-01-03 17:03+0000\n" +"POT-Creation-Date: 2023-01-05 10:06+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI +ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -58,6 +58,10 @@ msgstr "" msgid "Agricoltura, pesca, silvicoltura e prodotti alimentari" msgstr "" +#: design/plone/contenttypes/browser/move_content/templates/move_news_items.pt:62 +msgid "All the selected items will be moved to indicated path" +msgstr "Tutti gli elementi selezionati saranno spostati nella cartella indicata" + #: design/plone/contenttypes/vocabularies/dataset.py:36 msgid "Ambiente" msgstr "" @@ -353,6 +357,14 @@ msgstr "" msgid "Finanziamento impresa" msgstr "" +#: design/plone/contenttypes/browser/move_content/templates/move_news_items.pt:27 +msgid "Find news with the indicated Path" +msgstr "" + +#: design/plone/contenttypes/browser/move_content/templates/move_news_items.pt:20 +msgid "Find news with this News Type" +msgstr "" + #: design/plone/contenttypes/configure.zcml:52 msgid "Fix control panel of design.plone.contenttypes add-on." msgstr "" @@ -519,6 +531,10 @@ msgstr "Sposta" msgid "Move News Items" msgstr "Sposta le notizie" +#: design/plone/contenttypes/browser/move_content/templates/move_news_items.pt:61 +msgid "Move to Path" +msgstr "Sposta nella cartella" + #: design/plone/contenttypes/behaviors/configure.zcml:243 msgid "Multi File" msgstr "" @@ -531,6 +547,10 @@ msgstr "" msgid "Nazione" msgstr "" +#: design/plone/contenttypes/browser/move_content/templates/move_news_items.pt:19 +msgid "News Type" +msgstr "Tipo Notizia" + #. Default: "Nome e cognome" #: design/plone/contenttypes/restapi/services/types/get.py:152 msgid "Nome e Cognome" @@ -661,6 +681,10 @@ msgstr "" msgid "Scienza e tecnologia" msgstr "" +#: design/plone/contenttypes/browser/move_content/templates/move_news_items.pt:26 +msgid "Search Path" +msgstr "Cartella della ricerca" + #: design/plone/contenttypes/interfaces/unita_organizzativa.py:114 msgid "Sede" msgstr "" From 5cd09440e84a83ca1de9d2d7215af9f719b8116a Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 4 Jan 2023 16:03:10 +0100 Subject: [PATCH 106/487] New view 'change_news_type' --- .../plone/contenttypes/browser/configure.zcml | 3 + .../browser/manage_content/__init__.py | 0 .../manage_content/change_news_type.py | 54 ++++++++++++++++++ .../browser/manage_content/configure.zcml | 16 ++++++ .../templates/change_news_type.pt | 52 ++++++++++++++++++ .../tests/test_change_news_type.py | 55 +++++++++++++++++++ 6 files changed, 180 insertions(+) create mode 100644 src/design/plone/contenttypes/browser/manage_content/__init__.py create mode 100644 src/design/plone/contenttypes/browser/manage_content/change_news_type.py create mode 100644 src/design/plone/contenttypes/browser/manage_content/configure.zcml create mode 100644 src/design/plone/contenttypes/browser/manage_content/templates/change_news_type.pt create mode 100644 src/design/plone/contenttypes/tests/test_change_news_type.py diff --git a/src/design/plone/contenttypes/browser/configure.zcml b/src/design/plone/contenttypes/browser/configure.zcml index 6475299d..fc3bdd66 100644 --- a/src/design/plone/contenttypes/browser/configure.zcml +++ b/src/design/plone/contenttypes/browser/configure.zcml @@ -5,6 +5,8 @@ i18n_domain="design.plone.contenttypes" > + + + + + + + diff --git a/src/design/plone/contenttypes/browser/manage_content/templates/change_news_type.pt b/src/design/plone/contenttypes/browser/manage_content/templates/change_news_type.pt new file mode 100644 index 00000000..f24ae634 --- /dev/null +++ b/src/design/plone/contenttypes/browser/manage_content/templates/change_news_type.pt @@ -0,0 +1,52 @@ + + + + +

Change News Type

+
+ + + +
+ +
+ +
+ Find all the already existing News Types +
+
+ +
+ The News Type selected above will be substituted by the selected value +
+ +
+
+ +
+ +
+
+ + + diff --git a/src/design/plone/contenttypes/tests/test_change_news_type.py b/src/design/plone/contenttypes/tests/test_change_news_type.py new file mode 100644 index 00000000..a7c37aac --- /dev/null +++ b/src/design/plone/contenttypes/tests/test_change_news_type.py @@ -0,0 +1,55 @@ +from plone.app.testing import setRoles +from plone.app.testing import TEST_USER_ID +from plone import api + +from design.plone.contenttypes.testing import ( + DESIGN_PLONE_CONTENTTYPES_INTEGRATION_TESTING, +) + +import unittest + + +class MoveNewsItemView(unittest.TestCase): + + layer = DESIGN_PLONE_CONTENTTYPES_INTEGRATION_TESTING + + def setUp(self): + self.portal = self.layer["portal"] + self.request = self.layer["request"] + self.view = api.content.get_view( + "change_news_type", context=self.portal, request=self.request + ) + + setRoles(self.portal, TEST_USER_ID, ["Manager"]) + + self.news_container = api.content.create( + type="Folder", + title="News container", + container=self.portal, + ) + self.news_item = api.content.create( + type="News Item", + title="news item", + tipologia_notizia="Notizia", + container=self.portal, + ) + self.news_item1 = api.content.create( + type="News Item", + title="news item1", + tipologia_notizia="Notizia", + container=self.news_container, + ) + + def test_substitute_news_type(self): + new_news_type = "New news type" + self.view.request.form["news_type_in_catalog"] = "Notizia" + self.view.request.form["news_type_portal"] = "New news type" + self.view.request.form["substitute"] = "true" + + # mock the helper methods of our view + self.view.news_types = lambda: [new_news_type] + + self.view.substitute_news_type() + + self.assertEqual(new_news_type, self.news_item.tipologia_notizia) + self.assertEqual(new_news_type, self.news_item1.tipologia_notizia) From ade7b360ba499d3582fcd50ef019f1b3bac5b5b8 Mon Sep 17 00:00:00 2001 From: Roman Date: Wed, 4 Jan 2023 16:16:49 +0100 Subject: [PATCH 107/487] Update locales --- .../templates/change_news_type.pt | 10 +++--- .../locales/design.plone.contenttypes.pot | 36 +++++++++++++++++++ .../LC_MESSAGES/design.plone.contenttypes.po | 25 ++++++++++++- .../LC_MESSAGES/design.plone.contenttypes.po | 28 +++++++++++++-- 4 files changed, 91 insertions(+), 8 deletions(-) diff --git a/src/design/plone/contenttypes/browser/manage_content/templates/change_news_type.pt b/src/design/plone/contenttypes/browser/manage_content/templates/change_news_type.pt index f24ae634..222009ab 100644 --- a/src/design/plone/contenttypes/browser/manage_content/templates/change_news_type.pt +++ b/src/design/plone/contenttypes/browser/manage_content/templates/change_news_type.pt @@ -16,17 +16,17 @@
- -
- Find all the already existing News Types + +
+ All the already existing News Types

- -
+ +
The News Type selected above will be substituted by the selected value

- Find news with the indicated Path + Find news with the indicated Path, put attention than generaly sites have the root name "/Plone/"
From 7203bf5f581b2f6aff269714137bbe361399a090 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 5 Jan 2023 15:14:09 +0100 Subject: [PATCH 119/487] Update locales + change move_news_items view behavior --- .../browser/manage_content/move_news_items.py | 9 ++++----- .../__pycache__/LC_MESSAGES/design.plone.contenttypes.po | 4 ++-- .../contenttypes/locales/design.plone.contenttypes.pot | 4 ++-- .../locales/en/LC_MESSAGES/design.plone.contenttypes.po | 4 ++-- .../locales/it/LC_MESSAGES/design.plone.contenttypes.po | 6 +++--- 5 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/design/plone/contenttypes/browser/manage_content/move_news_items.py b/src/design/plone/contenttypes/browser/manage_content/move_news_items.py index eb99a9ce..c7e7e6b4 100644 --- a/src/design/plone/contenttypes/browser/manage_content/move_news_items.py +++ b/src/design/plone/contenttypes/browser/manage_content/move_news_items.py @@ -55,12 +55,11 @@ def news_results(self): path = self.request.form.get("path", "") query = {} - if news_type: - query["tipologia_notizia"] = news_type - if path: - query["path"] = path + query["tipologia_notizia"] = news_type + if path: + query["path"] = path - return api.portal.get_tool("portal_catalog")(**query) + return api.portal.get_tool("portal_catalog")(**query) def news_types(self): return getUtility( diff --git a/src/design/plone/contenttypes/locales/__pycache__/LC_MESSAGES/design.plone.contenttypes.po b/src/design/plone/contenttypes/locales/__pycache__/LC_MESSAGES/design.plone.contenttypes.po index 5e10a414..39914670 100644 --- a/src/design/plone/contenttypes/locales/__pycache__/LC_MESSAGES/design.plone.contenttypes.po +++ b/src/design/plone/contenttypes/locales/__pycache__/LC_MESSAGES/design.plone.contenttypes.po @@ -4,7 +4,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2023-01-05 13:48+0000\n" +"POT-Creation-Date: 2023-01-05 14:10+0000\n" "PO-Revision-Date: 2023-01-03 18:01+0100\n" "Last-Translator: Roman Kysil \n" "Language-Team: Language\n" @@ -374,7 +374,7 @@ msgid "Finanziamento impresa" msgstr "" #: design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt:27 -msgid "Find news with the indicated Path" +msgid "Find news with the indicated Path, put attention than generaly sites have the root name \"/Plone/\"" msgstr "" #: design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt:20 diff --git a/src/design/plone/contenttypes/locales/design.plone.contenttypes.pot b/src/design/plone/contenttypes/locales/design.plone.contenttypes.pot index b0c3f09e..44812c51 100644 --- a/src/design/plone/contenttypes/locales/design.plone.contenttypes.pot +++ b/src/design/plone/contenttypes/locales/design.plone.contenttypes.pot @@ -4,7 +4,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2023-01-05 10:07+0000\n" +"POT-Creation-Date: 2023-01-05 14:10+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI +ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -381,7 +381,7 @@ msgid "Finanziamento impresa" msgstr "" #: design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt:27 -msgid "Find news with the indicated Path" +msgid "Find news with the indicated Path, put attention than generaly sites have the root name \"/Plone/\"" msgstr "" #: design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt:20 diff --git a/src/design/plone/contenttypes/locales/en/LC_MESSAGES/design.plone.contenttypes.po b/src/design/plone/contenttypes/locales/en/LC_MESSAGES/design.plone.contenttypes.po index dabf7210..bca785f3 100644 --- a/src/design/plone/contenttypes/locales/en/LC_MESSAGES/design.plone.contenttypes.po +++ b/src/design/plone/contenttypes/locales/en/LC_MESSAGES/design.plone.contenttypes.po @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2023-01-05 13:48+0000\n" +"POT-Creation-Date: 2023-01-05 14:10+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI +ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -369,7 +369,7 @@ msgid "Finanziamento impresa" msgstr "" #: design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt:27 -msgid "Find news with the indicated Path" +msgid "Find news with the indicated Path, put attention than generaly sites have the root name \"/Plone/\"" msgstr "" #: design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt:20 diff --git a/src/design/plone/contenttypes/locales/it/LC_MESSAGES/design.plone.contenttypes.po b/src/design/plone/contenttypes/locales/it/LC_MESSAGES/design.plone.contenttypes.po index 83ac2b44..a5b708a9 100644 --- a/src/design/plone/contenttypes/locales/it/LC_MESSAGES/design.plone.contenttypes.po +++ b/src/design/plone/contenttypes/locales/it/LC_MESSAGES/design.plone.contenttypes.po @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2023-01-05 13:48+0000\n" +"POT-Creation-Date: 2023-01-05 14:10+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI +ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -374,8 +374,8 @@ msgid "Finanziamento impresa" msgstr "" #: design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt:27 -msgid "Find news with the indicated Path" -msgstr "Trova le Notizie nella cartella indicata" +msgid "Find news with the indicated Path, put attention than generaly sites have the root name \"/Plone/\"" +msgstr "Trova le notizie in path indicato. Attenzione, in maggior parte dei casi il sito ha il nome \"/Plone/\" #: design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt:20 msgid "Find news with this News Type" From 0cec67b7b41a47067eb671bcff26cb40054c6b1d Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 5 Jan 2023 15:21:50 +0100 Subject: [PATCH 120/487] Update locale + fix move_news_items view --- .../contenttypes/browser/manage_content/move_news_items.py | 2 +- .../__pycache__/LC_MESSAGES/design.plone.contenttypes.po | 2 +- .../plone/contenttypes/locales/design.plone.contenttypes.pot | 2 +- .../locales/en/LC_MESSAGES/design.plone.contenttypes.po | 2 +- .../locales/it/LC_MESSAGES/design.plone.contenttypes.po | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/design/plone/contenttypes/browser/manage_content/move_news_items.py b/src/design/plone/contenttypes/browser/manage_content/move_news_items.py index c7e7e6b4..4463c9ca 100644 --- a/src/design/plone/contenttypes/browser/manage_content/move_news_items.py +++ b/src/design/plone/contenttypes/browser/manage_content/move_news_items.py @@ -53,7 +53,7 @@ def move_data(self): def news_results(self): news_type = self.request.form.get("news_type", "") path = self.request.form.get("path", "") - query = {} + query = {"portal_type": "News Item"} query["tipologia_notizia"] = news_type if path: diff --git a/src/design/plone/contenttypes/locales/__pycache__/LC_MESSAGES/design.plone.contenttypes.po b/src/design/plone/contenttypes/locales/__pycache__/LC_MESSAGES/design.plone.contenttypes.po index 39914670..79e8adf7 100644 --- a/src/design/plone/contenttypes/locales/__pycache__/LC_MESSAGES/design.plone.contenttypes.po +++ b/src/design/plone/contenttypes/locales/__pycache__/LC_MESSAGES/design.plone.contenttypes.po @@ -4,7 +4,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2023-01-05 14:10+0000\n" +"POT-Creation-Date: 2023-01-05 14:19+0000\n" "PO-Revision-Date: 2023-01-03 18:01+0100\n" "Last-Translator: Roman Kysil \n" "Language-Team: Language\n" diff --git a/src/design/plone/contenttypes/locales/design.plone.contenttypes.pot b/src/design/plone/contenttypes/locales/design.plone.contenttypes.pot index 44812c51..6eb3eb53 100644 --- a/src/design/plone/contenttypes/locales/design.plone.contenttypes.pot +++ b/src/design/plone/contenttypes/locales/design.plone.contenttypes.pot @@ -4,7 +4,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2023-01-05 14:10+0000\n" +"POT-Creation-Date: 2023-01-05 14:19+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI +ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/src/design/plone/contenttypes/locales/en/LC_MESSAGES/design.plone.contenttypes.po b/src/design/plone/contenttypes/locales/en/LC_MESSAGES/design.plone.contenttypes.po index bca785f3..2680d82b 100644 --- a/src/design/plone/contenttypes/locales/en/LC_MESSAGES/design.plone.contenttypes.po +++ b/src/design/plone/contenttypes/locales/en/LC_MESSAGES/design.plone.contenttypes.po @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2023-01-05 14:10+0000\n" +"POT-Creation-Date: 2023-01-05 14:19+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI +ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/src/design/plone/contenttypes/locales/it/LC_MESSAGES/design.plone.contenttypes.po b/src/design/plone/contenttypes/locales/it/LC_MESSAGES/design.plone.contenttypes.po index a5b708a9..3a47f1f6 100644 --- a/src/design/plone/contenttypes/locales/it/LC_MESSAGES/design.plone.contenttypes.po +++ b/src/design/plone/contenttypes/locales/it/LC_MESSAGES/design.plone.contenttypes.po @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2023-01-05 14:10+0000\n" +"POT-Creation-Date: 2023-01-05 14:19+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI +ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" From 51504c59e785947a81d7219e8389dff44eb155c0 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 5 Jan 2023 15:26:01 +0100 Subject: [PATCH 121/487] Fix locales, fix view move_news_items --- .../contenttypes/browser/manage_content/move_news_items.py | 3 ++- .../locales/it/LC_MESSAGES/design.plone.contenttypes.po | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/design/plone/contenttypes/browser/manage_content/move_news_items.py b/src/design/plone/contenttypes/browser/manage_content/move_news_items.py index 4463c9ca..6683a2f3 100644 --- a/src/design/plone/contenttypes/browser/manage_content/move_news_items.py +++ b/src/design/plone/contenttypes/browser/manage_content/move_news_items.py @@ -55,7 +55,8 @@ def news_results(self): path = self.request.form.get("path", "") query = {"portal_type": "News Item"} - query["tipologia_notizia"] = news_type + if news_type + query["tipologia_notizia"] = news_type if path: query["path"] = path diff --git a/src/design/plone/contenttypes/locales/it/LC_MESSAGES/design.plone.contenttypes.po b/src/design/plone/contenttypes/locales/it/LC_MESSAGES/design.plone.contenttypes.po index 3a47f1f6..119f83a9 100644 --- a/src/design/plone/contenttypes/locales/it/LC_MESSAGES/design.plone.contenttypes.po +++ b/src/design/plone/contenttypes/locales/it/LC_MESSAGES/design.plone.contenttypes.po @@ -375,7 +375,7 @@ msgstr "" #: design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt:27 msgid "Find news with the indicated Path, put attention than generaly sites have the root name \"/Plone/\"" -msgstr "Trova le notizie in path indicato. Attenzione, in maggior parte dei casi il sito ha il nome \"/Plone/\" +msgstr "Trova le notizie in path indicato. Attenzione, in maggior parte dei casi il sito ha il nome \"/Plone/\"" #: design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt:20 msgid "Find news with this News Type" From 7b12d20be53c87f9ddeff414c3c7d9448db3e99c Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 5 Jan 2023 15:31:45 +0100 Subject: [PATCH 122/487] Fix view --- .../contenttypes/browser/manage_content/move_news_items.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/design/plone/contenttypes/browser/manage_content/move_news_items.py b/src/design/plone/contenttypes/browser/manage_content/move_news_items.py index 6683a2f3..35ec9562 100644 --- a/src/design/plone/contenttypes/browser/manage_content/move_news_items.py +++ b/src/design/plone/contenttypes/browser/manage_content/move_news_items.py @@ -55,7 +55,7 @@ def news_results(self): path = self.request.form.get("path", "") query = {"portal_type": "News Item"} - if news_type + if news_type: query["tipologia_notizia"] = news_type if path: query["path"] = path From 674cf1848a6f4a287930916c021b1cf6835f730f Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 5 Jan 2023 16:46:07 +0100 Subject: [PATCH 123/487] Changes requested by ceck --- .../manage_content/change_news_type.py | 19 +++--- .../browser/manage_content/move_news_items.py | 5 ++ .../templates/change_news_type.pt | 1 + .../templates/move_news_items.pt | 3 +- .../LC_MESSAGES/design.plone.contenttypes.po | 56 +++++++++++------- .../locales/design.plone.contenttypes.pot | 59 +++++++++++++------ .../LC_MESSAGES/design.plone.contenttypes.po | 52 +++++++++------- .../LC_MESSAGES/design.plone.contenttypes.po | 58 ++++++++++-------- 8 files changed, 159 insertions(+), 94 deletions(-) diff --git a/src/design/plone/contenttypes/browser/manage_content/change_news_type.py b/src/design/plone/contenttypes/browser/manage_content/change_news_type.py index bae0a567..bcbbed2d 100644 --- a/src/design/plone/contenttypes/browser/manage_content/change_news_type.py +++ b/src/design/plone/contenttypes/browser/manage_content/change_news_type.py @@ -38,23 +38,24 @@ def substitute_news_type(self): news_new_type = self.request.form.get("news_type_portal", "") if not old_news_type or not news_new_type: - self.context.plone_utils.addPortalMessage(_("Not enaught data"), "error") + self.context.plone_utils.addPortalMessage( + _("One of the fields was not populated"), "error" + ) return if ( news_new_type not in self.news_types() or old_news_type not in self.news_types_in_catalog() ): - self.context.plone_utils.addPortalMessage(_("Bad data was send"), "error") - - news_to_update = [ - i.getObject() - for i in api.portal.get_tool("portal_catalog")( - tipologia_notizia=old_news_type + # It will happen only if the form will be used by somebody cunning + self.context.plone_utils.addPortalMessage( + _("Bad old or new 'tipologia_notizia' was send"), "error" ) - ] - for news in news_to_update: + for news in api.portal.get_tool("portal_catalog")( + tipologia_notizia=old_news_type + ): + news = news.getObject() news.tipologia_notizia = news_new_type news.reindexObject(idxs=["tipologia_notizia"]) diff --git a/src/design/plone/contenttypes/browser/manage_content/move_news_items.py b/src/design/plone/contenttypes/browser/manage_content/move_news_items.py index 35ec9562..a5ec7f17 100644 --- a/src/design/plone/contenttypes/browser/manage_content/move_news_items.py +++ b/src/design/plone/contenttypes/browser/manage_content/move_news_items.py @@ -34,6 +34,7 @@ def move_data(self): ) return + # in the generator expression below we are trying to extract the News Items uuids form the form for item_uid in [i for i, j in self.request.form.items() if j == "on"]: item = api.content.get(UID=item_uid) if item: @@ -49,6 +50,10 @@ def move_data(self): self.context.plone_utils.addPortalMessage( _("Items moved with success"), "info" ) + else: + self.context.plone_utils.addPortalMessage( + _("The path was not indicated"), "warning" + ) def news_results(self): news_type = self.request.form.get("news_type", "") diff --git a/src/design/plone/contenttypes/browser/manage_content/templates/change_news_type.pt b/src/design/plone/contenttypes/browser/manage_content/templates/change_news_type.pt index 222009ab..46a71449 100644 --- a/src/design/plone/contenttypes/browser/manage_content/templates/change_news_type.pt +++ b/src/design/plone/contenttypes/browser/manage_content/templates/change_news_type.pt @@ -11,6 +11,7 @@

Change News Type

+ Questo tool viene usato per cambiare il valore del campo 'Tipologia Notizia' in tutte le notizie che hanno il valore del campo selezionato.
diff --git a/src/design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt b/src/design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt index bebdf291..96376474 100644 --- a/src/design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt +++ b/src/design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt @@ -11,6 +11,7 @@

Move News Items

+ Questo tool viewne usato per trovare e spostare le Notizie con una Tipologia Notizia determinata.
@@ -20,7 +21,7 @@
Find news with this News Type
-
diff --git a/src/design/plone/contenttypes/restapi/deserializers/news.py b/src/design/plone/contenttypes/restapi/deserializers/news.py index 7ad890d9..c69e3ec8 100644 --- a/src/design/plone/contenttypes/restapi/deserializers/news.py +++ b/src/design/plone/contenttypes/restapi/deserializers/news.py @@ -136,6 +136,7 @@ def __call__( if errors: raise BadRequest(errors) + return super(DeserializeNewsFromJson, self).__call__( validate_all=False, data=data, create=False ) From 0fd1a9ec16f3d5b896989a217c3409279c55d970 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Mon, 23 Jan 2023 16:36:49 +0100 Subject: [PATCH 159/487] [doc] updated CHAGES --- CHANGES.rst | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 94c244bf..775796be 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -5,7 +5,10 @@ Changelog 6.0.0a8 (unreleased) -------------------- -- Nothing changed yet. +- Fixed some field in event and news ct. +- Add news argomenti_evento behavior for event. +- Remove old argomenti behavior for news item. + [eikichi18] 6.0.0a7 (2023-01-20) From 48f7174c7f1f7704212ffd91e4e29e56f3a61203 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Mon, 23 Jan 2023 16:39:10 +0100 Subject: [PATCH 160/487] Preparing release 6.0.0a8 --- CHANGES.rst | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 775796be..156db136 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -2,7 +2,7 @@ Changelog ========= -6.0.0a8 (unreleased) +6.0.0a8 (2023-01-23) -------------------- - Fixed some field in event and news ct. diff --git a/setup.py b/setup.py index abb6b8fc..1ee4e193 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.0.0a8.dev0", + version="6.0.0a8", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From f54e8570f67ba624969aed87585f3d980cdf771a Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Mon, 23 Jan 2023 16:43:48 +0100 Subject: [PATCH 161/487] Back to development: 6.0.0a9 --- CHANGES.rst | 6 ++++++ setup.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 156db136..4b41115d 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -2,6 +2,12 @@ Changelog ========= +6.0.0a9 (unreleased) +-------------------- + +- Nothing changed yet. + + 6.0.0a8 (2023-01-23) -------------------- diff --git a/setup.py b/setup.py index 1ee4e193..2d0c6001 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.0.0a8", + version="6.0.0a9.dev0", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 137464b6cefaeb5787d6ea42ba3cca3ed765e84f Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Tue, 24 Jan 2023 16:03:31 +0100 Subject: [PATCH 162/487] [fix] removed wrong criteria for collective.taxonomy --- .../profiles/default/registry/criteria.xml | 148 ++++++++++++++---- 1 file changed, 118 insertions(+), 30 deletions(-) diff --git a/src/design/plone/contenttypes/profiles/default/registry/criteria.xml b/src/design/plone/contenttypes/profiles/default/registry/criteria.xml index 319f7305..2ca97f8e 100644 --- a/src/design/plone/contenttypes/profiles/default/registry/criteria.xml +++ b/src/design/plone/contenttypes/profiles/default/registry/criteria.xml @@ -1,5 +1,7 @@ - + Metadata - - - - Argomenti correlati - Argomenti correlati (con uid) - True - False - - plone.app.querystring.operation.selection.any - plone.app.querystring.operation.selection.all - - design.plone.vocabularies.argomenti_uid - Metadata - - Ruolo - Ruolo - True - False - - plone.app.querystring.operation.selection.any - plone.app.querystring.operation.selection.all - - design.plone.contenttypes.RuoliPersona - Metadata - + + Argomenti correlati + Argomenti correlati (con uid) + True + False + + plone.app.querystring.operation.selection.any + plone.app.querystring.operation.selection.all + + design.plone.vocabularies.argomenti_uid + Metadata + + + + Ruolo + Ruolo + True + False + + plone.app.querystring.operation.selection.any + plone.app.querystring.operation.selection.all + + design.plone.contenttypes.RuoliPersona + Metadata + - + remove="True" + > + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From eefd88bb18aaae27f23b68712053267255170a04 Mon Sep 17 00:00:00 2001 From: Luca Date: Wed, 25 Jan 2023 16:57:25 +0100 Subject: [PATCH 163/487] Update design.plone.contenttypes.po Fix simple conflict --- .../locales/en/LC_MESSAGES/design.plone.contenttypes.po | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/design/plone/contenttypes/locales/en/LC_MESSAGES/design.plone.contenttypes.po b/src/design/plone/contenttypes/locales/en/LC_MESSAGES/design.plone.contenttypes.po index 03a745e8..69f5e5e7 100644 --- a/src/design/plone/contenttypes/locales/en/LC_MESSAGES/design.plone.contenttypes.po +++ b/src/design/plone/contenttypes/locales/en/LC_MESSAGES/design.plone.contenttypes.po @@ -64,12 +64,10 @@ msgstr "" #: design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt:63 msgid "All the selected items will be moved to indicated path" -<<<<<<< HEAD +msgstr "" #: design/plone/contenttypes/browser/manage_content/templates/change_news_type.pt:20 msgid "All the already existing News Types" -======= ->>>>>>> origin/pnrr msgstr "" #: design/plone/contenttypes/vocabularies/dataset.py:36 From 27e454d7d7f03978dc38184d44a27c9c62a789d6 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Fri, 27 Jan 2023 13:08:54 +0100 Subject: [PATCH 164/487] [fix] fix test for plone 6 --- test_plone60.cfg | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/test_plone60.cfg b/test_plone60.cfg index 68afffe6..8c885d8d 100644 --- a/test_plone60.cfg +++ b/test_plone60.cfg @@ -3,7 +3,7 @@ extends = https://raw.github.com/collective/buildout.plonetest/master/test-6.0.x.cfg https://raw.githubusercontent.com/collective/buildout.plonetest/master/qa.cfg - https://raw.githubusercontent.com/RedTurtle/dist.design.plone/6.0/versions.cfg + https://raw.githubusercontent.com/RedTurtle/iocomune-backend/main/versions.cfg base.cfg update-versions-file = test_plone60.cfg @@ -20,10 +20,6 @@ plone.recipe.codeanalysis = 3.0.1 pyflakes = 2.3.1 zpretty = 2.1.0 -# Required by: -# redturtle.volto==3.7.4.dev0 -collective.purgebyid = 1.1.1 - # Required by: # flake8-debugger==3.2.1 # flake8-print==3.1.4 @@ -52,10 +48,6 @@ check-manifest = 0.48 # eea.api.taxonomy==1.5 collective.taxonomy = 3.0.0 -# Required by: -# design.plone.contenttypes==6.0.0.dev0 -collective.z3cform.datagridfield = 2.0 - # Required by: # zest.releaser==7.2.0 colorama = 0.4.6 From df17ee68e0a58f39d9452b35792af48b9c1df4eb Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Wed, 1 Feb 2023 17:21:00 +0100 Subject: [PATCH 165/487] update some label --- src/design/plone/contenttypes/interfaces/persona.py | 2 +- src/design/plone/contenttypes/interfaces/servizio.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/design/plone/contenttypes/interfaces/persona.py b/src/design/plone/contenttypes/interfaces/persona.py index 276b7c34..cfa30704 100644 --- a/src/design/plone/contenttypes/interfaces/persona.py +++ b/src/design/plone/contenttypes/interfaces/persona.py @@ -57,7 +57,7 @@ class IPersona(model.Schema, IDesignPloneContentType): ), description=_( "incarichi_help", - default="Seleziona la lista di incarichi della persona.", + default="Seleziona l'incarico corrente della persona.", ), value_type=RelationChoice( title=_("Incarichi"), diff --git a/src/design/plone/contenttypes/interfaces/servizio.py b/src/design/plone/contenttypes/interfaces/servizio.py index 801893f0..64fbf36c 100644 --- a/src/design/plone/contenttypes/interfaces/servizio.py +++ b/src/design/plone/contenttypes/interfaces/servizio.py @@ -186,7 +186,7 @@ class IServizio(model.Schema, IDesignPloneContentType): title=_("canale_fisico", default="Canale fisico"), description=_( "canale_fisico_help", - default="Sedi per la fruizione del servizio", + default="Unità organizzative per la fruizione del servizio", ), required=True, default=[], From ede1712c024f7b87b180474220623d46e7bcd733 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Thu, 2 Feb 2023 09:31:04 +0100 Subject: [PATCH 166/487] spostato il campo notizie collegate --- .../plone/contenttypes/behaviors/news_additional_fields.py | 6 +++++- src/design/plone/contenttypes/profiles/default/metadata.xml | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/design/plone/contenttypes/behaviors/news_additional_fields.py b/src/design/plone/contenttypes/behaviors/news_additional_fields.py index 990de1f9..0a20c31e 100644 --- a/src/design/plone/contenttypes/behaviors/news_additional_fields.py +++ b/src/design/plone/contenttypes/behaviors/news_additional_fields.py @@ -118,7 +118,11 @@ class INewsAdditionalFields(model.Schema): "maximumSelectionSize": 50, }, ) - + model.fieldset( + "correlati", + label=_("correlati_label", default="Contenuti collegati"), + fields=["notizie_correlate"], + ) # custom fieldsets and order form.order_before(descrizione_estesa="ILeadImageBehavior.image") form.order_before(numero_progressivo_cs="ILeadImageBehavior.image") diff --git a/src/design/plone/contenttypes/profiles/default/metadata.xml b/src/design/plone/contenttypes/profiles/default/metadata.xml index 024e6ff8..58837395 100644 --- a/src/design/plone/contenttypes/profiles/default/metadata.xml +++ b/src/design/plone/contenttypes/profiles/default/metadata.xml @@ -1,6 +1,6 @@ - 7003 + 7004 profile-redturtle.bandi:default profile-collective.venue:default From eb90c6231ab74a4cc2d2b3df2204d95b47eed7b2 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Thu, 2 Feb 2023 10:16:11 +0100 Subject: [PATCH 167/487] Preparing release 6.0.0a9 --- CHANGES.rst | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 8147e0b6..560f2f2e 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -2,7 +2,7 @@ Changelog ========= -6.0.0a9 (unreleased) +6.0.0a9 (2023-02-02) -------------------- - New view 'change_news_type' [foxtrot-dfm1] diff --git a/setup.py b/setup.py index 2d0c6001..acf9295d 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.0.0a9.dev0", + version="6.0.0a9", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From dc5eba18214e25cac41bbca427936fe8455864e0 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Thu, 2 Feb 2023 10:16:36 +0100 Subject: [PATCH 168/487] Back to development: 6.0.0a10 --- CHANGES.rst | 6 ++++++ setup.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 560f2f2e..6b19134d 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -2,6 +2,12 @@ Changelog ========= +6.0.0a10 (unreleased) +--------------------- + +- Nothing changed yet. + + 6.0.0a9 (2023-02-02) -------------------- - New view 'change_news_type' diff --git a/setup.py b/setup.py index acf9295d..f01e8ccb 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.0.0a9", + version="6.0.0a10.dev0", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 713a87f1c4d21a286dca2f0bf4ed34da7f4648e7 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Fri, 3 Feb 2023 12:54:23 +0100 Subject: [PATCH 169/487] fix serializer to return taxonomies in a correct way --- .../restapi/serializers/configure.zcml | 13 +- .../restapi/serializers/servizio.py | 6 + .../restapi/serializers/summary.py | 141 ++++++++++++++++-- .../serializers/unita_organizzativa.py | 5 + .../contenttypes/restapi/serializers/venue.py | 6 + 5 files changed, 157 insertions(+), 14 deletions(-) diff --git a/src/design/plone/contenttypes/restapi/serializers/configure.zcml b/src/design/plone/contenttypes/restapi/serializers/configure.zcml index 8ff7407f..58787130 100644 --- a/src/design/plone/contenttypes/restapi/serializers/configure.zcml +++ b/src/design/plone/contenttypes/restapi/serializers/configure.zcml @@ -9,19 +9,24 @@ + + + + + + + + + - - - - diff --git a/src/design/plone/contenttypes/restapi/serializers/servizio.py b/src/design/plone/contenttypes/restapi/serializers/servizio.py index 5d1e9856..4d3241fa 100644 --- a/src/design/plone/contenttypes/restapi/serializers/servizio.py +++ b/src/design/plone/contenttypes/restapi/serializers/servizio.py @@ -3,6 +3,9 @@ from design.plone.contenttypes.restapi.serializers.summary import ( DefaultJSONSummarySerializer, ) +from design.plone.contenttypes.restapi.serializers.summary import ( + get_taxonomy_information, +) from plone.dexterity.utils import iterSchemata from plone.restapi.interfaces import IFieldSerializer from plone.restapi.interfaces import ISerializeToJsonSummary @@ -17,6 +20,7 @@ @adapter(IServizio, Interface) class SerializeServizioToJsonSummary(DefaultJSONSummarySerializer): def __call__(self, force_all_metadata=False): + # import pdb;pdb.set_trace() summary = super().__call__(force_all_metadata=force_all_metadata) fields = ["canale_digitale"] for schema in iterSchemata(self.context): @@ -34,4 +38,6 @@ def __call__(self, force_all_metadata=False): parent = self.context.aq_inner.aq_parent summary["parent_title"] = parent.title summary["parent_url"] = parent.absolute_url() + get_taxonomy_information("person_life_events", self.context, summary) + get_taxonomy_information("business_events", self.context, summary) return summary diff --git a/src/design/plone/contenttypes/restapi/serializers/summary.py b/src/design/plone/contenttypes/restapi/serializers/summary.py index a95e990a..e33578d8 100644 --- a/src/design/plone/contenttypes/restapi/serializers/summary.py +++ b/src/design/plone/contenttypes/restapi/serializers/summary.py @@ -2,14 +2,19 @@ from collective.taxonomy import PATH_SEPARATOR from collective.taxonomy.interfaces import ITaxonomy from design.plone.contenttypes.interfaces import IDesignPloneContenttypesLayer +from design.plone.contenttypes.interfaces.dataset import IDataset +from design.plone.contenttypes.interfaces.documento import IDocumento from design.plone.contenttypes.interfaces.incarico import IIncarico from design.plone.contenttypes.interfaces.persona import IPersona +from design.plone.contenttypes.interfaces.pratica import IPratica from design.plone.contenttypes.interfaces.punto_di_contatto import IPuntoDiContatto from plone import api from plone.app.contenttypes.interfaces import IEvent +from plone.app.contenttypes.interfaces import INewsItem from plone.base.interfaces import IImageScalesAdapter from plone.restapi.interfaces import ISerializeToJsonSummary from plone.restapi.serializer.converters import json_compatible +from Products.ZCatalog.interfaces import ICatalogBrain from redturtle.volto.restapi.serializer.summary import ( DefaultJSONSummarySerializer as BaseSerializer, ) @@ -17,6 +22,7 @@ from zope.component import getMultiAdapter from zope.component import getUtility from zope.component import queryMultiAdapter +from zope.globalrequest import getRequest from zope.i18n import translate from zope.interface import implementer from zope.interface import Interface @@ -28,6 +34,85 @@ RESOLVEUID_RE = re.compile(".*?/resolve[Uu]id/([^/]*)/?(.*)$") +def get_taxonomy_information(field_name, context, res): + """ + Get the proper values for taxonomy fields + """ + request = getRequest() + taxonomy = getUtility(ITaxonomy, name=f"collective.taxonomy.{field_name}") + taxonomy_voc = taxonomy.makeVocabulary(request.get("LANGUAGE")) + + # il summary di un fullobject torna un value + # il summary di un brain torna una lista (collective.taxonomy ha motivi per + # fare così). + + # se abbiamo il summary di un fullobject o il summary di un brain non importa + # ritorna quello che avevi in pancia, se non avevi nulla. + + # Hai quel campo compilato? Ti trasformo come serve al frontend + if ICatalogBrain.providedBy(context): + fullterms = [] + # delle volte posso avere il brain senza quel dato + if field_name not in res: + res[field_name] = getattr(context, field_name) + + for token in res[field_name]: + title = taxonomy_voc.inv_data.get(token) + if title.startswith(PATH_SEPARATOR): + title.replace(PATH_SEPARATOR, "", 1) + fullterms.append({"token": token, "title": title}) + res[field_name] = fullterms + else: + value = getattr(context, field_name) + # if not value: + # return res + + def get_fullterms(token): + title = taxonomy_voc.inv_data.get(token) + if title.startswith(PATH_SEPARATOR): + title.replace(PATH_SEPARATOR, "", 1) + return { + "token": token, + "title": title, + } + + if isinstance(value, list): + res[field_name] = [get_fullterms(token) for token in value] + elif isinstance(value, str): + res[field_name] = get_fullterms(value) + + return res + + +def get_taxonomy_information_by_type(res, context): + portal_type = res.get("portal_type", None) or res.get("@type") + portal_type_mapping = { + "News Item": ("tipologia_notizia",), + "Event": ("tipologia_evento",), + "Venue": ("tipologia_luogo",), + "Dataset": ( + "temi_dataset", + "tipologia_frequenza_aggiornamento", + "tipologia_licenze", + ), + "Documento": ( + "tipologia_documenti_albopretorio", + "tipologia_documento", + "tipologia_licenze", + "person_life_events", + "business_events", + ), + "Pratica": ("tipologia_stati_pratica",), + "UnitaOrganizzativa": ("tipologia_organizzazione",), + "Incarico": ("tipologia_incarico",), + "Servizio": ("person_life_events", "business_events"), + } + for field_name in portal_type_mapping.get(portal_type, []): + get_taxonomy_information(field_name, context, res) + + return res + + @implementer(ISerializeToJsonSummary) @adapter(Interface, IDesignPloneContenttypesLayer) class DefaultJSONSummarySerializer(BaseSerializer): @@ -59,6 +144,8 @@ def __call__(self, force_all_metadata=False): if res["tassonomia_argomenti"]: res["tassonomia_argomenti"] = self.expand_tassonomia_argomenti() + get_taxonomy_information_by_type(res, self.context) + if self.is_get_call(): res["has_children"] = self.has_children() @@ -138,15 +225,7 @@ def get_incarichi(self): class IncaricoDefaultJSONSummarySerializer(DefaultJSONSummarySerializer): def __call__(self, force_all_metadata=False): res = super().__call__(force_all_metadata=force_all_metadata) - taxonomy = getUtility(ITaxonomy, name="collective.taxonomy.tipologia_incarico") - taxonomy_voc = taxonomy.makeVocabulary(self.request.get("LANGUAGE")) - if "tipologia_incarico" not in res: - if self.context.tipologia_incarico: - res["tipologia_incarico"] = taxonomy_voc.inv_data.get( - self.context.tipologia_incarico - ).replace(PATH_SEPARATOR, "") - else: - res["tipologia_incarico"] = json_compatible(None) + get_taxonomy_information("tipologia_incarico", self.context, res) if "data_inizio_incarico" not in res: res["data_inizio_incarico"] = json_compatible( self.context.data_inizio_incarico @@ -193,7 +272,7 @@ def __call__(self, force_all_metadata=False): class EventDefaultJSONSummarySerializer(DefaultJSONSummarySerializer): def __call__(self, force_all_metadata=False): res = super().__call__(force_all_metadata=force_all_metadata) - + get_taxonomy_information("tipologia_evento", self.context, res) # Il summary dell'evento riceve in ingresso un obj generico che può # essere un brain (gli items figli dell'evento) oppure un oggtto (il # parent). Gli attributi per le immagini vengono presi solo nel caso @@ -211,3 +290,45 @@ def __call__(self, force_all_metadata=False): elif "image" in scales: res["image_field"] = "image" return res + + +@implementer(ISerializeToJsonSummary) +@adapter(INewsItem, IDesignPloneContenttypesLayer) +class NewsDefaultJSONSummarySerializer(DefaultJSONSummarySerializer): + def __call__(self, force_all_metadata=False): + res = super().__call__(force_all_metadata=force_all_metadata) + get_taxonomy_information("tipologia_notizia", self.context, res) + return res + + +@implementer(ISerializeToJsonSummary) +@adapter(IDataset, IDesignPloneContenttypesLayer) +class DatasetDefaultJSONSummarySerializer(DefaultJSONSummarySerializer): + def __call__(self, force_all_metadata=False): + res = super().__call__(force_all_metadata=force_all_metadata) + get_taxonomy_information("temi_dataset", self.context, res) + get_taxonomy_information("tipologia_frequenza_aggiornamento", self.context, res) + get_taxonomy_information("tipologia_licenze", self.context, res) + return res + + +@implementer(ISerializeToJsonSummary) +@adapter(IDocumento, IDesignPloneContenttypesLayer) +class DocumentoPubblicoDefaultJSONSummarySerializer(DefaultJSONSummarySerializer): + def __call__(self, force_all_metadata=False): + res = super().__call__(force_all_metadata=force_all_metadata) + get_taxonomy_information("tipologia_documenti_albopretorio", self.context, res) + get_taxonomy_information("tipologia_documento", self.context, res) + get_taxonomy_information("tipologia_licenze", self.context, res) + get_taxonomy_information("person_life_events", self.context, res) + get_taxonomy_information("business_events", self.context, res) + return res + + +@implementer(ISerializeToJsonSummary) +@adapter(IPratica, IDesignPloneContenttypesLayer) +class PraticaDefaultJSONSummarySerializer(DefaultJSONSummarySerializer): + def __call__(self, force_all_metadata=False): + res = super().__call__(force_all_metadata=force_all_metadata) + get_taxonomy_information("tipologia_stati_pratica", self.context, res) + return res diff --git a/src/design/plone/contenttypes/restapi/serializers/unita_organizzativa.py b/src/design/plone/contenttypes/restapi/serializers/unita_organizzativa.py index 62747726..11dce3a2 100644 --- a/src/design/plone/contenttypes/restapi/serializers/unita_organizzativa.py +++ b/src/design/plone/contenttypes/restapi/serializers/unita_organizzativa.py @@ -5,6 +5,9 @@ from design.plone.contenttypes.restapi.serializers.summary import ( DefaultJSONSummarySerializer, ) +from design.plone.contenttypes.restapi.serializers.summary import ( + get_taxonomy_information, +) from plone import api from plone.restapi.interfaces import ISerializeToJson from plone.restapi.interfaces import ISerializeToJsonSummary @@ -139,6 +142,8 @@ def __call__(self, force_all_metadata=False): data["geolocation"] = self.getGeolocation() + get_taxonomy_information("tipologia_organizzazione", self.context, data) + return data def getGeolocation(self): diff --git a/src/design/plone/contenttypes/restapi/serializers/venue.py b/src/design/plone/contenttypes/restapi/serializers/venue.py index 51d98917..a75766d9 100644 --- a/src/design/plone/contenttypes/restapi/serializers/venue.py +++ b/src/design/plone/contenttypes/restapi/serializers/venue.py @@ -5,6 +5,9 @@ from design.plone.contenttypes.restapi.serializers.summary import ( DefaultJSONSummarySerializer, ) +from design.plone.contenttypes.restapi.serializers.summary import ( + get_taxonomy_information, +) from plone import api from plone.restapi.interfaces import ISerializeToJson from plone.restapi.interfaces import ISerializeToJsonSummary @@ -102,4 +105,7 @@ def __call__(self, force_all_metadata=False): if callable(value): value = value() summary[field] = json_compatible(value) + + get_taxonomy_information("tipologia_luogo", self.context, summary) + return summary From 6f30df6ee8ef4f1433064d1d7e758bbce1f11a88 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Fri, 3 Feb 2023 13:59:35 +0100 Subject: [PATCH 170/487] remove pdb --- src/design/plone/contenttypes/restapi/serializers/servizio.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/design/plone/contenttypes/restapi/serializers/servizio.py b/src/design/plone/contenttypes/restapi/serializers/servizio.py index 4d3241fa..f9399827 100644 --- a/src/design/plone/contenttypes/restapi/serializers/servizio.py +++ b/src/design/plone/contenttypes/restapi/serializers/servizio.py @@ -20,7 +20,6 @@ @adapter(IServizio, Interface) class SerializeServizioToJsonSummary(DefaultJSONSummarySerializer): def __call__(self, force_all_metadata=False): - # import pdb;pdb.set_trace() summary = super().__call__(force_all_metadata=force_all_metadata) fields = ["canale_digitale"] for schema in iterSchemata(self.context): From 1523ffe1120fdc088f88bb78a1c9e3805ade5703 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Fri, 3 Feb 2023 14:01:36 +0100 Subject: [PATCH 171/487] handle a case that could happen serialing taxonomy data --- src/design/plone/contenttypes/restapi/serializers/summary.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/design/plone/contenttypes/restapi/serializers/summary.py b/src/design/plone/contenttypes/restapi/serializers/summary.py index e33578d8..1c2778fd 100644 --- a/src/design/plone/contenttypes/restapi/serializers/summary.py +++ b/src/design/plone/contenttypes/restapi/serializers/summary.py @@ -68,6 +68,8 @@ def get_taxonomy_information(field_name, context, res): # return res def get_fullterms(token): + if not token: + return None title = taxonomy_voc.inv_data.get(token) if title.startswith(PATH_SEPARATOR): title.replace(PATH_SEPARATOR, "", 1) From 5f0756a7abc8f94a5d964727b4c70d6f70dcabfa Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Thu, 2 Feb 2023 09:31:04 +0100 Subject: [PATCH 172/487] spostato il campo notizie collegate --- .../plone/contenttypes/behaviors/news_additional_fields.py | 6 +++++- src/design/plone/contenttypes/profiles/default/metadata.xml | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/design/plone/contenttypes/behaviors/news_additional_fields.py b/src/design/plone/contenttypes/behaviors/news_additional_fields.py index 990de1f9..0a20c31e 100644 --- a/src/design/plone/contenttypes/behaviors/news_additional_fields.py +++ b/src/design/plone/contenttypes/behaviors/news_additional_fields.py @@ -118,7 +118,11 @@ class INewsAdditionalFields(model.Schema): "maximumSelectionSize": 50, }, ) - + model.fieldset( + "correlati", + label=_("correlati_label", default="Contenuti collegati"), + fields=["notizie_correlate"], + ) # custom fieldsets and order form.order_before(descrizione_estesa="ILeadImageBehavior.image") form.order_before(numero_progressivo_cs="ILeadImageBehavior.image") diff --git a/src/design/plone/contenttypes/profiles/default/metadata.xml b/src/design/plone/contenttypes/profiles/default/metadata.xml index 024e6ff8..58837395 100644 --- a/src/design/plone/contenttypes/profiles/default/metadata.xml +++ b/src/design/plone/contenttypes/profiles/default/metadata.xml @@ -1,6 +1,6 @@ - 7003 + 7004 profile-redturtle.bandi:default profile-collective.venue:default From 015b948b28e925c05d877a0a79b2ff672c813ef8 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Fri, 3 Feb 2023 14:53:19 +0100 Subject: [PATCH 173/487] cambiato il campo timeline tempi e scadenze --- .../plone/contenttypes/interfaces/servizio.py | 38 ++++++++----------- 1 file changed, 15 insertions(+), 23 deletions(-) diff --git a/src/design/plone/contenttypes/interfaces/servizio.py b/src/design/plone/contenttypes/interfaces/servizio.py index 64fbf36c..0ec1a294 100644 --- a/src/design/plone/contenttypes/interfaces/servizio.py +++ b/src/design/plone/contenttypes/interfaces/servizio.py @@ -16,28 +16,22 @@ class ITempiEScadenzeValueSchema(model.Schema): - data_scadenza = schema.Date( - title=_("data_scadenza_label", default="Data scadenza"), - description=_( - "data_scadenza_help", - default="Data di scadenza della fase", - ), - required=False, - ) + milestone = schema.TextLine( title=_("milestone_label", default="Titolo"), - description=_( - "milestone_help", - default="Titolo della fase", - ), required=True, default="", ) + milestone_description = schema.TextLine( + title=_("milestone_description_label", default="Sottotitolo"), + required=False, + default="", + ) interval_qt = schema.TextLine( title=_("interval_qt_label", default="Intervallo"), description=_( "interval_qt_help", - default="Intervallo della fase", + default="Intervallo della fase (es. 1)", ), required=False, default="", @@ -51,14 +45,9 @@ class ITempiEScadenzeValueSchema(model.Schema): required=False, default="", ) - milestone_description = schema.TextLine( - title=_("milestone_description_label", default="Sottotitolo"), - description=_( - "milestone_description_help", - default="Sottotitolo della fase", - ), + data_scadenza = schema.Date( + title=_("data_scadenza_label", default="Data scadenza"), required=False, - default="", ) form.widget( @@ -259,9 +248,12 @@ class IServizio(model.Schema, IDesignPloneContentType): description=_( "timeline_tempi_scadenze_help", default="Timeline tempi e scadenze del servizio: indicare per ogni " - "scadenza un titolo descritttivo di tale scadenza e, opzionalmente," - " informazioni sulle date o gli intervalli di tempo che " - "intercorrono tra una fase e la successiva.", + "scadenza un titolo descrittivo ed un eventuale sottotitolo." + "Per ogni scadenza, selezionare opzionalmente o l'intervallo (Campi" + ' "Intervallo" e "Tipo Intervallo", es. "1" e "settimana"),' + ' oppure direttamente una data di scadenza (campo: "Data Scadenza"' + ", esempio 31/12/2023). " + 'Se vengono compilati entrambi, ha priorità il campo "Data Scadenza".', ), required=False, ) From 8577f8604ab53e87bbf62b05bfbdead437c1b714 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Fri, 3 Feb 2023 15:12:48 +0100 Subject: [PATCH 174/487] update servizio fields as asked in us 38344 --- .../plone/contenttypes/interfaces/servizio.py | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/design/plone/contenttypes/interfaces/servizio.py b/src/design/plone/contenttypes/interfaces/servizio.py index 0ec1a294..de00da9b 100644 --- a/src/design/plone/contenttypes/interfaces/servizio.py +++ b/src/design/plone/contenttypes/interfaces/servizio.py @@ -185,15 +185,16 @@ class IServizio(model.Schema, IDesignPloneContentType): ), ) - autenticazione = BlocksField( - title=_("autenticazione", default="Autenticazione"), - description=_( - "autenticazione_help", - default="Indicare, se previste, le modalità di autenticazione" - " necessarie per poter accedere al servizio.", - ), - required=False, - ) + # US38344 rimuovere + # autenticazione = BlocksField( + # title=_("autenticazione", default="Autenticazione"), + # description=_( + # "autenticazione_help", + # default="Indicare, se previste, le modalità di autenticazione" + # " necessarie per poter accedere al servizio.", + # ), + # required=False, + # ) dove_rivolgersi = RelationList( title="Dove rivolgersi", @@ -483,7 +484,7 @@ class IServizio(model.Schema, IDesignPloneContentType): "canale_digitale", "canale_digitale_link", "canale_fisico", - "autenticazione", + # "autenticazione", "dove_rivolgersi", "dove_rivolgersi_extra", "prenota_appuntamento", @@ -536,9 +537,11 @@ class IServizio(model.Schema, IDesignPloneContentType): model.fieldset( "categorization", - fields=["codice_ipa", "settore_merceologico", "identificativo"], + fields=["identificativo"], ) + model.fieldset("informazioni", fields=["codice_ipa", "settore_merceologico"]) + # SearchableText fields textindexer.searchable("sottotitolo") textindexer.searchable("a_chi_si_rivolge") From ca4eef12f604f26fd40c49fd7e127d531e35ad21 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Fri, 3 Feb 2023 16:10:53 +0100 Subject: [PATCH 175/487] upgrade steps to remove useless metadata --- .../profiles/default/metadata.xml | 2 +- .../contenttypes/upgrades/configure.zcml | 11 ++++ .../plone/contenttypes/upgrades/upgrades.py | 57 +++++++++++++++++++ 3 files changed, 69 insertions(+), 1 deletion(-) diff --git a/src/design/plone/contenttypes/profiles/default/metadata.xml b/src/design/plone/contenttypes/profiles/default/metadata.xml index 58837395..2cc36758 100644 --- a/src/design/plone/contenttypes/profiles/default/metadata.xml +++ b/src/design/plone/contenttypes/profiles/default/metadata.xml @@ -1,6 +1,6 @@ - 7004 + 7005 profile-redturtle.bandi:default profile-collective.venue:default diff --git a/src/design/plone/contenttypes/upgrades/configure.zcml b/src/design/plone/contenttypes/upgrades/configure.zcml index 2f94613e..6be2764c 100644 --- a/src/design/plone/contenttypes/upgrades/configure.zcml +++ b/src/design/plone/contenttypes/upgrades/configure.zcml @@ -679,4 +679,15 @@ handler=".upgrades.update_ruolo_indexing" /> + + + diff --git a/src/design/plone/contenttypes/upgrades/upgrades.py b/src/design/plone/contenttypes/upgrades/upgrades.py index 98990c41..bd8eab91 100644 --- a/src/design/plone/contenttypes/upgrades/upgrades.py +++ b/src/design/plone/contenttypes/upgrades/upgrades.py @@ -1657,3 +1657,60 @@ def update_ruolo_indexing(context): for brain in brains: persona = brain.getObject() persona.reindexObject(idxs=idxs) + + +def fix_ctaxonomy_indexes_and_metadata(context): + logger.info(f"{colors.DARKCYAN} Fix taxonomy indexes {colors.ENDC}") # noqa + bad_names = [ + "taxonomy_person_life_events", + "taxonomy_business_events", + "taxonomy_temi_dataset", + "taxonomy_tipologia_documenti_albopretorio", + "taxonomy_tipologia_documento", + "taxonomy_tipologia_evento", + "taxonomy_tipologia_frequenza_aggiornamento", + "taxonomy_tipologia_incarico", + "taxonomy_tipologia_licenze", + "taxonomy_tipologia_luogo", + "taxonomy_tipologia_notizia", + "taxonomy_tipologia_organizzazione", + "taxonomy_tipologia_pdc", + "taxonomy_tipologia_stati_pratica", + ] + good_names = [name.replace("taxonomy_", "") for name in bad_names] + catalog = api.portal.get_tool(name="portal_catalog") + catalog_metadata = catalog.schema() + catalog_indexes = catalog.indexes() + + for name in bad_names: + # metadata + if name in catalog_metadata: + catalog.delColumn(name) + logger.info(f"{colors.GREEN} Remove {name} from metadata {colors.ENDC}") + + # indexes + if name in catalog_indexes: + catalog.delIndex(name) + logger.info(f"{colors.GREEN} Remove {name} from indexes {colors.ENDC}") + + context.runImportStepFromProfile( + "design.plone.contenttypes:taxonomy", "collective.taxonomy" + ) + brains = catalog.search( + portal_type=[ + "News Item", + "Event", + "Venue", + "Servizio", + "Documento", + "Dataset", + "UnitaOrganizzativa", + "Incarico", + "Pratica", + ] + ) + logger.info(f"{colors.GREEN} Reindex contents with taxonomies {colors.ENDC}") + for brain in brains: + obj = brain.getObject() + obj.reindexObject(idxs=good_names) + logger.info(f"{colors.GREEN} End of update {colors.ENDC}") From 21e5c59d5d033097587e8c969360bf3d06eb9ec1 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Fri, 3 Feb 2023 16:17:45 +0100 Subject: [PATCH 176/487] fix wrong use of replace --- src/design/plone/contenttypes/restapi/serializers/summary.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/design/plone/contenttypes/restapi/serializers/summary.py b/src/design/plone/contenttypes/restapi/serializers/summary.py index 1c2778fd..c78e95ef 100644 --- a/src/design/plone/contenttypes/restapi/serializers/summary.py +++ b/src/design/plone/contenttypes/restapi/serializers/summary.py @@ -59,7 +59,7 @@ def get_taxonomy_information(field_name, context, res): for token in res[field_name]: title = taxonomy_voc.inv_data.get(token) if title.startswith(PATH_SEPARATOR): - title.replace(PATH_SEPARATOR, "", 1) + title = title.replace(PATH_SEPARATOR, "", 1) fullterms.append({"token": token, "title": title}) res[field_name] = fullterms else: @@ -72,7 +72,7 @@ def get_fullterms(token): return None title = taxonomy_voc.inv_data.get(token) if title.startswith(PATH_SEPARATOR): - title.replace(PATH_SEPARATOR, "", 1) + title = title.replace(PATH_SEPARATOR, "", 1) return { "token": token, "title": title, From 2c03e69376a2f9c00444ea1ff99b37417aa3395d Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Fri, 3 Feb 2023 17:10:55 +0100 Subject: [PATCH 177/487] remove useless uo fields --- .../plone/contenttypes/behaviors/address.py | 28 ------------------- .../contenttypes/behaviors/configure.zcml | 8 ------ .../plone/contenttypes/behaviors/contatti.py | 15 +++++++++- .../contenttypes/profiles/default/catalog.xml | 2 +- .../profiles/default/metadata.xml | 2 +- .../default/types/UnitaOrganizzativa.xml | 6 ++-- .../tests/test_change_news_type.py | 7 ++--- .../tests/test_move_news_items_view.py | 7 ++--- .../contenttypes/upgrades/configure.zcml | 11 ++++++++ 9 files changed, 37 insertions(+), 49 deletions(-) diff --git a/src/design/plone/contenttypes/behaviors/address.py b/src/design/plone/contenttypes/behaviors/address.py index c2cd63ed..f8ce2a0e 100644 --- a/src/design/plone/contenttypes/behaviors/address.py +++ b/src/design/plone/contenttypes/behaviors/address.py @@ -1,7 +1,6 @@ # -*- coding: utf-8 -*- from collective.address.behaviors import IAddress from design.plone.contenttypes import _ -from design.plone.contenttypes.interfaces.unita_organizzativa import IUnitaOrganizzativa from plone.app.dexterity import textindexer from plone.autoform.interfaces import IFormFieldProvider from plone.dexterity.interfaces import IDexterityContent @@ -45,24 +44,6 @@ class IAddressLocal(model.Schema): textindexer.searchable("circoscrizione") -@provider(IFormFieldProvider) -class IAddressUnitaOrganizzativa(IAddress, IAddressNomeSede, IAddressLocal): - - model.fieldset( - "contatti", - label=_("contatti_label", default="Contatti"), - fields=[ - "nome_sede", - "street", - "zip_code", - "city", - "quartiere", - "circoscrizione", - "country", - ], - ) - - @provider(IFormFieldProvider) class IAddressVenue(IAddress, IAddressLocal): """""" @@ -100,15 +81,6 @@ class IAddressEvent(IAddress, IAddressNomeSede, IAddressLocal): ) -@implementer(IAddressUnitaOrganizzativa) -@adapter(IUnitaOrganizzativa) -class AddressUnitaOrganizzativa(object): - """ """ - - def __init__(self, context): - self.context = context - - @implementer(IAddressVenue) @adapter(IDexterityContent) class AddressVenue(object): diff --git a/src/design/plone/contenttypes/behaviors/configure.zcml b/src/design/plone/contenttypes/behaviors/configure.zcml index 6ad09bf8..204c1e03 100644 --- a/src/design/plone/contenttypes/behaviors/configure.zcml +++ b/src/design/plone/contenttypes/behaviors/configure.zcml @@ -195,14 +195,6 @@ for="plone.dexterity.interfaces.IDexterityContent" marker=".info_testata.IInfoTestata" /> - - + diff --git a/src/design/plone/contenttypes/profiles/default/metadata.xml b/src/design/plone/contenttypes/profiles/default/metadata.xml index 58837395..08d31f90 100644 --- a/src/design/plone/contenttypes/profiles/default/metadata.xml +++ b/src/design/plone/contenttypes/profiles/default/metadata.xml @@ -1,6 +1,6 @@ - 7004 + 7006 profile-redturtle.bandi:default profile-collective.venue:default diff --git a/src/design/plone/contenttypes/profiles/default/types/UnitaOrganizzativa.xml b/src/design/plone/contenttypes/profiles/default/types/UnitaOrganizzativa.xml index f4f705e3..1debf40a 100644 --- a/src/design/plone/contenttypes/profiles/default/types/UnitaOrganizzativa.xml +++ b/src/design/plone/contenttypes/profiles/default/types/UnitaOrganizzativa.xml @@ -50,8 +50,10 @@ - - + + diff --git a/src/design/plone/contenttypes/tests/test_change_news_type.py b/src/design/plone/contenttypes/tests/test_change_news_type.py index a7c37aac..44a7ae69 100644 --- a/src/design/plone/contenttypes/tests/test_change_news_type.py +++ b/src/design/plone/contenttypes/tests/test_change_news_type.py @@ -1,10 +1,9 @@ -from plone.app.testing import setRoles -from plone.app.testing import TEST_USER_ID -from plone import api - from design.plone.contenttypes.testing import ( DESIGN_PLONE_CONTENTTYPES_INTEGRATION_TESTING, ) +from plone import api +from plone.app.testing import setRoles +from plone.app.testing import TEST_USER_ID import unittest diff --git a/src/design/plone/contenttypes/tests/test_move_news_items_view.py b/src/design/plone/contenttypes/tests/test_move_news_items_view.py index 16786d8b..e0d45ed3 100644 --- a/src/design/plone/contenttypes/tests/test_move_news_items_view.py +++ b/src/design/plone/contenttypes/tests/test_move_news_items_view.py @@ -1,10 +1,9 @@ -from plone.app.testing import setRoles -from plone.app.testing import TEST_USER_ID -from plone import api - from design.plone.contenttypes.testing import ( DESIGN_PLONE_CONTENTTYPES_INTEGRATION_TESTING, ) +from plone import api +from plone.app.testing import setRoles +from plone.app.testing import TEST_USER_ID import unittest diff --git a/src/design/plone/contenttypes/upgrades/configure.zcml b/src/design/plone/contenttypes/upgrades/configure.zcml index 2f94613e..d0ca964f 100644 --- a/src/design/plone/contenttypes/upgrades/configure.zcml +++ b/src/design/plone/contenttypes/upgrades/configure.zcml @@ -679,4 +679,15 @@ handler=".upgrades.update_ruolo_indexing" /> + + + From f32de8e2dc3205ac3dfb74626bc5f50b24588a27 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Fri, 3 Feb 2023 17:15:05 +0100 Subject: [PATCH 178/487] fix typo in zcml --- src/design/plone/contenttypes/upgrades/configure.zcml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/design/plone/contenttypes/upgrades/configure.zcml b/src/design/plone/contenttypes/upgrades/configure.zcml index b9ce0b2e..b1fa3715 100644 --- a/src/design/plone/contenttypes/upgrades/configure.zcml +++ b/src/design/plone/contenttypes/upgrades/configure.zcml @@ -690,6 +690,8 @@ handler=".upgrades.fix_ctaxonomy_indexes_and_metadata" /> + From c88737dc0d6d3070709a5991a0e7ec0c8fa9ec1b Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Fri, 3 Feb 2023 17:16:26 +0100 Subject: [PATCH 179/487] update changes --- CHANGES.rst | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 6b19134d..88955b1d 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -5,7 +5,11 @@ Changelog 6.0.0a10 (unreleased) --------------------- -- Nothing changed yet. +- Update some tickets to show or hide fields + in Servizo and UO. + Fix problems with taxonomies + upgrade steps to clean catalog + [lucabel] 6.0.0a9 (2023-02-02) From a3f3a20d232b1ca41b6f5adfd62f36052d27419d Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Fri, 3 Feb 2023 17:16:36 +0100 Subject: [PATCH 180/487] Preparing release 6.0.0a10 --- CHANGES.rst | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 88955b1d..6cecadee 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -2,7 +2,7 @@ Changelog ========= -6.0.0a10 (unreleased) +6.0.0a10 (2023-02-03) --------------------- - Update some tickets to show or hide fields diff --git a/setup.py b/setup.py index f01e8ccb..e6111652 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.0.0a10.dev0", + version="6.0.0a10", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From bb1437d28e047d2bdb50812d06eb9ea7c7149cb5 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Fri, 3 Feb 2023 17:17:07 +0100 Subject: [PATCH 181/487] Back to development: 6.0.0a11 --- CHANGES.rst | 6 ++++++ setup.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 6cecadee..d52e276d 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -2,6 +2,12 @@ Changelog ========= +6.0.0a11 (unreleased) +--------------------- + +- Nothing changed yet. + + 6.0.0a10 (2023-02-03) --------------------- diff --git a/setup.py b/setup.py index e6111652..d1cee573 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.0.0a10", + version="6.0.0a11.dev0", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 5bf99ba319d5641931c63a75707810d1963917f5 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Fri, 3 Feb 2023 18:04:15 +0100 Subject: [PATCH 182/487] fix upgrade step --- .../plone/contenttypes/upgrades/upgrades.py | 53 +++++++++---------- 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/src/design/plone/contenttypes/upgrades/upgrades.py b/src/design/plone/contenttypes/upgrades/upgrades.py index bd8eab91..18068caa 100644 --- a/src/design/plone/contenttypes/upgrades/upgrades.py +++ b/src/design/plone/contenttypes/upgrades/upgrades.py @@ -337,9 +337,7 @@ def to_1016(context): sections.append({"title": item.title, "linkUrl": [item.UID()]}) settings = [{"rootPath": "/", "items": sections}] api.portal.set_registry_record( - "search_sections", - json.dumps(settings), - interface=IDesignPloneSettings, + "search_sections", json.dumps(settings), interface=IDesignPloneSettings, ) @@ -458,9 +456,7 @@ def to_3000(context): try: value = api.portal.get_registry_record(old_entry.format(field)) api.portal.set_registry_record( - field, - json.dumps({"it": value}), - interface=IDesignPloneSettings, + field, json.dumps({"it": value}), interface=IDesignPloneSettings, ) except Exception: continue @@ -1677,6 +1673,9 @@ def fix_ctaxonomy_indexes_and_metadata(context): "taxonomy_tipologia_pdc", "taxonomy_tipologia_stati_pratica", ] + import pdb + + pdb.set_trace() good_names = [name.replace("taxonomy_", "") for name in bad_names] catalog = api.portal.get_tool(name="portal_catalog") catalog_metadata = catalog.schema() @@ -1693,24 +1692,24 @@ def fix_ctaxonomy_indexes_and_metadata(context): catalog.delIndex(name) logger.info(f"{colors.GREEN} Remove {name} from indexes {colors.ENDC}") - context.runImportStepFromProfile( - "design.plone.contenttypes:taxonomy", "collective.taxonomy" - ) - brains = catalog.search( - portal_type=[ - "News Item", - "Event", - "Venue", - "Servizio", - "Documento", - "Dataset", - "UnitaOrganizzativa", - "Incarico", - "Pratica", - ] - ) - logger.info(f"{colors.GREEN} Reindex contents with taxonomies {colors.ENDC}") - for brain in brains: - obj = brain.getObject() - obj.reindexObject(idxs=good_names) - logger.info(f"{colors.GREEN} End of update {colors.ENDC}") + context.runImportStepFromProfile( + "design.plone.contenttypes:taxonomy", "collective.taxonomy" + ) + brains = catalog( + portal_type=[ + "News Item", + "Event", + "Venue", + "Servizio", + "Documento", + "Dataset", + "UnitaOrganizzativa", + "Incarico", + "Pratica", + ] + ) + logger.info(f"{colors.GREEN} Reindex contents with taxonomies {colors.ENDC}") + for brain in brains: + obj = brain.getObject() + obj.reindexObject(idxs=good_names) + logger.info(f"{colors.GREEN} End of update {colors.ENDC}") From deec738b6f84e451eaea87ee72405c862c10b9a5 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Fri, 3 Feb 2023 18:04:37 +0100 Subject: [PATCH 183/487] fix upgrade step --- CHANGES.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index d52e276d..e5599cf4 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -5,7 +5,7 @@ Changelog 6.0.0a11 (unreleased) --------------------- -- Nothing changed yet. +- Fix upgrade step. 6.0.0a10 (2023-02-03) From b89a8f19a6f743f2ad724045aa6d757de8df4699 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Fri, 3 Feb 2023 18:33:33 +0100 Subject: [PATCH 184/487] fix version --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index d1cee573..5acdbcfb 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.0.0a11.dev0", + version="6.0.0a11", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From e115e3dd286c90bb8615a40325ff243f4fe2a874 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Fri, 3 Feb 2023 18:34:34 +0100 Subject: [PATCH 185/487] Preparing release 6.0.0a11 --- CHANGES.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index e5599cf4..1e75e5bf 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -2,7 +2,7 @@ Changelog ========= -6.0.0a11 (unreleased) +6.0.0a11 (2023-02-03) --------------------- - Fix upgrade step. From b8ba0544492bc76272c5546a95e512d81785f08c Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Mon, 6 Feb 2023 09:18:29 +0100 Subject: [PATCH 186/487] update description for tempi scadenze --- CHANGES.rst | 7 +++++++ setup.py | 2 +- src/design/plone/contenttypes/interfaces/servizio.py | 2 +- src/design/plone/contenttypes/upgrades/upgrades.py | 10 ++++++---- 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 1e75e5bf..07472d65 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -2,6 +2,13 @@ Changelog ========= +6.0.0a12 (unreleased) +--------------------- + +- Cambiato descrizione tempi e scadenze + [lucabel] + + 6.0.0a11 (2023-02-03) --------------------- diff --git a/setup.py b/setup.py index 5acdbcfb..a20ae2e8 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.0.0a11", + version="6.0.0a12.dev0", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", diff --git a/src/design/plone/contenttypes/interfaces/servizio.py b/src/design/plone/contenttypes/interfaces/servizio.py index de00da9b..95b809f1 100644 --- a/src/design/plone/contenttypes/interfaces/servizio.py +++ b/src/design/plone/contenttypes/interfaces/servizio.py @@ -249,7 +249,7 @@ class IServizio(model.Schema, IDesignPloneContentType): description=_( "timeline_tempi_scadenze_help", default="Timeline tempi e scadenze del servizio: indicare per ogni " - "scadenza un titolo descrittivo ed un eventuale sottotitolo." + "scadenza un titolo descrittivo ed un eventuale sottotitolo. " "Per ogni scadenza, selezionare opzionalmente o l'intervallo (Campi" ' "Intervallo" e "Tipo Intervallo", es. "1" e "settimana"),' ' oppure direttamente una data di scadenza (campo: "Data Scadenza"' diff --git a/src/design/plone/contenttypes/upgrades/upgrades.py b/src/design/plone/contenttypes/upgrades/upgrades.py index 18068caa..2377b5e6 100644 --- a/src/design/plone/contenttypes/upgrades/upgrades.py +++ b/src/design/plone/contenttypes/upgrades/upgrades.py @@ -337,7 +337,9 @@ def to_1016(context): sections.append({"title": item.title, "linkUrl": [item.UID()]}) settings = [{"rootPath": "/", "items": sections}] api.portal.set_registry_record( - "search_sections", json.dumps(settings), interface=IDesignPloneSettings, + "search_sections", + json.dumps(settings), + interface=IDesignPloneSettings, ) @@ -456,7 +458,9 @@ def to_3000(context): try: value = api.portal.get_registry_record(old_entry.format(field)) api.portal.set_registry_record( - field, json.dumps({"it": value}), interface=IDesignPloneSettings, + field, + json.dumps({"it": value}), + interface=IDesignPloneSettings, ) except Exception: continue @@ -1673,9 +1677,7 @@ def fix_ctaxonomy_indexes_and_metadata(context): "taxonomy_tipologia_pdc", "taxonomy_tipologia_stati_pratica", ] - import pdb - pdb.set_trace() good_names = [name.replace("taxonomy_", "") for name in bad_names] catalog = api.portal.get_tool(name="portal_catalog") catalog_metadata = catalog.schema() From 52987219471b34ba3abc3b27b10fc4bf5ecb51ad Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Mon, 6 Feb 2023 09:19:26 +0100 Subject: [PATCH 187/487] Preparing release 6.0.0a12 --- CHANGES.rst | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 07472d65..d6b23525 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -2,7 +2,7 @@ Changelog ========= -6.0.0a12 (unreleased) +6.0.0a12 (2023-02-06) --------------------- - Cambiato descrizione tempi e scadenze diff --git a/setup.py b/setup.py index a20ae2e8..d7d42266 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.0.0a12.dev0", + version="6.0.0a12", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 8476ceeccfbe8e9f945366ed07b66156bfdaed35 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Mon, 6 Feb 2023 10:02:02 +0100 Subject: [PATCH 188/487] Back to development: 6.0.0a13 --- CHANGES.rst | 6 ++++++ setup.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index d6b23525..2f220219 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -2,6 +2,12 @@ Changelog ========= +6.0.0a13 (unreleased) +--------------------- + +- Nothing changed yet. + + 6.0.0a12 (2023-02-06) --------------------- diff --git a/setup.py b/setup.py index d7d42266..33aefa7f 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.0.0a12", + version="6.0.0a13.dev0", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 8c2cef6197f5312d2dfbb36cf31345ddd8f34214 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Mon, 6 Feb 2023 13:15:27 +0100 Subject: [PATCH 189/487] [fix] fixed get taxonomy --- .../plone/contenttypes/restapi/serializers/summary.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/design/plone/contenttypes/restapi/serializers/summary.py b/src/design/plone/contenttypes/restapi/serializers/summary.py index c78e95ef..78d81c57 100644 --- a/src/design/plone/contenttypes/restapi/serializers/summary.py +++ b/src/design/plone/contenttypes/restapi/serializers/summary.py @@ -57,20 +57,18 @@ def get_taxonomy_information(field_name, context, res): res[field_name] = getattr(context, field_name) for token in res[field_name]: - title = taxonomy_voc.inv_data.get(token) + title = taxonomy_voc.inv_data.get(token, None) if title.startswith(PATH_SEPARATOR): title = title.replace(PATH_SEPARATOR, "", 1) fullterms.append({"token": token, "title": title}) res[field_name] = fullterms else: - value = getattr(context, field_name) - # if not value: - # return res + value = getattr(context, field_name, None) def get_fullterms(token): if not token: return None - title = taxonomy_voc.inv_data.get(token) + title = taxonomy_voc.inv_data.get(token, None) if title.startswith(PATH_SEPARATOR): title = title.replace(PATH_SEPARATOR, "", 1) return { From 0c7daef2a8f7f935c7551140d73209e9f2ca553d Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Mon, 6 Feb 2023 13:21:24 +0100 Subject: [PATCH 190/487] update description; fix taxonomies and change field fieldset --- CHANGES.rst | 5 ++++- .../plone/contenttypes/behaviors/argomenti.py | 21 +++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 2f220219..a3a7f8db 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -5,7 +5,10 @@ Changelog 6.0.0a13 (unreleased) --------------------- -- Nothing changed yet. +- Fix field description + Fix bug with taxonomies for old contenttypes + Change field fieldset + [lucabel] 6.0.0a12 (2023-02-06) diff --git a/src/design/plone/contenttypes/behaviors/argomenti.py b/src/design/plone/contenttypes/behaviors/argomenti.py index 8acaffaa..096d6f1b 100644 --- a/src/design/plone/contenttypes/behaviors/argomenti.py +++ b/src/design/plone/contenttypes/behaviors/argomenti.py @@ -99,6 +99,27 @@ class IArgomentiNews(IArgomentiSchema): default=[], ) + correlato_in_evidenza = RelationList( + title=_("correlato_in_evidenza_label", default="Correlato in evidenza"), + description=_( + "correlato_in_evidenza_help", + default="Seleziona un correlato da mettere in evidenza per questo" + " contenuto.", + ), + value_type=RelationChoice( + title=_("Correlato in evidenza"), + vocabulary="plone.app.vocabularies.Catalog", + ), + required=False, + default=[], + ) + + model.fieldset( + "correlati", + label=_("correlati_label", default="Contenuti collegati"), + fields=["correlato_in_evidenza"], + ) + @provider(IFormFieldProvider) class IArgomentiEvento(IArgomentiSchema): From fc3026f1f993c0e0546348b00cee513ade83ee42 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Mon, 6 Feb 2023 13:21:33 +0100 Subject: [PATCH 191/487] Preparing release 6.0.0a13 --- CHANGES.rst | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index a3a7f8db..c4f68935 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -2,7 +2,7 @@ Changelog ========= -6.0.0a13 (unreleased) +6.0.0a13 (2023-02-06) --------------------- - Fix field description diff --git a/setup.py b/setup.py index 33aefa7f..c5835b65 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.0.0a13.dev0", + version="6.0.0a13", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 6a7c52c81b143db28b169e97432f99f6e4cebcce Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Mon, 6 Feb 2023 13:22:10 +0100 Subject: [PATCH 192/487] Back to development: 6.0.0a14 --- CHANGES.rst | 6 ++++++ setup.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index c4f68935..e79aff36 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -2,6 +2,12 @@ Changelog ========= +6.0.0a14 (unreleased) +--------------------- + +- Nothing changed yet. + + 6.0.0a13 (2023-02-06) --------------------- diff --git a/setup.py b/setup.py index c5835b65..172ef718 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.0.0a13", + version="6.0.0a14.dev0", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From d7a7f5aa26f110a1f12988a88058ab6225de0f6c Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Tue, 7 Feb 2023 17:28:06 +0100 Subject: [PATCH 193/487] [fix] fixed tipologia_notizia field --- .../contenttypes/patches/baseserializer.py | 15 ++++++----- .../restapi/serializers/dxcontent.py | 26 ++++++++++++++----- 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/src/design/plone/contenttypes/patches/baseserializer.py b/src/design/plone/contenttypes/patches/baseserializer.py index b717af07..c21665db 100644 --- a/src/design/plone/contenttypes/patches/baseserializer.py +++ b/src/design/plone/contenttypes/patches/baseserializer.py @@ -10,6 +10,7 @@ SerializeToJson and SerializeFolderToJson classes """ +from collective.taxonomy.interfaces import ITaxonomy from plone import api from plone.restapi.batching import HypermediaBatch from plone.restapi.deserializer import boolean_value @@ -19,6 +20,7 @@ from plone.restapi.serializer.dxcontent import SerializeToJson from Products.CMFCore.utils import getToolByName from zope.component import getMultiAdapter +from zope.component import getUtility from zope.i18n import translate @@ -30,13 +32,14 @@ def design_italia_serialize_to_json_call(self, version=None, include_items=True) result = original_serialize_to_json__call__( self, version=version, include_items=include_items ) + if self.context.portal_type == "News Item": - try: - tipologia_news = self.context.tipologia_notizia - except AttributeError: - # fallback if we don't have c.taxonomy configured yet - tipologia_news = self.context.tipologia_notizia - result["design_italia_meta_type"] = tipologia_news + taxonomy = getUtility(ITaxonomy, name="collective.taxonomy.tipologia_notizia") + taxonomy_voc = taxonomy.makeVocabulary(self.request.get("LANGUAGE")) + + result["design_italia_meta_type"] = taxonomy_voc.inv_data.get( + self.context.tipologia_notizia[0], None + ) else: result["design_italia_meta_type"] = translate( ttool[self.context.portal_type].Title(), context=self.request diff --git a/src/design/plone/contenttypes/restapi/serializers/dxcontent.py b/src/design/plone/contenttypes/restapi/serializers/dxcontent.py index 2dcfd28e..a5dc0a6b 100644 --- a/src/design/plone/contenttypes/restapi/serializers/dxcontent.py +++ b/src/design/plone/contenttypes/restapi/serializers/dxcontent.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +from collective.taxonomy.interfaces import ITaxonomy from design.plone.contenttypes.interfaces import IDesignPloneContenttypesLayer from plone import api from plone.dexterity.interfaces import IDexterityContainer @@ -9,6 +10,7 @@ ) from plone.restapi.serializer.dxcontent import SerializeToJson as BaseSerializer from zope.component import adapter +from zope.component import getUtility from zope.i18n import translate from zope.interface import implementer @@ -22,7 +24,14 @@ def __call__(self, version=None, include_items=True): ) ttool = api.portal.get_tool("portal_types") if self.context.portal_type == "News Item": - result["design_italia_meta_type"] = self.context.tipologia_notizia + taxonomy = getUtility( + ITaxonomy, name="collective.taxonomy.tipologia_notizia" + ) + taxonomy_voc = taxonomy.makeVocabulary(self.request.get("LANGUAGE")) + + result["design_italia_meta_type"] = taxonomy_voc.inv_data.get( + self.context.tipologia_notizia[0], None + ) else: result["design_italia_meta_type"] = translate( ttool[self.context.portal_type].Title(), context=self.request @@ -39,13 +48,16 @@ def __call__(self, version=None, include_items=True): ) result["@id"] = self.context.absolute_url() ttool = api.portal.get_tool("portal_types") + if self.context.portal_type == "News Item": - try: - tipologia_news = self.context.tipologia_notizia - except AttributeError: - # fallback if we don't have c.taxonomy configured yet - tipologia_news = self.context.tipologia_notizia - result["design_italia_meta_type"] = tipologia_news + taxonomy = getUtility( + ITaxonomy, name="collective.taxonomy.tipologia_notizia" + ) + taxonomy_voc = taxonomy.makeVocabulary(self.request.get("LANGUAGE")) + + result["design_italia_meta_type"] = taxonomy_voc.inv_data.get( + self.context.tipologia_notizia[0], None + ) else: result["design_italia_meta_type"] = translate( ttool[self.context.portal_type].Title(), context=self.request From bb12a4134a3033a073f27fbbc6827a88e2f6a232 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Wed, 8 Feb 2023 09:09:21 +0100 Subject: [PATCH 194/487] [fix] fixed summary --- .../contenttypes/restapi/serializers/summary.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/design/plone/contenttypes/restapi/serializers/summary.py b/src/design/plone/contenttypes/restapi/serializers/summary.py index 78d81c57..e3f23452 100644 --- a/src/design/plone/contenttypes/restapi/serializers/summary.py +++ b/src/design/plone/contenttypes/restapi/serializers/summary.py @@ -171,13 +171,16 @@ def is_get_call(self): def get_design_meta_type(self): ttool = api.portal.get_tool("portal_types") - if self.context.portal_type == "News Item": - # return translate( - # self.context.tipologia_notizia, - # domain="design.plone.contenttypes", - # context=self.request, - # ) - return self.context.tipologia_notizia + if self.context.portal_type == "News Item" and self.context.tipologia_notizia: + taxonomy = getUtility( + ITaxonomy, name="collective.taxonomy.tipologia_notizia" + ) + taxonomy_voc = taxonomy.makeVocabulary(self.request.get("LANGUAGE")) + title = taxonomy_voc.inv_data.get(self.context.tipologia_notizia[0], None) + if title.startswith(PATH_SEPARATOR): + title = title.replace(PATH_SEPARATOR, "", 1) + + return title else: return translate( ttool[self.context.portal_type].Title(), context=self.request From 02ccda8f186b7a702583ebc0e0ab896192503331 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Wed, 8 Feb 2023 09:16:15 +0100 Subject: [PATCH 195/487] [fix] minor fix --- .../contenttypes/patches/baseserializer.py | 15 ++++--- .../restapi/serializers/dxcontent.py | 41 ++++++++++++------- .../restapi/serializers/summary.py | 23 ++++++----- 3 files changed, 50 insertions(+), 29 deletions(-) diff --git a/src/design/plone/contenttypes/patches/baseserializer.py b/src/design/plone/contenttypes/patches/baseserializer.py index c21665db..2c14c1f3 100644 --- a/src/design/plone/contenttypes/patches/baseserializer.py +++ b/src/design/plone/contenttypes/patches/baseserializer.py @@ -10,6 +10,7 @@ SerializeToJson and SerializeFolderToJson classes """ +from collective.taxonomy import PATH_SEPARATOR from collective.taxonomy.interfaces import ITaxonomy from plone import api from plone.restapi.batching import HypermediaBatch @@ -34,12 +35,16 @@ def design_italia_serialize_to_json_call(self, version=None, include_items=True) ) if self.context.portal_type == "News Item": - taxonomy = getUtility(ITaxonomy, name="collective.taxonomy.tipologia_notizia") - taxonomy_voc = taxonomy.makeVocabulary(self.request.get("LANGUAGE")) + if self.context.tipologia_notizia: + taxonomy = getUtility( + ITaxonomy, name="collective.taxonomy.tipologia_notizia" + ) + taxonomy_voc = taxonomy.makeVocabulary(self.request.get("LANGUAGE")) - result["design_italia_meta_type"] = taxonomy_voc.inv_data.get( - self.context.tipologia_notizia[0], None - ) + title = taxonomy_voc.inv_data.get(self.context.tipologia_notizia[0], None) + + if title.startswith(PATH_SEPARATOR): + result["design_italia_meta_type"] = title.replace(PATH_SEPARATOR, "", 1) else: result["design_italia_meta_type"] = translate( ttool[self.context.portal_type].Title(), context=self.request diff --git a/src/design/plone/contenttypes/restapi/serializers/dxcontent.py b/src/design/plone/contenttypes/restapi/serializers/dxcontent.py index a5dc0a6b..5c0a3f61 100644 --- a/src/design/plone/contenttypes/restapi/serializers/dxcontent.py +++ b/src/design/plone/contenttypes/restapi/serializers/dxcontent.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +from collective.taxonomy import PATH_SEPARATOR from collective.taxonomy.interfaces import ITaxonomy from design.plone.contenttypes.interfaces import IDesignPloneContenttypesLayer from plone import api @@ -24,14 +25,20 @@ def __call__(self, version=None, include_items=True): ) ttool = api.portal.get_tool("portal_types") if self.context.portal_type == "News Item": - taxonomy = getUtility( - ITaxonomy, name="collective.taxonomy.tipologia_notizia" - ) - taxonomy_voc = taxonomy.makeVocabulary(self.request.get("LANGUAGE")) + if self.context.tipologia_notizia: + taxonomy = getUtility( + ITaxonomy, name="collective.taxonomy.tipologia_notizia" + ) + taxonomy_voc = taxonomy.makeVocabulary(self.request.get("LANGUAGE")) - result["design_italia_meta_type"] = taxonomy_voc.inv_data.get( - self.context.tipologia_notizia[0], None - ) + title = taxonomy_voc.inv_data.get( + self.context.tipologia_notizia[0], None + ) + + if title.startswith(PATH_SEPARATOR): + result["design_italia_meta_type"] = title.replace( + PATH_SEPARATOR, "", 1 + ) else: result["design_italia_meta_type"] = translate( ttool[self.context.portal_type].Title(), context=self.request @@ -50,14 +57,20 @@ def __call__(self, version=None, include_items=True): ttool = api.portal.get_tool("portal_types") if self.context.portal_type == "News Item": - taxonomy = getUtility( - ITaxonomy, name="collective.taxonomy.tipologia_notizia" - ) - taxonomy_voc = taxonomy.makeVocabulary(self.request.get("LANGUAGE")) + if self.context.tipologia_notizia: + taxonomy = getUtility( + ITaxonomy, name="collective.taxonomy.tipologia_notizia" + ) + taxonomy_voc = taxonomy.makeVocabulary(self.request.get("LANGUAGE")) - result["design_italia_meta_type"] = taxonomy_voc.inv_data.get( - self.context.tipologia_notizia[0], None - ) + title = taxonomy_voc.inv_data.get( + self.context.tipologia_notizia[0], None + ) + + if title.startswith(PATH_SEPARATOR): + result["design_italia_meta_type"] = title.replace( + PATH_SEPARATOR, "", 1 + ) else: result["design_italia_meta_type"] = translate( ttool[self.context.portal_type].Title(), context=self.request diff --git a/src/design/plone/contenttypes/restapi/serializers/summary.py b/src/design/plone/contenttypes/restapi/serializers/summary.py index e3f23452..12afbf02 100644 --- a/src/design/plone/contenttypes/restapi/serializers/summary.py +++ b/src/design/plone/contenttypes/restapi/serializers/summary.py @@ -171,16 +171,19 @@ def is_get_call(self): def get_design_meta_type(self): ttool = api.portal.get_tool("portal_types") - if self.context.portal_type == "News Item" and self.context.tipologia_notizia: - taxonomy = getUtility( - ITaxonomy, name="collective.taxonomy.tipologia_notizia" - ) - taxonomy_voc = taxonomy.makeVocabulary(self.request.get("LANGUAGE")) - title = taxonomy_voc.inv_data.get(self.context.tipologia_notizia[0], None) - if title.startswith(PATH_SEPARATOR): - title = title.replace(PATH_SEPARATOR, "", 1) - - return title + if self.context.portal_type == "News Item": + if self.context.tipologia_notizia: + taxonomy = getUtility( + ITaxonomy, name="collective.taxonomy.tipologia_notizia" + ) + taxonomy_voc = taxonomy.makeVocabulary(self.request.get("LANGUAGE")) + title = taxonomy_voc.inv_data.get( + self.context.tipologia_notizia[0], None + ) + if title.startswith(PATH_SEPARATOR): + title = title.replace(PATH_SEPARATOR, "", 1) + + return title else: return translate( ttool[self.context.portal_type].Title(), context=self.request From 5a0e8365ecd1d320d56304ebc6bbb7e1a07f938a Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Wed, 8 Feb 2023 11:49:19 +0100 Subject: [PATCH 196/487] [dev] black --- .pre-commit-config.yaml | 2 +- .../plone/contenttypes/behaviors/additional_help_infos.py | 1 - src/design/plone/contenttypes/behaviors/argomenti.py | 1 - .../plone/contenttypes/behaviors/dataset_correlati.py | 1 - src/design/plone/contenttypes/behaviors/geolocation.py | 3 --- src/design/plone/contenttypes/behaviors/luoghi_correlati.py | 1 - .../plone/contenttypes/behaviors/servizi_correlati.py | 1 - src/design/plone/contenttypes/behaviors/show_modified.py | 1 - .../plone/contenttypes/behaviors/strutture_correlate.py | 1 - .../contenttypes/browser/manage_content/check_servizi.py | 1 - src/design/plone/contenttypes/events/common.py | 1 - src/design/plone/contenttypes/indexers/bando.py | 1 - src/design/plone/contenttypes/interfaces/servizio.py | 1 - src/design/plone/contenttypes/patches/patches.py | 1 - .../plone/contenttypes/restapi/deserializers/documento.py | 1 - src/design/plone/contenttypes/restapi/deserializers/news.py | 1 - .../plone/contenttypes/restapi/deserializers/persona.py | 1 - .../plone/contenttypes/restapi/deserializers/servizio.py | 1 - .../restapi/deserializers/unitaorganizzativa.py | 1 - .../plone/contenttypes/restapi/deserializers/venue.py | 2 -- .../plone/contenttypes/restapi/services/trasparenza/get.py | 1 - src/design/plone/contenttypes/restapi/types/adapters.py | 1 - src/design/plone/contenttypes/schema_overrides.py | 1 - .../contenttypes/tests/test_behavior_descrizione_estesa.py | 2 -- src/design/plone/contenttypes/tests/test_behavior_luogo.py | 1 - .../plone/contenttypes/tests/test_behavior_show_modified.py | 3 --- .../plone/contenttypes/tests/test_behavior_update_note.py | 2 -- .../plone/contenttypes/tests/test_change_news_type.py | 1 - src/design/plone/contenttypes/tests/test_ct_bando.py | 1 - src/design/plone/contenttypes/tests/test_ct_documento.py | 1 - src/design/plone/contenttypes/tests/test_ct_event.py | 1 - src/design/plone/contenttypes/tests/test_ct_luogo.py | 1 - src/design/plone/contenttypes/tests/test_ct_news.py | 1 - src/design/plone/contenttypes/tests/test_ct_servizio.py | 6 ------ .../plone/contenttypes/tests/test_move_news_items_view.py | 1 - .../contenttypes/tests/test_relateditems_with_dates.py | 2 -- .../contenttypes/tests/test_settings_controlpanel_api.py | 1 - src/design/plone/contenttypes/tests/test_setup.py | 1 - .../plone/contenttypes/tests/test_summary_serializer.py | 5 ----- .../plone/contenttypes/tests/test_uo_summary_serializer.py | 1 - src/design/plone/contenttypes/upgrades/upgrades.py | 6 ------ .../contenttypes/vocabularies/controlapanel_vocabularies.py | 2 -- .../contenttypes/vocabularies/reference_vocabularies.py | 4 ---- 43 files changed, 1 insertion(+), 69 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 39c0d06c..53e5542e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -14,7 +14,7 @@ repos: - id: end-of-file-fixer - id: check-yaml - repo: https://github.com/psf/black - rev: 22.6.0 + rev: 23.1.0 hooks: - id: black # args: ["--line-length=88", "--check", "--diff", "--force-exclude=migrations", "src/"] diff --git a/src/design/plone/contenttypes/behaviors/additional_help_infos.py b/src/design/plone/contenttypes/behaviors/additional_help_infos.py index e5b93c7b..10f11f36 100644 --- a/src/design/plone/contenttypes/behaviors/additional_help_infos.py +++ b/src/design/plone/contenttypes/behaviors/additional_help_infos.py @@ -14,7 +14,6 @@ # e bisognerebbe metterlo unifrme per tutti in barba alle linee guida @provider(IFormFieldProvider) class IAdditionalHelpInfos(model.Schema): - ulteriori_informazioni = BlocksField( title=_("ulteriori_informazioni", default="Ulteriori informazioni"), description=_( diff --git a/src/design/plone/contenttypes/behaviors/argomenti.py b/src/design/plone/contenttypes/behaviors/argomenti.py index 096d6f1b..c35caa97 100644 --- a/src/design/plone/contenttypes/behaviors/argomenti.py +++ b/src/design/plone/contenttypes/behaviors/argomenti.py @@ -143,7 +143,6 @@ class IArgomentiEvento(IArgomentiSchema): @provider(IFormFieldProvider) class IArgomentiServizio(IArgomentiSchema): - tassonomia_argomenti = RelationList( title=_("tassonomia_argomenti_label", default="Argomenti"), description=_( diff --git a/src/design/plone/contenttypes/behaviors/dataset_correlati.py b/src/design/plone/contenttypes/behaviors/dataset_correlati.py index 2c402745..ac2fe90e 100644 --- a/src/design/plone/contenttypes/behaviors/dataset_correlati.py +++ b/src/design/plone/contenttypes/behaviors/dataset_correlati.py @@ -15,7 +15,6 @@ # TODO: merge with NEWS @provider(IFormFieldProvider) class IDatasetCorrelati(model.Schema): - dataset_correlati = RelationList( title=_("dataset_correlati_label", default="Dataset correlati"), description=_( diff --git a/src/design/plone/contenttypes/behaviors/geolocation.py b/src/design/plone/contenttypes/behaviors/geolocation.py index 4ca75720..71c00498 100644 --- a/src/design/plone/contenttypes/behaviors/geolocation.py +++ b/src/design/plone/contenttypes/behaviors/geolocation.py @@ -13,7 +13,6 @@ @provider(IFormFieldProvider) class IGeolocatableUnitaOrganizzativa(IGeolocatable): - model.fieldset( "contatti", label=_("contatti_label", default="Contatti"), @@ -23,7 +22,6 @@ class IGeolocatableUnitaOrganizzativa(IGeolocatable): @provider(IFormFieldProvider) class IGeolocatableVenue(IGeolocatable): - model.fieldset( "dove", label=_("dove_label", default="Dove"), fields=["geolocation"] ) @@ -31,7 +29,6 @@ class IGeolocatableVenue(IGeolocatable): @provider(IFormFieldProvider) class IGeolocatableEvent(IGeolocatable): - model.fieldset( "luogo", label=_("luogo_label", default="Luogo"), diff --git a/src/design/plone/contenttypes/behaviors/luoghi_correlati.py b/src/design/plone/contenttypes/behaviors/luoghi_correlati.py index 4b0a8531..da545131 100644 --- a/src/design/plone/contenttypes/behaviors/luoghi_correlati.py +++ b/src/design/plone/contenttypes/behaviors/luoghi_correlati.py @@ -14,7 +14,6 @@ # TODO: merge with NEWS class ILuoghiCorrelatiSchema(model.Schema): - luoghi_correlati = RelationList( title=_("luoghi_correlati_label", default="Luoghi correlati"), description=_( diff --git a/src/design/plone/contenttypes/behaviors/servizi_correlati.py b/src/design/plone/contenttypes/behaviors/servizi_correlati.py index e8fb2b24..74828cbf 100644 --- a/src/design/plone/contenttypes/behaviors/servizi_correlati.py +++ b/src/design/plone/contenttypes/behaviors/servizi_correlati.py @@ -15,7 +15,6 @@ # TODO: merge with NEWS @provider(IFormFieldProvider) class IServiziCorrelati(model.Schema): - servizi_correlati = RelationList( title=_("servizi_correlati_label", default="Servizi correlati"), description=_( diff --git a/src/design/plone/contenttypes/behaviors/show_modified.py b/src/design/plone/contenttypes/behaviors/show_modified.py index 691fcde2..daad6607 100644 --- a/src/design/plone/contenttypes/behaviors/show_modified.py +++ b/src/design/plone/contenttypes/behaviors/show_modified.py @@ -19,7 +19,6 @@ def showModifiedDefaultValue(context=None): @provider(IFormFieldProvider) class IShowModified(model.Schema): - show_modified = schema.Bool( title=_("show_modified_label", default="Mostra la data di ultima modifica"), description=_( diff --git a/src/design/plone/contenttypes/behaviors/strutture_correlate.py b/src/design/plone/contenttypes/behaviors/strutture_correlate.py index c9174a9e..14c21654 100644 --- a/src/design/plone/contenttypes/behaviors/strutture_correlate.py +++ b/src/design/plone/contenttypes/behaviors/strutture_correlate.py @@ -14,7 +14,6 @@ @provider(IFormFieldProvider) class IStruttureCorrelate(model.Schema): - strutture_politiche = RelationList( title="Strutture politiche coinvolte", default=[], diff --git a/src/design/plone/contenttypes/browser/manage_content/check_servizi.py b/src/design/plone/contenttypes/browser/manage_content/check_servizi.py index 7063c0c3..fcabd07b 100644 --- a/src/design/plone/contenttypes/browser/manage_content/check_servizi.py +++ b/src/design/plone/contenttypes/browser/manage_content/check_servizi.py @@ -26,7 +26,6 @@ class ISearchForm(Interface): @implementer(ISearchForm) class CheckServizi(form.Form): - ignoreContext = True # template = ViewPageTemplateFile("templates/check_servizi.pt") prefix = "" diff --git a/src/design/plone/contenttypes/events/common.py b/src/design/plone/contenttypes/events/common.py index 6f0f4d03..dcbbb620 100644 --- a/src/design/plone/contenttypes/events/common.py +++ b/src/design/plone/contenttypes/events/common.py @@ -2,7 +2,6 @@ def onModify(context, event): - for description in event.descriptions: if "IBasic.title" in getattr(description, "attributes", []): for child in context.listFolderContents(): diff --git a/src/design/plone/contenttypes/indexers/bando.py b/src/design/plone/contenttypes/indexers/bando.py index 27eb198c..582e3d5b 100644 --- a/src/design/plone/contenttypes/indexers/bando.py +++ b/src/design/plone/contenttypes/indexers/bando.py @@ -11,5 +11,4 @@ def ufficio_responsabile_bando(context, **kw): @indexer(IBandoAgidSchema) def Subject_bando(context, **kw): - return context.Subject diff --git a/src/design/plone/contenttypes/interfaces/servizio.py b/src/design/plone/contenttypes/interfaces/servizio.py index 95b809f1..721f80fb 100644 --- a/src/design/plone/contenttypes/interfaces/servizio.py +++ b/src/design/plone/contenttypes/interfaces/servizio.py @@ -16,7 +16,6 @@ class ITempiEScadenzeValueSchema(model.Schema): - milestone = schema.TextLine( title=_("milestone_label", default="Titolo"), required=True, diff --git a/src/design/plone/contenttypes/patches/patches.py b/src/design/plone/contenttypes/patches/patches.py index d7798765..e55baa43 100644 --- a/src/design/plone/contenttypes/patches/patches.py +++ b/src/design/plone/contenttypes/patches/patches.py @@ -2,7 +2,6 @@ def eea_api_taxonomy_taxonomy_call(self, context): - if not self.data: return Vocabulary(self.name, {}, {}, {}, 2) diff --git a/src/design/plone/contenttypes/restapi/deserializers/documento.py b/src/design/plone/contenttypes/restapi/deserializers/documento.py index ee9a25eb..b29ed8e9 100644 --- a/src/design/plone/contenttypes/restapi/deserializers/documento.py +++ b/src/design/plone/contenttypes/restapi/deserializers/documento.py @@ -54,7 +54,6 @@ class DeserializeDocumentoFromJson(DeserializeFromJson): def __call__( self, validate_all=False, data=None, create=False ): # noqa: ignore=C901 - if data is None: data = json_body(self.request) diff --git a/src/design/plone/contenttypes/restapi/deserializers/news.py b/src/design/plone/contenttypes/restapi/deserializers/news.py index c69e3ec8..bb374a58 100644 --- a/src/design/plone/contenttypes/restapi/deserializers/news.py +++ b/src/design/plone/contenttypes/restapi/deserializers/news.py @@ -53,7 +53,6 @@ class DeserializeNewsFromJson(DeserializeFromJson): def __call__( self, validate_all=False, data=None, create=False ): # noqa: ignore=C901 - if data is None: data = json_body(self.request) diff --git a/src/design/plone/contenttypes/restapi/deserializers/persona.py b/src/design/plone/contenttypes/restapi/deserializers/persona.py index de734fda..ea4248a5 100644 --- a/src/design/plone/contenttypes/restapi/deserializers/persona.py +++ b/src/design/plone/contenttypes/restapi/deserializers/persona.py @@ -23,7 +23,6 @@ def __init__(self, context, request): def __call__( self, validate_all=False, data=None, create=False ): # noqa: ignore=C901 - if data is None: data = json_body(self.request) if data: diff --git a/src/design/plone/contenttypes/restapi/deserializers/servizio.py b/src/design/plone/contenttypes/restapi/deserializers/servizio.py index 9687d776..1a861216 100644 --- a/src/design/plone/contenttypes/restapi/deserializers/servizio.py +++ b/src/design/plone/contenttypes/restapi/deserializers/servizio.py @@ -57,7 +57,6 @@ class DeserializeServizioFromJson(DeserializeFromJson): def __call__( self, validate_all=False, data=None, create=False ): # noqa: ignore=C901 - if data is None: data = json_body(self.request) diff --git a/src/design/plone/contenttypes/restapi/deserializers/unitaorganizzativa.py b/src/design/plone/contenttypes/restapi/deserializers/unitaorganizzativa.py index 0ba28ce1..c7094709 100644 --- a/src/design/plone/contenttypes/restapi/deserializers/unitaorganizzativa.py +++ b/src/design/plone/contenttypes/restapi/deserializers/unitaorganizzativa.py @@ -51,7 +51,6 @@ class DeserializeUnitaOrganizzativaFromJson(DeserializeFromJson): def __call__( self, validate_all=False, data=None, create=False ): # noqa: ignore=C901 - if data is None: data = json_body(self.request) diff --git a/src/design/plone/contenttypes/restapi/deserializers/venue.py b/src/design/plone/contenttypes/restapi/deserializers/venue.py index f46ebead..11cadff4 100644 --- a/src/design/plone/contenttypes/restapi/deserializers/venue.py +++ b/src/design/plone/contenttypes/restapi/deserializers/venue.py @@ -51,7 +51,6 @@ class DeserializeLuogoFromJson(DeserializeFromJson): def __call__( self, validate_all=False, data=None, create=False ): # noqa: ignore=C901 - if data is None: data = json_body(self.request) @@ -105,7 +104,6 @@ def __call__( errors.append(new_error("Il campo {} è obbligatorio".format(field))) if is_patch: - # Title validation if "title" in data and not title: errors.append(new_error("Il titolo del luogo è obbligatorio")) diff --git a/src/design/plone/contenttypes/restapi/services/trasparenza/get.py b/src/design/plone/contenttypes/restapi/services/trasparenza/get.py index 21ce832c..2f1f9856 100644 --- a/src/design/plone/contenttypes/restapi/services/trasparenza/get.py +++ b/src/design/plone/contenttypes/restapi/services/trasparenza/get.py @@ -87,7 +87,6 @@ def get_trasparenza_data(self, context=None): ) data = serializer() if child.portal_type == "Document": - if IFolderish.providedBy(child): children = [ x diff --git a/src/design/plone/contenttypes/restapi/types/adapters.py b/src/design/plone/contenttypes/restapi/types/adapters.py index 70b4799a..dbcde152 100644 --- a/src/design/plone/contenttypes/restapi/types/adapters.py +++ b/src/design/plone/contenttypes/restapi/types/adapters.py @@ -22,7 +22,6 @@ @implementer(IJsonSchemaProvider) class LeadImageJsonSchemaProvider(ObjectJsonSchemaProvider): def get_size_vocabulary(self): - factory = getUtility( IVocabularyFactory, "design.plone.vocabularies.leadimage_dimension" ) diff --git a/src/design/plone/contenttypes/schema_overrides.py b/src/design/plone/contenttypes/schema_overrides.py index b8658028..589895d0 100644 --- a/src/design/plone/contenttypes/schema_overrides.py +++ b/src/design/plone/contenttypes/schema_overrides.py @@ -18,7 +18,6 @@ def __init__(self, schema): self.schema = schema def __call__(self): - if self.schema.getName() == "IRelatedItems": fieldset = Fieldset( "correlati", diff --git a/src/design/plone/contenttypes/tests/test_behavior_descrizione_estesa.py b/src/design/plone/contenttypes/tests/test_behavior_descrizione_estesa.py index 30d71457..3386e56f 100644 --- a/src/design/plone/contenttypes/tests/test_behavior_descrizione_estesa.py +++ b/src/design/plone/contenttypes/tests/test_behavior_descrizione_estesa.py @@ -15,7 +15,6 @@ class TestDescrizioneEstesaBehavior(unittest.TestCase): - layer = DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING def setUp(self): @@ -32,7 +31,6 @@ def tearDown(self): self.api_session.close() def test_descrizione_estesa_indexed(self): - # Servizio have design.plone.contenttypes.behavior.descrizione_estesa # behavior servizio = api.content.create( diff --git a/src/design/plone/contenttypes/tests/test_behavior_luogo.py b/src/design/plone/contenttypes/tests/test_behavior_luogo.py index 5942c631..14d959d4 100644 --- a/src/design/plone/contenttypes/tests/test_behavior_luogo.py +++ b/src/design/plone/contenttypes/tests/test_behavior_luogo.py @@ -12,7 +12,6 @@ class LuogoBehaviorIndexerFunctionalTest(unittest.TestCase): - layer = DESIGN_PLONE_CONTENTTYPES_FUNCTIONAL_TESTING def setUp(self): diff --git a/src/design/plone/contenttypes/tests/test_behavior_show_modified.py b/src/design/plone/contenttypes/tests/test_behavior_show_modified.py index edef403d..b8eecc1c 100644 --- a/src/design/plone/contenttypes/tests/test_behavior_show_modified.py +++ b/src/design/plone/contenttypes/tests/test_behavior_show_modified.py @@ -17,7 +17,6 @@ class TestShowModifiedBehavior(unittest.TestCase): - layer = DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING def setUp(self): @@ -41,7 +40,6 @@ def tearDown(self): transaction.commit() def test_if_not_set_return_site_default(self): - page = api.content.create( container=self.portal, type="Document", @@ -65,7 +63,6 @@ def test_if_not_set_return_site_default(self): self.assertFalse(resp.json().get("show_modified", None)) def test_if_set_will_override_default(self): - page = api.content.create( container=self.portal, type="Document", diff --git a/src/design/plone/contenttypes/tests/test_behavior_update_note.py b/src/design/plone/contenttypes/tests/test_behavior_update_note.py index 992ffb45..dba7e57a 100644 --- a/src/design/plone/contenttypes/tests/test_behavior_update_note.py +++ b/src/design/plone/contenttypes/tests/test_behavior_update_note.py @@ -16,7 +16,6 @@ class TestUpdateNoteBehavior(unittest.TestCase): - layer = DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING def setUp(self): @@ -33,7 +32,6 @@ def tearDown(self): self.api_session.close() def test_is_enabled_in_bando(self): - portal_types = api.portal.get_tool(name="portal_types") self.assertIn( "design.plone.contenttypes.behavior.update_note", diff --git a/src/design/plone/contenttypes/tests/test_change_news_type.py b/src/design/plone/contenttypes/tests/test_change_news_type.py index 44a7ae69..bc26b4f0 100644 --- a/src/design/plone/contenttypes/tests/test_change_news_type.py +++ b/src/design/plone/contenttypes/tests/test_change_news_type.py @@ -9,7 +9,6 @@ class MoveNewsItemView(unittest.TestCase): - layer = DESIGN_PLONE_CONTENTTYPES_INTEGRATION_TESTING def setUp(self): diff --git a/src/design/plone/contenttypes/tests/test_ct_bando.py b/src/design/plone/contenttypes/tests/test_ct_bando.py index e6e524b0..a11587df 100644 --- a/src/design/plone/contenttypes/tests/test_ct_bando.py +++ b/src/design/plone/contenttypes/tests/test_ct_bando.py @@ -39,7 +39,6 @@ def test_disabled_default_ente(self): self.assertEqual(default_ente, ()) def test_bando_substructure_created(self): - bando = api.content.create(container=self.portal, type="Bando", title="Bando") self.assertIn("documenti", bando.keys()) diff --git a/src/design/plone/contenttypes/tests/test_ct_documento.py b/src/design/plone/contenttypes/tests/test_ct_documento.py index 1fe11213..6ec688a1 100644 --- a/src/design/plone/contenttypes/tests/test_ct_documento.py +++ b/src/design/plone/contenttypes/tests/test_ct_documento.py @@ -60,7 +60,6 @@ def test_event_addable_types(self): class TestDocumentoApi(unittest.TestCase): - layer = DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING def setUp(self): diff --git a/src/design/plone/contenttypes/tests/test_ct_event.py b/src/design/plone/contenttypes/tests/test_ct_event.py index d1f64ca8..600c8442 100644 --- a/src/design/plone/contenttypes/tests/test_ct_event.py +++ b/src/design/plone/contenttypes/tests/test_ct_event.py @@ -66,7 +66,6 @@ def test_event_addable_types(self): class TestEventApi(unittest.TestCase): - layer = DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING def setUp(self): diff --git a/src/design/plone/contenttypes/tests/test_ct_luogo.py b/src/design/plone/contenttypes/tests/test_ct_luogo.py index 815ff171..01d89774 100644 --- a/src/design/plone/contenttypes/tests/test_ct_luogo.py +++ b/src/design/plone/contenttypes/tests/test_ct_luogo.py @@ -59,7 +59,6 @@ def test_luogo_ct_title(self): class TestLuogoApi(unittest.TestCase): - layer = DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING def setUp(self): diff --git a/src/design/plone/contenttypes/tests/test_ct_news.py b/src/design/plone/contenttypes/tests/test_ct_news.py index a72f38a9..47c0f94d 100644 --- a/src/design/plone/contenttypes/tests/test_ct_news.py +++ b/src/design/plone/contenttypes/tests/test_ct_news.py @@ -63,7 +63,6 @@ def test_news_item_addable_types(self): class TestNewsApi(unittest.TestCase): - layer = DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING def setUp(self): diff --git a/src/design/plone/contenttypes/tests/test_ct_servizio.py b/src/design/plone/contenttypes/tests/test_ct_servizio.py index 61720655..0274a5c8 100644 --- a/src/design/plone/contenttypes/tests/test_ct_servizio.py +++ b/src/design/plone/contenttypes/tests/test_ct_servizio.py @@ -124,7 +124,6 @@ def test_sottotitolo_indexed_in_searchabletext(self): self.assertEqual(res[0].UID, servizio.UID()) def test_a_chi_si_rivolge_indexed_in_searchabletext(self): - #  Servizio is the only ct with this field servizio = api.content.create( container=self.portal, @@ -139,7 +138,6 @@ def test_a_chi_si_rivolge_indexed_in_searchabletext(self): self.assertEqual(res[0].UID, servizio.UID()) def test_chi_puo_presentare_indexed_in_searchabletext(self): - #  Servizio is the only ct with this field servizio = api.content.create( container=self.portal, @@ -154,7 +152,6 @@ def test_chi_puo_presentare_indexed_in_searchabletext(self): self.assertEqual(res[0].UID, servizio.UID()) def test_come_si_fa_indexed_in_searchabletext(self): - #  Servizio is the only ct with this field servizio = api.content.create( container=self.portal, @@ -169,7 +166,6 @@ def test_come_si_fa_indexed_in_searchabletext(self): self.assertEqual(res[0].UID, servizio.UID()) def test_cosa_si_ottiene_indexed_in_searchabletext(self): - #  Servizio is the only ct with this field servizio = api.content.create( container=self.portal, @@ -184,7 +180,6 @@ def test_cosa_si_ottiene_indexed_in_searchabletext(self): self.assertEqual(res[0].UID, servizio.UID()) def test_cosa_serve_indexed_in_searchabletext(self): - #  Servizio is the only ct with this field servizio = api.content.create( container=self.portal, @@ -199,7 +194,6 @@ def test_cosa_serve_indexed_in_searchabletext(self): self.assertEqual(res[0].UID, servizio.UID()) def test_ulteriori_informazioni_indexed_in_searchabletext(self): - #  Servizio is the only ct with this field servizio = api.content.create( container=self.portal, diff --git a/src/design/plone/contenttypes/tests/test_move_news_items_view.py b/src/design/plone/contenttypes/tests/test_move_news_items_view.py index e0d45ed3..3dc94320 100644 --- a/src/design/plone/contenttypes/tests/test_move_news_items_view.py +++ b/src/design/plone/contenttypes/tests/test_move_news_items_view.py @@ -9,7 +9,6 @@ class MoveNewsItemView(unittest.TestCase): - layer = DESIGN_PLONE_CONTENTTYPES_INTEGRATION_TESTING def setUp(self): diff --git a/src/design/plone/contenttypes/tests/test_relateditems_with_dates.py b/src/design/plone/contenttypes/tests/test_relateditems_with_dates.py index 0e24dc77..96e86691 100644 --- a/src/design/plone/contenttypes/tests/test_relateditems_with_dates.py +++ b/src/design/plone/contenttypes/tests/test_relateditems_with_dates.py @@ -19,7 +19,6 @@ class VocabulariesControlpanelTest(unittest.TestCase): - layer = DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING def setUp(self): @@ -110,7 +109,6 @@ def test_api_do_return_start_end_on_events(self): def test_api_do_not_return_related_items_with_effective_date_in_future_for_anon( self, ): - present = api.content.create( container=self.portal, type="Document", title="present" ) diff --git a/src/design/plone/contenttypes/tests/test_settings_controlpanel_api.py b/src/design/plone/contenttypes/tests/test_settings_controlpanel_api.py index 8590dca9..cb7213d3 100644 --- a/src/design/plone/contenttypes/tests/test_settings_controlpanel_api.py +++ b/src/design/plone/contenttypes/tests/test_settings_controlpanel_api.py @@ -12,7 +12,6 @@ class SettingsControlpanelTest(unittest.TestCase): - layer = DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING def setUp(self): diff --git a/src/design/plone/contenttypes/tests/test_setup.py b/src/design/plone/contenttypes/tests/test_setup.py index 6664220c..e019c31b 100644 --- a/src/design/plone/contenttypes/tests/test_setup.py +++ b/src/design/plone/contenttypes/tests/test_setup.py @@ -49,7 +49,6 @@ def test_show_modified_default_enabled(self): class TestUninstall(unittest.TestCase): - layer = DESIGN_PLONE_CONTENTTYPES_INTEGRATION_TESTING def setUp(self): diff --git a/src/design/plone/contenttypes/tests/test_summary_serializer.py b/src/design/plone/contenttypes/tests/test_summary_serializer.py index f3b20443..2c2a8eba 100644 --- a/src/design/plone/contenttypes/tests/test_summary_serializer.py +++ b/src/design/plone/contenttypes/tests/test_summary_serializer.py @@ -20,7 +20,6 @@ class SummarySerializerTest(unittest.TestCase): - layer = DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING def setUp(self): @@ -44,7 +43,6 @@ def tearDown(self): self.api_session.close() def test_has_children_returned_in_get_content(self): - api.content.create(container=self.document, type="Document", title="empty") api.content.create(container=self.document, type="Document", title="filled") @@ -65,7 +63,6 @@ def test_has_children_returned_in_get_content(self): self.assertTrue(items[1]["has_children"]) def test_has_children_not_returned_in_searches(self): - api.content.create(container=self.document, type="Document", title="empty") api.content.create(container=self.document, type="Document", title="filled") @@ -88,7 +85,6 @@ def test_has_children_not_returned_in_searches(self): self.assertNotIn("has_children", items[1]) def test_has_children_not_returned_in_backend_serialization(self): - empty = api.content.create( container=self.document, type="Document", title="empty" ) @@ -151,7 +147,6 @@ def test_summary_return_formatted_remote_url_for_links(self): self.assertEqual(serializer["remoteUrl"], self.document.absolute_url()) def test_summary_return_persona_role(self): - api.content.create( container=self.portal, type="Persona", title="John Doe", ruolo="unknown" ) diff --git a/src/design/plone/contenttypes/tests/test_uo_summary_serializer.py b/src/design/plone/contenttypes/tests/test_uo_summary_serializer.py index 3b0e35b8..77086d50 100644 --- a/src/design/plone/contenttypes/tests/test_uo_summary_serializer.py +++ b/src/design/plone/contenttypes/tests/test_uo_summary_serializer.py @@ -13,7 +13,6 @@ class UOSummarySerializerTest(unittest.TestCase): - layer = DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING def setUp(self): diff --git a/src/design/plone/contenttypes/upgrades/upgrades.py b/src/design/plone/contenttypes/upgrades/upgrades.py index 2377b5e6..d5cf2990 100644 --- a/src/design/plone/contenttypes/upgrades/upgrades.py +++ b/src/design/plone/contenttypes/upgrades/upgrades.py @@ -95,7 +95,6 @@ def remap_fields(mapping): def to_1001(context): - update_types(context) # cleanup event behaviors @@ -124,7 +123,6 @@ def to_1001(context): def to_1003(context): - update_types(context) mapping = { @@ -957,7 +955,6 @@ def to_5400(context): def to_5410(context): - # cleanup Document behaviors portal_types = api.portal.get_tool(name="portal_types") behaviors = portal_types["Document"].behaviors @@ -1223,7 +1220,6 @@ class colors(object): def to_7001(context): - installer = get_installer(context=api.portal.get()) installer.install_product("eea.api.taxonomy") logger.info( @@ -1304,7 +1300,6 @@ def create_incarico_for_persona(context): "Altro tipo": "altro", } for brain in brains: - persona = brain.getObject() incarichi_folder = persona["incarichi"] @@ -1596,7 +1591,6 @@ def update_taxonomies_on_blocks(context): for block in blocks.values(): if block.get("@type", "") == "listing": for query in block.get("querystring", {}).get("query", []): - if query["i"] in [ "tipologia_notizia", "tipologia_documento", diff --git a/src/design/plone/contenttypes/vocabularies/controlapanel_vocabularies.py b/src/design/plone/contenttypes/vocabularies/controlapanel_vocabularies.py index 857426da..8c762911 100644 --- a/src/design/plone/contenttypes/vocabularies/controlapanel_vocabularies.py +++ b/src/design/plone/contenttypes/vocabularies/controlapanel_vocabularies.py @@ -15,7 +15,6 @@ class BaseVocabulary(object): def __call__(self, context): - values = get_settings_for_language(field=self.field) if not values: return SimpleVocabulary([]) @@ -34,7 +33,6 @@ class LeadImageDimension(BaseVocabulary): field = "lead_image_dimension" def __call__(self, context): - values = api.portal.get_registry_record( self.field, interface=IDesignPloneSettings, default=[] ) diff --git a/src/design/plone/contenttypes/vocabularies/reference_vocabularies.py b/src/design/plone/contenttypes/vocabularies/reference_vocabularies.py index 89c1f828..4b9ff97b 100644 --- a/src/design/plone/contenttypes/vocabularies/reference_vocabularies.py +++ b/src/design/plone/contenttypes/vocabularies/reference_vocabularies.py @@ -10,7 +10,6 @@ class ReferencesVocabulary(object): - INDEX = "" def get_all_index_values(self): @@ -32,19 +31,16 @@ def __call__(self, registry=None): @implementer(IVocabularyFactory) class EventLocationVocabulary(ReferencesVocabulary): - INDEX = "event_location" @implementer(IVocabularyFactory) class OfficeLocationVocabulary(ReferencesVocabulary): - INDEX = "ufficio_responsabile" @implementer(IVocabularyFactory) class UOLocationVocabulary(ReferencesVocabulary): - INDEX = "uo_location" From 7e0869f9bba751115c0e77da845760bbc6dd5c29 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Wed, 8 Feb 2023 12:17:02 +0100 Subject: [PATCH 197/487] [doc] updated CHANGES --- CHANGES.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index e79aff36..f33582e0 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -5,7 +5,8 @@ Changelog 6.0.0a14 (unreleased) --------------------- -- Nothing changed yet. +- Fixed design_italia_meta_type data in summary for News Item. + [eikichi18] 6.0.0a13 (2023-02-06) From 2aa774f1bbe16aab3ee36ed3375c59e5df507852 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Wed, 8 Feb 2023 12:17:17 +0100 Subject: [PATCH 198/487] Preparing release 6.0.0a14 --- CHANGES.rst | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index f33582e0..75707541 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -2,7 +2,7 @@ Changelog ========= -6.0.0a14 (unreleased) +6.0.0a14 (2023-02-08) --------------------- - Fixed design_italia_meta_type data in summary for News Item. diff --git a/setup.py b/setup.py index 172ef718..9a59a1ec 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.0.0a14.dev0", + version="6.0.0a14", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 4ae6f873c6fc20763e06feabc2b145f36d61a247 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Wed, 8 Feb 2023 12:17:39 +0100 Subject: [PATCH 199/487] Back to development: 6.0.0a15 --- CHANGES.rst | 6 ++++++ setup.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 75707541..9ee753a3 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -2,6 +2,12 @@ Changelog ========= +6.0.0a15 (unreleased) +--------------------- + +- Nothing changed yet. + + 6.0.0a14 (2023-02-08) --------------------- diff --git a/setup.py b/setup.py index 9a59a1ec..e81885a2 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.0.0a14", + version="6.0.0a15.dev0", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 91b0d9b12290ce2a15bef4d9f0168c83c200ec52 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Wed, 8 Feb 2023 15:31:59 +0100 Subject: [PATCH 200/487] [fix] tipologia_notizia --- src/design/plone/contenttypes/patches/baseserializer.py | 2 +- .../plone/contenttypes/restapi/serializers/dxcontent.py | 8 ++------ 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/design/plone/contenttypes/patches/baseserializer.py b/src/design/plone/contenttypes/patches/baseserializer.py index 2c14c1f3..15c4231e 100644 --- a/src/design/plone/contenttypes/patches/baseserializer.py +++ b/src/design/plone/contenttypes/patches/baseserializer.py @@ -41,7 +41,7 @@ def design_italia_serialize_to_json_call(self, version=None, include_items=True) ) taxonomy_voc = taxonomy.makeVocabulary(self.request.get("LANGUAGE")) - title = taxonomy_voc.inv_data.get(self.context.tipologia_notizia[0], None) + title = taxonomy_voc.inv_data.get(self.context.tipologia_notizia, None) if title.startswith(PATH_SEPARATOR): result["design_italia_meta_type"] = title.replace(PATH_SEPARATOR, "", 1) diff --git a/src/design/plone/contenttypes/restapi/serializers/dxcontent.py b/src/design/plone/contenttypes/restapi/serializers/dxcontent.py index 5c0a3f61..ea345dff 100644 --- a/src/design/plone/contenttypes/restapi/serializers/dxcontent.py +++ b/src/design/plone/contenttypes/restapi/serializers/dxcontent.py @@ -31,9 +31,7 @@ def __call__(self, version=None, include_items=True): ) taxonomy_voc = taxonomy.makeVocabulary(self.request.get("LANGUAGE")) - title = taxonomy_voc.inv_data.get( - self.context.tipologia_notizia[0], None - ) + title = taxonomy_voc.inv_data.get(self.context.tipologia_notizia, None) if title.startswith(PATH_SEPARATOR): result["design_italia_meta_type"] = title.replace( @@ -63,9 +61,7 @@ def __call__(self, version=None, include_items=True): ) taxonomy_voc = taxonomy.makeVocabulary(self.request.get("LANGUAGE")) - title = taxonomy_voc.inv_data.get( - self.context.tipologia_notizia[0], None - ) + title = taxonomy_voc.inv_data.get(self.context.tipologia_notizia, None) if title.startswith(PATH_SEPARATOR): result["design_italia_meta_type"] = title.replace( From 357c53c3fff8c225b72dd3c982cbfa28730724f6 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Wed, 8 Feb 2023 15:33:14 +0100 Subject: [PATCH 201/487] [doc] updated CHANGES --- CHANGES.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 9ee753a3..297bbb02 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -5,7 +5,8 @@ Changelog 6.0.0a15 (unreleased) --------------------- -- Nothing changed yet. +- Fixed tipologia_notizia in serializer. + [eikichi18] 6.0.0a14 (2023-02-08) From d5bc4c92cdcd2728b0f1205927259919974a8385 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Wed, 8 Feb 2023 15:35:45 +0100 Subject: [PATCH 202/487] Preparing release 6.0.0a15 --- CHANGES.rst | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 297bbb02..f0f96239 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -2,7 +2,7 @@ Changelog ========= -6.0.0a15 (unreleased) +6.0.0a15 (2023-02-08) --------------------- - Fixed tipologia_notizia in serializer. diff --git a/setup.py b/setup.py index e81885a2..60a1c4d0 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.0.0a15.dev0", + version="6.0.0a15", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 026f27dd502e0889329cae5e40468dc795d78ae2 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Wed, 8 Feb 2023 15:36:21 +0100 Subject: [PATCH 203/487] Back to development: 6.0.0a16 --- CHANGES.rst | 6 ++++++ setup.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index f0f96239..e9b65673 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -2,6 +2,12 @@ Changelog ========= +6.0.0a16 (unreleased) +--------------------- + +- Nothing changed yet. + + 6.0.0a15 (2023-02-08) --------------------- diff --git a/setup.py b/setup.py index 60a1c4d0..6079570f 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.0.0a15", + version="6.0.0a16.dev0", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 036111d22a03c99fb413ab1645c77b5c349fd517 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Wed, 8 Feb 2023 16:59:54 +0100 Subject: [PATCH 204/487] [fix] tipologia_notizia --- .../plone/contenttypes/restapi/serializers/summary.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/design/plone/contenttypes/restapi/serializers/summary.py b/src/design/plone/contenttypes/restapi/serializers/summary.py index 12afbf02..08436ffa 100644 --- a/src/design/plone/contenttypes/restapi/serializers/summary.py +++ b/src/design/plone/contenttypes/restapi/serializers/summary.py @@ -177,9 +177,11 @@ def get_design_meta_type(self): ITaxonomy, name="collective.taxonomy.tipologia_notizia" ) taxonomy_voc = taxonomy.makeVocabulary(self.request.get("LANGUAGE")) - title = taxonomy_voc.inv_data.get( - self.context.tipologia_notizia[0], None - ) + if isinstance(self.context.tipologia_notizia, list): + token = self.context.tipologia_notizia[0] + else: + token = self.context.tipologia_notizia + title = taxonomy_voc.inv_data.get(token, None) if title.startswith(PATH_SEPARATOR): title = title.replace(PATH_SEPARATOR, "", 1) From 91597f4b032d5fcea936f2ae39c6c1b6b416528a Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Wed, 8 Feb 2023 17:01:38 +0100 Subject: [PATCH 205/487] [doc] updated CHANGES --- CHANGES.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index e9b65673..92ee5c4f 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -5,7 +5,9 @@ Changelog 6.0.0a16 (unreleased) --------------------- -- Nothing changed yet. +- Improved github action for automatic deploy. +- Fixed tipologia_notizia in serializer. + [eikichi18] 6.0.0a15 (2023-02-08) From a03c5b8c7b97bfff88f340ff070dd97913dae3fe Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Wed, 8 Feb 2023 17:01:56 +0100 Subject: [PATCH 206/487] Preparing release 6.0.0a16 --- CHANGES.rst | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 92ee5c4f..110a9d72 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -2,7 +2,7 @@ Changelog ========= -6.0.0a16 (unreleased) +6.0.0a16 (2023-02-08) --------------------- - Improved github action for automatic deploy. diff --git a/setup.py b/setup.py index 6079570f..49580cc6 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.0.0a16.dev0", + version="6.0.0a16", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 03bb1463441bdb6b8b6901723dc3865d836d9d02 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Wed, 8 Feb 2023 17:02:24 +0100 Subject: [PATCH 207/487] Back to development: 6.0.0a17 --- CHANGES.rst | 6 ++++++ setup.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 110a9d72..809ee20e 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -2,6 +2,12 @@ Changelog ========= +6.0.0a17 (unreleased) +--------------------- + +- Nothing changed yet. + + 6.0.0a16 (2023-02-08) --------------------- diff --git a/setup.py b/setup.py index 49580cc6..d91b5f5f 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.0.0a16", + version="6.0.0a17.dev0", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From ecb323e6b2175a9c7be426711f666fa1a65c38ab Mon Sep 17 00:00:00 2001 From: Sabrina Bongiovanni Date: Fri, 10 Feb 2023 16:56:49 +0100 Subject: [PATCH 208/487] fix taxonomy (wip) --- .../plone/contenttypes/restapi/serializers/summary.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/design/plone/contenttypes/restapi/serializers/summary.py b/src/design/plone/contenttypes/restapi/serializers/summary.py index 08436ffa..1fba75c8 100644 --- a/src/design/plone/contenttypes/restapi/serializers/summary.py +++ b/src/design/plone/contenttypes/restapi/serializers/summary.py @@ -54,11 +54,11 @@ def get_taxonomy_information(field_name, context, res): fullterms = [] # delle volte posso avere il brain senza quel dato if field_name not in res: - res[field_name] = getattr(context, field_name) + res[field_name] = getattr(context, field_name, []) for token in res[field_name]: title = taxonomy_voc.inv_data.get(token, None) - if title.startswith(PATH_SEPARATOR): + if title and title.startswith(PATH_SEPARATOR): title = title.replace(PATH_SEPARATOR, "", 1) fullterms.append({"token": token, "title": title}) res[field_name] = fullterms @@ -69,7 +69,7 @@ def get_fullterms(token): if not token: return None title = taxonomy_voc.inv_data.get(token, None) - if title.startswith(PATH_SEPARATOR): + if title and title.startswith(PATH_SEPARATOR): title = title.replace(PATH_SEPARATOR, "", 1) return { "token": token, @@ -182,7 +182,7 @@ def get_design_meta_type(self): else: token = self.context.tipologia_notizia title = taxonomy_voc.inv_data.get(token, None) - if title.startswith(PATH_SEPARATOR): + if title and title.startswith(PATH_SEPARATOR): title = title.replace(PATH_SEPARATOR, "", 1) return title From 19aee2c160ef661bf5c835e272429e633a45cb11 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Fri, 10 Feb 2023 17:18:22 +0100 Subject: [PATCH 209/487] [doc] udpated CHANGES --- CHANGES.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 809ee20e..5b24dd87 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -5,7 +5,8 @@ Changelog 6.0.0a17 (unreleased) --------------------- -- Nothing changed yet. +- Improved check for taxonomy data. + [sabrina-bongiovanni] 6.0.0a16 (2023-02-08) From a3d9a8b4065c81ff457927f139adc8c8e6b3daf3 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Mon, 20 Feb 2023 10:47:34 +0100 Subject: [PATCH 210/487] prima implementazione del check servizi (senza check reale, solo lista) --- .../browser/manage_content/check_servizi.py | 97 ++------ .../browser/manage_content/configure.zcml | 7 + .../templates/change_news_type.pt | 111 ++++++--- .../manage_content/templates/check_servizi.pt | 225 +++++------------- .../templates/move_news_items.pt | 181 +++++++++----- 5 files changed, 271 insertions(+), 350 deletions(-) diff --git a/src/design/plone/contenttypes/browser/manage_content/check_servizi.py b/src/design/plone/contenttypes/browser/manage_content/check_servizi.py index fcabd07b..dac6bf80 100644 --- a/src/design/plone/contenttypes/browser/manage_content/check_servizi.py +++ b/src/design/plone/contenttypes/browser/manage_content/check_servizi.py @@ -1,87 +1,28 @@ -from design.plone.contenttypes import _ from plone import api -from plone.z3cform.layout import wrap_form -from z3c.form import button -from z3c.form import field -from z3c.form import form -from zope import schema -from zope.component import getMultiAdapter -from zope.interface import implementer -from zope.interface import Interface +from Products.Five import BrowserView -class ISearchForm(Interface): - """ - Form to search Servizio by path - """ - - path = schema.TextLine( - title=_( - "licenza_distribuzione_label", - default="Seleziona il percorso sotto il quale cercare", - ), - required=False, - ) - - -@implementer(ISearchForm) -class CheckServizi(form.Form): - ignoreContext = True - # template = ViewPageTemplateFile("templates/check_servizi.pt") - prefix = "" - brains = [] - fields = field.Fields(ISearchForm) - method = "GET" - - def search_servizi(self): +class CheckServizi(BrowserView): + def get_servizi(self): pc = api.portal.get_tool("portal_catalog") - query = {"portal_type": "Servizio", "sort_on": "sortable_title"} - if self.request.form.get("widgets.path") and self.request.form.get( - "buttons.action_search" - ): - path = self.request.form.get("widgets.path") - prefix = api.portal.get().getId() - if not path.startswith(f"/{prefix}"): - path = f"/{prefix}/{path}" - query["path"] = {"query": path} - brains = pc(**query) - servizi = [brain.getObject() for brain in brains] - results = [] - for servizio in servizi: - results.append( + brains = pc(portal_type="Servizio") + results = {} + for brain in brains: + servizio = brain.getObject() + parent = servizio.aq_inner.aq_parent + if parent.title not in results: + results[parent.title] = { + "url": parent.absolute_url().replace("/api/", "/"), + "children": [], + } + results[parent.title]["children"].append( { "title": servizio.title, - "url": "/".join(servizio.getPhysicalPath()), - "breadcrumbs": getMultiAdapter( - (servizio, self.request), name="breadcrumbs_view" - ).breadcrumbs(), + "url": servizio.absolute_url().replace("/api/", "/"), } ) - return results + results = dict(sorted(results.items())) + for key in results: + results[key]["children"].sort(key=lambda x: x["title"]) - def updateWidgets(self): - super(CheckServizi, self).updateWidgets() - for k, v in self.request.form.items(): - if k in self.widgets: - self.widgets[k].value = v - - @button.buttonAndHandler(_("action_search", default="Cerca")) - def action_search(self, action): - """ - Search in prenotazioni SearchableText - """ - data, errors = self.extractData() - if errors: - self.status = self.formErrorsMessage - return - - @button.buttonAndHandler(_("move_back_message", default="Reset")) - def action_cancel(self, action): - """ - Cancel and go back to the week view - """ - target = self.context.absolute_url() + "/check_servizi" - return self.request.response.redirect(target) - - -WrappedCheckServiziForm = wrap_form(CheckServizi) + return results diff --git a/src/design/plone/contenttypes/browser/manage_content/configure.zcml b/src/design/plone/contenttypes/browser/manage_content/configure.zcml index ea1a616b..bd438265 100644 --- a/src/design/plone/contenttypes/browser/manage_content/configure.zcml +++ b/src/design/plone/contenttypes/browser/manage_content/configure.zcml @@ -20,5 +20,12 @@ template="templates/move_news_items.pt" permission="cmf.ManagePortal" /> + diff --git a/src/design/plone/contenttypes/browser/manage_content/templates/change_news_type.pt b/src/design/plone/contenttypes/browser/manage_content/templates/change_news_type.pt index b70e5d6c..db19c7c9 100644 --- a/src/design/plone/contenttypes/browser/manage_content/templates/change_news_type.pt +++ b/src/design/plone/contenttypes/browser/manage_content/templates/change_news_type.pt @@ -1,54 +1,87 @@ - + xml:lang="en" + i18n:domain="design.plone.contenttypes" +> - + -

Change News Type

+

Change News Type

- + Questo tool viene usato per cambiare il valore del campo 'Tipologia Notizia' in tutte le notizie che hanno il valore del campo selezionato. Fa anche il giro su tutti i blocchi elenco -
-
-
- -
+
+ +
+ +
All the already existing News Types -
-
- -
+
+
+ +
The News Type selected above will be substituted by the selected value -
- -
-
- -
- -
+
+ +
+
+ +
+ +
- + diff --git a/src/design/plone/contenttypes/browser/manage_content/templates/check_servizi.pt b/src/design/plone/contenttypes/browser/manage_content/templates/check_servizi.pt index 5ec2363a..9c7dda26 100644 --- a/src/design/plone/contenttypes/browser/manage_content/templates/check_servizi.pt +++ b/src/design/plone/contenttypes/browser/manage_content/templates/check_servizi.pt @@ -1,172 +1,57 @@ - - - - - - - - - -
- - - Various slots where you can insert elements in the header from a template. - - - - - -
- - - - + + + + - - - -
-
-
- -
- The main navigation -
- - - -
- - -
-
-
- - - - -
+ + + + +

Verifica dello stato dei servizi

+
+ +
+
+
+ + diff --git a/src/design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt b/src/design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt index fcedc29a..c195cb98 100644 --- a/src/design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt +++ b/src/design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt @@ -1,83 +1,138 @@ - + xml:lang="en" + i18n:domain="design.plone.contenttypes" +> - + -

Move News Items

+

Move News Items

- + Questo tool viene usato per trovare e spostare le Notizie con una Tipologia Notizia determinata. -
-
-
- -
+
+ +
+ +
Find news with this News Type -
-
- -
+
+
+ +
Find news with the indicated Path, put attention than generaly sites have the root name "/Plone/" -
- +
+ +
+
+ +
+ +
+
+
+
+

Found ${tot_results} items

+
    +
  • +
    + +

    Select all

    -
    - +
  • +
  • +
    + +
    +

    Contained by + ${python: '/'.join(item.getPath().split('/')[:-1])}

    -
  • -
-
-
-
-

Found ${tot_results} items

-
    -
  • -
    - -

    Select all

    -
    -
  • -
  • -
    - -
    -

    Contained by ${python: '/'.join(item.getPath().split('/')[:-1])}

    -
    -
  • -
-
- -
+ + +
+ +
All the selected items will be moved to indicated path -
-
+
-
- -
- -
+
+
+ +
+ +
- + From 5006cb351d32c6ab59b212850dd58a4399e576fb Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Mon, 20 Feb 2023 10:52:28 +0100 Subject: [PATCH 211/487] update changes --- CHANGES.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGES.rst b/CHANGES.rst index 5b24dd87..cb3255a6 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -5,6 +5,8 @@ Changelog 6.0.0a17 (unreleased) --------------------- +- Start implement a view to check service for new data + [lucabel] - Improved check for taxonomy data. [sabrina-bongiovanni] From 434348f3de1aa2dc947d6e832e3ea5e564fc294b Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Mon, 20 Feb 2023 10:53:16 +0100 Subject: [PATCH 212/487] Preparing release 6.0.0a17 --- CHANGES.rst | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index cb3255a6..1d8891ba 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -2,7 +2,7 @@ Changelog ========= -6.0.0a17 (unreleased) +6.0.0a17 (2023-02-20) --------------------- - Start implement a view to check service for new data diff --git a/setup.py b/setup.py index d91b5f5f..832786ae 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.0.0a17.dev0", + version="6.0.0a17", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 900b72fa1a158f86bdd020e07852fdbc8974c4ca Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Mon, 20 Feb 2023 10:54:36 +0100 Subject: [PATCH 213/487] Back to development: 6.0.0a18 --- CHANGES.rst | 6 ++++++ setup.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 1d8891ba..65b65943 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -2,6 +2,12 @@ Changelog ========= +6.0.0a18 (unreleased) +--------------------- + +- Nothing changed yet. + + 6.0.0a17 (2023-02-20) --------------------- diff --git a/setup.py b/setup.py index 832786ae..b75fa703 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.0.0a17", + version="6.0.0a18.dev0", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 73c047f27a6f5cebc65cb9df33c52dcce25e099b Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Mon, 20 Feb 2023 14:32:06 +0100 Subject: [PATCH 214/487] fix versions for P6 buildout --- .github/workflows/flake8.yml | 4 ++-- .github/workflows/test.yml | 2 +- test_plone60.cfg | 9 +++++---- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/.github/workflows/flake8.yml b/.github/workflows/flake8.yml index 97c7dfa4..7ed6ab47 100644 --- a/.github/workflows/flake8.yml +++ b/.github/workflows/flake8.yml @@ -6,7 +6,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: [3.8] + python-version: [3.11] steps: # git checkout @@ -32,4 +32,4 @@ jobs: # run black - name: run flake8 - run: flake8 src/ setup.py + run: flake8 src/ setup.py --ignore E203 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 9a0ddf41..bceb9e40 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,7 +8,7 @@ jobs: strategy: max-parallel: 4 matrix: - python: ["3.8"] + python: ["3.8", "3.9", "3.10", "3.11"] plone: ["60"] # exclude: # - python: "3.7" diff --git a/test_plone60.cfg b/test_plone60.cfg index 8c885d8d..e6252fd8 100644 --- a/test_plone60.cfg +++ b/test_plone60.cfg @@ -11,19 +11,20 @@ update-versions-file = test_plone60.cfg [versions] # Added by buildout at 2021-12-29 11:05:41.321569 -flake8 = 3.9.2 +flake8 = 5.0.0 flake8-coding = 1.3.2 flake8-debugger = 3.2.1 flake8-print = 3.1.4 -mccabe = 0.6.1 +mccabe = 0.7.0 +importlib-metadata=4.2 plone.recipe.codeanalysis = 3.0.1 -pyflakes = 2.3.1 +pyflakes = 2.5.0 zpretty = 2.1.0 # Required by: # flake8-debugger==3.2.1 # flake8-print==3.1.4 -pycodestyle = 2.7.0 +pycodestyle = 2.9.0 # Added by buildout at 2023-01-12 09:16:52.328614 bleach = 5.0.1 From 900eef0ebd11fe6289e46db7f2e7b76476f1d656 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Mon, 20 Feb 2023 14:56:11 +0100 Subject: [PATCH 215/487] update versions --- test_plone60.cfg | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/test_plone60.cfg b/test_plone60.cfg index e6252fd8..e6b0983a 100644 --- a/test_plone60.cfg +++ b/test_plone60.cfg @@ -11,20 +11,19 @@ update-versions-file = test_plone60.cfg [versions] # Added by buildout at 2021-12-29 11:05:41.321569 -flake8 = 5.0.0 +flake8 = 6.0.0 flake8-coding = 1.3.2 -flake8-debugger = 3.2.1 -flake8-print = 3.1.4 +flake8-debugger = 4.1.2 +flake8-print = 5.0.0 mccabe = 0.7.0 -importlib-metadata=4.2 plone.recipe.codeanalysis = 3.0.1 -pyflakes = 2.5.0 -zpretty = 2.1.0 +pyflakes = 3.0.1 +zpretty = 3.0.1 # Required by: # flake8-debugger==3.2.1 # flake8-print==3.1.4 -pycodestyle = 2.9.0 +pycodestyle = 2.10.0 # Added by buildout at 2023-01-12 09:16:52.328614 bleach = 5.0.1 @@ -37,9 +36,10 @@ pkginfo = 1.8.3 readme-renderer = 37.3 requests-toolbelt = 0.10.1 rfc3986 = 2.0.0 -rich = 12.6.0 +rich = 13.3.1 +pygments = 2.14.0 twine = 4.0.1 -zest.releaser = 7.2.0 +zest.releaser = 7.3.0 # Required by: # plone.recipe.codeanalysis==3.0.1 @@ -72,3 +72,16 @@ tomli = 2.0.1 # Required by: # bleach==5.0.1 webencodings = 0.5.1 + +dataclasses = 0.8 + +# Added by buildout at 2023-02-20 14:52:32.917956 +backports.functools-lru-cache = 1.6.4 +markdown-it-py = 2.1.0 +mdurl = 0.1.2 +pkgutil-resolve-name = 1.3.10 + +# Required by: +# PasteDeploy==3.0.1 +# plone.restapi==8.33.3 +importlib-metadata = 5.2.0 From d37ab4d873b2018fce7859d64238f307fda7cdd7 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Mon, 20 Feb 2023 17:30:14 +0100 Subject: [PATCH 216/487] start to fix some test --- setup.cfg | 3 ++- src/design/plone/contenttypes/testing.py | 11 ++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/setup.cfg b/setup.cfg index ad42f735..c726a5e2 100644 --- a/setup.cfg +++ b/setup.cfg @@ -20,4 +20,5 @@ max-complexity = 15 max-line-length = 100000 extend-ignore = E203, - C901 + C901, + C101 diff --git a/src/design/plone/contenttypes/testing.py b/src/design/plone/contenttypes/testing.py index 92432113..998789d8 100644 --- a/src/design/plone/contenttypes/testing.py +++ b/src/design/plone/contenttypes/testing.py @@ -8,7 +8,7 @@ from zope.configuration import xmlconfig import collective.address -import collective.folderishtypes +# import collective.folderishtypes import collective.venue import collective.volto.blocksfield import collective.volto.cookieconsent @@ -19,6 +19,9 @@ import plone.restapi import redturtle.bandi import redturtle.volto +import eea.api.taxonomy +import collective.taxonomy +import collective.z3cform.datagridfield class DesignPloneContenttypesLayer(RedturtleVoltoLayer): @@ -39,6 +42,9 @@ def setUpZope(self, app, configurationContext): ) self.loadZCML(package=redturtle.bandi) self.loadZCML(package=kitconcept.seo) + self.loadZCML(package=eea.api.taxonomy) + self.loadZCML(package=collective.taxonomy) + self.loadZCML(package=collective.z3cform.datagridfield) def setUpPloneSite(self, portal): super().setUpPloneSite(portal) @@ -75,6 +81,9 @@ def setUpZope(self, app, configurationContext): ) self.loadZCML(package=redturtle.bandi) self.loadZCML(package=kitconcept.seo) + self.loadZCML(package=eea.api.taxonomy) + self.loadZCML(package=collective.taxonomy) + self.loadZCML(package=collective.z3cform.datagridfield) def setUpPloneSite(self, portal): super().setUpPloneSite(portal) From 7b1b28af6a496ca5736731a0970d43a7a1598a8d Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Wed, 22 Feb 2023 13:32:58 +0100 Subject: [PATCH 217/487] release check_servizi view --- CHANGES.rst | 4 +- .../browser/manage_content/check_servizi.py | 10 +++++ .../browser/manage_content/configure.zcml | 2 +- .../manage_content/templates/check_servizi.pt | 37 +++++++++---------- 4 files changed, 32 insertions(+), 21 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 65b65943..a85ce6d9 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -5,7 +5,9 @@ Changelog 6.0.0a18 (unreleased) --------------------- -- Nothing changed yet. +- First release of check_service view; need to test on + a staging + [lucabel] 6.0.0a17 (2023-02-20) diff --git a/src/design/plone/contenttypes/browser/manage_content/check_servizi.py b/src/design/plone/contenttypes/browser/manage_content/check_servizi.py index dac6bf80..79583e04 100644 --- a/src/design/plone/contenttypes/browser/manage_content/check_servizi.py +++ b/src/design/plone/contenttypes/browser/manage_content/check_servizi.py @@ -1,14 +1,24 @@ from plone import api from Products.Five import BrowserView +from Products.CMFPlone.utils import safe_hasattr class CheckServizi(BrowserView): + def is_anonymous(self): + return api.user.is_anonymous() + def get_servizi(self): + if self.is_anonymous(): + return [] pc = api.portal.get_tool("portal_catalog") brains = pc(portal_type="Servizio") results = {} for brain in brains: servizio = brain.getObject() + if safe_hasattr(servizio, "condizioni_di_servizio") and getattr( + servizio, "condizioni_di_servizio" + ): + continue parent = servizio.aq_inner.aq_parent if parent.title not in results: results[parent.title] = { diff --git a/src/design/plone/contenttypes/browser/manage_content/configure.zcml b/src/design/plone/contenttypes/browser/manage_content/configure.zcml index bd438265..959ff3e2 100644 --- a/src/design/plone/contenttypes/browser/manage_content/configure.zcml +++ b/src/design/plone/contenttypes/browser/manage_content/configure.zcml @@ -25,7 +25,7 @@ for="*" class=".check_servizi.CheckServizi" template="templates/check_servizi.pt" - permission="cmf.ManagePortal" + permission="zope2.Public" /> diff --git a/src/design/plone/contenttypes/browser/manage_content/templates/check_servizi.pt b/src/design/plone/contenttypes/browser/manage_content/templates/check_servizi.pt index 9c7dda26..e68f2a8b 100644 --- a/src/design/plone/contenttypes/browser/manage_content/templates/check_servizi.pt +++ b/src/design/plone/contenttypes/browser/manage_content/templates/check_servizi.pt @@ -22,29 +22,28 @@

Verifica dello stato dei servizi

+
+ Non hai i permessi per vedere questo elenco di informazioni. Se pensi + che questo non sia corretto verifica di essere autenticato oppure rivolgiti + agli amministratori del sito. +
+ tal:condition="not:view/is_anonymous" + tal:define="servizi view/get_servizi;"> +

+ La lista seguente elenca tutti quei servizi per i quali non sono + ancora stati aggiunti i campi che AGID indica come obbligatori. + Ogni redattore può vedere in questa lista tutti i servizi e, + cliccando su ognuno, andare alla vista di dettaglio del servizio, + editarlo e compilare tutti i campi obbligatori.

  • - -

    ${categoria}

    + tal:repeat="categoria servizi"> + +

    ${categoria}

    From c019ad5da38e1f41c444de9851b3369936a23fbf Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Wed, 22 Feb 2023 15:40:28 +0100 Subject: [PATCH 218/487] Preparing release 6.0.0a18 --- CHANGES.rst | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index a85ce6d9..f75472f6 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -2,7 +2,7 @@ Changelog ========= -6.0.0a18 (unreleased) +6.0.0a18 (2023-02-22) --------------------- - First release of check_service view; need to test on diff --git a/setup.py b/setup.py index b75fa703..94ae8f9d 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.0.0a18.dev0", + version="6.0.0a18", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 59b0fe9c9ccc206908b7c6c1a71e6f25a613c177 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Wed, 22 Feb 2023 15:40:57 +0100 Subject: [PATCH 219/487] Back to development: 6.0.0a19 --- CHANGES.rst | 6 ++++++ setup.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index f75472f6..f74d22dc 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -2,6 +2,12 @@ Changelog ========= +6.0.0a19 (unreleased) +--------------------- + +- Nothing changed yet. + + 6.0.0a18 (2023-02-22) --------------------- diff --git a/setup.py b/setup.py index 94ae8f9d..552c312b 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.0.0a18", + version="6.0.0a19.dev0", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 5b150900a5177c82a22d80afcfb00d6060f62f1f Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Thu, 23 Feb 2023 12:26:39 +0100 Subject: [PATCH 220/487] Fix typo in event behavior; change checked size in title/description deserializers (but these data are checked in FE); change field label for event and made his description required --- .../plone/contenttypes/behaviors/evento.py | 17 ++++------------- .../profiles/default/types/Event.xml | 2 +- .../restapi/deserializers/documento.py | 4 ++-- .../contenttypes/restapi/deserializers/news.py | 4 ++-- .../restapi/deserializers/servizio.py | 4 ++-- .../restapi/deserializers/unitaorganizzativa.py | 2 +- .../contenttypes/restapi/deserializers/venue.py | 4 ++-- .../contenttypes/restapi/services/types/get.py | 6 ++++++ 8 files changed, 20 insertions(+), 23 deletions(-) diff --git a/src/design/plone/contenttypes/behaviors/evento.py b/src/design/plone/contenttypes/behaviors/evento.py index 7fb6512b..ba865993 100644 --- a/src/design/plone/contenttypes/behaviors/evento.py +++ b/src/design/plone/contenttypes/behaviors/evento.py @@ -38,11 +38,11 @@ class IEvento(model.Schema): ) descrizione_destinatari = BlocksField( - title=_("descrizione_destinatari", default="Descrizione destinatari"), - required=False, + title=_("a_chi_si_rivolge_label", default="A chi è rivolto"), + required=True, description=_( - "descrizione_destinatari_help", - default="Descrizione dei principali interlocutori dell'evento.", + "a_chi_si_rivolge_help", + default="Descrizione testuale dei principali destinatari dell'Evento", ), ) @@ -121,15 +121,6 @@ class IEvento(model.Schema): ), ) - a_chi_si_rivolge = BlocksField( - title=_("a_chi_si_rivolge_label", default="A chi è rivolto"), - required=True, - description=_( - "a_chi_si_rivolge_help", - default="Descrizione testuale dei principali destinatari dell'Evento", - ), - ) - # custom widgets form.widget( "supportato_da", diff --git a/src/design/plone/contenttypes/profiles/default/types/Event.xml b/src/design/plone/contenttypes/profiles/default/types/Event.xml index c4072c2e..412101c9 100644 --- a/src/design/plone/contenttypes/profiles/default/types/Event.xml +++ b/src/design/plone/contenttypes/profiles/default/types/Event.xml @@ -20,7 +20,7 @@ - diff --git a/src/design/plone/contenttypes/restapi/deserializers/documento.py b/src/design/plone/contenttypes/restapi/deserializers/documento.py index b29ed8e9..949b3bdb 100644 --- a/src/design/plone/contenttypes/restapi/deserializers/documento.py +++ b/src/design/plone/contenttypes/restapi/deserializers/documento.py @@ -11,8 +11,8 @@ from zope.interface import Interface -TITLE_MAX_LEN = 160 -DESCRIPTION_MAX_LEN = 160 +TITLE_MAX_LEN = 255 +DESCRIPTION_MAX_LEN = 255 EMPTY_BLOCK_MARKER = {"@type": "text"} MANDATORY_RICH_TEXT_FIELDS = [ # "descrizione_estesa", diff --git a/src/design/plone/contenttypes/restapi/deserializers/news.py b/src/design/plone/contenttypes/restapi/deserializers/news.py index bb374a58..ae1c1004 100644 --- a/src/design/plone/contenttypes/restapi/deserializers/news.py +++ b/src/design/plone/contenttypes/restapi/deserializers/news.py @@ -11,8 +11,8 @@ from zope.interface import Interface -TITLE_MAX_LEN = 160 -DESCRIPTION_MAX_LEN = 160 +TITLE_MAX_LEN = 255 +DESCRIPTION_MAX_LEN = 255 EMPTY_BLOCK_MARKER = {"@type": "text"} MANDATORY_RICH_TEXT_FIELDS = [ "descrizione_estesa", diff --git a/src/design/plone/contenttypes/restapi/deserializers/servizio.py b/src/design/plone/contenttypes/restapi/deserializers/servizio.py index 1a861216..4fa51574 100644 --- a/src/design/plone/contenttypes/restapi/deserializers/servizio.py +++ b/src/design/plone/contenttypes/restapi/deserializers/servizio.py @@ -11,8 +11,8 @@ from zope.interface import Interface -TITLE_MAX_LEN = 160 -DESCRIPTION_MAX_LEN = 160 +TITLE_MAX_LEN = 255 +DESCRIPTION_MAX_LEN = 255 EMPTY_BLOCK_MARKER = {"@type": "text"} MANDATORY_RICH_TEXT_FIELDS = [ "a_chi_si_rivolge", diff --git a/src/design/plone/contenttypes/restapi/deserializers/unitaorganizzativa.py b/src/design/plone/contenttypes/restapi/deserializers/unitaorganizzativa.py index c7094709..540a9822 100644 --- a/src/design/plone/contenttypes/restapi/deserializers/unitaorganizzativa.py +++ b/src/design/plone/contenttypes/restapi/deserializers/unitaorganizzativa.py @@ -11,7 +11,7 @@ from zope.interface import Interface -TITLE_MAX_LEN = 160 +TITLE_MAX_LEN = 255 DESCRIPTION_MAX_LEN = 255 EMPTY_BLOCK_MARKER = {"@type": "text"} MANDATORY_RICH_TEXT_FIELDS = ["competenze"] diff --git a/src/design/plone/contenttypes/restapi/deserializers/venue.py b/src/design/plone/contenttypes/restapi/deserializers/venue.py index 11cadff4..96eb9186 100644 --- a/src/design/plone/contenttypes/restapi/deserializers/venue.py +++ b/src/design/plone/contenttypes/restapi/deserializers/venue.py @@ -11,8 +11,8 @@ from zope.interface import Interface -TITLE_MAX_LEN = 160 -DESCRIPTION_MAX_LEN = 160 +TITLE_MAX_LEN = 255 +DESCRIPTION_MAX_LEN = 255 EMPTY_BLOCK_MARKER = {"@type": "text"} MANDATORY_RICH_TEXT_FIELDS = ["modalita_accesso"] diff --git a/src/design/plone/contenttypes/restapi/services/types/get.py b/src/design/plone/contenttypes/restapi/services/types/get.py index 74e6d61a..4f983935 100644 --- a/src/design/plone/contenttypes/restapi/services/types/get.py +++ b/src/design/plone/contenttypes/restapi/services/types/get.py @@ -241,6 +241,10 @@ def customize_servizio_schema(self, result): result.get("required").append("description") return result + def customize_evento_schema(self, result): + result.get("required").append("description") + return result + def customize_uo_schema(self, result): result.get("required").append("description") versioning_fields = ["contact_info"] @@ -293,6 +297,8 @@ def reply(self): result = self.customize_news_schema(result) if pt == "Documento": result = self.customize_documento_schema(result) + if pt == "Event": + result = self.customize_evento_schema(result) result = self.customize_versioning_fields_fieldset(result) return result From eb5adab60dd4b13a6818b9f195c3c5628f4a8eaf Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Fri, 24 Feb 2023 15:52:23 +0100 Subject: [PATCH 221/487] change event schema for patrocinato_da field to change from textline to blockfield --- CHANGES.rst | 4 +- .../plone/contenttypes/behaviors/evento.py | 4 +- .../profiles/default/metadata.xml | 2 +- .../contenttypes/upgrades/configure.zcml | 11 ++++ .../plone/contenttypes/upgrades/upgrades.py | 56 +++++++++++++++++-- 5 files changed, 67 insertions(+), 10 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index f74d22dc..3690e0e3 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -5,7 +5,9 @@ Changelog 6.0.0a19 (unreleased) --------------------- -- Nothing changed yet. +- Change event schema: "patrocinato da" right now is a + rich text + [lucabel] 6.0.0a18 (2023-02-22) diff --git a/src/design/plone/contenttypes/behaviors/evento.py b/src/design/plone/contenttypes/behaviors/evento.py index ba865993..b619e427 100644 --- a/src/design/plone/contenttypes/behaviors/evento.py +++ b/src/design/plone/contenttypes/behaviors/evento.py @@ -100,8 +100,8 @@ class IEvento(model.Schema): ), ) - # campi aggiunti con il pnrr - patrocinato_da = schema.TextLine( + # campi aggiunti con il pnrr + patrocinato_da = BlocksField( title=_("patrocinato_da_label", default="Patrocinato da"), required=False, description=_( diff --git a/src/design/plone/contenttypes/profiles/default/metadata.xml b/src/design/plone/contenttypes/profiles/default/metadata.xml index 08d31f90..20db4e0f 100644 --- a/src/design/plone/contenttypes/profiles/default/metadata.xml +++ b/src/design/plone/contenttypes/profiles/default/metadata.xml @@ -1,6 +1,6 @@ - 7006 + 7007 profile-redturtle.bandi:default profile-collective.venue:default diff --git a/src/design/plone/contenttypes/upgrades/configure.zcml b/src/design/plone/contenttypes/upgrades/configure.zcml index b1fa3715..74eb09f0 100644 --- a/src/design/plone/contenttypes/upgrades/configure.zcml +++ b/src/design/plone/contenttypes/upgrades/configure.zcml @@ -701,4 +701,15 @@ handler=".upgrades.update_types" /> + + + diff --git a/src/design/plone/contenttypes/upgrades/upgrades.py b/src/design/plone/contenttypes/upgrades/upgrades.py index d5cf2990..54a9ef71 100644 --- a/src/design/plone/contenttypes/upgrades/upgrades.py +++ b/src/design/plone/contenttypes/upgrades/upgrades.py @@ -335,9 +335,7 @@ def to_1016(context): sections.append({"title": item.title, "linkUrl": [item.UID()]}) settings = [{"rootPath": "/", "items": sections}] api.portal.set_registry_record( - "search_sections", - json.dumps(settings), - interface=IDesignPloneSettings, + "search_sections", json.dumps(settings), interface=IDesignPloneSettings, ) @@ -456,9 +454,7 @@ def to_3000(context): try: value = api.portal.get_registry_record(old_entry.format(field)) api.portal.set_registry_record( - field, - json.dumps({"it": value}), - interface=IDesignPloneSettings, + field, json.dumps({"it": value}), interface=IDesignPloneSettings, ) except Exception: continue @@ -1709,3 +1705,51 @@ def fix_ctaxonomy_indexes_and_metadata(context): obj = brain.getObject() obj.reindexObject(idxs=good_names) logger.info(f"{colors.GREEN} End of update {colors.ENDC}") + + +def update_patrocinato_da(self): + EMPTY_BLOCKS_FIELD = {"blocks": {}, "blocks_layout": {"items": []}} + logger.info( + f"{colors.DARKCYAN} Change patrocinato_da field in events {colors.ENDC}" + ) + pc = api.portal.get_tool(name="portal_catalog") + for brain in pc(portal_type="Event"): + obj = brain.getObject() + patrocinato_da = getattr(obj, "patrocinato_da") + if patrocinato_da == EMPTY_BLOCKS_FIELD: + logger.info( + f"{colors.YELLOW} Nessuna informazione da modificare{colors.ENDC}" + ) + continue + logger.info( + f"{colors.GREEN} Modificato patrocinato_da per {obj.absolute_url()} {colors.ENDC}" + ) + + setattr( + obj, + "patrocinato_da", + { + "blocks": { + "d252fe92-ce88-4866-b77d-501e7275cfc0": { + "@type": "text", + "text": { + "blocks": [ + { + "data": {}, + "depth": 0, + "entityRanges": [], + "inlineStyleRanges": [], + "key": "e23it", + "text": patrocinato_da, + "type": "unstyled", + } + ], + "entityMap": {}, + }, + } + }, + "blocks_layout": {"items": ["d252fe92-ce88-4866-b77d-501e7275cfc0"]}, + }, + ) + obj.reindexObject() + logger.info(f"{colors.DARKCYAN} End of update {colors.ENDC}") From af7255c89e29bd3db9e86bec7e45ce42d80313f0 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Fri, 24 Feb 2023 15:52:37 +0100 Subject: [PATCH 222/487] change event schema for patrocinato_da field to change from textline to blockfield --- src/design/plone/contenttypes/behaviors/evento.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/design/plone/contenttypes/behaviors/evento.py b/src/design/plone/contenttypes/behaviors/evento.py index b619e427..f61f4207 100644 --- a/src/design/plone/contenttypes/behaviors/evento.py +++ b/src/design/plone/contenttypes/behaviors/evento.py @@ -100,7 +100,7 @@ class IEvento(model.Schema): ), ) - # campi aggiunti con il pnrr + #  campi aggiunti con il pnrr patrocinato_da = BlocksField( title=_("patrocinato_da_label", default="Patrocinato da"), required=False, From 66d0eb76d418bdf1a786706f3c2622c0a4115b81 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Fri, 24 Feb 2023 16:03:56 +0100 Subject: [PATCH 223/487] fix black and flake8 --- .../browser/manage_content/check_servizi.py | 2 +- .../profiles/default/types/UnitaOrganizzativa.xml | 10 ++++++---- src/design/plone/contenttypes/testing.py | 7 ++++--- src/design/plone/contenttypes/upgrades/upgrades.py | 13 ++++++++----- 4 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/design/plone/contenttypes/browser/manage_content/check_servizi.py b/src/design/plone/contenttypes/browser/manage_content/check_servizi.py index 79583e04..368b5e00 100644 --- a/src/design/plone/contenttypes/browser/manage_content/check_servizi.py +++ b/src/design/plone/contenttypes/browser/manage_content/check_servizi.py @@ -1,6 +1,6 @@ from plone import api -from Products.Five import BrowserView from Products.CMFPlone.utils import safe_hasattr +from Products.Five import BrowserView class CheckServizi(BrowserView): diff --git a/src/design/plone/contenttypes/profiles/default/types/UnitaOrganizzativa.xml b/src/design/plone/contenttypes/profiles/default/types/UnitaOrganizzativa.xml index 1debf40a..8f184912 100644 --- a/src/design/plone/contenttypes/profiles/default/types/UnitaOrganizzativa.xml +++ b/src/design/plone/contenttypes/profiles/default/types/UnitaOrganizzativa.xml @@ -50,10 +50,12 @@ - - + + diff --git a/src/design/plone/contenttypes/testing.py b/src/design/plone/contenttypes/testing.py index 998789d8..020f85e7 100644 --- a/src/design/plone/contenttypes/testing.py +++ b/src/design/plone/contenttypes/testing.py @@ -8,20 +8,21 @@ from zope.configuration import xmlconfig import collective.address +import collective.taxonomy + # import collective.folderishtypes import collective.venue import collective.volto.blocksfield import collective.volto.cookieconsent +import collective.z3cform.datagridfield import design.plone.contenttypes +import eea.api.taxonomy import kitconcept.seo import plone.app.caching import plone.formwidget.geolocation import plone.restapi import redturtle.bandi import redturtle.volto -import eea.api.taxonomy -import collective.taxonomy -import collective.z3cform.datagridfield class DesignPloneContenttypesLayer(RedturtleVoltoLayer): diff --git a/src/design/plone/contenttypes/upgrades/upgrades.py b/src/design/plone/contenttypes/upgrades/upgrades.py index 54a9ef71..db565006 100644 --- a/src/design/plone/contenttypes/upgrades/upgrades.py +++ b/src/design/plone/contenttypes/upgrades/upgrades.py @@ -335,7 +335,9 @@ def to_1016(context): sections.append({"title": item.title, "linkUrl": [item.UID()]}) settings = [{"rootPath": "/", "items": sections}] api.portal.set_registry_record( - "search_sections", json.dumps(settings), interface=IDesignPloneSettings, + "search_sections", + json.dumps(settings), + interface=IDesignPloneSettings, ) @@ -454,7 +456,9 @@ def to_3000(context): try: value = api.portal.get_registry_record(old_entry.format(field)) api.portal.set_registry_record( - field, json.dumps({"it": value}), interface=IDesignPloneSettings, + field, + json.dumps({"it": value}), + interface=IDesignPloneSettings, ) except Exception: continue @@ -1721,9 +1725,8 @@ def update_patrocinato_da(self): f"{colors.YELLOW} Nessuna informazione da modificare{colors.ENDC}" ) continue - logger.info( - f"{colors.GREEN} Modificato patrocinato_da per {obj.absolute_url()} {colors.ENDC}" - ) + url = obj.absolute_url() + logger.info(f"{colors.GREEN} patrocinato_da ({url}){colors.ENDC}") setattr( obj, From 0a0770cd8aa90ff5816fbb6792e246c5cf4e8736 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Fri, 24 Feb 2023 16:10:17 +0100 Subject: [PATCH 224/487] fix flake8 github action --- .github/workflows/flake8.yml | 4 ++-- .../browser/manage_content/templates/check_servizi.pt | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/flake8.yml b/.github/workflows/flake8.yml index 7ed6ab47..0fb3d9b7 100644 --- a/.github/workflows/flake8.yml +++ b/.github/workflows/flake8.yml @@ -30,6 +30,6 @@ jobs: - name: install flake8 run: pip install flake8 - # run black + # run flake8 - name: run flake8 - run: flake8 src/ setup.py --ignore E203 + run: flake8 src/ setup.py --ignore E203,W503 diff --git a/src/design/plone/contenttypes/browser/manage_content/templates/check_servizi.pt b/src/design/plone/contenttypes/browser/manage_content/templates/check_servizi.pt index e68f2a8b..bf28e80d 100644 --- a/src/design/plone/contenttypes/browser/manage_content/templates/check_servizi.pt +++ b/src/design/plone/contenttypes/browser/manage_content/templates/check_servizi.pt @@ -31,7 +31,7 @@ tal:condition="not:view/is_anonymous" tal:define="servizi view/get_servizi;">

    - La lista seguente elenca tutti quei servizi per i quali non sono + La lista seguente elenca tutti quei servizi per i quali non sono ancora stati aggiunti i campi che AGID indica come obbligatori. Ogni redattore può vedere in questa lista tutti i servizi e, cliccando su ognuno, andare alla vista di dettaglio del servizio, From 2c98e98750acbe18e03b4e6d4fc7f00e124f41a2 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Mon, 27 Feb 2023 11:12:17 +0100 Subject: [PATCH 225/487] fix check on news type --- src/design/plone/contenttypes/patches/baseserializer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/design/plone/contenttypes/patches/baseserializer.py b/src/design/plone/contenttypes/patches/baseserializer.py index 15c4231e..aa7a5c3c 100644 --- a/src/design/plone/contenttypes/patches/baseserializer.py +++ b/src/design/plone/contenttypes/patches/baseserializer.py @@ -43,7 +43,7 @@ def design_italia_serialize_to_json_call(self, version=None, include_items=True) title = taxonomy_voc.inv_data.get(self.context.tipologia_notizia, None) - if title.startswith(PATH_SEPARATOR): + if title and title.startswith(PATH_SEPARATOR): result["design_italia_meta_type"] = title.replace(PATH_SEPARATOR, "", 1) else: result["design_italia_meta_type"] = translate( From ca17e03f1089770840806ae4cf925b169e369de2 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Mon, 27 Feb 2023 11:21:56 +0100 Subject: [PATCH 226/487] Preparing release 6.0.0a19 --- CHANGES.rst | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 3690e0e3..95d8f307 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -2,7 +2,7 @@ Changelog ========= -6.0.0a19 (unreleased) +6.0.0a19 (2023-02-27) --------------------- - Change event schema: "patrocinato da" right now is a diff --git a/setup.py b/setup.py index 552c312b..aa4fecbb 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.0.0a19.dev0", + version="6.0.0a19", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 7979c50d3820d9b48412530a7269492c1cb4f7e4 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Mon, 27 Feb 2023 11:22:33 +0100 Subject: [PATCH 227/487] Back to development: 6.0.0a110 --- CHANGES.rst | 6 ++++++ setup.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 95d8f307..1e901234 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -2,6 +2,12 @@ Changelog ========= +6.0.0a110 (unreleased) +---------------------- + +- Nothing changed yet. + + 6.0.0a19 (2023-02-27) --------------------- diff --git a/setup.py b/setup.py index aa4fecbb..62d5641f 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.0.0a19", + version="6.0.0a110.dev0", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 8d2fc8c03547c6bf2ba087fb76d633310e47b2d2 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Mon, 27 Feb 2023 11:23:15 +0100 Subject: [PATCH 228/487] fix version --- CHANGES.rst | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 1e901234..b438aed9 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -2,7 +2,7 @@ Changelog ========= -6.0.0a110 (unreleased) +6.0.0a20 (unreleased) ---------------------- - Nothing changed yet. diff --git a/setup.py b/setup.py index 62d5641f..a4170b65 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.0.0a110.dev0", + version="6.0.0a20.dev0", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From bad68528eb8943eedc902fbb4f1059cdd98dc9d7 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Mon, 27 Feb 2023 14:33:38 +0100 Subject: [PATCH 229/487] add a new upgrade steps to fix event subfolder --- CHANGES.rst | 4 ++- .../profiles/default/metadata.xml | 2 +- .../contenttypes/upgrades/configure.zcml | 12 +++++++ .../plone/contenttypes/upgrades/upgrades.py | 34 +++++++++++++++++++ 4 files changed, 50 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index b438aed9..ff20345b 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -5,7 +5,9 @@ Changelog 6.0.0a20 (unreleased) ---------------------- -- Nothing changed yet. +- Add a new upgrade step to rename "multimedia" in "immagini" + under an event and add the new "video" folder. + [lucabel] 6.0.0a19 (2023-02-27) diff --git a/src/design/plone/contenttypes/profiles/default/metadata.xml b/src/design/plone/contenttypes/profiles/default/metadata.xml index 20db4e0f..7e8818e7 100644 --- a/src/design/plone/contenttypes/profiles/default/metadata.xml +++ b/src/design/plone/contenttypes/profiles/default/metadata.xml @@ -1,6 +1,6 @@ - 7007 + 7008 profile-redturtle.bandi:default profile-collective.venue:default diff --git a/src/design/plone/contenttypes/upgrades/configure.zcml b/src/design/plone/contenttypes/upgrades/configure.zcml index 74eb09f0..7d31b98b 100644 --- a/src/design/plone/contenttypes/upgrades/configure.zcml +++ b/src/design/plone/contenttypes/upgrades/configure.zcml @@ -712,4 +712,16 @@ handler=".upgrades.update_patrocinato_da" /> + + + + diff --git a/src/design/plone/contenttypes/upgrades/upgrades.py b/src/design/plone/contenttypes/upgrades/upgrades.py index db565006..768b3e39 100644 --- a/src/design/plone/contenttypes/upgrades/upgrades.py +++ b/src/design/plone/contenttypes/upgrades/upgrades.py @@ -6,6 +6,7 @@ from design.plone.contenttypes.controlpanels.settings import IDesignPloneSettings from design.plone.contenttypes.setuphandlers import remove_blocks_behavior from design.plone.contenttypes.upgrades.draftjs_converter import to_draftjs +from design.plone.contenttypes.utils import create_default_blocks from plone import api from plone.app.textfield.value import RichTextValue from plone.app.upgrade.utils import installOrReinstallProduct @@ -1756,3 +1757,36 @@ def update_patrocinato_da(self): ) obj.reindexObject() logger.info(f"{colors.DARKCYAN} End of update {colors.ENDC}") + + +def update_folder_for_gallery(self): + logger.info(f"{colors.DARKCYAN} Update events {colors.ENDC}") + pc = api.portal.get_tool(name="portal_catalog") + for brain in pc(portal_type="Event"): + evento = brain.getObject() + + logger.info(f"{colors.DARKCYAN} Event: {evento.absolute_url()} {colors.ENDC}") + if "multimedia" in evento.keys(): + renamed_event = api.content.rename(evento["multimedia"], new_id="immagini") + renamed_event.title = "Immagini" + renamed_event.reindexObject(idxs=["id", "title"]) + logger.info(f"{colors.GREEN} Rename multimedia {colors.ENDC}") + + if "video" not in evento.keys(): + galleria_video = api.content.create( + container=evento, + type="Document", + title="Video", + id="video", + ) + create_default_blocks(context=galleria_video) + + # select constraints + constraintsGalleriaVideo = ISelectableConstrainTypes(galleria_video) + constraintsGalleriaVideo.setConstrainTypesMode(1) + constraintsGalleriaVideo.setLocallyAllowedTypes(("Link",)) + + with api.env.adopt_roles(["Reviewer"]): + api.content.transition(obj=galleria_video, transition="publish") + + logger.info(f"{colors.GREEN} Create video {colors.ENDC}") From d7b241789842456a7982ff878abc22ece5dadae8 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Mon, 27 Feb 2023 14:40:25 +0100 Subject: [PATCH 230/487] Preparing release 6.0.0a20 --- CHANGES.rst | 4 ++-- setup.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index ff20345b..08e0a869 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -2,8 +2,8 @@ Changelog ========= -6.0.0a20 (unreleased) ----------------------- +6.0.0a20 (2023-02-27) +--------------------- - Add a new upgrade step to rename "multimedia" in "immagini" under an event and add the new "video" folder. diff --git a/setup.py b/setup.py index a4170b65..00068d94 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.0.0a20.dev0", + version="6.0.0a20", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From f6b4f1714512e0e63a9be28087a192d4ede0fdcd Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Mon, 27 Feb 2023 14:41:01 +0100 Subject: [PATCH 231/487] Back to development: 6.0.0a21 --- CHANGES.rst | 6 ++++++ setup.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 08e0a869..6b62708e 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -2,6 +2,12 @@ Changelog ========= +6.0.0a21 (unreleased) +--------------------- + +- Nothing changed yet. + + 6.0.0a20 (2023-02-27) --------------------- diff --git a/setup.py b/setup.py index 00068d94..76cf1eb9 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.0.0a20", + version="6.0.0a21.dev0", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 968a51472606622f8ff786aa63a786d475e0fd4a Mon Sep 17 00:00:00 2001 From: Mauro Amico Date: Mon, 27 Feb 2023 16:13:42 +0100 Subject: [PATCH 232/487] ci: temp remove tests on 3.10 / 3.11 --- .github/workflows/test.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index bceb9e40..84982c63 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,7 +8,8 @@ jobs: strategy: max-parallel: 4 matrix: - python: ["3.8", "3.9", "3.10", "3.11"] + python: ["3.8", "3.9"] + # , "3.10", "3.11"] plone: ["60"] # exclude: # - python: "3.7" From 08e4126ebe3157cb3ffba58bc744e4db1b6ecef3 Mon Sep 17 00:00:00 2001 From: Andrea Cecchi Date: Tue, 28 Feb 2023 12:21:30 +0100 Subject: [PATCH 233/487] fix: better handle default language in upgrade-step --- src/design/plone/contenttypes/upgrades/upgrades.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/design/plone/contenttypes/upgrades/upgrades.py b/src/design/plone/contenttypes/upgrades/upgrades.py index 768b3e39..fbaba1eb 100644 --- a/src/design/plone/contenttypes/upgrades/upgrades.py +++ b/src/design/plone/contenttypes/upgrades/upgrades.py @@ -1544,7 +1544,7 @@ def update_taxonomies(context): ) for brain in brains: obj = brain.getObject() - obj_language = getattr(obj, "language", "it") + obj_language = getattr(obj, "language", "it") or "it" for taxonomy in TYPE_TO_TAXONOMIES_MAPPING[portal_type]: old_value = getattr(obj, taxonomy) if ( From 2d13017c3d16c4b3d92b264bade6006ac0bbd6f5 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Wed, 1 Mar 2023 12:07:51 +0100 Subject: [PATCH 234/487] update changes --- CHANGES.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 6b62708e..e95d6932 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -5,7 +5,8 @@ Changelog 6.0.0a21 (unreleased) --------------------- -- Nothing changed yet. +- Better handle default language in upgrade-step + [cekk] 6.0.0a20 (2023-02-27) From edb652c24e6a7ed49f1c4aa00b4e464b5035b9ed Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Wed, 1 Mar 2023 12:08:23 +0100 Subject: [PATCH 235/487] Preparing release 6.0.0a21 --- CHANGES.rst | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index e95d6932..6f1051a1 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -2,7 +2,7 @@ Changelog ========= -6.0.0a21 (unreleased) +6.0.0a21 (2023-03-01) --------------------- - Better handle default language in upgrade-step diff --git a/setup.py b/setup.py index 76cf1eb9..77c09a4b 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.0.0a21.dev0", + version="6.0.0a21", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 1ed8a50a392042b1fd2ec44921e623500827dc27 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Wed, 1 Mar 2023 12:08:59 +0100 Subject: [PATCH 236/487] Back to development: 6.0.0a22 --- CHANGES.rst | 6 ++++++ setup.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 6f1051a1..515d389e 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -2,6 +2,12 @@ Changelog ========= +6.0.0a22 (unreleased) +--------------------- + +- Nothing changed yet. + + 6.0.0a21 (2023-03-01) --------------------- diff --git a/setup.py b/setup.py index 77c09a4b..962e2aa0 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.0.0a21", + version="6.0.0a22.dev0", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 5f023e26d2f5689b01985b11514fa965aa6f1c52 Mon Sep 17 00:00:00 2001 From: Mauro Amico Date: Fri, 3 Mar 2023 09:01:43 +0100 Subject: [PATCH 237/487] Fix tests per branch pnrr (#158) --- .github/workflows/test.yml | 25 +- .gitignore | 1 + README.md | 9 + base.cfg | 24 ++ .../manage_content/change_news_type.py | 4 + .../contenttypes/patches/baseserializer.py | 9 +- .../taxonomies/tipologia_documento.xml | 2 +- .../profiles/default/types/News_Item.xml | 18 +- .../restapi/serializers/dxcontent.py | 18 +- .../restapi/serializers/summary.py | 16 +- .../tests/test_base_serializer.py | 10 +- .../tests/test_behavior_descrizione_estesa.py | 1 + .../contenttypes/tests/test_behavior_luogo.py | 1 + .../tests/test_behavior_show_modified.py | 1 + .../tests/test_behavior_update_note.py | 1 + .../contenttypes/tests/test_ct_documento.py | 6 + .../plone/contenttypes/tests/test_ct_event.py | 28 ++- .../plone/contenttypes/tests/test_ct_luogo.py | 46 +++- .../plone/contenttypes/tests/test_ct_news.py | 85 +++++-- .../contenttypes/tests/test_ct_persona.py | 3 +- .../contenttypes/tests/test_ct_servizio.py | 14 +- .../tests/test_ct_unita_organizzativa.py | 14 +- .../tests/test_relateditems_with_dates.py | 4 +- .../plone/contenttypes/tests/test_setup.py | 29 ++- .../tests/test_summary_serializer.py | 81 +++--- .../contenttypes/tests/test_vocabularies.py | 234 +++++++++--------- .../plone/contenttypes/upgrades/upgrades.py | 6 - test_plone60.cfg | 4 + 28 files changed, 434 insertions(+), 260 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 84982c63..fd16c996 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,21 +8,20 @@ jobs: strategy: max-parallel: 4 matrix: - python: ["3.8", "3.9"] - # , "3.10", "3.11"] + python: ["3.8", "3.9", "3.10", "3.11"] plone: ["60"] # exclude: # - python: "3.7" # plone: "51" steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v3 - name: Cache eggs - uses: actions/cache@v1 + uses: actions/cache@v3 with: path: eggs key: ${{ runner.OS }}-build-python${{ matrix.python }}-${{ matrix.plone }} - name: Set up Python ${{ matrix.python }} - uses: actions/setup-python@v1 + uses: actions/setup-python@v3 with: python-version: ${{ matrix.python }} - name: Install dependencies @@ -34,4 +33,18 @@ jobs: buildout -N -t 3 - name: Run tests run: | - bin/test + bin/test-coverage + - name: Coveralls + uses: AndreMiras/coveralls-python-action@develop + with: + parallel: true + flag-name: ${{ matrix.plone }}-${{ matrix.python }} + + coveralls_finish: + needs: build + runs-on: ubuntu-latest + steps: + - name: Coveralls Finished + uses: AndreMiras/coveralls-python-action@develop + with: + parallel-finished: true diff --git a/.gitignore b/.gitignore index e376ec3b..032b4ebf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ .DS_Store .python-version .coverage +coverage.json *.egg-info *.log *.mo diff --git a/README.md b/README.md index 051edb95..c0aa6f76 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,15 @@ + +[![Latest Version](https://img.shields.io/pypi/v/design.plone.contenttypes.svg)](https://pypi.python.org/pypi/design.plone.contenttypes/) +[![Supported - Python Versions](https://img.shields.io/pypi/pyversions/design.plone.contenttypes.svg?style=plastic)](https://pypi.python.org/pypi/design.plone.contenttypes/) +[![Number of PyPI downloads](https://img.shields.io/pypi/dm/design.plone.contenttypes.svg)](https://pypi.python.org/pypi/design.plone.contenttypes/) +[![License](https://img.shields.io/pypi/l/design.plone.contenttypes.svg)](https://pypi.python.org/pypi/design.plone.contenttypes/) +[![Tests](https://github.com/collective/design.plone.contenttypes/actions/workflows/tests.yml/badge.svg)](https://github.com/collective/design.plone.contenttypes/actions) +[![Coverage](https://coveralls.io/repos/github/collective/design.plone.contenttypes/badge.svg?branch=master)](https://coveralls.io/github/collective/design.plone.contenttypes?branch=master) + + - [Design Plone Content-types](#design-plone-content-types) - [Features](#features) - [Tipi di contenuto](#tipi-di-contenuto) diff --git a/base.cfg b/base.cfg index 6cab78b7..ac8646cd 100644 --- a/base.cfg +++ b/base.cfg @@ -15,6 +15,9 @@ parts = plone-helper-scripts zpretty zpretty-run + createcoverage + coverage + test-coverage develop = . sources-dir = extras @@ -108,6 +111,27 @@ input = inline: output = ${buildout:directory}/bin/zpretty-run mode = 755 +[coverage] +recipe = zc.recipe.egg +eggs = coverage + +[test-coverage] +recipe = collective.recipe.template +input = inline: + #!/bin/bash + export TZ=UTC + ${buildout:directory}/bin/coverage run bin/test $* + ${buildout:directory}/bin/coverage html + ${buildout:directory}/bin/coverage report -m --fail-under=75 + # Fail (exit status 1) if coverage returns exit status 2 (this happens + # when test coverage is below 100%. + ${buildout:directory}/bin/coverage json -i +output = ${buildout:directory}/bin/test-coverage +mode = 755 + +[createcoverage] +recipe = zc.recipe.egg +eggs = createcoverage [versions] # Don't use a released version of design.plone.contenttypes diff --git a/src/design/plone/contenttypes/browser/manage_content/change_news_type.py b/src/design/plone/contenttypes/browser/manage_content/change_news_type.py index 7799d7fb..4c0f674b 100644 --- a/src/design/plone/contenttypes/browser/manage_content/change_news_type.py +++ b/src/design/plone/contenttypes/browser/manage_content/change_news_type.py @@ -8,6 +8,8 @@ from zope.component import getUtility from zope.interface.interfaces import ComponentLookupError +import json + logger = getLogger(__name__) @@ -83,6 +85,8 @@ def substitute_news_type(self): blocks = deepcopy(item.blocks) if blocks: + if isinstance(blocks, str): + blocks = json.loads(blocks) for block in blocks.values(): if block.get("@type", "") == "listing": for query in block.get("querystring", {}).get("query", []): diff --git a/src/design/plone/contenttypes/patches/baseserializer.py b/src/design/plone/contenttypes/patches/baseserializer.py index aa7a5c3c..1ac8ca6d 100644 --- a/src/design/plone/contenttypes/patches/baseserializer.py +++ b/src/design/plone/contenttypes/patches/baseserializer.py @@ -33,7 +33,9 @@ def design_italia_serialize_to_json_call(self, version=None, include_items=True) result = original_serialize_to_json__call__( self, version=version, include_items=include_items ) - + result["design_italia_meta_type"] = translate( + ttool[self.context.portal_type].Title(), context=self.request + ) if self.context.portal_type == "News Item": if self.context.tipologia_notizia: taxonomy = getUtility( @@ -45,11 +47,6 @@ def design_italia_serialize_to_json_call(self, version=None, include_items=True) if title and title.startswith(PATH_SEPARATOR): result["design_italia_meta_type"] = title.replace(PATH_SEPARATOR, "", 1) - else: - result["design_italia_meta_type"] = translate( - ttool[self.context.portal_type].Title(), context=self.request - ) - return result diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_documento.xml b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_documento.xml index 501f0afc..cea0a288 100644 --- a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_documento.xml +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_documento.xml @@ -43,7 +43,7 @@ documento_attivita_politica - Documento attivita politica + Documento attività politica diff --git a/src/design/plone/contenttypes/profiles/default/types/News_Item.xml b/src/design/plone/contenttypes/profiles/default/types/News_Item.xml index 7ab7dba2..9e540e0a 100644 --- a/src/design/plone/contenttypes/profiles/default/types/News_Item.xml +++ b/src/design/plone/contenttypes/profiles/default/types/News_Item.xml @@ -5,23 +5,15 @@ i18n:domain="plone" > - - Notizie e comunicati stampa - + Notizie e comunicati stampa - + - + @@ -30,9 +22,7 @@ - +

diff --git a/src/design/plone/contenttypes/restapi/serializers/dxcontent.py b/src/design/plone/contenttypes/restapi/serializers/dxcontent.py index ea345dff..c499da46 100644 --- a/src/design/plone/contenttypes/restapi/serializers/dxcontent.py +++ b/src/design/plone/contenttypes/restapi/serializers/dxcontent.py @@ -24,6 +24,9 @@ def __call__(self, version=None, include_items=True): version=version, include_items=include_items ) ttool = api.portal.get_tool("portal_types") + result["design_italia_meta_type"] = translate( + ttool[self.context.portal_type].Title(), context=self.request + ) if self.context.portal_type == "News Item": if self.context.tipologia_notizia: taxonomy = getUtility( @@ -33,14 +36,10 @@ def __call__(self, version=None, include_items=True): title = taxonomy_voc.inv_data.get(self.context.tipologia_notizia, None) - if title.startswith(PATH_SEPARATOR): + if title and title.startswith(PATH_SEPARATOR): result["design_italia_meta_type"] = title.replace( PATH_SEPARATOR, "", 1 ) - else: - result["design_italia_meta_type"] = translate( - ttool[self.context.portal_type].Title(), context=self.request - ) return result @@ -54,6 +53,9 @@ def __call__(self, version=None, include_items=True): result["@id"] = self.context.absolute_url() ttool = api.portal.get_tool("portal_types") + result["design_italia_meta_type"] = translate( + ttool[self.context.portal_type].Title(), context=self.request + ) if self.context.portal_type == "News Item": if self.context.tipologia_notizia: taxonomy = getUtility( @@ -63,14 +65,10 @@ def __call__(self, version=None, include_items=True): title = taxonomy_voc.inv_data.get(self.context.tipologia_notizia, None) - if title.startswith(PATH_SEPARATOR): + if title and title.startswith(PATH_SEPARATOR): result["design_italia_meta_type"] = title.replace( PATH_SEPARATOR, "", 1 ) - else: - result["design_italia_meta_type"] = translate( - ttool[self.context.portal_type].Title(), context=self.request - ) if "items_total" not in result: # siamo in un sotto-elemento di quello richiesto dalla query. #  ritorniamo il numero di elementi totale, senza doverli ritornare diff --git a/src/design/plone/contenttypes/restapi/serializers/summary.py b/src/design/plone/contenttypes/restapi/serializers/summary.py index 1fba75c8..e55b0e96 100644 --- a/src/design/plone/contenttypes/restapi/serializers/summary.py +++ b/src/design/plone/contenttypes/restapi/serializers/summary.py @@ -54,8 +54,7 @@ def get_taxonomy_information(field_name, context, res): fullterms = [] # delle volte posso avere il brain senza quel dato if field_name not in res: - res[field_name] = getattr(context, field_name, []) - + res[field_name] = getattr(context, field_name, None) or [] for token in res[field_name]: title = taxonomy_voc.inv_data.get(token, None) if title and title.startswith(PATH_SEPARATOR): @@ -182,14 +181,11 @@ def get_design_meta_type(self): else: token = self.context.tipologia_notizia title = taxonomy_voc.inv_data.get(token, None) - if title and title.startswith(PATH_SEPARATOR): - title = title.replace(PATH_SEPARATOR, "", 1) - - return title - else: - return translate( - ttool[self.context.portal_type].Title(), context=self.request - ) + if title: + if title.startswith(PATH_SEPARATOR): + title = title.replace(PATH_SEPARATOR, "", 1) + return title + return translate(ttool[self.context.portal_type].Title(), context=self.request) def expand_tassonomia_argomenti(self): try: diff --git a/src/design/plone/contenttypes/tests/test_base_serializer.py b/src/design/plone/contenttypes/tests/test_base_serializer.py index 048dc102..59e0753c 100644 --- a/src/design/plone/contenttypes/tests/test_base_serializer.py +++ b/src/design/plone/contenttypes/tests/test_base_serializer.py @@ -48,8 +48,9 @@ def test_design_italia_meta_type_with_news(self): Other types shoule return their own portal_type. """ response_news = self.api_session.get(self.news.absolute_url() + "?fullobjects") - self.assertTrue( - response_news.json()["design_italia_meta_type"] == "Comunicati stampa" + self.assertEqual( + response_news.json()["design_italia_meta_type"], + "Notizie e comunicati stampa", ) def test_design_italia_meta_type_with_type_different_from_news(self): @@ -60,6 +61,7 @@ def test_design_italia_meta_type_with_type_different_from_news(self): response_service = self.api_session.get( self.service.absolute_url() + "?fullobjects" ) - self.assertTrue( - response_service.json()["design_italia_meta_type"] == "Servizio" + self.assertEqual( + response_service.json()["design_italia_meta_type"], + "Servizio", ) diff --git a/src/design/plone/contenttypes/tests/test_behavior_descrizione_estesa.py b/src/design/plone/contenttypes/tests/test_behavior_descrizione_estesa.py index 3386e56f..8876e3ea 100644 --- a/src/design/plone/contenttypes/tests/test_behavior_descrizione_estesa.py +++ b/src/design/plone/contenttypes/tests/test_behavior_descrizione_estesa.py @@ -16,6 +16,7 @@ class TestDescrizioneEstesaBehavior(unittest.TestCase): layer = DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING + maxDiff = None def setUp(self): self.app = self.layer["app"] diff --git a/src/design/plone/contenttypes/tests/test_behavior_luogo.py b/src/design/plone/contenttypes/tests/test_behavior_luogo.py index 14d959d4..9149c3ee 100644 --- a/src/design/plone/contenttypes/tests/test_behavior_luogo.py +++ b/src/design/plone/contenttypes/tests/test_behavior_luogo.py @@ -13,6 +13,7 @@ class LuogoBehaviorIndexerFunctionalTest(unittest.TestCase): layer = DESIGN_PLONE_CONTENTTYPES_FUNCTIONAL_TESTING + maxDiff = None def setUp(self): self.portal = self.layer["portal"] diff --git a/src/design/plone/contenttypes/tests/test_behavior_show_modified.py b/src/design/plone/contenttypes/tests/test_behavior_show_modified.py index b8eecc1c..9374d09a 100644 --- a/src/design/plone/contenttypes/tests/test_behavior_show_modified.py +++ b/src/design/plone/contenttypes/tests/test_behavior_show_modified.py @@ -18,6 +18,7 @@ class TestShowModifiedBehavior(unittest.TestCase): layer = DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING + maxDiff = None def setUp(self): self.app = self.layer["app"] diff --git a/src/design/plone/contenttypes/tests/test_behavior_update_note.py b/src/design/plone/contenttypes/tests/test_behavior_update_note.py index dba7e57a..8c700b0f 100644 --- a/src/design/plone/contenttypes/tests/test_behavior_update_note.py +++ b/src/design/plone/contenttypes/tests/test_behavior_update_note.py @@ -17,6 +17,7 @@ class TestUpdateNoteBehavior(unittest.TestCase): layer = DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING + maxDiff = None def setUp(self): self.app = self.layer["app"] diff --git a/src/design/plone/contenttypes/tests/test_ct_documento.py b/src/design/plone/contenttypes/tests/test_ct_documento.py index 6ec688a1..15fd5d82 100644 --- a/src/design/plone/contenttypes/tests/test_ct_documento.py +++ b/src/design/plone/contenttypes/tests/test_ct_documento.py @@ -21,6 +21,7 @@ class TestDocument(unittest.TestCase): layer = DESIGN_PLONE_CONTENTTYPES_INTEGRATION_TESTING + maxDiff = None def setUp(self): """Custom shared utility setup for tests.""" @@ -48,6 +49,11 @@ def test_behaviors_enabled_for_documento(self): "plone.translatable", "kitconcept.seo", "plone.versioning", + "collective.taxonomy.generated.person_life_events", + "collective.taxonomy.generated.business_events", + "collective.taxonomy.generated.tipologia_documenti_albopretorio", + "collective.taxonomy.generated.tipologia_documento", + "collective.taxonomy.generated.tipologia_licenze", ), ) diff --git a/src/design/plone/contenttypes/tests/test_ct_event.py b/src/design/plone/contenttypes/tests/test_ct_event.py index 600c8442..7b177f19 100644 --- a/src/design/plone/contenttypes/tests/test_ct_event.py +++ b/src/design/plone/contenttypes/tests/test_ct_event.py @@ -21,6 +21,7 @@ class TestEvent(unittest.TestCase): layer = DESIGN_PLONE_CONTENTTYPES_INTEGRATION_TESTING + maxDiff = None def setUp(self): """Custom shared utility setup for tests.""" @@ -34,7 +35,7 @@ def test_behaviors_enabled_for_event(self): "plone.eventbasic", "plone.leadimage", "volto.preview_image", - "design.plone.contenttypes.behavior.argomenti", + "design.plone.contenttypes.behavior.argomenti_evento", "plone.eventrecurrence", "design.plone.contenttypes.behavior.additional_help_infos", "design.plone.contenttypes.behavior.evento", @@ -42,6 +43,7 @@ def test_behaviors_enabled_for_event(self): "design.plone.contenttypes.behavior.address_event", "design.plone.contenttypes.behavior.geolocation_event", "design.plone.contenttypes.behavior.strutture_correlate", + "design.plone.contenttypes.behavior.contatti_event", "plone.dublincore", "plone.namefromtitle", "plone.allowdiscussion", @@ -54,6 +56,7 @@ def test_behaviors_enabled_for_event(self): "plone.textindexer", "plone.translatable", "kitconcept.seo", + "collective.taxonomy.generated.tipologia_evento", ), ) @@ -90,13 +93,13 @@ def test_event_substructure_created(self): event = self.portal["evento"] self.assertEqual( - sorted(["multimedia", "documenti", "sponsor_evento"]), + sorted(["documenti", "immagini", "sponsor_evento", "video"]), sorted(event.keys()), ) - self.assertEqual(event["multimedia"].portal_type, "Document") - self.assertEqual(event["multimedia"].constrain_types_mode, 1) - self.assertEqual(event["multimedia"].locally_allowed_types, ("Image", "Link")) + self.assertEqual(event["immagini"].portal_type, "Document") + self.assertEqual(event["immagini"].constrain_types_mode, 1) + self.assertEqual(event["immagini"].locally_allowed_types, ("Image", "Link")) self.assertEqual(event["sponsor_evento"].portal_type, "Document") self.assertEqual(event["sponsor_evento"].constrain_types_mode, 1) @@ -106,10 +109,13 @@ def test_event_substructure_created(self): self.assertEqual(event["documenti"].constrain_types_mode, 1) self.assertEqual(event["documenti"].locally_allowed_types, ("File",)) - multimedia_wf = api.content.get_state(obj=event["multimedia"]) - sponsor_wf = api.content.get_state(obj=event["sponsor_evento"]) - documenti_wf = api.content.get_state(obj=event["documenti"]) + self.assertEqual(event["video"].portal_type, "Document") + self.assertEqual(event["video"].constrain_types_mode, 1) + self.assertEqual(event["video"].locally_allowed_types, ("Link",)) - self.assertEqual(multimedia_wf, "published") - self.assertEqual(sponsor_wf, "published") - self.assertEqual(documenti_wf, "published") + self.assertEqual(api.content.get_state(obj=event["immagini"]), "published") + self.assertEqual(api.content.get_state(obj=event["video"]), "published") + self.assertEqual( + api.content.get_state(obj=event["sponsor_evento"]), "published" + ) + self.assertEqual(api.content.get_state(obj=event["documenti"]), "published") diff --git a/src/design/plone/contenttypes/tests/test_ct_luogo.py b/src/design/plone/contenttypes/tests/test_ct_luogo.py index 01d89774..80247ab9 100644 --- a/src/design/plone/contenttypes/tests/test_ct_luogo.py +++ b/src/design/plone/contenttypes/tests/test_ct_luogo.py @@ -14,6 +14,7 @@ from plone.restapi.testing import RelativeSession from Products.CMFPlone.utils import getToolByName from transaction import commit +from uuid import uuid4 from z3c.relationfield import RelationValue from zope.component import getUtility from zope.intid.interfaces import IIntIds @@ -23,6 +24,7 @@ class TestLuogo(unittest.TestCase): layer = DESIGN_PLONE_CONTENTTYPES_INTEGRATION_TESTING + maxDiff = None def setUp(self): """Custom shared utility setup for tests.""" @@ -46,10 +48,12 @@ def test_behaviors_enabled_for_luogo(self): "design.plone.contenttypes.behavior.address_venue", "design.plone.contenttypes.behavior.geolocation_venue", "design.plone.contenttypes.behavior.additional_help_infos", + "design.plone.contenttypes.behavior.luoghi_correlati", "plone.textindexer", "plone.translatable", "kitconcept.seo", "plone.versioning", + "collective.taxonomy.generated.tipologia_luogo", ), ) @@ -125,11 +129,14 @@ def test_venue_geolocation_deserializer_wrong_structure(self): venue.absolute_url(), json={"@type": "Venue", "title": "Foo", "geolocation": {"foo": "bar"}}, ) - message = response.json()["message"] + # message = response.json()["message"] self.assertEqual(400, response.status_code) - self.assertIn("Invalid geolocation data", message) - self.assertEqual(venue.geolocation, None) + # TODO: anzichè `invalid geolocation data` ritorna + # `Il campo geolocation è obbligatorio` + # self.assertIn("Invalid geolocation data", message) + # TODO: i dati vanno verificati con una chiamata alla api_session + # self.assertEqual(venue.geolocation, None) def test_venue_geolocation_deserializer_right_structure(self): venue = api.content.create( @@ -147,11 +154,36 @@ def test_venue_geolocation_deserializer_right_structure(self): "geolocation": {"latitude": 11.0, "longitude": 10.0}, }, ) - commit() - self.assertEqual(204, response.status_code) - self.assertEqual(venue.geolocation.latitude, 11.0) - self.assertEqual(venue.geolocation.longitude, 10.0) + self.assertEqual(response.status_code, 400) + self.assertEqual( + response.json()["message"], + "[{'error': 'ValidationError', " + "'message': 'Il campo modalita_accesso è obbligatorio'}]", + ) + + text_uuid = str(uuid4()) + response = self.api_session.patch( + venue.absolute_url(), + json={ + "@type": "Venue", + "title": "Foo", + "geolocation": {"latitude": 11.0, "longitude": 10.0}, + "modalita_accesso": { + "blocks": { + text_uuid: { + "@type": "text", + "text": {"blocks": [{"text": "Test", "type": "paragraph"}]}, + } + }, + "blocks_layout": {"items": [text_uuid]}, + }, + }, + ) + self.assertEqual(response.status_code, 204) + # TODO: i dati vanno verificati con una chiamata alla api_session + # self.assertEqual(venue.geolocation.longitude, 10.0) + # self.assert ... (venue.modalita_accesso) def test_venue_services(self): response = self.api_session.get(self.venue.absolute_url() + "?fullobjects") diff --git a/src/design/plone/contenttypes/tests/test_ct_news.py b/src/design/plone/contenttypes/tests/test_ct_news.py index 47c0f94d..3a7b79c5 100644 --- a/src/design/plone/contenttypes/tests/test_ct_news.py +++ b/src/design/plone/contenttypes/tests/test_ct_news.py @@ -12,6 +12,7 @@ from plone.app.testing import SITE_OWNER_PASSWORD from plone.app.testing import TEST_USER_ID from plone.restapi.testing import RelativeSession +from uuid import uuid4 import json import transaction @@ -20,6 +21,7 @@ class TestNews(unittest.TestCase): layer = DESIGN_PLONE_CONTENTTYPES_INTEGRATION_TESTING + maxDiff = None def setUp(self): """Custom shared utility setup for tests.""" @@ -42,11 +44,12 @@ def test_behaviors_enabled_for_news(self): "plone.locking", "volto.preview_image", "design.plone.contenttypes.behavior.news", - "design.plone.contenttypes.behavior.argomenti", + "design.plone.contenttypes.behavior.argomenti_news", "plone.constraintypes", "plone.textindexer", "plone.translatable", "kitconcept.seo", + "collective.taxonomy.generated.tipologia_notizia", ), ) @@ -96,43 +99,89 @@ def test_newsitem_required_fields(self): self.portal_url, json={"@type": "News Item", "title": "Foo"} ) - self.assertEqual(400, response.status_code) + self.assertEqual(response.status_code, 400) message = response.json()["message"] - self.assertIn("tipologia_notizia", message) + # TODO: anche `tipologia_notizia` è obbligatorio ? + # self.assertIn("tipologia_notizia", message) + self.assertIn("descrizione_estesa", message) + text_uuid = str(uuid4()) response = self.api_session.post( self.portal_url, json={ "@type": "News Item", "title": "Foo", - "tipologia_notizia": "foo", + # TODO: se la tipologia non è nel vocabolario della + # tassonomia, il server restituisce un errore 500 + # "tipologia_notizia": "foo", + "tipologia_notizia": "avviso", "a_cura_di": self.document.UID(), + # campo obbligatorio + "description": "Test", + # campo obbligatorio + "descrizione_estesa": { + "blocks": { + text_uuid: { + "@type": "text", + "text": {"blocks": [{"text": "Test", "type": "paragraph"}]}, + }, + }, + "blocks_layout": {"items": [text_uuid]}, + }, }, ) - self.assertEqual(201, response.status_code) + self.assertEqual(response.status_code, 201) def test_newsitem_substructure_created(self): - self.api_session.post( + text_uuid = str(uuid4()) + response = self.api_session.post( self.portal_url, json={ "@type": "News Item", "title": "Foo", - "tipologia_notizia": "foo", + # TODO: se la tipologia non è nel vocabolario della + # tassonomia, il server restituisce un errore 500 + # "tipologia_notizia": "foo", + "tipologia_notizia": "avviso", "a_cura_di": self.document.UID(), + # campo obbligatorio + "description": "Test", + # campo obbligatorio + "descrizione_estesa": { + "blocks": { + text_uuid: { + "@type": "text", + "text": {"blocks": [{"text": "Test", "type": "paragraph"}]}, + }, + }, + "blocks_layout": {"items": [text_uuid]}, + }, }, ) + self.assertEqual(response.status_code, 201) - transaction.commit() - news = self.portal["foo"] - - self.assertEqual(["multimedia", "documenti-allegati"], news.keys()) - - self.assertEqual(news["multimedia"].portal_type, "Document") - self.assertEqual(news["multimedia"].constrain_types_mode, 1) - self.assertEqual(news["multimedia"].locally_allowed_types, ("Link", "Image")) + response = self.api_session.get( + f"{self.portal_url}/foo", params={"fullobjects": 1} + ) + self.assertEqual(response.status_code, 200) + news = response.json() - self.assertEqual(news["documenti-allegati"].portal_type, "Document") - self.assertEqual(news["documenti-allegati"].constrain_types_mode, 1) self.assertEqual( - news["documenti-allegati"].locally_allowed_types, ("File", "Image") + set([i["id"] for i in news["items"]]), + set(["multimedia", "documenti-allegati"]), + ) + self.assertEqual(news["description"], "Test") + self.assertIn( + '"text": "Test"', + json.dumps(news["descrizione_estesa"]), ) + + # self.assertEqual(news["multimedia"].portal_type, "Document") + # self.assertEqual(news["multimedia"].constrain_types_mode, 1) + # self.assertEqual(news["multimedia"].locally_allowed_types, ("Link", "Image")) + + # self.assertEqual(news["documenti-allegati"].portal_type, "Document") + # self.assertEqual(news["documenti-allegati"].constrain_types_mode, 1) + # self.assertEqual( + # news["documenti-allegati"].locally_allowed_types, ("File", "Image") + # ) diff --git a/src/design/plone/contenttypes/tests/test_ct_persona.py b/src/design/plone/contenttypes/tests/test_ct_persona.py index d9641ec7..540374ef 100644 --- a/src/design/plone/contenttypes/tests/test_ct_persona.py +++ b/src/design/plone/contenttypes/tests/test_ct_persona.py @@ -43,6 +43,7 @@ def test_behaviors_enabled_for_persona(self): "plone.basic", "plone.locking", "design.plone.contenttypes.behavior.additional_help_infos", + "design.plone.contenttypes.behavior.contatti_persona", "plone.textindexer", "plone.translatable", "kitconcept.seo", @@ -52,7 +53,7 @@ def test_behaviors_enabled_for_persona(self): def test_persona_ct_title(self): portal_types = api.portal.get_tool(name="portal_types") - self.assertEqual("Persona", portal_types["Persona"].title) + self.assertEqual("Persona pubblica", portal_types["Persona"].title) class TestPersonaEndpoint(unittest.TestCase): diff --git a/src/design/plone/contenttypes/tests/test_ct_servizio.py b/src/design/plone/contenttypes/tests/test_ct_servizio.py index 0274a5c8..487dc35d 100644 --- a/src/design/plone/contenttypes/tests/test_ct_servizio.py +++ b/src/design/plone/contenttypes/tests/test_ct_servizio.py @@ -1,11 +1,11 @@ # -*- coding: utf-8 -*- """Setup tests for this package.""" -from design.plone.contenttypes.testing import ( # noqa +from design.plone.contenttypes.testing import ( DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING, -) -from design.plone.contenttypes.testing import ( # noqa +) # noqa +from design.plone.contenttypes.testing import ( DESIGN_PLONE_CONTENTTYPES_INTEGRATION_TESTING, -) +) # noqa from plone import api from plone.app.testing import setRoles from plone.app.testing import SITE_OWNER_NAME @@ -45,6 +45,7 @@ class TestServizio(unittest.TestCase): layer = DESIGN_PLONE_CONTENTTYPES_INTEGRATION_TESTING + maxDiff = None def setUp(self): """Custom shared utility setup for tests.""" @@ -69,12 +70,15 @@ def test_behaviors_enabled_for_servizio(self): "plone.leadimage", "volto.preview_image", "plone.relateditems", - "design.plone.contenttypes.behavior.argomenti", + "design.plone.contenttypes.behavior.argomenti_servizio", "design.plone.contenttypes.behavior.additional_help_infos", + "design.plone.contenttypes.behavior.contatti_servizio", "plone.textindexer", "plone.translatable", "kitconcept.seo", "plone.versioning", + "collective.taxonomy.generated.person_life_events", + "collective.taxonomy.generated.business_events", ), ) diff --git a/src/design/plone/contenttypes/tests/test_ct_unita_organizzativa.py b/src/design/plone/contenttypes/tests/test_ct_unita_organizzativa.py index 2d35e2de..5c433cb1 100644 --- a/src/design/plone/contenttypes/tests/test_ct_unita_organizzativa.py +++ b/src/design/plone/contenttypes/tests/test_ct_unita_organizzativa.py @@ -25,6 +25,7 @@ class TestUO(unittest.TestCase): """Test that design.plone.contenttypes is properly installed.""" layer = DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING + maxDiff = None def setUp(self): self.app = self.layer["app"] @@ -107,8 +108,8 @@ def test_behaviors_enabled_for_uo(self): "plone.leadimage", "volto.preview_image", "plone.relateditems", - "design.plone.contenttypes.behavior.address_uo", - "design.plone.contenttypes.behavior.geolocation_uo", + # "design.plone.contenttypes.behavior.address_uo", + # "design.plone.contenttypes.behavior.geolocation_uo", "design.plone.contenttypes.behavior.contatti_uo", "design.plone.contenttypes.behavior.argomenti", "plone.textindexer", @@ -116,6 +117,7 @@ def test_behaviors_enabled_for_uo(self): "plone.translatable", "kitconcept.seo", "plone.versioning", + "collective.taxonomy.generated.tipologia_organizzazione", ), ) @@ -160,7 +162,7 @@ def test_uo_sede_data(self): "riferimento_pec_struttura", ] for field in fields: - self.assertEqual(sede[field], getattr(self.luogo, field, "")) + self.assertEqual(sede[field], getattr(self.luogo, field, None)) def test_uo_location_indexer_populated(self): pc = api.portal.get_tool(name="portal_catalog") @@ -213,12 +215,14 @@ def test_uo_locations_vocabulary_populated(self): def test_do_not_show_parent_uo_if_not_present(self): response = self.api_session.get(self.uo.absolute_url()) + self.assertEqual(response.status_code, 200) uo_parent = response.json()["uo_parent"] self.assertIsNone(uo_parent) def test_show_parent_uo_if_present(self): response = self.api_session.get(self.uo_child.absolute_url()) + self.assertEqual(response.status_code, 200) uo_parent = response.json()["uo_parent"] self.assertIsNotNone(uo_parent) @@ -230,12 +234,14 @@ def test_show_parent_uo_if_present(self): def test_do_not_show_children_uo_if_not_present(self): response = self.api_session.get(self.uo_child.absolute_url()) + self.assertEqual(response.status_code, 200) uo_children = response.json()["uo_children"] self.assertEqual(uo_children, []) def test_show_children_uo_if_present(self): response = self.api_session.get(self.uo.absolute_url()) + self.assertEqual(response.status_code, 200) uo_children = response.json()["uo_children"] self.assertEqual(len(uo_children), 1) @@ -255,7 +261,7 @@ def test_backref_to_servizio_dove_rivolgersi(self): transaction.commit() response = self.api_session.get(self.uo.absolute_url()) - + self.assertEqual(response.status_code, 200) self.assertIn( self.service.absolute_url(), [i["@id"] for i in response.json()["prestazioni"]], diff --git a/src/design/plone/contenttypes/tests/test_relateditems_with_dates.py b/src/design/plone/contenttypes/tests/test_relateditems_with_dates.py index 96e86691..2ac280dc 100644 --- a/src/design/plone/contenttypes/tests/test_relateditems_with_dates.py +++ b/src/design/plone/contenttypes/tests/test_relateditems_with_dates.py @@ -145,12 +145,12 @@ def test_api_do_not_return_related_items_with_effective_date_in_future_for_users api.user.create( email="foo@example.com", username="foo", - password="secret", + password="secret!!!", ) api_session = RelativeSession(self.portal_url) api_session.headers.update({"Accept": "application/json"}) - api_session.auth = ("foo", "secret") + api_session.auth = ("foo", "secret!!!") present = api.content.create( container=self.portal, type="Document", title="present" diff --git a/src/design/plone/contenttypes/tests/test_setup.py b/src/design/plone/contenttypes/tests/test_setup.py index e019c31b..1f9d3e5a 100644 --- a/src/design/plone/contenttypes/tests/test_setup.py +++ b/src/design/plone/contenttypes/tests/test_setup.py @@ -32,7 +32,16 @@ def setUp(self): def test_product_installed(self): """Test if design.plone.contenttypes is installed.""" - self.assertTrue(self.installer.isProductInstalled("design.plone.contenttypes")) + if hasattr(self.installer, "is_product_installed"): + # Plone 6 + self.assertTrue( + self.installer.is_product_installed("design.plone.contenttypes") + ) + else: + # Plone 5 + self.assertTrue( + self.installer.isProductInstalled("design.plone.contenttypes") + ) def test_browserlayer(self): """Test that IDesignPloneContenttypesLayer is registered.""" @@ -59,12 +68,26 @@ def setUp(self): self.installer = api.portal.get_tool("portal_quickinstaller") roles_before = api.user.get_roles(TEST_USER_ID) setRoles(self.portal, TEST_USER_ID, ["Manager"]) - self.installer.uninstallProducts(["design.plone.contenttypes"]) + if hasattr(self.installer, "uninstall_product"): + # Plone 6 + self.installer.uninstall_product("design.plone.contenttypes") + else: + # Plone 5 + self.installer.uninstallProducts(["design.plone.contenttypes"]) setRoles(self.portal, TEST_USER_ID, roles_before) def test_product_uninstalled(self): """Test if design.plone.contenttypes is cleanly uninstalled.""" - self.assertFalse(self.installer.isProductInstalled("design.plone.contenttypes")) + if hasattr(self.installer, "is_product_installed"): + # Plone 6 + self.assertFalse( + self.installer.is_product_installed("design.plone.contenttypes") + ) + else: + # Plone 5 + self.assertFalse( + self.installer.isProductInstalled("design.plone.contenttypes") + ) def test_browserlayer_removed(self): """Test that IDesignPloneContenttypesLayer is removed.""" diff --git a/src/design/plone/contenttypes/tests/test_summary_serializer.py b/src/design/plone/contenttypes/tests/test_summary_serializer.py index 2c2a8eba..9bb43496 100644 --- a/src/design/plone/contenttypes/tests/test_summary_serializer.py +++ b/src/design/plone/contenttypes/tests/test_summary_serializer.py @@ -7,7 +7,6 @@ from plone.app.testing import SITE_OWNER_NAME from plone.app.testing import SITE_OWNER_PASSWORD from plone.app.testing import TEST_USER_ID -from plone.restapi.interfaces import ISerializeToJson from plone.restapi.interfaces import ISerializeToJsonSummary from plone.restapi.testing import RelativeSession from transaction import commit @@ -146,53 +145,54 @@ def test_summary_return_formatted_remote_url_for_links(self): serializer = getMultiAdapter((link, self.request), ISerializeToJsonSummary)() self.assertEqual(serializer["remoteUrl"], self.document.absolute_url()) - def test_summary_return_persona_role(self): - api.content.create( - container=self.portal, type="Persona", title="John Doe", ruolo="unknown" - ) - api.content.create(container=self.portal, type="Persona", title="Mario Rossi") + # il campo `ruolo` non è più presente nel tipo Persona + # def test_summary_return_persona_role(self): + # api.content.create( + # container=self.portal, type="Persona", title="John Doe", ruolo="unknown" + # ) + # api.content.create(container=self.portal, type="Persona", title="Mario Rossi") - commit() + # commit() - brains = api.content.find(portal_type="Persona", id="mario-rossi") - results = getMultiAdapter((brains, self.request), ISerializeToJson)( - fullobjects=False - ) + # brains = api.content.find(portal_type="Persona", id="mario-rossi") + # results = getMultiAdapter((brains, self.request), ISerializeToJson)( + # fullobjects=False + # ) - self.assertEqual(results["items"][0]["ruolo"], None) - self.assertEqual(results["items"][0]["title"], "Mario Rossi") + # self.assertEqual(results["items"][0]["ruolo"], None) + # self.assertEqual(results["items"][0]["title"], "Mario Rossi") - brains = api.content.find(portal_type="Persona", id="john-doe") - results = getMultiAdapter((brains, self.request), ISerializeToJson)( - fullobjects=False - ) + # brains = api.content.find(portal_type="Persona", id="john-doe") + # results = getMultiAdapter((brains, self.request), ISerializeToJson)( + # fullobjects=False + # ) - self.assertEqual(results["items"][0]["ruolo"], "unknown") - self.assertEqual(results["items"][0]["title"], "John Doe") + # self.assertEqual(results["items"][0]["ruolo"], "unknown") + # self.assertEqual(results["items"][0]["title"], "John Doe") - # test also with restapi call - response = self.api_session.get( - "{}/@search?portal_type=Persona&id=mario-rossi".format(self.portal_url) - ) + # # test also with restapi call + # response = self.api_session.get( + # "{}/@search?portal_type=Persona&id=mario-rossi".format(self.portal_url) + # ) - result = response.json() - items = result.get("items", []) + # result = response.json() + # items = result.get("items", []) - self.assertEqual(items[0]["title"], "Mario Rossi") - self.assertEqual(items[0]["ruolo"], None) + # self.assertEqual(items[0]["title"], "Mario Rossi") + # self.assertEqual(items[0]["ruolo"], None) - response = self.api_session.get( - "{}/@search?portal_type=Persona&id=john-doe".format(self.portal_url) - ) + # response = self.api_session.get( + # "{}/@search?portal_type=Persona&id=john-doe".format(self.portal_url) + # ) - result = response.json() - items = result.get("items", []) + # result = response.json() + # items = result.get("items", []) - self.assertEqual(items[0]["title"], "John Doe") - self.assertEqual(items[0]["ruolo"], "unknown") + # self.assertEqual(items[0]["title"], "John Doe") + # self.assertEqual(items[0]["ruolo"], "unknown") def test_summary_return_design_meta_type(self): - news = api.content.create( + api.content.create( container=self.portal, type="News Item", title="News", @@ -204,11 +204,14 @@ def test_summary_return_design_meta_type(self): result = response.json() items = result.get("items", []) - self.assertEqual(len(items), 1) - self.assertEqual(items[0]["design_italia_meta_type"], "foo") + # TODO: non basta che `foo` sia una tipologia di notizia, serve che sia presente + # anche nella tassonomia delle tipologie di notizia - serializer = getMultiAdapter((news, self.request), ISerializeToJsonSummary)() - self.assertEqual(serializer["design_italia_meta_type"], "foo") + # self.assertEqual(len(items), 1) + # self.assertEqual(items[0]["design_italia_meta_type"], "foo") + + # serializer = getMultiAdapter((news, self.request), ISerializeToJsonSummary)() + # self.assertEqual(serializer["design_italia_meta_type"], "foo") # other contents return their name response = self.api_session.get("@search?UID={}".format(self.document.UID())) diff --git a/src/design/plone/contenttypes/tests/test_vocabularies.py b/src/design/plone/contenttypes/tests/test_vocabularies.py index d5ed2106..d5e3e58f 100644 --- a/src/design/plone/contenttypes/tests/test_vocabularies.py +++ b/src/design/plone/contenttypes/tests/test_vocabularies.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +from collective.taxonomy.interfaces import ITaxonomy from design.plone.contenttypes.controlpanels.settings import IDesignPloneSettings from design.plone.contenttypes.testing import ( DESIGN_PLONE_CONTENTTYPES_INTEGRATION_TESTING, @@ -8,6 +9,7 @@ from plone.app.testing import TEST_USER_ID from transaction import commit from zope.component import getUtility +from zope.component import queryUtility from zope.schema.interfaces import IVocabularyFactory import json @@ -38,128 +40,134 @@ def set_value_for_language(self, field, data): ) commit() + # vocabulary design.plone.vocabularies.tipologie_notizia => collective.taxonomy.tipologia_notizia def test_tipologia_notizia_vocab(self): - factory = getUtility( - IVocabularyFactory, "design.plone.vocabularies.tipologie_notizia" - ) - vocab = factory(self.portal) - self.assertEqual( - ["", "Avviso", "Comunicato stampa", "Novità"], - [(x.value) for x in vocab], - ) - - def test_tipologia_notizia_vocab_in_another_language(self): - self.request["LANGUAGE"] = "en" - factory = getUtility( - IVocabularyFactory, "design.plone.vocabularies.tipologie_notizia" - ) - vocab = factory(self.portal) - self.assertEqual( - [], - [(x.value) for x in vocab], - ) - - #  set values also for en - self.set_value_for_language( - field="tipologie_notizia", data={"en": ["news-foo", "news-bar"]} - ) - - factory = getUtility( - IVocabularyFactory, "design.plone.vocabularies.tipologie_notizia" - ) - vocab = factory(self.portal) - self.assertEqual( - ["", "news-foo", "news-bar"], - [(x.value) for x in vocab], - ) - - def test_tipologie_unita_organizzativa_vocab(self): - factory = getUtility( - IVocabularyFactory, - "design.plone.vocabularies.tipologie_unita_organizzativa", - ) - vocab = factory(self.portal) + # factory = getUtility( + # IVocabularyFactory, "design.plone.vocabularies.tipologie_notizia" + # ) + # vocab = factory(self.portal) + taxonomy = queryUtility(ITaxonomy, name="collective.taxonomy.tipologia_notizia") + vocab = taxonomy.makeVocabulary("it") self.assertEqual( - ["", "Politica", "Amministrativa", "Altro"], - [(x.value) for x in vocab], - ) - - def test_tipologia_unita_organizzativa_vocab_in_another_language(self): - self.request["LANGUAGE"] = "en" - factory = getUtility( - IVocabularyFactory, - "design.plone.vocabularies.tipologie_unita_organizzativa", - ) - vocab = factory(self.portal) - self.assertEqual( - [], - [(x.value) for x in vocab], - ) - - #  set values also for en - self.set_value_for_language( - field="tipologie_unita_organizzativa", - data={"en": ["uo-foo", "uo-bar"]}, - ) - - factory = getUtility( - IVocabularyFactory, - "design.plone.vocabularies.tipologie_unita_organizzativa", - ) - vocab = factory(self.portal) - self.assertEqual( - ["", "uo-foo", "uo-bar"], - [(x.value) for x in vocab], - ) + ["Notizia", "Comunicato (stampa)", "Avviso"], + [self.portal.translate(x.title) for x in vocab], + ) + + # TODO: en + # def test_tipologia_notizia_vocab_in_another_language(self): + # self.request["LANGUAGE"] = "en" + # factory = getUtility( + # IVocabularyFactory, "design.plone.vocabularies.tipologie_notizia" + # ) + # vocab = factory(self.portal) + # self.assertEqual( + # [], + # [(x.value) for x in vocab], + # ) + # #  set values also for en + # self.set_value_for_language( + # field="tipologie_notizia", data={"en": ["news-foo", "news-bar"]} + # ) + # factory = getUtility( + # IVocabularyFactory, "design.plone.vocabularies.tipologie_notizia" + # ) + # vocab = factory(self.portal) + # self.assertEqual( + # ["", "news-foo", "news-bar"], + # [(x.value) for x in vocab], + # ) + + # TODO + # def test_tipologie_unita_organizzativa_vocab(self): + # factory = getUtility( + # IVocabularyFactory, + # "design.plone.vocabularies.tipologie_unita_organizzativa", + # ) + # vocab = factory(self.portal) + # self.assertEqual( + # ["", "Politica", "Amministrativa", "Altro"], + # [(x.value) for x in vocab], + # ) + + # def test_tipologia_unita_organizzativa_vocab_in_another_language(self): + # self.request["LANGUAGE"] = "en" + # factory = getUtility( + # IVocabularyFactory, + # "design.plone.vocabularies.tipologie_unita_organizzativa", + # ) + # vocab = factory(self.portal) + # self.assertEqual( + # [], + # [(x.value) for x in vocab], + # ) + + # #  set values also for en + # self.set_value_for_language( + # field="tipologie_unita_organizzativa", + # data={"en": ["uo-foo", "uo-bar"]}, + # ) + + # factory = getUtility( + # IVocabularyFactory, + # "design.plone.vocabularies.tipologie_unita_organizzativa", + # ) + # vocab = factory(self.portal) + # self.assertEqual( + # ["", "uo-foo", "uo-bar"], + # [(x.value) for x in vocab], + # ) def test_tipologie_tipologie_documento_vocab(self): - factory = getUtility( - IVocabularyFactory, - "design.plone.vocabularies.tipologie_documento", - ) - vocab = factory(self.portal) + # factory = getUtility( + # IVocabularyFactory, + # "design.plone.vocabularies.tipologie_documento", + # ) + # vocab = factory(self.portal) + taxonomy = queryUtility( + ITaxonomy, name="collective.taxonomy.tipologia_documento" + ) + vocab = taxonomy.makeVocabulary("it") self.assertEqual( [ - "", - "Accordi tra enti", - "Atti normativi", - "Dataset", - "Documenti (tecnici) di supporto", "Documenti albo pretorio", - "Documenti attività politica", - "Documenti funzionamento interno", - "Istanze", "Modulistica", + "Documento funzionamento interno", + "Atto normativo", + "Accordo tra enti", + "Documento attività politica", + "Documento (tecnico) di supporto", + "Istanza", + "Dataset", ], - [(x.value) for x in vocab], - ) - - def test_tipologie_documento_vocab_in_another_language(self): - self.request["LANGUAGE"] = "en" - factory = getUtility( - IVocabularyFactory, - "design.plone.vocabularies.tipologie_documento", - ) - vocab = factory(self.portal) - self.assertEqual( - [], - [(x.value) for x in vocab], - ) - - #  set values also for en - self.set_value_for_language( - field="tipologie_documento", - data={"en": ["doc-foo", "doc-bar"]}, - ) - - factory = getUtility( - IVocabularyFactory, "design.plone.vocabularies.tipologie_documento" - ) - vocab = factory(self.portal) - self.assertEqual( - ["", "doc-foo", "doc-bar"], - [(x.value) for x in vocab], - ) + [self.portal.translate(x.title) for x in vocab], + ) + + # def test_tipologie_documento_vocab_in_another_language(self): + # self.request["LANGUAGE"] = "en" + # factory = getUtility( + # IVocabularyFactory, + # "design.plone.vocabularies.tipologie_documento", + # ) + # vocab = factory(self.portal) + # self.assertEqual( + # [], + # [(x.value) for x in vocab], + # ) + + # #  set values also for en + # self.set_value_for_language( + # field="tipologie_documento", + # data={"en": ["doc-foo", "doc-bar"]}, + # ) + + # factory = getUtility( + # IVocabularyFactory, "design.plone.vocabularies.tipologie_documento" + # ) + # vocab = factory(self.portal) + # self.assertEqual( + # ["", "doc-foo", "doc-bar"], + # [(x.value) for x in vocab], + # ) def test_dimensioni_immagini(self): factory = getUtility( diff --git a/src/design/plone/contenttypes/upgrades/upgrades.py b/src/design/plone/contenttypes/upgrades/upgrades.py index fbaba1eb..f27af87c 100644 --- a/src/design/plone/contenttypes/upgrades/upgrades.py +++ b/src/design/plone/contenttypes/upgrades/upgrades.py @@ -515,9 +515,6 @@ def fix_listing(blocks, url): for block in blocks.values(): if block.get("@type", "") == "listing": if block.get("template", False) and not block.get("variation", False): - # import pdb - - # pdb.set_trace() logger.error("- {}".format(url)) if block.get("template", False) and block.get("variation", False): logger.error("- {}".format(url)) @@ -1194,9 +1191,6 @@ def createPDCandMigrateOldCTs(portal_type): **kwargs, ) intids = getUtility(IIntIds) - # import pdb - - # pdb.set_trace() item.contact_info = [RelationValue(intids.getId(new_pdc))] fixed_total += 1 commit() diff --git a/test_plone60.cfg b/test_plone60.cfg index e6b0983a..7a85774b 100644 --- a/test_plone60.cfg +++ b/test_plone60.cfg @@ -85,3 +85,7 @@ pkgutil-resolve-name = 1.3.10 # PasteDeploy==3.0.1 # plone.restapi==8.33.3 importlib-metadata = 5.2.0 + +# Added by buildout at 2023-03-01 12:57:48.164146 +coverage = 7.0.5 +createcoverage = 1.5 From 833f01b5cd3a0119e570dd6c1bc2ef6dabbbdf40 Mon Sep 17 00:00:00 2001 From: Piero Nicolli Date: Tue, 7 Mar 2023 15:11:44 +0100 Subject: [PATCH 238/487] =?UTF-8?q?timeline=5Ftempi=5Fscadenze=20non=20pi?= =?UTF-8?q?=C3=B9=20obbligatorio?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/design/plone/contenttypes/interfaces/servizio.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/design/plone/contenttypes/interfaces/servizio.py b/src/design/plone/contenttypes/interfaces/servizio.py index 721f80fb..7c257134 100644 --- a/src/design/plone/contenttypes/interfaces/servizio.py +++ b/src/design/plone/contenttypes/interfaces/servizio.py @@ -18,7 +18,7 @@ class ITempiEScadenzeValueSchema(model.Schema): milestone = schema.TextLine( title=_("milestone_label", default="Titolo"), - required=True, + required=False, default="", ) milestone_description = schema.TextLine( From 4ba2fd8b07734ba6d402713fe5313e7d2a0aa8eb Mon Sep 17 00:00:00 2001 From: Piero Nicolli Date: Tue, 7 Mar 2023 15:21:12 +0100 Subject: [PATCH 239/487] Changelog --- CHANGES.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 515d389e..95626fed 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -5,7 +5,8 @@ Changelog 6.0.0a22 (unreleased) --------------------- -- Nothing changed yet. +- timeline_tempi_scadenze non più obbligatorio + [pnicolli] 6.0.0a21 (2023-03-01) From fd2ad104b812e05c59a7495a7c4687511f2bd817 Mon Sep 17 00:00:00 2001 From: Piero Nicolli Date: Tue, 7 Mar 2023 15:22:23 +0100 Subject: [PATCH 240/487] Updated MANIFEST --- MANIFEST.in | 1 + 1 file changed, 1 insertion(+) diff --git a/MANIFEST.in b/MANIFEST.in index 202055a3..f97e1a17 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -6,3 +6,4 @@ include *.GPL include *.disabled include *.txt exclude .flake8 +exclude .pre-commit-config.yaml From 1d60f3dffd8fe12269ede6af8c909dcea9eb545f Mon Sep 17 00:00:00 2001 From: Piero Nicolli Date: Tue, 7 Mar 2023 15:25:12 +0100 Subject: [PATCH 241/487] Preparing release 6.0.0a22 --- CHANGES.rst | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 95626fed..25a6aa82 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -2,7 +2,7 @@ Changelog ========= -6.0.0a22 (unreleased) +6.0.0a22 (2023-03-07) --------------------- - timeline_tempi_scadenze non più obbligatorio diff --git a/setup.py b/setup.py index 962e2aa0..23eacc3d 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.0.0a22.dev0", + version="6.0.0a22", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 6e4bbe658b7eaf8db35300fa98f8cfd74106ee38 Mon Sep 17 00:00:00 2001 From: Piero Nicolli Date: Tue, 7 Mar 2023 15:27:41 +0100 Subject: [PATCH 242/487] Back to development: 6.0.0a23 --- CHANGES.rst | 6 ++++++ setup.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 25a6aa82..19f739fc 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -2,6 +2,12 @@ Changelog ========= +6.0.0a23 (unreleased) +--------------------- + +- Nothing changed yet. + + 6.0.0a22 (2023-03-07) --------------------- diff --git a/setup.py b/setup.py index 23eacc3d..714ff1a6 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.0.0a22", + version="6.0.0a23.dev0", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 3303b281e0c4d5d2ceecac448e96147432a761e7 Mon Sep 17 00:00:00 2001 From: Mauro Amico Date: Thu, 9 Mar 2023 10:44:19 +0100 Subject: [PATCH 243/487] Integration with redturtle.prenotazioni (#159) --------- Co-authored-by: Roman --- CHANGES.rst | 4 +- base.cfg | 4 + setup.py | 6 +- src/design/plone/contenttypes/configure.zcml | 5 -- .../plone/contenttypes/events/configure.zcml | 10 +++ .../plone/contenttypes/events/servizio.py | 19 +++++ .../taxonomies/tipologia_notizia.xml | 1 - .../profiles/default/types/Servizio.xml | 6 ++ .../restapi/services/configure.zcml | 7 ++ .../prenotazioni_folders_list/__init__.py | 0 .../prenotazioni_folders_list/configure.zcml | 19 +++++ .../services/prenotazioni_folders_list/get.py | 27 +++++++ src/design/plone/contenttypes/testing.py | 15 +++- .../tests/test_change_news_type.py | 13 +-- .../tests/test_move_news_items_view.py | 8 +- .../test_service_prenotazioni_folders_list.py | 61 ++++++++++++++ .../contenttypes/upgrades/configure.zcml | 2 +- .../plone/contenttypes/upgrades/upgrades.py | 23 ++++++ test_plone60.cfg | 81 +++++++------------ 19 files changed, 238 insertions(+), 73 deletions(-) create mode 100644 src/design/plone/contenttypes/restapi/services/prenotazioni_folders_list/__init__.py create mode 100644 src/design/plone/contenttypes/restapi/services/prenotazioni_folders_list/configure.zcml create mode 100644 src/design/plone/contenttypes/restapi/services/prenotazioni_folders_list/get.py create mode 100644 src/design/plone/contenttypes/tests/test_service_prenotazioni_folders_list.py diff --git a/CHANGES.rst b/CHANGES.rst index 19f739fc..e2f1b6bb 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -5,8 +5,8 @@ Changelog 6.0.0a23 (unreleased) --------------------- -- Nothing changed yet. - +- Optional integration with redturtle.prenotazioni + [foxtrot-dfm1] 6.0.0a22 (2023-03-07) --------------------- diff --git a/base.cfg b/base.cfg index ac8646cd..ccc06c9e 100644 --- a/base.cfg +++ b/base.cfg @@ -142,3 +142,7 @@ design.plone.contenttypes = #redturtle.volto = git https://github.com/RedTurtle/redturtle.volto.git pushurl=git@github.com:RedTurtle/redturtle.volto.git #redturtle.bandi = git https://github.com/RedTurtle/redturtle.bandi.git pushurl=git@github.com:RedTurtle/redturtle.bandi.git #plone.restapi = git https://github.com/plone/plone.restapi.git + +# use for integration development btw design.plone.contenttypes and redturtle.prenotazioni +redturtle.prenotazioni = git https://github.com/RedTurtle/redturtle.prenotazioni.git +# collective.contentrules.mailfromfield = git https://github.com/RedTurtle/collective.contentrules.mailfromfield.git diff --git a/setup.py b/setup.py index 714ff1a6..803fc005 100644 --- a/setup.py +++ b/setup.py @@ -76,7 +76,11 @@ "plone.app.contenttypes", "plone.app.robotframework[debug]", "collective.MockMailHost", - ] + "redturtle.prenotazioni", + ], + "ioprenoto": [ + "redturtle.prenotazioni", + ], }, entry_points=""" [z3c.autoinclude.plugin] diff --git a/src/design/plone/contenttypes/configure.zcml b/src/design/plone/contenttypes/configure.zcml index 5c07e72b..e90460e7 100644 --- a/src/design/plone/contenttypes/configure.zcml +++ b/src/design/plone/contenttypes/configure.zcml @@ -8,11 +8,6 @@ - - diff --git a/src/design/plone/contenttypes/events/configure.zcml b/src/design/plone/contenttypes/events/configure.zcml index 85c451a0..e3efa3f6 100644 --- a/src/design/plone/contenttypes/events/configure.zcml +++ b/src/design/plone/contenttypes/events/configure.zcml @@ -1,5 +1,7 @@ @@ -75,5 +77,13 @@ handler=".common.onModify" /> + + + + diff --git a/src/design/plone/contenttypes/events/servizio.py b/src/design/plone/contenttypes/events/servizio.py index 1a37f81e..7f14a02d 100644 --- a/src/design/plone/contenttypes/events/servizio.py +++ b/src/design/plone/contenttypes/events/servizio.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +from design.plone.contenttypes import _ from design.plone.contenttypes.utils import create_default_blocks from plone import api from Products.CMFPlone.interfaces import ISelectableConstrainTypes @@ -27,3 +28,21 @@ def servizioCreateHandler(servizio, event): childConstraints = ISelectableConstrainTypes(child) childConstraints.setConstrainTypesMode(1) childConstraints.setLocallyAllowedTypes(folder["contains"]) + + +# TODO: rivalutare se è necessario, o se i folder delle prenotazioni +# vanno creati manualmente al di fuori del servizio +def prenotazioni_folder_create(servizio, event): + """Create Prenotazioni folder inside of the created object, + but only if `redturtle.prenotazioni` is installed. + """ + if api.portal.get_tool("portal_types").get("PrenotazioniFolderContainer"): + if not api.portal.get_tool("portal_catalog")( + portal_type="PrenotazioniFolderContainer", + path="/".join(servizio.getPhysicalPath()), + ): + api.content.create( + type="PrenotazioniFolderContainer", + title=_("Cartella delle prenotazioni"), + container=servizio, + ) diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_notizia.xml b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_notizia.xml index 5af6f429..27b2ab51 100644 --- a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_notizia.xml +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_notizia.xml @@ -25,7 +25,6 @@ avviso - Avviso diff --git a/src/design/plone/contenttypes/profiles/default/types/Servizio.xml b/src/design/plone/contenttypes/profiles/default/types/Servizio.xml index fec732d7..0ce1e2ce 100644 --- a/src/design/plone/contenttypes/profiles/default/types/Servizio.xml +++ b/src/design/plone/contenttypes/profiles/default/types/Servizio.xml @@ -26,6 +26,12 @@ + + design.plone.contenttypes.AddServizio diff --git a/src/design/plone/contenttypes/restapi/services/configure.zcml b/src/design/plone/contenttypes/restapi/services/configure.zcml index fcb4a87f..853dda46 100644 --- a/src/design/plone/contenttypes/restapi/services/configure.zcml +++ b/src/design/plone/contenttypes/restapi/services/configure.zcml @@ -1,6 +1,7 @@ @@ -9,6 +10,12 @@ + + + + + + + + + diff --git a/src/design/plone/contenttypes/restapi/services/prenotazioni_folders_list/get.py b/src/design/plone/contenttypes/restapi/services/prenotazioni_folders_list/get.py new file mode 100644 index 00000000..3dcb3821 --- /dev/null +++ b/src/design/plone/contenttypes/restapi/services/prenotazioni_folders_list/get.py @@ -0,0 +1,27 @@ +from plone import api +from plone.restapi.interfaces import ISerializeToJsonSummary +from plone.restapi.services import Service +from zope.component import getMultiAdapter + + +class PrenotazioniFoldersList(Service): + def reply(self): + """Lists the PrenotableFolders inside of Servizio + Returns: + list: List of PrenotableFolders serialized to JSON summary + """ + result = [] + + prenotazioni_folders = api.portal.get_tool("portal_catalog")( + portal_type="PrenotazioniFolder", + path="/".join(self.context.getPhysicalPath()), + ) + + for item in prenotazioni_folders: + result.append( + getMultiAdapter( + (item.getObject(), self.request), ISerializeToJsonSummary + )() + ) + + return result diff --git a/src/design/plone/contenttypes/testing.py b/src/design/plone/contenttypes/testing.py index 020f85e7..90d5fb8d 100644 --- a/src/design/plone/contenttypes/testing.py +++ b/src/design/plone/contenttypes/testing.py @@ -8,6 +8,7 @@ from zope.configuration import xmlconfig import collective.address +import collective.contentrules.mailfromfield import collective.taxonomy # import collective.folderishtypes @@ -22,6 +23,7 @@ import plone.formwidget.geolocation import plone.restapi import redturtle.bandi +import redturtle.prenotazioni import redturtle.volto @@ -74,7 +76,8 @@ def setUpZope(self, app, configurationContext): self.loadZCML(package=collective.volto.blocksfield) self.loadZCML(package=design.plone.contenttypes, context=configurationContext) self.loadZCML(package=plone.formwidget.geolocation) - self.loadZCML(name="overrides.zcml", package=design.plone.contenttypes) + self.loadZCML(package=eea.api.taxonomy) + self.loadZCML(package=collective.taxonomy) xmlconfig.file( "configure.zcml", design.plone.contenttypes, @@ -82,13 +85,19 @@ def setUpZope(self, app, configurationContext): ) self.loadZCML(package=redturtle.bandi) self.loadZCML(package=kitconcept.seo) - self.loadZCML(package=eea.api.taxonomy) - self.loadZCML(package=collective.taxonomy) + + # TODO: valutare un layer a parte per i test di redturtle.prenotazioni + self.loadZCML(package=redturtle.prenotazioni) self.loadZCML(package=collective.z3cform.datagridfield) + self.loadZCML(package=collective.contentrules.mailfromfield) + + self.loadZCML(name="overrides.zcml", package=design.plone.contenttypes) def setUpPloneSite(self, portal): super().setUpPloneSite(portal) applyProfile(portal, "design.plone.contenttypes:default") + # TODO: valutare un layer a parte per i test di redturtle.prenotazioni + applyProfile(portal, "redturtle.prenotazioni:default") DESIGN_PLONE_CONTENTTYPES_API_FIXTURE = DesignPloneContenttypesRestApiLayer() diff --git a/src/design/plone/contenttypes/tests/test_change_news_type.py b/src/design/plone/contenttypes/tests/test_change_news_type.py index bc26b4f0..e3ff1d2c 100644 --- a/src/design/plone/contenttypes/tests/test_change_news_type.py +++ b/src/design/plone/contenttypes/tests/test_change_news_type.py @@ -14,6 +14,8 @@ class MoveNewsItemView(unittest.TestCase): def setUp(self): self.portal = self.layer["portal"] self.request = self.layer["request"] + # default values are set in italian + self.request["LANGUAGE"] = "it" self.view = api.content.get_view( "change_news_type", context=self.portal, request=self.request ) @@ -28,25 +30,26 @@ def setUp(self): self.news_item = api.content.create( type="News Item", title="news item", - tipologia_notizia="Notizia", + tipologia_notizia=["notizia"], container=self.portal, ) self.news_item1 = api.content.create( type="News Item", title="news item1", - tipologia_notizia="Notizia", + tipologia_notizia=["notizia"], container=self.news_container, ) def test_substitute_news_type(self): - new_news_type = "New news type" - self.view.request.form["news_type_in_catalog"] = "Notizia" - self.view.request.form["news_type_portal"] = "New news type" + new_news_type = "comunicato_stampa" + self.view.request.form["news_type_in_catalog"] = "notizia" + self.view.request.form["news_type_portal"] = new_news_type self.view.request.form["substitute"] = "true" # mock the helper methods of our view self.view.news_types = lambda: [new_news_type] + # self.portal.portal_catalog(ti) self.view.substitute_news_type() self.assertEqual(new_news_type, self.news_item.tipologia_notizia) diff --git a/src/design/plone/contenttypes/tests/test_move_news_items_view.py b/src/design/plone/contenttypes/tests/test_move_news_items_view.py index 3dc94320..4af359e4 100644 --- a/src/design/plone/contenttypes/tests/test_move_news_items_view.py +++ b/src/design/plone/contenttypes/tests/test_move_news_items_view.py @@ -14,6 +14,8 @@ class MoveNewsItemView(unittest.TestCase): def setUp(self): self.portal = self.layer["portal"] self.request = self.layer["request"] + # default values are set in italian + self.request["LANGUAGE"] = "it" self.view = api.content.get_view( "move_news_items", context=self.portal, request=self.request ) @@ -28,18 +30,18 @@ def setUp(self): self.news_item = api.content.create( type="News Item", title="news item", - tipologia_notizia="Notizia", + tipologia_notizia="notizia", container=self.portal, ) self.news_item1 = api.content.create( type="News Item", title="news item1", - tipologia_notizia="Notizia", + tipologia_notizia="notizia", container=self.news_container, ) def test_news_result(self): - self.view.request.form["news_type"] = "Notizia" + self.view.request.form["news_type"] = "notizia" result = self.view.news_results() diff --git a/src/design/plone/contenttypes/tests/test_service_prenotazioni_folders_list.py b/src/design/plone/contenttypes/tests/test_service_prenotazioni_folders_list.py new file mode 100644 index 00000000..83c8295c --- /dev/null +++ b/src/design/plone/contenttypes/tests/test_service_prenotazioni_folders_list.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +# TODO: skip se redturtle.prenotazioni non è presente +from design.plone.contenttypes.testing import ( + DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING, +) +from plone import api +from plone.app.testing import setRoles +from plone.app.testing import SITE_OWNER_NAME +from plone.app.testing import SITE_OWNER_PASSWORD +from plone.app.testing import TEST_USER_ID +from plone.restapi.testing import RelativeSession + +import transaction +import unittest + + +class TestServicePrnotazioniFoldersList(unittest.TestCase): + layer = DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING + + def setUp(self): + self.app = self.layer["app"] + self.portal = self.layer["portal"] + self.portal_url = self.portal.absolute_url() + self.testing_view_name = "@prenotazioni_folders-list" + + self.api_session = RelativeSession(self.portal_url) + self.api_session.headers.update({"Accept": "application/json"}) + + self.api_session.auth = (SITE_OWNER_NAME, SITE_OWNER_PASSWORD) + + setRoles(self.portal, TEST_USER_ID, ["Manager"]) + + self.servizio = api.content.create( + type="Servizio", title="servizio", container=self.portal + ) + self.prenotazioni_folders_folder = api.content.create( + type="Folder", title="PrenotazioniFolders", container=self.servizio + ) + + transaction.commit() + + def test_no_prenotazioni_folders(self): + res = self.api_session.get( + self.servizio.absolute_url() + "/" + self.testing_view_name + ).json() + + self.assertFalse(res) + + def test_prenotazioni_folders(self): + prenotazione_folder = api.content.create( + type="PrenotazioniFolder", + title="prenotazioni_folder", + container=self.prenotazioni_folders_folder, + ) + transaction.commit() + + res = self.api_session.get( + self.servizio.absolute_url() + "/" + self.testing_view_name + ).json() + + self.assertIn(prenotazione_folder.absolute_url(), [item["@id"] for item in res]) diff --git a/src/design/plone/contenttypes/upgrades/configure.zcml b/src/design/plone/contenttypes/upgrades/configure.zcml index 7d31b98b..215852e2 100644 --- a/src/design/plone/contenttypes/upgrades/configure.zcml +++ b/src/design/plone/contenttypes/upgrades/configure.zcml @@ -717,11 +717,11 @@ source="7007" destination="7008" > + - diff --git a/src/design/plone/contenttypes/upgrades/upgrades.py b/src/design/plone/contenttypes/upgrades/upgrades.py index f27af87c..9bb63a7a 100644 --- a/src/design/plone/contenttypes/upgrades/upgrades.py +++ b/src/design/plone/contenttypes/upgrades/upgrades.py @@ -1612,6 +1612,29 @@ def update_taxonomies_on_blocks(context): ) +# XXX: le prenotazioni non sono necessariamente all'interno del servizio +# def add_ioprenoto_folder(context): +# """Adds PrenotazioniFoldersContainer object to Servizio c.t. object""" +# catalog = api.portal.get_tool("portal_catalog") +# for servizio in catalog(portal_type="Servizio"): +# if not catalog( +# portal_type="PrenotazioniFolderContainer", path=servizio.getPath() +# ): +# container = servizio.getObject() +# if "PrenotazioniFolderContainer" in getattr( +# context, "allowedContentTypes", None +# ): +# api.content.create( +# type="PrenotazioniFolderContainer", +# title="Cartella delle prenotazioni", +# container=container, +# ) +# else: +# raise Exception( +# "Can not mirgate so as PrenotazioniFolderContainer is not allowed" +# ) + + def update_uo_contact_info(context): brains = api.portal.get_tool("portal_catalog")(portal_type="UnitaOrganizzativa") logger.info( diff --git a/test_plone60.cfg b/test_plone60.cfg index 7a85774b..68df7f0b 100644 --- a/test_plone60.cfg +++ b/test_plone60.cfg @@ -10,82 +10,59 @@ update-versions-file = test_plone60.cfg [versions] -# Added by buildout at 2021-12-29 11:05:41.321569 +# Added by buildout at 2023-03-03 11:30:23.040213 +bleach = 3.3.1 +build = 0.10.0 +coverage = 7.1.0 +createcoverage = 1.5 flake8 = 6.0.0 flake8-coding = 1.3.2 flake8-debugger = 4.1.2 flake8-print = 5.0.0 +i18ndude = 5.5.0 +keyring = 22.0.1 +lml = 0.1.0 mccabe = 0.7.0 +pkginfo = 1.8.3 plone.recipe.codeanalysis = 3.0.1 +pyexcel-ezodf = 0.3.4 +pyexcel-io = 0.6.6 +pyexcel-ods3 = 0.6.1 pyflakes = 3.0.1 -zpretty = 3.0.1 - -# Required by: -# flake8-debugger==3.2.1 -# flake8-print==3.1.4 -pycodestyle = 2.10.0 - -# Added by buildout at 2023-01-12 09:16:52.328614 -bleach = 5.0.1 -build = 0.9.0 -commonmark = 0.9.1 -i18ndude = 5.3.4 -keyring = 23.11.0 -pep517 = 0.13.0 -pkginfo = 1.8.3 -readme-renderer = 37.3 +pyproject-hooks = 1.0.0 +readme-renderer = 28.0 requests-toolbelt = 0.10.1 rfc3986 = 2.0.0 -rich = 13.3.1 -pygments = 2.14.0 -twine = 4.0.1 -zest.releaser = 7.3.0 +tqdm = 4.64.1 +twine = 3.3.0 +zest.releaser = 6.22.2 +zpretty = 2.4.1 # Required by: # plone.recipe.codeanalysis==3.0.1 -check-manifest = 0.48 +check-manifest = 0.49 # Required by: -# eea.api.taxonomy==1.5 -collective.taxonomy = 3.0.0 +# redturtle.prenotazioni==1.6.2.dev0 +click = 8.1.3 # Required by: -# zest.releaser==7.2.0 +# zest.releaser==6.22.2 colorama = 0.4.6 # Required by: -# design.plone.contenttypes==6.0.0.dev0 -eea.api.taxonomy = 1.5 - -# Required by: -# keyring==23.11.0 -jaraco.classes = 3.2.3 +# flake8-debugger==4.1.2 +# flake8-print==5.0.0 +pycodestyle = 2.10.0 # Required by: -# jaraco.classes==3.2.3 -more-itertools = 9.0.0 +# redturtle.prenotazioni==1.6.2.dev0 +pyinter = 0.2.0 # Required by: -# check-manifest==0.48 +# check-manifest==0.49 tomli = 2.0.1 # Required by: -# bleach==5.0.1 +# bleach==3.3.1 webencodings = 0.5.1 - -dataclasses = 0.8 - -# Added by buildout at 2023-02-20 14:52:32.917956 -backports.functools-lru-cache = 1.6.4 -markdown-it-py = 2.1.0 -mdurl = 0.1.2 -pkgutil-resolve-name = 1.3.10 - -# Required by: -# PasteDeploy==3.0.1 -# plone.restapi==8.33.3 -importlib-metadata = 5.2.0 - -# Added by buildout at 2023-03-01 12:57:48.164146 -coverage = 7.0.5 -createcoverage = 1.5 From be07d80bd64c30c429b1181934276f4171c18416 Mon Sep 17 00:00:00 2001 From: Mauro Amico Date: Thu, 9 Mar 2023 10:48:41 +0100 Subject: [PATCH 244/487] badges --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c0aa6f76..a30cf961 100644 --- a/README.md +++ b/README.md @@ -6,8 +6,8 @@ [![Supported - Python Versions](https://img.shields.io/pypi/pyversions/design.plone.contenttypes.svg?style=plastic)](https://pypi.python.org/pypi/design.plone.contenttypes/) [![Number of PyPI downloads](https://img.shields.io/pypi/dm/design.plone.contenttypes.svg)](https://pypi.python.org/pypi/design.plone.contenttypes/) [![License](https://img.shields.io/pypi/l/design.plone.contenttypes.svg)](https://pypi.python.org/pypi/design.plone.contenttypes/) -[![Tests](https://github.com/collective/design.plone.contenttypes/actions/workflows/tests.yml/badge.svg)](https://github.com/collective/design.plone.contenttypes/actions) -[![Coverage](https://coveralls.io/repos/github/collective/design.plone.contenttypes/badge.svg?branch=master)](https://coveralls.io/github/collective/design.plone.contenttypes?branch=master) +[![Tests](https://github.com/RedTurtle/design.plone.contenttypes/actions/workflows/test.yml/badge.svg)](https://github.com/collective/design.plone.contenttypes/actions) +[![Coverage](https://coveralls.io/repos/github/RedTurtle/design.plone.contenttypes/badge.svg?branch=master)](https://coveralls.io/github/RedTurtle/design.plone.contenttypes?branch=master) - [Design Plone Content-types](#design-plone-content-types) From ffdd6b6d7099d7155efeff6a135f37efca86481b Mon Sep 17 00:00:00 2001 From: Roman <72063601+foxtrot-dfm1@users.noreply.github.com> Date: Fri, 10 Mar 2023 08:29:10 +0100 Subject: [PATCH 245/487] Fix package links for PyPi (#160) Co-authored-by: Roman --- setup.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 4d10ac92..59c30b86 100644 --- a/setup.py +++ b/setup.py @@ -40,8 +40,8 @@ url="https://github.com/collective/design.plone.contenttypes", project_urls={ "PyPI": "https://pypi.python.org/pypi/design.plone.contenttypes", - "Source": "https://github.com/collective/design.plone.contenttypes", - "Tracker": "https://github.com/collective/design.plone.contenttypes/issues", + "Source": "https://github.com/RedTurtle/design.plone.contenttypes", + "Tracker": "https://github.com/RedTurtle/design.plone.contenttypes/issues", # 'Documentation': 'https://design.plone.contenttypes.readthedocs.io/en/latest/', }, license="GPL version 2", From 31134653fa54b7049a1933c6417b137631565dba Mon Sep 17 00:00:00 2001 From: Mauro Amico Date: Tue, 14 Mar 2023 19:44:00 +0100 Subject: [PATCH 246/487] refactor: split upgrade steps --- .../contenttypes/upgrades/configure.zcml | 21 +- .../plone/contenttypes/upgrades/to_7001.py | 288 +++++++++++++ .../plone/contenttypes/upgrades/to_7002.py | 135 ++++++ .../plone/contenttypes/upgrades/upgrades.py | 403 ------------------ 4 files changed, 438 insertions(+), 409 deletions(-) create mode 100644 src/design/plone/contenttypes/upgrades/to_7001.py create mode 100644 src/design/plone/contenttypes/upgrades/to_7002.py diff --git a/src/design/plone/contenttypes/upgrades/configure.zcml b/src/design/plone/contenttypes/upgrades/configure.zcml index 215852e2..45eb9e06 100644 --- a/src/design/plone/contenttypes/upgrades/configure.zcml +++ b/src/design/plone/contenttypes/upgrades/configure.zcml @@ -602,6 +602,7 @@ handler=".upgrades.to_6010" /> + + + + + + + + + to 7001 + """ + logger.info( + f"{colors.DARKCYAN} Inizio a creare la cartella Incarichi nelle persone {colors.ENDC}" # noqa + ) + pc = api.portal.get_tool(name="portal_catalog") + wftool = api.portal.get_tool(name="portal_workflow") + brains = pc({"portal_type": "Persona"}) + target = {"id": "incarichi", "title": "Incarichi", "contains": ("Incarico",)} + for brain in brains: + persona = brain.getObject() + if target["id"] in persona: + logger.info( + f"{colors.YELLOW} {persona.title} contiene già la cartella incarichi {colors.ENDC}" # noqa + ) + continue + suboject = api.content.create( + type="Document", id=target["id"], title=target["title"], container=persona + ) + subobjectConstraints = ISelectableConstrainTypes(suboject) + subobjectConstraints.setConstrainTypesMode(1) + subobjectConstraints.setLocallyAllowedTypes(target["contains"]) + + if api.content.get_state(obj=persona) == "published": + wftool.doActionFor(suboject, "publish") + + logger.info( + f"{colors.GREEN} Creato la cartella incarichi per {persona.title}{colors.ENDC}" # noqa + ) + logger.info( + f"{colors.DARKCYAN} Finito di creare la cartella Incarichi{colors.ENDC}" + ) + + +def create_incarico_for_persona(context): + """TODO: documentare""" + logger.info( + f"{colors.DARKCYAN} Inizio a creare gli incarichi delle persone {colors.ENDC}" + ) + # intids = getUtility(IIntIds) + pc = api.portal.get_tool(name="portal_catalog") + wftool = api.portal.get_tool(name="portal_workflow") + brains = pc({"portal_type": "Persona"}) + MAPPING_TIPO = { + "Amministrativa": "amministrativo", + "Politica": "politico", + "Altro tipo": "altro", + } + for brain in brains: + persona = brain.getObject() + + incarichi_folder = persona["incarichi"] + + if incarichi_folder.values(): + logger.info( + f"{colors.RED}{persona.title} ha già un incarico creato {colors.ENDC}" + ) # noqa + continue + + if safe_hasattr(persona, "ruolo"): + incarico_title = persona.ruolo + else: + logger.info( + f"{colors.RED} Attenzione: {persona.title} non ha un ruolo {colors.ENDC}" # noqa + ) + incarico_title = f"Incarico di {persona.title}" + + incarico = api.content.create( + type="Incarico", title=incarico_title, container=incarichi_folder + ) + # incarico.persona = [RelationValue(intids.getId(persona))] + api.relation.create(source=incarico, target=persona, relationship="persona") + if safe_hasattr(persona, "organizzazione_riferimento"): + incarico.unita_organizzativa = persona.organizzazione_riferimento + + if safe_hasattr(persona, "data_insediamento"): + incarico.data_inizio_incarico = persona.data_insediamento + incarico.data_insediamento = persona.data_insediamento + + if safe_hasattr(persona, "data_conclusione_incarico"): + incarico.data_conclusione_incarico = persona.data_conclusione_incarico + + atto_nomina = None + if safe_hasattr(persona, "atto_nomina"): + atto_nomina = api.content.create( + type="Documento", + id="atto-di-nomina", + title="Atto di nomina", + container=incarico, + ) + atto_nomina.description = f"Atto di nomina di {persona.title} per il ruolo di {incarico_title}" # noqa + atto_nomina.file_correlato = NamedBlobFile( + data=persona.atto_nomina.data, + filename=persona.atto_nomina.filename, + contentType="application/pdf", + ) + atto_nomina.tipologia_documento = ["documento_attivita_politica"] + # incarico.atto_nomina = [RelationValue(intids.getId(atto_nomina))] + api.relation.create( + source=incarico, target=atto_nomina, relationship="atto_nomina" + ) + + if safe_hasattr(persona, "tipologia_persona"): + incarico.tipologia_incarico = MAPPING_TIPO[persona.tipologia_persona] + + # persona.incarichi_persona = [RelationValue(intids.getId(incarico))] + api.relation.create( + source=persona, target=incarico, relationship="incarichi_persona" + ) + + if api.content.get_state(obj=persona) == "published": + wftool.doActionFor(incarico, "publish") + wftool.doActionFor(incarico["compensi-file"], "publish") + wftool.doActionFor(incarico["importi-di-viaggio-e-o-servizi"], "publish") + if atto_nomina: + wftool.doActionFor(atto_nomina, "publish") + + logger.info(f"{colors.GREEN} Creato incarico per {persona.title}{colors.ENDC}") + + logger.info( + f"{colors.DARKCYAN} Finito di creare gli incarichi delle persone{colors.ENDC}" + ) + + +def create_pdc(context): + """TODO: documentare (pdc = "punto di contatto")""" + portal_types = ["UnitaOrganizzativa", "Persona", "Event", "Venue"] + MAPPINGS = { + "Persona": { + "telefono": "telefono", + "fax": "fax", + "email": "email", + "pec": "pec", + }, + "UnitaOrganizzativa": { + "telefono": "telefono", + "fax": "fax", + "email": "email", + "pec": "pec", + "web": "url", + }, + "Event": { + "telefono": "telefono", + "fax": "fax", + "email": "email", + "web": "url", + }, + "Venue": { + "telefono": "telefono", + "fax": "fax", + "email": "email", + "pec": "pec", + "web": "url", + }, + } + + def migrated_contact_info(source): + # we check if we have attribute, if it's a list and no more a json (block field) + # finally we check if we have at least a value. + if ( + safe_hasattr(source, "contact_info") + and type(obj.contact_info) == list + and len(obj.contact_info) > 0 + ): + return True + + pc = api.portal.get_tool(name="portal_catalog") + wftool = api.portal.get_tool(name="portal_workflow") + portal = api.portal.get() + punti_contatto_id = "punti-di-contatto" + punti_contatto_title = "Punti di contatto" + if "punti-di-contatto" not in portal: + punti_contatto = api.content.create( + type="Document", + id=punti_contatto_id, + title=punti_contatto_title, + container=portal, + ) + punti_contatto.exclude_from_nav = True + punti_contatto.reindexObject() + wftool.doActionFor(punti_contatto, "publish") + logger.info( + f"{colors.GREEN} Creato cartella punti di contatto nella radice del portal{colors.ENDC}" # noqa + ) + else: + punti_contatto = portal[punti_contatto_id] + + for portal_type in portal_types: + brains = pc(**{"portal_type": portal_type}) + logger.info( + f"{colors.YELLOW} Stiamo per creare i PDC per {len(brains)} oggetti di tipo {portal_type}{colors.ENDC}" # noqa + ) + for brain in brains: + obj = brain.getObject() + mapping = MAPPINGS[portal_type] + data = [] + for field in mapping: + field_value = getattr(obj, field, None) + if not field_value: + continue + if type(field_value) != list: + # in some case we have a f*****g list + field_value = [ + field_value, + ] + for value in field_value: + data.append({"pdc_type": mapping[field], "pdc_value": value}) + + if not data: + continue + + if not migrated_contact_info(obj): + obj.old_contact_info = obj.contact_info + if obj.portal_type == "UnitaOrganizzativa": + del obj.contact_info + else: + logger.info( + f"{colors.RED} Esiste già un punto di contatto per {obj.title}({obj.absolute_url()}){colors.ENDC}" # noqa + ) + continue + + pdc = api.content.create( + type="PuntoDiContatto", + title=f"Punto di contatto per: {obj.title}", + container=punti_contatto, + ) + + api.relation.create(source=obj, target=pdc, relationship="contact_info") + + pdc.value_punto_contatto = data + # publish + wftool.doActionFor(pdc, "publish") + + logger.info( + f"{colors.GREEN} Creato il punto di contatto per {obj.title}({obj.absolute_url()}){colors.ENDC}" # noqa + ) diff --git a/src/design/plone/contenttypes/upgrades/to_7002.py b/src/design/plone/contenttypes/upgrades/to_7002.py new file mode 100644 index 00000000..ae02911d --- /dev/null +++ b/src/design/plone/contenttypes/upgrades/to_7002.py @@ -0,0 +1,135 @@ +from .upgrades import logger +from .upgrades import colors +from Acquisition import aq_base +from plone import api +from copy import deepcopy + + +TYPE_TO_TAXONOMIES_MAPPING = { + "News Item": { + "tipologia_notizia": { + "it": { + "Avviso": "avviso", + "Comunicato stampa": "comunicato_stampa", + "Novit\u00e0": "notizia", + } + } + }, + "Documento": { + "tipologia_documento": { + "it": { + "Accordi tra enti": "accordo_tra_enti", + "Atti normativi": "atto_normativo", + "Dataset": "Dataset", + "Documenti (tecnici) di supporto": "documento_tecnico_di_supporto", + "Documenti albo pretorio": "documenti_albo_pretorio", + "Documenti attivit\u00e0 politica": "documento_attivita_politica", + "Documenti funzionamento interno": "documento_funzionamento_interno", + "Istanze": "istanza", + "Modulistica": "modulistica", + } + } + }, + "UnitaOrganizzativa": { + "tipologia_organizzazione": { + "it": { + "Politica": "struttura_politica", + "Amministrativa": "struttura_amministrativa", + "Altro": "altra_struttura", + } + } + }, +} + +TAXONOMIES_MAPPING = {} +for portal_type in TYPE_TO_TAXONOMIES_MAPPING: + for TAXONOMY in TYPE_TO_TAXONOMIES_MAPPING[portal_type]: + TAXONOMIES_MAPPING[TAXONOMY] = TYPE_TO_TAXONOMIES_MAPPING[portal_type][TAXONOMY] + + +def update_taxonomies(context): + """TODO: documentare""" + # delete actual index from portal_catalog + logger.info( + f"{colors.DARKCYAN} Migrazione delle tassonomie dai vecchi ai nuovi valori {colors.ENDC}" # noqa + ) + pc = api.portal.get_tool("portal_catalog") + for portal_type in TYPE_TO_TAXONOMIES_MAPPING: + brains = pc(**{"portal_type": portal_type}) + logger.info( + f"{colors.DARKCYAN} Modifica delle tassonomie per {len(brains)} {portal_type}{colors.ENDC}" # noqa + ) + import pdb + + pdb.set_trace() + for brain in brains: + obj = brain.getObject() + obj_language = getattr(obj, "language", "it") or "it" + for taxonomy in TYPE_TO_TAXONOMIES_MAPPING[portal_type]: + mapping = TYPE_TO_TAXONOMIES_MAPPING[portal_type][taxonomy][ + obj_language + ] + old_value = getattr(aq_base(obj), taxonomy) + if old_value and old_value in mapping: + new_value = mapping[old_value] + if taxonomy == "tipologia_documento": + new_value = [new_value] + setattr(obj, taxonomy, new_value) + logger.info( + f"{colors.GREEN} Modifica della tassonomia '{taxonomy}' di {obj.title} da {old_value} a {new_value}{colors.ENDC}" # noqa + ) + obj.reindexObject() + + +def update_taxonomies_on_blocks(context): + """ + Code from + https://github.com/RedTurtle/design.plone.contenttypes/pull/139/files#diff-330d75e9be6e5193ab4622582fe7031d05094784e08aa3ada201a4e3d1642632R33 + """ + # https://www.comune.novellara.re.it/novita/notizie/archivio-notizie + import pdb + + pdb.set_trace() + + logger.info( + f"{colors.DARKCYAN} Update dei blocchi listing basati sulle nuove tassonomie {colors.ENDC}" # noqa + ) + brains = api.portal.get_tool("portal_catalog")() + for index, brain in list(enumerate(brains)): + item = aq_base(brain.getObject()) + item_language = item.language or "it" + if not index % 500: + logger.info( + f"{colors.DARKCYAN} ({index}/{len(brains)}) Proseguo l'analisi delle pagine {colors.ENDC}" # noqa + ) + if getattr(item, "blocks", {}): + blocks = deepcopy(item.blocks) + + if blocks: + for block in blocks.values(): + if block.get("@type", "") == "listing": + for query in block.get("querystring", {}).get("query", []): + if query["i"] in [ + "tipologia_notizia", + "tipologia_documento", + "tipologia_organizzazione", + ]: + new_values = [] + for v in query["v"]: + old_value = query["v"] + if ( + v + in TAXONOMIES_MAPPING[query["i"]][item_language] + ): + v = TAXONOMIES_MAPPING[query["i"]][ + item_language + ][v] + new_values.append(v) + query["v"] = new_values + logger.info( + f"{colors.GREEN} Modifica della query per '{query['i']}' di {item.title} da {old_value} a {query['v']}{colors.ENDC}" # noqa + ) + item.blocks = blocks + logger.info( + f"{colors.DARKCYAN} Terminato l'update dei blocchi {colors.ENDC}" # noqa + ) diff --git a/src/design/plone/contenttypes/upgrades/upgrades.py b/src/design/plone/contenttypes/upgrades/upgrades.py index 9bb63a7a..541d6221 100644 --- a/src/design/plone/contenttypes/upgrades/upgrades.py +++ b/src/design/plone/contenttypes/upgrades/upgrades.py @@ -1,6 +1,5 @@ # -*- coding: utf-8 -*- from Acquisition import aq_base -from collective.taxonomy.interfaces import ITaxonomy from collective.volto.blocksfield.field import BlocksField from copy import deepcopy from design.plone.contenttypes.controlpanels.settings import IDesignPloneSettings @@ -10,15 +9,11 @@ from plone import api from plone.app.textfield.value import RichTextValue from plone.app.upgrade.utils import installOrReinstallProduct -from plone.base.utils import get_installer from plone.dexterity.utils import iterSchemata -from plone.namedfile.file import NamedBlobFile from Products.CMFPlone.interfaces import ISelectableConstrainTypes -from Products.CMFPlone.utils import safe_hasattr from redturtle.bandi.interfaces.settings import IBandoSettings from transaction import commit from z3c.relationfield import RelationValue -from zope.component import getUtilitiesFor from zope.component import getUtility from zope.event import notify from zope.intid.interfaces import IIntIds @@ -1214,404 +1209,6 @@ class colors(object): YELLOW = "\033[93m" -def to_7001(context): - installer = get_installer(context=api.portal.get()) - installer.install_product("eea.api.taxonomy") - logger.info( - f"{colors.DARKCYAN} eea.api.taxonomy and collective.taxonomy installed {colors.ENDC}" # noqa - ) - # delete actual index from portal_catalog - for index in [ - "tipologia_notizia", - "tipologia_documento", - "tipologia_organizzazione", - ]: - api.portal.get_tool("portal_catalog").delIndex(index) - - context.runImportStepFromProfile( - "design.plone.contenttypes:taxonomy", "collective.taxonomy" - ) - for utility_name, utility in list(getUtilitiesFor(ITaxonomy)): - utility.updateBehavior(**{"field_prefix": ""}) - logger.info( - f"{colors.DARKCYAN} Change taxonomy prefix for {utility_name} {colors.ENDC}" # noqa - ) - logger.info( - f"{colors.DARKCYAN} design.plone.contentypes taxonomies imported {colors.ENDC}" # noqa - ) - update_types(context) - update_registry(context) - update_catalog(context) - update_rolemap(context) - logger.info( - f"{colors.DARKCYAN} Upgraded types, registry, catalog and rolemap {colors.ENDC}" # noqa - ) - - -def create_incarichi_folder(context): - logger.info( - f"{colors.DARKCYAN} Inizio a creare la cartella Incarichi nelle persone {colors.ENDC}" # noqa - ) - pc = api.portal.get_tool(name="portal_catalog") - wftool = api.portal.get_tool(name="portal_workflow") - brains = pc({"portal_type": "Persona"}) - target = {"id": "incarichi", "title": "Incarichi", "contains": ("Incarico",)} - for brain in brains: - persona = brain.getObject() - if target["id"] in persona: - logger.info( - f"{colors.YELLOW} {persona.title} contiene già la cartella incarichi {colors.ENDC}" # noqa - ) - continue - suboject = api.content.create( - type="Document", id=target["id"], title=target["title"], container=persona - ) - subobjectConstraints = ISelectableConstrainTypes(suboject) - subobjectConstraints.setConstrainTypesMode(1) - subobjectConstraints.setLocallyAllowedTypes(target["contains"]) - - if api.content.get_state(obj=persona) == "published": - wftool.doActionFor(suboject, "publish") - - logger.info( - f"{colors.GREEN} Creato la cartella incarichi per {persona.title}{colors.ENDC}" # noqa - ) - logger.info( - f"{colors.DARKCYAN} Finito di creare la cartella Incarichi{colors.ENDC}" - ) - - -def create_incarico_for_persona(context): - logger.info( - f"{colors.DARKCYAN} Inizio a creare gli incarichi delle persone {colors.ENDC}" - ) - # intids = getUtility(IIntIds) - pc = api.portal.get_tool(name="portal_catalog") - wftool = api.portal.get_tool(name="portal_workflow") - brains = pc({"portal_type": "Persona"}) - MAPPING_TIPO = { - "Amministrativa": "amministrativo", - "Politica": "politico", - "Altro tipo": "altro", - } - for brain in brains: - persona = brain.getObject() - - incarichi_folder = persona["incarichi"] - - if incarichi_folder.values(): - logger.info( - f"{colors.RED}{persona.title} ha già un incarico creato {colors.ENDC}" - ) # noqa - continue - - if safe_hasattr(persona, "ruolo"): - incarico_title = persona.ruolo - else: - logger.info( - f"{colors.RED} Attenzione: {persona.title} non ha un ruolo {colors.ENDC}" # noqa - ) - incarico_title = f"Incarico di {persona.title}" - - incarico = api.content.create( - type="Incarico", title=incarico_title, container=incarichi_folder - ) - # incarico.persona = [RelationValue(intids.getId(persona))] - api.relation.create(source=incarico, target=persona, relationship="persona") - if safe_hasattr(persona, "organizzazione_riferimento"): - incarico.unita_organizzativa = persona.organizzazione_riferimento - - if safe_hasattr(persona, "data_insediamento"): - incarico.data_inizio_incarico = persona.data_insediamento - incarico.data_insediamento = persona.data_insediamento - - if safe_hasattr(persona, "data_conclusione_incarico"): - incarico.data_conclusione_incarico = persona.data_conclusione_incarico - - atto_nomina = None - if safe_hasattr(persona, "atto_nomina"): - atto_nomina = api.content.create( - type="Documento", - id="atto-di-nomina", - title="Atto di nomina", - container=incarico, - ) - atto_nomina.description = f"Atto di nomina di {persona.title} per il ruolo di {incarico_title}" # noqa - atto_nomina.file_correlato = NamedBlobFile( - data=persona.atto_nomina.data, - filename=persona.atto_nomina.filename, - contentType="application/pdf", - ) - atto_nomina.tipologia_documento = ["documento_attivita_politica"] - # incarico.atto_nomina = [RelationValue(intids.getId(atto_nomina))] - api.relation.create( - source=incarico, target=atto_nomina, relationship="atto_nomina" - ) - - if safe_hasattr(persona, "tipologia_persona"): - incarico.tipologia_incarico = MAPPING_TIPO[persona.tipologia_persona] - - # persona.incarichi_persona = [RelationValue(intids.getId(incarico))] - api.relation.create( - source=persona, target=incarico, relationship="incarichi_persona" - ) - - if api.content.get_state(obj=persona) == "published": - wftool.doActionFor(incarico, "publish") - wftool.doActionFor(incarico["compensi-file"], "publish") - wftool.doActionFor(incarico["importi-di-viaggio-e-o-servizi"], "publish") - if atto_nomina: - wftool.doActionFor(atto_nomina, "publish") - - logger.info(f"{colors.GREEN} Creato incarico per {persona.title}{colors.ENDC}") - - logger.info( - f"{colors.DARKCYAN} Finito di creare gli incarichi delle persone{colors.ENDC}" - ) - - -def create_pdc(context): - portal_types = ["UnitaOrganizzativa", "Persona", "Event", "Venue"] - MAPPINGS = { - "Persona": { - "telefono": "telefono", - "fax": "fax", - "email": "email", - "pec": "pec", - }, - "UnitaOrganizzativa": { - "telefono": "telefono", - "fax": "fax", - "email": "email", - "pec": "pec", - "web": "url", - }, - "Event": { - "telefono": "telefono", - "fax": "fax", - "email": "email", - "web": "url", - }, - "Venue": { - "telefono": "telefono", - "fax": "fax", - "email": "email", - "pec": "pec", - "web": "url", - }, - } - - def migrated_contact_info(source): - # we check if we have attribute, if it's a list and no more a json (block field) - # finally we check if we have at least a value. - if ( - safe_hasattr(source, "contact_info") - and type(obj.contact_info) == list - and len(obj.contact_info) > 0 - ): - return True - - pc = api.portal.get_tool(name="portal_catalog") - wftool = api.portal.get_tool(name="portal_workflow") - portal = api.portal.get() - punti_contatto_id = "punti-di-contatto" - punti_contatto_title = "Punti di contatto" - if "punti-di-contatto" not in portal: - punti_contatto = api.content.create( - type="Document", - id=punti_contatto_id, - title=punti_contatto_title, - container=portal, - ) - punti_contatto.exclude_from_nav = True - punti_contatto.reindexObject() - wftool.doActionFor(punti_contatto, "publish") - logger.info( - f"{colors.GREEN} Creato cartella punti di contatto nella radice del portal{colors.ENDC}" # noqa - ) - else: - punti_contatto = portal[punti_contatto_id] - - for portal_type in portal_types: - brains = pc(**{"portal_type": portal_type}) - logger.info( - f"{colors.YELLOW} Stiamo per creare i PDC per {len(brains)} oggetti di tipo {portal_type}{colors.ENDC}" # noqa - ) - for brain in brains: - obj = brain.getObject() - mapping = MAPPINGS[portal_type] - data = [] - for field in mapping: - field_value = getattr(obj, field, None) - if not field_value: - continue - if type(field_value) != list: - # in some case we have a f*****g list - field_value = [ - field_value, - ] - for value in field_value: - data.append({"pdc_type": mapping[field], "pdc_value": value}) - - if not data: - continue - - if not migrated_contact_info(obj): - obj.old_contact_info = obj.contact_info - if obj.portal_type == "UnitaOrganizzativa": - del obj.contact_info - else: - logger.info( - f"{colors.RED} Esiste già un punto di contatto per {obj.title}({obj.absolute_url()}){colors.ENDC}" # noqa - ) - continue - - pdc = api.content.create( - type="PuntoDiContatto", - title=f"Punto di contatto per: {obj.title}", - container=punti_contatto, - ) - - api.relation.create(source=obj, target=pdc, relationship="contact_info") - - pdc.value_punto_contatto = data - # publish - wftool.doActionFor(pdc, "publish") - - logger.info( - f"{colors.GREEN} Creato il punto di contatto per {obj.title}({obj.absolute_url()}){colors.ENDC}" # noqa - ) - - -TYPE_TO_TAXONOMIES_MAPPING = { - "News Item": { - "tipologia_notizia": { - "it": { - "Avviso": "avviso", - "Comunicato stampa": "comunicato_stampa", - "Novit\u00e0": "notizia", - } - } - }, - "Documento": { - "tipologia_documento": { - "it": { - "Accordi tra enti": "accordo_tra_enti", - "Atti normativi": "atto_normativo", - "Dataset": "Dataset", - "Documenti (tecnici) di supporto": "documento_tecnico_di_supporto", - "Documenti albo pretorio": "documenti_albo_pretorio", - "Documenti attivit\u00e0 politica": "documento_attivita_politica", - "Documenti funzionamento interno": "documento_funzionamento_interno", - "Istanze": "istanza", - "Modulistica": "modulistica", - } - } - }, - "UnitaOrganizzativa": { - "tipologia_organizzazione": { - "it": { - "Politica": "struttura_politica", - "Amministrativa": "struttura_amministrativa", - "Altro": "altra_struttura", - } - } - }, -} - -TAXONOMIES_MAPPING = {} -for portal_type in TYPE_TO_TAXONOMIES_MAPPING: - for TAXONOMY in TYPE_TO_TAXONOMIES_MAPPING[portal_type]: - TAXONOMIES_MAPPING[TAXONOMY] = TYPE_TO_TAXONOMIES_MAPPING[portal_type][TAXONOMY] - - -def update_taxonomies(context): - # delete actual index from portal_catalog - logger.info( - f"{colors.DARKCYAN} Migrazione delle tassonomie dai vecchi ai nuovi valori {colors.ENDC}" # noqa - ) - pc = api.portal.get_tool("portal_catalog") - for portal_type in TYPE_TO_TAXONOMIES_MAPPING: - brains = pc(**{"portal_type": portal_type}) - logger.info( - f"{colors.DARKCYAN} Modifica delle tassonomie per {len(brains)} {portal_type}{colors.ENDC}" # noqa - ) - for brain in brains: - obj = brain.getObject() - obj_language = getattr(obj, "language", "it") or "it" - for taxonomy in TYPE_TO_TAXONOMIES_MAPPING[portal_type]: - old_value = getattr(obj, taxonomy) - if ( - old_value - and old_value - in TYPE_TO_TAXONOMIES_MAPPING[portal_type][taxonomy][obj_language] - ): - new_value = TYPE_TO_TAXONOMIES_MAPPING[portal_type][taxonomy][ - obj_language - ][old_value] - if taxonomy == "tipologia_documento": - new_value = [ - new_value, - ] - setattr(obj, taxonomy, new_value) - logger.info( - f"{colors.GREEN} Modifica della tassonomia '{taxonomy}' di {obj.title} da {old_value} a {new_value}{colors.ENDC}" # noqa - ) - - obj.reindexObject() - - -def update_taxonomies_on_blocks(context): - """ - Code from - https://github.com/RedTurtle/design.plone.contenttypes/pull/139/files#diff-330d75e9be6e5193ab4622582fe7031d05094784e08aa3ada201a4e3d1642632R33 - """ - # https://www.comune.novellara.re.it/novita/notizie/archivio-notizie - - logger.info( - f"{colors.DARKCYAN} Update dei blocchi listing basati sulle nuove tassonomie {colors.ENDC}" # noqa - ) - brains = api.portal.get_tool("portal_catalog")() - for index, brain in list(enumerate(brains)): - item = aq_base(brain.getObject()) - item_language = item.language or "it" - if not index % 500: - logger.info( - f"{colors.DARKCYAN} ({index}/{len(brains)}) Proseguo l'analisi delle pagine {colors.ENDC}" # noqa - ) - if getattr(item, "blocks", {}): - blocks = deepcopy(item.blocks) - - if blocks: - for block in blocks.values(): - if block.get("@type", "") == "listing": - for query in block.get("querystring", {}).get("query", []): - if query["i"] in [ - "tipologia_notizia", - "tipologia_documento", - "tipologia_organizzazione", - ]: - new_values = [] - for v in query["v"]: - old_value = query["v"] - if ( - v - in TAXONOMIES_MAPPING[query["i"]][item_language] - ): - v = TAXONOMIES_MAPPING[query["i"]][ - item_language - ][v] - new_values.append(v) - query["v"] = new_values - logger.info( - f"{colors.GREEN} Modifica della query per '{query['i']}' di {item.title} da {old_value} a {query['v']}{colors.ENDC}" # noqa - ) - item.blocks = blocks - logger.info( - f"{colors.DARKCYAN} Terminato l'update dei blocchi {colors.ENDC}" # noqa - ) - - # XXX: le prenotazioni non sono necessariamente all'interno del servizio # def add_ioprenoto_folder(context): # """Adds PrenotazioniFoldersContainer object to Servizio c.t. object""" From 95a238d209f1e77ea3afff4ab59d13395798e4e9 Mon Sep 17 00:00:00 2001 From: Mauro Amico Date: Tue, 14 Mar 2023 19:55:30 +0100 Subject: [PATCH 247/487] zpretty --- .../plone/contenttypes/upgrades/configure.zcml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/design/plone/contenttypes/upgrades/configure.zcml b/src/design/plone/contenttypes/upgrades/configure.zcml index 45eb9e06..3aba257e 100644 --- a/src/design/plone/contenttypes/upgrades/configure.zcml +++ b/src/design/plone/contenttypes/upgrades/configure.zcml @@ -602,7 +602,7 @@ handler=".upgrades.to_6010" /> - + - + - + - + - + - + Date: Thu, 16 Mar 2023 12:24:42 +0100 Subject: [PATCH 248/487] improvement for migration from io-comune2 to pnrr version --- CHANGES.rst | 1 + .../contenttypes/tests/test_vocabularies.py | 2 +- .../plone/contenttypes/upgrades/to_7001.py | 7 +++- .../plone/contenttypes/upgrades/to_7002.py | 38 ++++++++++--------- 4 files changed, 29 insertions(+), 19 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index e2f1b6bb..b69649a6 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -7,6 +7,7 @@ Changelog - Optional integration with redturtle.prenotazioni [foxtrot-dfm1] +- Update upgrade step after some more use case [lucabel] 6.0.0a22 (2023-03-07) --------------------- diff --git a/src/design/plone/contenttypes/tests/test_vocabularies.py b/src/design/plone/contenttypes/tests/test_vocabularies.py index d5e3e58f..41b6e239 100644 --- a/src/design/plone/contenttypes/tests/test_vocabularies.py +++ b/src/design/plone/contenttypes/tests/test_vocabularies.py @@ -40,7 +40,7 @@ def set_value_for_language(self, field, data): ) commit() - # vocabulary design.plone.vocabularies.tipologie_notizia => collective.taxonomy.tipologia_notizia + # vocabulary design.plone.vocabularies.tipologie_notizia => collective.taxonomy.tipologia_notizia # noqa def test_tipologia_notizia_vocab(self): # factory = getUtility( # IVocabularyFactory, "design.plone.vocabularies.tipologie_notizia" diff --git a/src/design/plone/contenttypes/upgrades/to_7001.py b/src/design/plone/contenttypes/upgrades/to_7001.py index b3d74600..3e6f0cc3 100644 --- a/src/design/plone/contenttypes/upgrades/to_7001.py +++ b/src/design/plone/contenttypes/upgrades/to_7001.py @@ -97,6 +97,8 @@ def create_incarico_for_persona(context): "Amministrativa": "amministrativo", "Politica": "politico", "Altro tipo": "altro", + "politica": "politico", # parma + "amministrativa": "amministrativo", # parma } for brain in brains: persona = brain.getObject() @@ -133,7 +135,7 @@ def create_incarico_for_persona(context): incarico.data_conclusione_incarico = persona.data_conclusione_incarico atto_nomina = None - if safe_hasattr(persona, "atto_nomina"): + if safe_hasattr(persona, "atto_nomina") and getattr(persona, "atto_nomina"): atto_nomina = api.content.create( type="Documento", id="atto-di-nomina", @@ -151,6 +153,9 @@ def create_incarico_for_persona(context): api.relation.create( source=incarico, target=atto_nomina, relationship="atto_nomina" ) + logger.info( + f"{colors.GREEN} Creato atto nomina per {persona.title} {colors.ENDC}" + ) if safe_hasattr(persona, "tipologia_persona"): incarico.tipologia_incarico = MAPPING_TIPO[persona.tipologia_persona] diff --git a/src/design/plone/contenttypes/upgrades/to_7002.py b/src/design/plone/contenttypes/upgrades/to_7002.py index ae02911d..c83c4270 100644 --- a/src/design/plone/contenttypes/upgrades/to_7002.py +++ b/src/design/plone/contenttypes/upgrades/to_7002.py @@ -1,8 +1,8 @@ -from .upgrades import logger from .upgrades import colors +from .upgrades import logger from Acquisition import aq_base -from plone import api from copy import deepcopy +from plone import api TYPE_TO_TAXONOMIES_MAPPING = { @@ -59,9 +59,6 @@ def update_taxonomies(context): logger.info( f"{colors.DARKCYAN} Modifica delle tassonomie per {len(brains)} {portal_type}{colors.ENDC}" # noqa ) - import pdb - - pdb.set_trace() for brain in brains: obj = brain.getObject() obj_language = getattr(obj, "language", "it") or "it" @@ -69,15 +66,25 @@ def update_taxonomies(context): mapping = TYPE_TO_TAXONOMIES_MAPPING[portal_type][taxonomy][ obj_language ] - old_value = getattr(aq_base(obj), taxonomy) - if old_value and old_value in mapping: - new_value = mapping[old_value] - if taxonomy == "tipologia_documento": - new_value = [new_value] - setattr(obj, taxonomy, new_value) - logger.info( - f"{colors.GREEN} Modifica della tassonomia '{taxonomy}' di {obj.title} da {old_value} a {new_value}{colors.ENDC}" # noqa - ) + old_value = getattr(aq_base(obj), taxonomy, None) + if type(old_value) == list: + # this is a sort of race condition. + # we already have created ct Documento for attonomina + # in case we are using atto di nomina, skip + if obj.portal_type != "Documento": + raise Exception + if obj.id != "atto-di-nomina": + raise Exception + continue + else: + if old_value and old_value in mapping: + new_value = mapping[old_value] + if taxonomy == "tipologia_documento": + new_value = [new_value] + setattr(obj, taxonomy, new_value) + logger.info( + f"{colors.GREEN} Modifica della tassonomia '{taxonomy}' di {obj.title} da {old_value} a {new_value}{colors.ENDC}" # noqa + ) obj.reindexObject() @@ -87,9 +94,6 @@ def update_taxonomies_on_blocks(context): https://github.com/RedTurtle/design.plone.contenttypes/pull/139/files#diff-330d75e9be6e5193ab4622582fe7031d05094784e08aa3ada201a4e3d1642632R33 """ # https://www.comune.novellara.re.it/novita/notizie/archivio-notizie - import pdb - - pdb.set_trace() logger.info( f"{colors.DARKCYAN} Update dei blocchi listing basati sulle nuove tassonomie {colors.ENDC}" # noqa From 0aadbc32dd55ab9aa59ac8e8f4e8cef7797d0f0a Mon Sep 17 00:00:00 2001 From: Andrea Cecchi Date: Thu, 16 Mar 2023 17:27:02 +0100 Subject: [PATCH 249/487] enable behavior in venue ct --- CHANGES.rst | 3 ++- .../profiles/default/metadata.xml | 2 +- .../profiles/default/types/Venue.xml | 1 + .../plone/contenttypes/tests/test_ct_luogo.py | 1 + .../contenttypes/upgrades/configure.zcml | 9 ++++++++ .../plone/contenttypes/upgrades/upgrades.py | 22 +++++++++++++++++++ 6 files changed, 36 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 3c51eabb..da0c2a82 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,7 +4,8 @@ Changelog 5.1.6 (unreleased) ------------------ -- Nothing changed yet. +- Enable plone.excludefromnavigation for Venue ct. + [cekk] 5.1.5 (2023-02-15) diff --git a/src/design/plone/contenttypes/profiles/default/metadata.xml b/src/design/plone/contenttypes/profiles/default/metadata.xml index 60920ed8..768bdec0 100644 --- a/src/design/plone/contenttypes/profiles/default/metadata.xml +++ b/src/design/plone/contenttypes/profiles/default/metadata.xml @@ -1,6 +1,6 @@ - 5500 + 5600 profile-redturtle.bandi:default profile-collective.venue:default diff --git a/src/design/plone/contenttypes/profiles/default/types/Venue.xml b/src/design/plone/contenttypes/profiles/default/types/Venue.xml index d6fce8c8..60cedb42 100644 --- a/src/design/plone/contenttypes/profiles/default/types/Venue.xml +++ b/src/design/plone/contenttypes/profiles/default/types/Venue.xml @@ -15,6 +15,7 @@ + diff --git a/src/design/plone/contenttypes/tests/test_ct_luogo.py b/src/design/plone/contenttypes/tests/test_ct_luogo.py index 02502dc1..c8d02740 100644 --- a/src/design/plone/contenttypes/tests/test_ct_luogo.py +++ b/src/design/plone/contenttypes/tests/test_ct_luogo.py @@ -35,6 +35,7 @@ def test_behaviors_enabled_for_luogo(self): "plone.app.dexterity.behaviors.id.IShortName", "plone.app.dexterity.behaviors.metadata.IBasic", "plone.app.dexterity.behaviors.metadata.ICategorization", + "plone.excludefromnavigation", "plone.relateditems", "plone.leadimage", "volto.preview_image", diff --git a/src/design/plone/contenttypes/upgrades/configure.zcml b/src/design/plone/contenttypes/upgrades/configure.zcml index 27b64f5a..10e243ae 100644 --- a/src/design/plone/contenttypes/upgrades/configure.zcml +++ b/src/design/plone/contenttypes/upgrades/configure.zcml @@ -582,4 +582,13 @@ handler=".upgrades.to_5500" /> + + + diff --git a/src/design/plone/contenttypes/upgrades/upgrades.py b/src/design/plone/contenttypes/upgrades/upgrades.py index 9754b095..2e22ee5a 100644 --- a/src/design/plone/contenttypes/upgrades/upgrades.py +++ b/src/design/plone/contenttypes/upgrades/upgrades.py @@ -1003,3 +1003,25 @@ def fix_block(blocks, argomenti_mapping): if blocks: fix_block(blocks, argomenti_mapping) setattr(item, name, value) + + +def to_5600(context): + portal_types = api.portal.get_tool(name="portal_types") + behaviors = list(portal_types["Venue"].behaviors) + if "plone.excludefromnavigation" in behaviors: + return + logger.info("Enable plone.excludefromnavigation behavior") + behaviors.append("plone.excludefromnavigation") + portal_types["Venue"].behaviors = tuple(behaviors) + logger.info("Reindex Venue objects") + brains = api.content.find(portal_type="Venue") + tot = len(brains) + i = 0 + for brain in brains: + i += 1 + if i % 100 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + venue = brain.getObject() + if not getattr(venue, "exclude_from_nav", None): + setattr(venue, "exclude_from_nav", False) + venue.reindexObject(idxs=["exclude_from_nav"]) From 2e5af4f984de04ed8db4fb5c26b0942f8d5d1f31 Mon Sep 17 00:00:00 2001 From: Andrea Cecchi Date: Thu, 16 Mar 2023 17:28:10 +0100 Subject: [PATCH 250/487] zpretty --- .../plone/contenttypes/upgrades/configure.zcml | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/design/plone/contenttypes/upgrades/configure.zcml b/src/design/plone/contenttypes/upgrades/configure.zcml index 10e243ae..01cd8aef 100644 --- a/src/design/plone/contenttypes/upgrades/configure.zcml +++ b/src/design/plone/contenttypes/upgrades/configure.zcml @@ -583,12 +583,13 @@ /> - - + profile="design.plone.contenttypes:default" + source="5500" + destination="5600" + > + + From 30f8da2c69129f43b974271567e487ed484979ac Mon Sep 17 00:00:00 2001 From: Andrea Cecchi Date: Thu, 16 Mar 2023 17:34:18 +0100 Subject: [PATCH 251/487] Preparing release 5.1.6 --- CHANGES.rst | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index da0c2a82..7e9f563e 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,7 +1,7 @@ Changelog ========= -5.1.6 (unreleased) +5.1.6 (2023-03-16) ------------------ - Enable plone.excludefromnavigation for Venue ct. diff --git a/setup.py b/setup.py index 59c30b86..94ecfaa4 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="5.1.6.dev0", + version="5.1.6", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 8927b1374710b29ca02503f31e4149a7f7bba6e2 Mon Sep 17 00:00:00 2001 From: Andrea Cecchi Date: Thu, 16 Mar 2023 17:34:35 +0100 Subject: [PATCH 252/487] Back to development: 5.1.7 --- CHANGES.rst | 6 ++++++ setup.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 7e9f563e..932e82ef 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,6 +1,12 @@ Changelog ========= +5.1.7 (unreleased) +------------------ + +- Nothing changed yet. + + 5.1.6 (2023-03-16) ------------------ diff --git a/setup.py b/setup.py index 94ecfaa4..cb0c1765 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="5.1.6", + version="5.1.7.dev0", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 1e6f97cca12fbc670d2121a0e421c915d94665a1 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Mon, 20 Mar 2023 13:19:37 +0100 Subject: [PATCH 253/487] update migration steps: we use a modulo ct under documento pubblico for atto di nomina --- .../plone/contenttypes/upgrades/to_7001.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/design/plone/contenttypes/upgrades/to_7001.py b/src/design/plone/contenttypes/upgrades/to_7001.py index 3e6f0cc3..30c03fdf 100644 --- a/src/design/plone/contenttypes/upgrades/to_7001.py +++ b/src/design/plone/contenttypes/upgrades/to_7001.py @@ -143,11 +143,25 @@ def create_incarico_for_persona(context): container=incarico, ) atto_nomina.description = f"Atto di nomina di {persona.title} per il ruolo di {incarico_title}" # noqa - atto_nomina.file_correlato = NamedBlobFile( + # questo sotto rimane valido col vecchio schema del documento pubblico + # atto_nomina.file_correlato = NamedBlobFile( + # data=persona.atto_nomina.data, + # filename=persona.atto_nomina.filename, + # contentType="application/pdf", + # ) + # invece aggiungiamo un modulo sotto al documento + modulo_atto_nomina = api.content.create( + type="Modulo", + id="atto-di-nomina", + title="Atto di nomina", + container=atto_nomina, + ) + modulo_atto_nomina.file_principale = NamedBlobFile( data=persona.atto_nomina.data, filename=persona.atto_nomina.filename, contentType="application/pdf", ) + atto_nomina.tipologia_documento = ["documento_attivita_politica"] # incarico.atto_nomina = [RelationValue(intids.getId(atto_nomina))] api.relation.create( From 755630ed992f15f5191d87b58adb54cc13e53c2e Mon Sep 17 00:00:00 2001 From: daniele-andreotti Date: Mon, 20 Mar 2023 14:46:52 +0100 Subject: [PATCH 254/487] extended mapping for taxonomies (#163) --- src/design/plone/contenttypes/upgrades/to_7002.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/design/plone/contenttypes/upgrades/to_7002.py b/src/design/plone/contenttypes/upgrades/to_7002.py index c83c4270..310ac307 100644 --- a/src/design/plone/contenttypes/upgrades/to_7002.py +++ b/src/design/plone/contenttypes/upgrades/to_7002.py @@ -11,7 +11,9 @@ "it": { "Avviso": "avviso", "Comunicato stampa": "comunicato_stampa", + "Comunicato (stampa)": "comunicato_stampa", "Novit\u00e0": "notizia", + "Notizia": "notizia", } } }, From 3e148b6ecbd27d90b9032381f66f18f8818ee926 Mon Sep 17 00:00:00 2001 From: Martina Bustacchini Date: Mon, 20 Mar 2023 15:02:21 +0100 Subject: [PATCH 255/487] feat: remove related_news serializer from UO --- .../contenttypes/restapi/serializers/unita_organizzativa.py | 4 ++-- .../plone/contenttypes/tests/test_ct_unita_organizzativa.py | 6 ------ 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/design/plone/contenttypes/restapi/serializers/unita_organizzativa.py b/src/design/plone/contenttypes/restapi/serializers/unita_organizzativa.py index 11dce3a2..a2e5f14b 100644 --- a/src/design/plone/contenttypes/restapi/serializers/unita_organizzativa.py +++ b/src/design/plone/contenttypes/restapi/serializers/unita_organizzativa.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from .related_news_serializer import SerializeFolderToJson as RelatedNewsSerializer +from .dxcontent import SerializeFolderToJson as BaseSerializer from Acquisition import aq_inner from design.plone.contenttypes.interfaces.unita_organizzativa import IUnitaOrganizzativa from design.plone.contenttypes.restapi.serializers.summary import ( @@ -25,7 +25,7 @@ @implementer(ISerializeToJson) @adapter(IUnitaOrganizzativa, Interface) -class UOSerializer(RelatedNewsSerializer): +class UOSerializer(BaseSerializer): def get_services(self): """ """ catalog = getUtility(ICatalog) diff --git a/src/design/plone/contenttypes/tests/test_ct_unita_organizzativa.py b/src/design/plone/contenttypes/tests/test_ct_unita_organizzativa.py index 5c433cb1..79773194 100644 --- a/src/design/plone/contenttypes/tests/test_ct_unita_organizzativa.py +++ b/src/design/plone/contenttypes/tests/test_ct_unita_organizzativa.py @@ -127,12 +127,6 @@ def test_uo_ct_title(self): "Unita Organizzativa", portal_types["UnitaOrganizzativa"].title ) - def test_uo_service_related_news(self): - response = self.api_session.get(self.uo.absolute_url() + "?fullobjects") - self.assertTrue( - response.json()["related_news"][0]["@id"], self.news.absolute_url() - ) - def test_uo_service_related_service_show_only_services(self): response = self.api_session.get(self.uo.absolute_url() + "?fullobjects") self.assertEqual( From f4dc7eff5df17d09e38f796c56ca636bd61738dd Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Tue, 21 Mar 2023 17:14:32 +0100 Subject: [PATCH 256/487] [doc] fix CHANGES --- CHANGES.rst | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index bf1b94dd..0aff4001 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,12 +4,7 @@ Changelog 6.0.0a23 (unreleased) --------------------- -5.1.7 (unreleased) ------------------- -- Optional integration with redturtle.prenotazioni - [foxtrot-dfm1] -- Update upgrade step after some more use case [lucabel] 6.0.0a22 (2023-03-07) --------------------- @@ -187,6 +182,13 @@ Changelog - Adjustments to the pnrr. [deodorhunter, lucabel, eikichi18] +5.1.7 (unreleased) +------------------ + +- Optional integration with redturtle.prenotazioni + [foxtrot-dfm1] +- Update upgrade step after some more use case [lucabel] + 5.1.6 (2023-03-16) ------------------ From 8bf7ed5eb25cd439bf556eea42fd90e1b25821a7 Mon Sep 17 00:00:00 2001 From: Mauro Amico Date: Wed, 22 Mar 2023 17:07:07 +0100 Subject: [PATCH 257/487] ci: default branch is main --- .github/workflows/toc.yml | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/toc.yml b/.github/workflows/toc.yml index e25b55d6..e00f771d 100644 --- a/.github/workflows/toc.yml +++ b/.github/workflows/toc.yml @@ -2,7 +2,7 @@ name: Toc on: push: branches: - - master + - main jobs: update-toc: name: TOC Generator and auto-commit diff --git a/README.md b/README.md index a30cf961..bbd002ba 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ [![Number of PyPI downloads](https://img.shields.io/pypi/dm/design.plone.contenttypes.svg)](https://pypi.python.org/pypi/design.plone.contenttypes/) [![License](https://img.shields.io/pypi/l/design.plone.contenttypes.svg)](https://pypi.python.org/pypi/design.plone.contenttypes/) [![Tests](https://github.com/RedTurtle/design.plone.contenttypes/actions/workflows/test.yml/badge.svg)](https://github.com/collective/design.plone.contenttypes/actions) -[![Coverage](https://coveralls.io/repos/github/RedTurtle/design.plone.contenttypes/badge.svg?branch=master)](https://coveralls.io/github/RedTurtle/design.plone.contenttypes?branch=master) +[![Coverage](https://coveralls.io/repos/github/RedTurtle/design.plone.contenttypes/badge.svg?branch=main)](https://coveralls.io/github/RedTurtle/design.plone.contenttypes?branch=main) - [Design Plone Content-types](#design-plone-content-types) From 6d8422a17c9d9f77656579a773871b3cb7536ce3 Mon Sep 17 00:00:00 2001 From: Mauro Amico Date: Wed, 22 Mar 2023 17:18:27 +0100 Subject: [PATCH 258/487] badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bbd002ba..dcb50fe9 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ [![Supported - Python Versions](https://img.shields.io/pypi/pyversions/design.plone.contenttypes.svg?style=plastic)](https://pypi.python.org/pypi/design.plone.contenttypes/) [![Number of PyPI downloads](https://img.shields.io/pypi/dm/design.plone.contenttypes.svg)](https://pypi.python.org/pypi/design.plone.contenttypes/) [![License](https://img.shields.io/pypi/l/design.plone.contenttypes.svg)](https://pypi.python.org/pypi/design.plone.contenttypes/) -[![Tests](https://github.com/RedTurtle/design.plone.contenttypes/actions/workflows/test.yml/badge.svg)](https://github.com/collective/design.plone.contenttypes/actions) +[![Tests](https://github.com/RedTurtle/design.plone.contenttypes/actions/workflows/test.yml/badge.svg)](https://github.com/RedTurtle/design.plone.contenttypes/actions) [![Coverage](https://coveralls.io/repos/github/RedTurtle/design.plone.contenttypes/badge.svg?branch=main)](https://coveralls.io/github/RedTurtle/design.plone.contenttypes?branch=main) From 2b5afd1767800fc7620e02d38c2645a3751e94b6 Mon Sep 17 00:00:00 2001 From: mamico Date: Wed, 22 Mar 2023 16:20:00 +0000 Subject: [PATCH 259/487] [lint] Update TOC. --- README.md | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/README.md b/README.md index dcb50fe9..c976db26 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,6 @@ - -[![Latest Version](https://img.shields.io/pypi/v/design.plone.contenttypes.svg)](https://pypi.python.org/pypi/design.plone.contenttypes/) -[![Supported - Python Versions](https://img.shields.io/pypi/pyversions/design.plone.contenttypes.svg?style=plastic)](https://pypi.python.org/pypi/design.plone.contenttypes/) -[![Number of PyPI downloads](https://img.shields.io/pypi/dm/design.plone.contenttypes.svg)](https://pypi.python.org/pypi/design.plone.contenttypes/) -[![License](https://img.shields.io/pypi/l/design.plone.contenttypes.svg)](https://pypi.python.org/pypi/design.plone.contenttypes/) -[![Tests](https://github.com/RedTurtle/design.plone.contenttypes/actions/workflows/test.yml/badge.svg)](https://github.com/RedTurtle/design.plone.contenttypes/actions) -[![Coverage](https://coveralls.io/repos/github/RedTurtle/design.plone.contenttypes/badge.svg?branch=main)](https://coveralls.io/github/RedTurtle/design.plone.contenttypes?branch=main) - - - [Design Plone Content-types](#design-plone-content-types) - [Features](#features) - [Tipi di contenuto](#tipi-di-contenuto) @@ -31,7 +22,7 @@ - [Campi indicizzati nel SearchableText](#campi-indicizzati-nel-searchabletext-2) - [Servizio](#servizio) - [Campi indicizzati nel SearchableText](#campi-indicizzati-nel-searchabletext-3) - - [Unità Organizzativa](#unità-organizzativa) + - [Unità Organizzativa](#unit%C3%A0-organizzativa) - [Campi indicizzati nel SearchableText](#campi-indicizzati-nel-searchabletext-4) - [Pannello di controllo](#pannello-di-controllo) - [Gestione modulistica](#gestione-modulistica) From d6def9b66ce6cab5579b637898f30ef63be26696 Mon Sep 17 00:00:00 2001 From: Mauro Amico Date: Wed, 22 Mar 2023 17:39:48 +0100 Subject: [PATCH 260/487] badges --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index c976db26..35b3f228 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,10 @@ +[![Latest Version](https://img.shields.io/pypi/v/design.plone.contenttypes.svg)](https://pypi.python.org/pypi/design.plone.contenttypes/) +[![Supported - Python Versions](https://img.shields.io/pypi/pyversions/design.plone.contenttypes.svg?style=plastic)](https://pypi.python.org/pypi/design.plone.contenttypes/) +[![Number of PyPI downloads](https://img.shields.io/pypi/dm/design.plone.contenttypes.svg)](https://pypi.python.org/pypi/design.plone.contenttypes/) +[![License](https://img.shields.io/pypi/l/design.plone.contenttypes.svg)](https://pypi.python.org/pypi/design.plone.contenttypes/) +[![Tests](https://github.com/RedTurtle/design.plone.contenttypes/actions/workflows/test.yml/badge.svg)](https://github.com/RedTurtle/design.plone.contenttypes/actions) +[![Coverage](https://coveralls.io/repos/github/RedTurtle/design.plone.contenttypes/badge.svg?branch=main)](https://coveralls.io/github/RedTurtle/design.plone.contenttypes?branch=main) + From 82165bbfc78297bf4de7ed08513ae967860df48d Mon Sep 17 00:00:00 2001 From: Andrea Cecchi Date: Thu, 23 Mar 2023 00:28:18 +0100 Subject: [PATCH 261/487] fix canale_digitale_link field type and restapi integration --- CHANGES.rst | 3 + .../plone/contenttypes/interfaces/servizio.py | 4 +- .../restapi/deserializers/configure.zcml | 1 + .../restapi/deserializers/dxfields.py | 22 ++++++ .../restapi/serializers/configure.zcml | 2 +- .../restapi/serializers/dxfields.py | 65 ++++++++--------- .../contenttypes/restapi/types/adapters.py | 18 ++++- .../contenttypes/restapi/types/configure.zcml | 2 +- .../contenttypes/tests/test_ct_servizio.py | 70 +++++++++++++++++++ test_plone60.cfg | 6 ++ 10 files changed, 152 insertions(+), 41 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 0aff4001..1112d1ad 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -5,6 +5,9 @@ Changelog 6.0.0a23 (unreleased) --------------------- +- Add serializer/deserializer for canale_digitale_link to handle internal/external links like remoteURL field. + [cekk] +- Force canale_digitale_link return `url` widget in Servizio schema. 6.0.0a22 (2023-03-07) --------------------- diff --git a/src/design/plone/contenttypes/interfaces/servizio.py b/src/design/plone/contenttypes/interfaces/servizio.py index 7c257134..2cf12693 100644 --- a/src/design/plone/contenttypes/interfaces/servizio.py +++ b/src/design/plone/contenttypes/interfaces/servizio.py @@ -7,6 +7,7 @@ from plone.app.dexterity import textindexer from plone.app.z3cform.widget import DateFieldWidget from plone.app.z3cform.widget import RelatedItemsFieldWidget +from plone.app.z3cform.widget import LinkFieldWidget from plone.autoform import directives as form from plone.namedfile import field from plone.supermodel import model @@ -160,7 +161,7 @@ class IServizio(model.Schema, IDesignPloneContentType): required=False, ) - canale_digitale_link = schema.URI( + canale_digitale_link = schema.TextLine( title=_("canale_digitale_link", default="Link al canale digitale"), description=_( "canale_digitale_link_help", @@ -465,6 +466,7 @@ class IServizio(model.Schema, IDesignPloneContentType): DataGridFieldFactory, frontendOptions={"widget": "data_grid"}, ) + form.widget("canale_digitale_link", LinkFieldWidget) # custom fieldset and order model.fieldset( diff --git a/src/design/plone/contenttypes/restapi/deserializers/configure.zcml b/src/design/plone/contenttypes/restapi/deserializers/configure.zcml index 4074b626..6b2d0c6a 100644 --- a/src/design/plone/contenttypes/restapi/deserializers/configure.zcml +++ b/src/design/plone/contenttypes/restapi/deserializers/configure.zcml @@ -7,6 +7,7 @@ + diff --git a/src/design/plone/contenttypes/restapi/deserializers/dxfields.py b/src/design/plone/contenttypes/restapi/deserializers/dxfields.py index 1edf89f2..820037e3 100644 --- a/src/design/plone/contenttypes/restapi/deserializers/dxfields.py +++ b/src/design/plone/contenttypes/restapi/deserializers/dxfields.py @@ -6,17 +6,23 @@ from plone.dexterity.interfaces import IDexterityContent from plone.formwidget.geolocation.geolocation import Geolocation from plone.formwidget.geolocation.interfaces import IGeolocationField +from plone.restapi.deserializer.blocks import path2uid from plone.restapi.deserializer.dxfields import CollectionFieldDeserializer from plone.restapi.deserializer.dxfields import DefaultFieldDeserializer +from plone.restapi.deserializer.dxfields import ( + TextLineFieldDeserializer as BaseTextLineDeserializer, +) from plone.restapi.interfaces import IBlockFieldDeserializationTransformer from plone.restapi.interfaces import IFieldDeserializer from zExceptions import BadRequest from zope.component import adapter +from zope.component import getMultiAdapter from zope.component import subscribers from zope.i18n import translate from zope.interface import implementer from zope.schema.interfaces import IList from zope.schema.interfaces import ISourceText +from zope.schema.interfaces import ITextLine import json @@ -125,3 +131,19 @@ def __call__(self, value): self.field.validate(timeline) return timeline + + +@implementer(IFieldDeserializer) +@adapter(ITextLine, IServizio, IDesignPloneContenttypesLayer) +class LinkTextLineFieldDeserializer(BaseTextLineDeserializer): + def __call__(self, value): + value = super().__call__(value) + if self.field.getName() == "canale_digitale_link": + portal = getMultiAdapter( + (self.context, self.context.REQUEST), name="plone_portal_state" + ).portal() + + transformed_url = path2uid(context=portal, link=value) + if transformed_url != value and "resolveuid" in transformed_url: + value = "${{portal_url}}/{uid}".format(uid=transformed_url) + return value diff --git a/src/design/plone/contenttypes/restapi/serializers/configure.zcml b/src/design/plone/contenttypes/restapi/serializers/configure.zcml index c03c65ea..fbbcff1d 100644 --- a/src/design/plone/contenttypes/restapi/serializers/configure.zcml +++ b/src/design/plone/contenttypes/restapi/serializers/configure.zcml @@ -23,6 +23,7 @@ + @@ -32,5 +33,4 @@ - diff --git a/src/design/plone/contenttypes/restapi/serializers/dxfields.py b/src/design/plone/contenttypes/restapi/serializers/dxfields.py index fd4c4ce3..cc6840c4 100644 --- a/src/design/plone/contenttypes/restapi/serializers/dxfields.py +++ b/src/design/plone/contenttypes/restapi/serializers/dxfields.py @@ -1,11 +1,11 @@ # -*- coding: utf-8 -*- from AccessControl.unauthorized import Unauthorized -from Acquisition import aq_inner from design.plone.contenttypes.interfaces import IDesignPloneContenttypesLayer from design.plone.contenttypes.interfaces.servizio import IServizio from plone import api +from plone.app.contenttypes.utils import replace_link_variables_by_paths from plone.dexterity.interfaces import IDexterityContent -from plone.namedfile.interfaces import INamedFileField +from plone.outputfilters.browser.resolveuid import uuidToURL from plone.restapi.interfaces import IBlockFieldSerializationTransformer from plone.restapi.interfaces import IFieldSerializer from plone.restapi.interfaces import ISerializeToJsonSummary @@ -18,10 +18,12 @@ from zope.interface import implementer from zope.schema.interfaces import IList from zope.schema.interfaces import ISourceText +from zope.schema.interfaces import ITextLine import json +import re - +RESOLVEUID_RE = re.compile(".*?/resolve[Uu]id/([^/]*)/?(.*)$") KEYS_WITH_URL = ["linkUrl", "navigationRoot", "showMoreLink"] @@ -49,40 +51,6 @@ def __call__(self): return value -@adapter(INamedFileField, IDexterityContent, IDesignPloneContenttypesLayer) -class FileFieldViewModeSerializer(DefaultFieldSerializer): - """Ovveride the basic DX serializer to handle the visualize file functionality""" - - def __call__(self): - namedfile = self.field.get(self.context) - if namedfile is None: - return - - url = "/".join( - ( - self.context.absolute_url(), - self.get_file_view_mode(namedfile.contentType), - self.field.__name__, - ) - ) - result = { - "filename": namedfile.filename, - "content-type": namedfile.contentType, - "size": namedfile.getSize(), - "download": url, - } - - return json_compatible(result) - - def get_file_view_mode(self, content_type): - """Pdf view depends on the visualize_files property in thq aq_chain""" - if self.context and "pdf" in content_type: - if getattr(aq_inner(self.context), "visualize_files", None): - return "@@display-file" - - return "@@download" - - def serialize_data(context, json_data, show_children=False): request = getRequest() if not json_data: @@ -147,3 +115,26 @@ def get_item_children(item): getMultiAdapter((brain, getRequest()), ISerializeToJsonSummary)() for brain in brains ] + + +@adapter(ITextLine, IServizio, IDesignPloneContenttypesLayer) +class ServizioTextLineFieldSerializer(DefaultFieldSerializer): + def __call__(self): + if self.field.getName() != "canale_digitale_link": + return super().__call__() + value = self.get_value() + + path = replace_link_variables_by_paths(context=self.context, url=value) + match = RESOLVEUID_RE.match(path) + if match: + uid, suffix = match.groups() + value = uuidToURL(uid) + else: + portal = getMultiAdapter( + (self.context, self.context.REQUEST), name="plone_portal_state" + ).portal() + ref_obj = portal.restrictedTraverse(path, None) + if ref_obj: + value = ref_obj.absolute_url() + + return json_compatible(value) diff --git a/src/design/plone/contenttypes/restapi/types/adapters.py b/src/design/plone/contenttypes/restapi/types/adapters.py index dbcde152..bb9b205f 100644 --- a/src/design/plone/contenttypes/restapi/types/adapters.py +++ b/src/design/plone/contenttypes/restapi/types/adapters.py @@ -1,7 +1,11 @@ # -*- coding: utf-8 -*- from collective.z3cform.datagridfield.interfaces import IRow from design.plone.contenttypes import _ +from design.plone.contenttypes.interfaces import IDesignPloneContenttypesLayer from plone.restapi.types.adapters import ObjectJsonSchemaProvider +from redturtle.volto.types.adapters import ( + TextLineJsonSchemaProvider as BaseTextLineJsonSchemaProvider, +) from plone.restapi.types.interfaces import IJsonSchemaProvider from plone.restapi.types.utils import get_fieldsets from plone.restapi.types.utils import get_jsonschema_properties @@ -12,9 +16,9 @@ from zope.interface import implementer from zope.interface import Interface from zope.schema.interfaces import IField +from zope.schema.interfaces import ITextLine from zope.schema.interfaces import IVocabularyFactory - DATAGRID_FIELDS = ["value_punto_contatto", "timeline_tempi_scadenze"] @@ -89,3 +93,15 @@ def additional(self): info["required"] = required info["properties"] = properties return info + + +@adapter(ITextLine, Interface, IDesignPloneContenttypesLayer) +@implementer(IJsonSchemaProvider) +class TextLineJsonSchemaProvider(BaseTextLineJsonSchemaProvider): + def get_widget(self): + """ + Force url widget to some fields + """ + if self.field.__name__ == "canale_digitale_link": + return "url" + return super().get_widget() diff --git a/src/design/plone/contenttypes/restapi/types/configure.zcml b/src/design/plone/contenttypes/restapi/types/configure.zcml index 9adca258..16e3fbae 100644 --- a/src/design/plone/contenttypes/restapi/types/configure.zcml +++ b/src/design/plone/contenttypes/restapi/types/configure.zcml @@ -9,6 +9,6 @@ name="ILeadImageBehavior.image" /> - + diff --git a/src/design/plone/contenttypes/tests/test_ct_servizio.py b/src/design/plone/contenttypes/tests/test_ct_servizio.py index 487dc35d..3ae3b668 100644 --- a/src/design/plone/contenttypes/tests/test_ct_servizio.py +++ b/src/design/plone/contenttypes/tests/test_ct_servizio.py @@ -12,6 +12,7 @@ from plone.app.testing import SITE_OWNER_PASSWORD from plone.app.testing import TEST_USER_ID from plone.restapi.testing import RelativeSession +from transaction import commit import unittest @@ -113,6 +114,11 @@ def test_related_widgets(self): ) self.assertTrue(properties[field]["type"] == "array") + def test_canale_digitale_link_widget_set_in_schema(self): + response = self.api_session.get("/@types/Servizio") + res = response.json() + self.assertEqual(res["properties"]["canale_digitale_link"]["widget"], "url") + def test_sottotitolo_indexed_in_searchabletext(self): #  Servizio is the only ct with this field servizio = api.content.create( @@ -210,3 +216,67 @@ def test_ulteriori_informazioni_indexed_in_searchabletext(self): self.assertEqual(len(res), 1) self.assertEqual(res[0].UID, servizio.UID()) + + def test_canale_digitale_link_serialized_as_url(self): + page = api.content.create( + container=self.portal, type="Document", title="Document" + ) + servizio = api.content.create( + container=self.portal, + type="Servizio", + title="Test servizio", + canale_digitale_link="/plone/resolveuid/{}".format(page.UID()), + ) + + commit() + res = self.api_session.get(servizio.absolute_url()).json() + self.assertEqual(res["canale_digitale_link"], page.absolute_url()) + + def test_canale_digitale_link_deserialized_as_plone_internal_url(self): + page = api.content.create( + container=self.portal, type="Document", title="Document" + ) + + servizio = api.content.create( + container=self.portal, + type="Servizio", + title="Test servizio", + description="xxx", + a_chi_si_rivolge={ + "blocks": {"xxx": {"@type": "foo", "searchableText": "aiuto"}}, + "blocks_layout": {"items": ["xxx"]}, + }, + canale_digitale={ + "blocks": {"xxx": {"@type": "foo", "searchableText": "aiuto"}}, + "blocks_layout": {"items": ["xxx"]}, + }, + come_si_fa={ + "blocks": {"xxx": {"@type": "foo", "searchableText": "aiuto"}}, + "blocks_layout": {"items": ["xxx"]}, + }, + cosa_serve={ + "blocks": {"xxx": {"@type": "foo", "searchableText": "aiuto"}}, + "blocks_layout": {"items": ["xxx"]}, + }, + cosa_si_ottiene={ + "blocks": {"xxx": {"@type": "foo", "searchableText": "aiuto"}}, + "blocks_layout": {"items": ["xxx"]}, + }, + tempi_e_scadenze={ + "blocks": {"xxx": {"@type": "foo", "searchableText": "aiuto"}}, + "blocks_layout": {"items": ["xxx"]}, + }, + ) + + commit() + + self.api_session.patch( + servizio.absolute_url(), + json={"canale_digitale_link": page.absolute_url()}, + ) + + commit() + self.assertEqual( + servizio.canale_digitale_link, + "${{portal_url}}/resolveuid/{}".format(page.UID()), + ) diff --git a/test_plone60.cfg b/test_plone60.cfg index 68df7f0b..d81a5291 100644 --- a/test_plone60.cfg +++ b/test_plone60.cfg @@ -66,3 +66,9 @@ tomli = 2.0.1 # Required by: # bleach==3.3.1 webencodings = 0.5.1 + +# Added by buildout at 2023-03-22 23:05:32.974075 + +# Required by: +# redturtle.prenotazioni==1.7.0.dev0 +collective.contentrules.mailfromfield = 1.1.0 From 21bf1ceb3aa2a100746b3045655e67b5661c4939 Mon Sep 17 00:00:00 2001 From: Mauro Amico Date: Thu, 23 Mar 2023 08:23:48 +0100 Subject: [PATCH 262/487] Update README.md --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 35b3f228..cbcb1b34 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,12 @@ Pacchetto per la gestione dei content-type per un sito Agid con Plone. Installando questo pacchetto, si rendono disponibili diversi content-type per la gestione di un sito Agid con Plone e Volto. + +# Compatibilità + +- Plone 6.0, design.plone.policy 5.*, design.plone.contenttypes 6.* +- Plone 5.2, design.plone.policy 4.*, design.plone.contenttypes 5.* + # Tipi di contenuto ## Elenco tipi implementati From d71195ccead0e1e141985927282c6566bc98dd37 Mon Sep 17 00:00:00 2001 From: mamico Date: Thu, 23 Mar 2023 07:24:11 +0000 Subject: [PATCH 263/487] [lint] Update TOC. --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index cbcb1b34..4f5c5b5a 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ - [Design Plone Content-types](#design-plone-content-types) - [Features](#features) +- [Compatibilità](#compatibilit%C3%A0) - [Tipi di contenuto](#tipi-di-contenuto) - [Elenco tipi implementati](#elenco-tipi-implementati) - [Bando](#bando) From ef94302b2be098aa638d146c336dd0d81e868c95 Mon Sep 17 00:00:00 2001 From: Andrea Cecchi Date: Thu, 23 Mar 2023 12:24:09 +0100 Subject: [PATCH 264/487] fix check --- src/design/plone/contenttypes/restapi/serializers/dxfields.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/design/plone/contenttypes/restapi/serializers/dxfields.py b/src/design/plone/contenttypes/restapi/serializers/dxfields.py index cc6840c4..552bdfe2 100644 --- a/src/design/plone/contenttypes/restapi/serializers/dxfields.py +++ b/src/design/plone/contenttypes/restapi/serializers/dxfields.py @@ -120,9 +120,9 @@ def get_item_children(item): @adapter(ITextLine, IServizio, IDesignPloneContenttypesLayer) class ServizioTextLineFieldSerializer(DefaultFieldSerializer): def __call__(self): - if self.field.getName() != "canale_digitale_link": - return super().__call__() value = self.get_value() + if self.field.getName() != "canale_digitale_link" or not value: + return super().__call__() path = replace_link_variables_by_paths(context=self.context, url=value) match = RESOLVEUID_RE.match(path) From e38f10c3a22c98592c8a9e92812394c80bcc61a5 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Thu, 23 Mar 2023 14:27:10 +0100 Subject: [PATCH 265/487] update upgrade step adding better check --- CHANGES.rst | 3 ++- src/design/plone/contenttypes/upgrades/to_7001.py | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 0aff4001..c422dc0c 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,7 +4,8 @@ Changelog 6.0.0a23 (unreleased) --------------------- - +- improve upgrade step + [lucabel] 6.0.0a22 (2023-03-07) --------------------- diff --git a/src/design/plone/contenttypes/upgrades/to_7001.py b/src/design/plone/contenttypes/upgrades/to_7001.py index 30c03fdf..84382077 100644 --- a/src/design/plone/contenttypes/upgrades/to_7001.py +++ b/src/design/plone/contenttypes/upgrades/to_7001.py @@ -112,7 +112,8 @@ def create_incarico_for_persona(context): continue if safe_hasattr(persona, "ruolo"): - incarico_title = persona.ruolo + # we could have the attribute and then remove the value + incarico_title = persona.ruolo or f"Incarico di {persona.title}" else: logger.info( f"{colors.RED} Attenzione: {persona.title} non ha un ruolo {colors.ENDC}" # noqa @@ -171,7 +172,7 @@ def create_incarico_for_persona(context): f"{colors.GREEN} Creato atto nomina per {persona.title} {colors.ENDC}" ) - if safe_hasattr(persona, "tipologia_persona"): + if safe_hasattr(persona, "tipologia_persona") and persona.tipologia_persona: incarico.tipologia_incarico = MAPPING_TIPO[persona.tipologia_persona] # persona.incarichi_persona = [RelationValue(intids.getId(incarico))] From a15991275ec745cd485ed619bb0a457dc7cdf9b1 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 23 Mar 2023 14:53:10 +0100 Subject: [PATCH 266/487] switch to 6.0.0 --- CHANGES.rst | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index c422dc0c..e11cef72 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -2,7 +2,7 @@ Changelog ========= -6.0.0a23 (unreleased) +6.0.0 (unreleased) --------------------- - improve upgrade step [lucabel] diff --git a/setup.py b/setup.py index 25dfd0cd..6dfc6c1a 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.0.0a23.dev0", + version="6.0.0.dev0", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 3bbf18bddb604bd041733a865eb5ed0e59cbe7e6 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 23 Mar 2023 14:53:37 +0100 Subject: [PATCH 267/487] Preparing release 6.0.0 --- CHANGES.rst | 4 ++-- setup.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index e11cef72..dfe60856 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -2,8 +2,8 @@ Changelog ========= -6.0.0 (unreleased) ---------------------- +6.0.0 (2023-03-23) +------------------ - improve upgrade step [lucabel] diff --git a/setup.py b/setup.py index 6dfc6c1a..8daad235 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.0.0.dev0", + version="6.0.0", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 7bf0f0c30c9507859df1f75369026f1c2fa6c0f7 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 23 Mar 2023 14:53:56 +0100 Subject: [PATCH 268/487] Back to development: 6.0.1 --- CHANGES.rst | 6 ++++++ setup.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index dfe60856..0906041c 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -2,6 +2,12 @@ Changelog ========= +6.0.1 (unreleased) +------------------ + +- Nothing changed yet. + + 6.0.0 (2023-03-23) ------------------ - improve upgrade step diff --git a/setup.py b/setup.py index 8daad235..3478eb72 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.0.0", + version="6.0.1.dev0", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From c2eef921509f23f7b34f0e0604472ab7ffbde979 Mon Sep 17 00:00:00 2001 From: Andrea Cecchi Date: Fri, 24 Mar 2023 08:51:33 +0100 Subject: [PATCH 269/487] Do not purge allowed_content_types filter for Servizio --- CHANGES.rst | 3 ++- .../contenttypes/profiles/default/types/Servizio.xml | 10 +++------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 0906041c..2938216b 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -5,7 +5,8 @@ Changelog 6.0.1 (unreleased) ------------------ -- Nothing changed yet. +- Do not purge allowed_content_types filter for Servizio. + [cekk] 6.0.0 (2023-03-23) diff --git a/src/design/plone/contenttypes/profiles/default/types/Servizio.xml b/src/design/plone/contenttypes/profiles/default/types/Servizio.xml index 0ce1e2ce..021eabde 100644 --- a/src/design/plone/contenttypes/profiles/default/types/Servizio.xml +++ b/src/design/plone/contenttypes/profiles/default/types/Servizio.xml @@ -6,12 +6,8 @@ > - Servizio - + Servizio + False Servizio @@ -21,7 +17,7 @@ True True - + From 0b2406bbcb5aa8dccf0478417714fc6462945222 Mon Sep 17 00:00:00 2001 From: daniele-andreotti Date: Mon, 27 Mar 2023 10:20:02 +0200 Subject: [PATCH 270/487] improved check (#167) * improved check * fix check --------- Co-authored-by: Mauro Amico --- src/design/plone/contenttypes/upgrades/to_7001.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/design/plone/contenttypes/upgrades/to_7001.py b/src/design/plone/contenttypes/upgrades/to_7001.py index 84382077..95cde46b 100644 --- a/src/design/plone/contenttypes/upgrades/to_7001.py +++ b/src/design/plone/contenttypes/upgrades/to_7001.py @@ -5,6 +5,7 @@ from .upgrades import update_registry from .upgrades import update_rolemap from .upgrades import update_types +from Acquisition import aq_base from collective.taxonomy.interfaces import ITaxonomy from plone import api from plone.base.utils import get_installer @@ -282,9 +283,10 @@ def migrated_contact_info(source): continue if not migrated_contact_info(obj): - obj.old_contact_info = obj.contact_info - if obj.portal_type == "UnitaOrganizzativa": - del obj.contact_info + if hasattr(aq_base(obj), "contact_info"): + obj.old_contact_info = obj.contact_info + if obj.portal_type == "UnitaOrganizzativa": + del obj.contact_info else: logger.info( f"{colors.RED} Esiste già un punto di contatto per {obj.title}({obj.absolute_url()}){colors.ENDC}" # noqa From f28b1b915a97a626764a538dbbbe19d3d5c90c39 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Thu, 30 Mar 2023 15:53:57 +0200 Subject: [PATCH 271/487] update check_servizi service view to show all missing mandatory attributes --- .../browser/manage_content/check_servizi.py | 96 ++++++++++++++++++ .../manage_content/templates/check_servizi.pt | 97 +++++++++++++++++-- 2 files changed, 183 insertions(+), 10 deletions(-) diff --git a/src/design/plone/contenttypes/browser/manage_content/check_servizi.py b/src/design/plone/contenttypes/browser/manage_content/check_servizi.py index 368b5e00..fd8f85cb 100644 --- a/src/design/plone/contenttypes/browser/manage_content/check_servizi.py +++ b/src/design/plone/contenttypes/browser/manage_content/check_servizi.py @@ -1,6 +1,49 @@ from plone import api +from plone.restapi.behaviors import IBlocks +from plone.restapi.indexers import SearchableText_blocks from Products.CMFPlone.utils import safe_hasattr from Products.Five import BrowserView +from zope.interface import implementer + + +FIELDS = [ + "title", + "description", + "condizioni_di_servizio", + "tassonomia_argomenti", + "a_chi_si_rivolge", + "come_si_fa", + "cosa_si_ottiene", + "canale_fisico", + "cosa_serve", + "tempi_e_scadenze", + "ufficio_responsabile", + "contact_info", +] + + +def text_in_block(blocks): + @implementer(IBlocks) + class FakeObject(object): + """ + We use a fake object to use SearchableText Indexer + """ + + def Subject(self): + return "" + + def __init__(self, blocks, blocks_layout): + self.blocks = blocks + self.blocks_layout = blocks_layout + self.id = "" + self.title = "" + self.description = "" + + if not blocks: + return None + + fakeObj = FakeObject(blocks.get("blocks", ""), blocks.get("blocks_layout", "")) + return SearchableText_blocks(fakeObj)() class CheckServizi(BrowserView): @@ -25,10 +68,63 @@ def get_servizi(self): "url": parent.absolute_url().replace("/api/", "/"), "children": [], } + results[parent.title]["children"].append( { "title": servizio.title, "url": servizio.absolute_url().replace("/api/", "/"), + "data": { + "title": getattr(servizio, "title") and "X" or "", + "description": getattr(servizio, "description", None) + and "X" + or "", + "condizioni_di_servizio": getattr( + servizio, "condizioni_di_servizio", None + ) + and "X" + or "", + "tassonomia_argomenti": getattr( + servizio, "tassonomia_argomenti", None + ) + and "X" + or "", + "a_chi_si_rivolge": text_in_block( + getattr(servizio, "a_chi_si_rivolge", None) + ) + and "X" + or "", + "come_si_fa": text_in_block( + getattr(servizio, "come_si_fa", None) + ) + and "X" + or "", + "cosa_si_ottiene": text_in_block( + getattr(servizio, "cosa_si_ottiene", None) + ) + and "X" + or "", + "canale_fisico": getattr(servizio, "canale_fisico", None) + and "X" + or "", + "cosa_serve": text_in_block( + getattr(servizio, "cosa_serve", None) + ) + and "X" + or "", + "tempi_e_scadenze": text_in_block( + getattr(servizio, "tempi_e_scadenze", None) + ) + and "X" + or "", + "ufficio_responsabile": getattr( + servizio, "ufficio_responsabile", None + ) + and "X" + or "", + "contact_info": getattr(servizio, "contact_info", None) + and "X" + or "", + }, } ) results = dict(sorted(results.items())) diff --git a/src/design/plone/contenttypes/browser/manage_content/templates/check_servizi.pt b/src/design/plone/contenttypes/browser/manage_content/templates/check_servizi.pt index bf28e80d..28292e77 100644 --- a/src/design/plone/contenttypes/browser/manage_content/templates/check_servizi.pt +++ b/src/design/plone/contenttypes/browser/manage_content/templates/check_servizi.pt @@ -9,6 +9,9 @@ > + + + @@ -28,24 +53,76 @@ agli amministratori del sito.
-

+ > +

La lista seguente elenca tutti quei servizi per i quali non sono ancora stati aggiunti i campi che AGID indica come obbligatori. - Ogni redattore può vedere in questa lista tutti i servizi e, + Ogni redattore può vedere in questa lista tutti i servizi e, cliccando su ognuno, andare alla vista di dettaglio del servizio, - editarlo e compilare tutti i campi obbligatori.

+ editarlo e compilare tutti i campi obbligatori.

  • - -

    ${categoria}

    -
      -
    • -
      ${servizio/title}
      + tal:repeat="categoria servizi" + > + +

      ${categoria}

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      TitoloDescrizioneCondizioni di servizioArgomentiA chi è rivoltoCome fare perCosa si ottieneCanale fisicoCosa serveTempi e scadenzeUnità org. responsabileContatto
      ${servizio/title}
    From 530c7efb4e4b49d88f3c2f88437bdd354edf14b4 Mon Sep 17 00:00:00 2001 From: Andrea Cecchi Date: Mon, 3 Apr 2023 09:48:15 +0200 Subject: [PATCH 272/487] Fix patch/post validations for required fields: do not return errors when sorting items --- CHANGES.rst | 2 + .../restapi/deserializers/documento.py | 140 +++++++++------- .../restapi/deserializers/news.py | 141 +++++++++------- .../restapi/deserializers/servizio.py | 141 +++++++++------- .../deserializers/unitaorganizzativa.py | 155 ++++++++++-------- 5 files changed, 320 insertions(+), 259 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 3c0aac3b..2a27765e 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -9,6 +9,8 @@ Changelog [cekk] - Force canale_digitale_link return `url` widget in Servizio schema. [cekk] +- Fix patch/post validations for required fields: do not return errors when sorting items. + [cekk] 6.0.0 (2023-03-23) ------------------ diff --git a/src/design/plone/contenttypes/restapi/deserializers/documento.py b/src/design/plone/contenttypes/restapi/deserializers/documento.py index 949b3bdb..ab5505c9 100644 --- a/src/design/plone/contenttypes/restapi/deserializers/documento.py +++ b/src/design/plone/contenttypes/restapi/deserializers/documento.py @@ -62,77 +62,91 @@ def __call__( is_patch = method == "PATCH" errors = [] - title = data.get("title") - description = data.get("description") - - if is_post: - # Title validation - if not title: - errors.append(new_error("Il titolo del servizio è obbligatorio")) - elif len(title) > TITLE_MAX_LEN: - errors.append( - new_error( - "Il titolo può avere una lunghezza di massimo {} caratteri".format( # noqa - TITLE_MAX_LEN + if list(data.keys()) != ["ordering"]: + title = data.get("title") + description = data.get("description") + if is_post: + # Title validation + if not title: + errors.append(new_error("Il titolo del servizio è obbligatorio")) + elif len(title) > TITLE_MAX_LEN: + errors.append( + new_error( + "Il titolo può avere una lunghezza di massimo {} caratteri".format( # noqa + TITLE_MAX_LEN + ) ) ) - ) - - # description validation - if not description: - errors.append(new_error("La descrizione del servizio è obbligatorio")) - elif len(description) > DESCRIPTION_MAX_LEN: - errors.append( - new_error( - "La descrizione del servizio deve avere una lunghezza di massimo {} caratteri".format( # noqa - DESCRIPTION_MAX_LEN + + # description validation + if not description: + errors.append( + new_error("La descrizione del servizio è obbligatoria") + ) + elif len(description) > DESCRIPTION_MAX_LEN: + errors.append( + new_error( + "La descrizione del servizio deve avere una lunghezza di massimo {} caratteri".format( # noqa + DESCRIPTION_MAX_LEN + ) ) ) - ) - - for field in MANDATORY_RICH_TEXT_FIELDS: - if field not in data: - errors.append(new_error("Il campo {} è obbligatorio".format(field))) - elif field in data and not text_in_block(data.get(field)): - errors.append(new_error("Il campo {} è obbligatorio".format(field))) - - if is_patch: - # Title validation - if "title" in data and not title: - errors.append(new_error("Il titolo del servizio è obbligatorio")) - if title and len(title) > TITLE_MAX_LEN: - errors.append( - new_error( - "Il titolo può avere una lunghezza di massimo {} caratteri".format( # noqa - TITLE_MAX_LEN + + for field in MANDATORY_RICH_TEXT_FIELDS: + if field not in data: + errors.append( + new_error("Il campo {} è obbligatorio".format(field)) + ) + elif field in data and not text_in_block(data.get(field)): + errors.append( + new_error("Il campo {} è obbligatorio".format(field)) + ) + + if is_patch: + # Title validation + if "title" in data and not title: + errors.append(new_error("Il titolo del servizio è obbligatorio")) + if title and len(title) > TITLE_MAX_LEN: + errors.append( + new_error( + "Il titolo può avere una lunghezza di massimo {} caratteri".format( # noqa + TITLE_MAX_LEN + ) ) ) - ) - # description validation - if "description" in data and not description: - errors.append(new_error("La descrizione del servizio è obbligatorio")) - if description and len(description) > DESCRIPTION_MAX_LEN: - errors.append( - new_error( - "La descrizione del servizio deve avere una lunghezza di massimo {} caratteri".format( # noqa - DESCRIPTION_MAX_LEN + # description validation + if "description" in data and not description: + errors.append( + new_error("La descrizione del servizio è obbligatoria") + ) + if description and len(description) > DESCRIPTION_MAX_LEN: + errors.append( + new_error( + "La descrizione del servizio deve avere una lunghezza di massimo {} caratteri".format( # noqa + DESCRIPTION_MAX_LEN + ) ) ) - ) - if "description" not in data and not self.context.description: - errors.append(new_error("La descrizione del servizio è obbligatorio")) - - for field in MANDATORY_RICH_TEXT_FIELDS: - if field in data and not text_in_block(data.get(field)): - errors.append(new_error("Il campo {} è obbligatorio".format(field))) - # Se siamo nella patch siamo in modifica. Se siamo in modifica e siamo - # su un sito che ha avuto upgrade alla versione pnrr può essere che - # dei campi obbligatori un tempo non lo fossero e quindi arriviamo - # fino a qui - if field not in data and not text_in_block( - getattr(self.context, field) - ): - errors.append(new_error("Il campo {} è obbligatorio".format(field))) + if "description" not in data and not self.context.description: + errors.append( + new_error("La descrizione del servizio è obbligatoria") + ) + + for field in MANDATORY_RICH_TEXT_FIELDS: + if field in data and not text_in_block(data.get(field)): + errors.append( + new_error("Il campo {} è obbligatorio".format(field)) + ) + # Se siamo nella patch siamo in modifica. Se siamo in modifica e siamo + # su un sito che ha avuto upgrade alla versione pnrr può essere che + # dei campi obbligatori un tempo non lo fossero e quindi arriviamo + # fino a qui + if field not in data and not text_in_block( + getattr(self.context, field) + ): + errors.append( + new_error("Il campo {} è obbligatorio".format(field)) + ) if errors: raise BadRequest(errors) diff --git a/src/design/plone/contenttypes/restapi/deserializers/news.py b/src/design/plone/contenttypes/restapi/deserializers/news.py index ae1c1004..5ead25ba 100644 --- a/src/design/plone/contenttypes/restapi/deserializers/news.py +++ b/src/design/plone/contenttypes/restapi/deserializers/news.py @@ -61,77 +61,92 @@ def __call__( is_patch = method == "PATCH" errors = [] - title = data.get("title") - description = data.get("description") - - if is_post: - # Title validation - if not title: - errors.append(new_error("Il titolo del servizio è obbligatorio")) - elif len(title) > TITLE_MAX_LEN: - errors.append( - new_error( - "Il titolo può avere una lunghezza di massimo {} caratteri".format( # noqa - TITLE_MAX_LEN + if list(data.keys()) != ["ordering"]: + title = data.get("title") + description = data.get("description") + + if is_post: + # Title validation + if not title: + errors.append(new_error("Il titolo del servizio è obbligatorio")) + elif len(title) > TITLE_MAX_LEN: + errors.append( + new_error( + "Il titolo può avere una lunghezza di massimo {} caratteri".format( # noqa + TITLE_MAX_LEN + ) ) ) - ) - - # description validation - if not description: - errors.append(new_error("La descrizione del servizio è obbligatorio")) - elif len(description) > DESCRIPTION_MAX_LEN: - errors.append( - new_error( - "La descrizione del servizio deve avere una lunghezza di massimo {} caratteri".format( # noqa - DESCRIPTION_MAX_LEN + + # description validation + if not description: + errors.append( + new_error("La descrizione del servizio è obbligatoria") + ) + elif len(description) > DESCRIPTION_MAX_LEN: + errors.append( + new_error( + "La descrizione del servizio deve avere una lunghezza di massimo {} caratteri".format( # noqa + DESCRIPTION_MAX_LEN + ) ) ) - ) - - for field in MANDATORY_RICH_TEXT_FIELDS: - if field not in data: - errors.append(new_error("Il campo {} è obbligatorio".format(field))) - elif field in data and not text_in_block(data.get(field)): - errors.append(new_error("Il campo {} è obbligatorio".format(field))) - - if is_patch: - # Title validation - if "title" in data and not title: - errors.append(new_error("Il titolo del servizio è obbligatorio")) - if title and len(title) > TITLE_MAX_LEN: - errors.append( - new_error( - "Il titolo può avere una lunghezza di massimo {} caratteri".format( # noqa - TITLE_MAX_LEN + + for field in MANDATORY_RICH_TEXT_FIELDS: + if field not in data: + errors.append( + new_error("Il campo {} è obbligatorio".format(field)) + ) + elif field in data and not text_in_block(data.get(field)): + errors.append( + new_error("Il campo {} è obbligatorio".format(field)) + ) + + if is_patch: + # Title validation + if "title" in data and not title: + errors.append(new_error("Il titolo del servizio è obbligatorio")) + if title and len(title) > TITLE_MAX_LEN: + errors.append( + new_error( + "Il titolo può avere una lunghezza di massimo {} caratteri".format( # noqa + TITLE_MAX_LEN + ) ) ) - ) - # description validation - if "description" in data and not description: - errors.append(new_error("La descrizione del servizio è obbligatorio")) - if description and len(description) > DESCRIPTION_MAX_LEN: - errors.append( - new_error( - "La descrizione del servizio deve avere una lunghezza di massimo {} caratteri".format( # noqa - DESCRIPTION_MAX_LEN + # description validation + if "description" in data and not description: + errors.append( + new_error("La descrizione del servizio è obbligatoria") + ) + if description and len(description) > DESCRIPTION_MAX_LEN: + errors.append( + new_error( + "La descrizione del servizio deve avere una lunghezza di massimo {} caratteri".format( # noqa + DESCRIPTION_MAX_LEN + ) ) ) - ) - if "description" not in data and not self.context.description: - errors.append(new_error("La descrizione del servizio è obbligatorio")) - - for field in MANDATORY_RICH_TEXT_FIELDS: - if field in data and not text_in_block(data.get(field)): - errors.append(new_error("Il campo {} è obbligatorio".format(field))) - # Se siamo nella patch siamo in modifica. Se siamo in modifica e siamo - # su un sito che ha avuto upgrade alla versione pnrr può essere che - # dei campi obbligatori un tempo non lo fossero e quindi arriviamo - # fino a qui - if field not in data and not text_in_block( - getattr(self.context, field) - ): - errors.append(new_error("Il campo {} è obbligatorio".format(field))) + if "description" not in data and not self.context.description: + errors.append( + new_error("La descrizione del servizio è obbligatoria") + ) + + for field in MANDATORY_RICH_TEXT_FIELDS: + if field in data and not text_in_block(data.get(field)): + errors.append( + new_error("Il campo {} è obbligatorio".format(field)) + ) + # Se siamo nella patch siamo in modifica. Se siamo in modifica e siamo + # su un sito che ha avuto upgrade alla versione pnrr può essere che + # dei campi obbligatori un tempo non lo fossero e quindi arriviamo + # fino a qui + if field not in data and not text_in_block( + getattr(self.context, field) + ): + errors.append( + new_error("Il campo {} è obbligatorio".format(field)) + ) if errors: raise BadRequest(errors) diff --git a/src/design/plone/contenttypes/restapi/deserializers/servizio.py b/src/design/plone/contenttypes/restapi/deserializers/servizio.py index 4fa51574..bdbad7bf 100644 --- a/src/design/plone/contenttypes/restapi/deserializers/servizio.py +++ b/src/design/plone/contenttypes/restapi/deserializers/servizio.py @@ -65,77 +65,92 @@ def __call__( is_patch = method == "PATCH" errors = [] - title = data.get("title") - description = data.get("description") - - if is_post: - # Title validation - if not title: - errors.append(new_error("Il titolo del servizio è obbligatorio")) - elif len(title) > TITLE_MAX_LEN: - errors.append( - new_error( - "Il titolo può avere una lunghezza di massimo {} caratteri".format( # noqa - TITLE_MAX_LEN + if list(data.keys()) != ["ordering"]: + title = data.get("title") + description = data.get("description") + + if is_post: + # Title validation + if not title: + errors.append(new_error("Il titolo del servizio è obbligatorio")) + elif len(title) > TITLE_MAX_LEN: + errors.append( + new_error( + "Il titolo può avere una lunghezza di massimo {} caratteri".format( # noqa + TITLE_MAX_LEN + ) ) ) - ) - - # description validation - if not description: - errors.append(new_error("La descrizione del servizio è obbligatorio")) - elif len(description) > DESCRIPTION_MAX_LEN: - errors.append( - new_error( - "La descrizione del servizio deve avere una lunghezza di massimo {} caratteri".format( # noqa - DESCRIPTION_MAX_LEN + + # description validation + if not description: + errors.append( + new_error("La descrizione del servizio è obbligatoria") + ) + elif len(description) > DESCRIPTION_MAX_LEN: + errors.append( + new_error( + "La descrizione del servizio deve avere una lunghezza di massimo {} caratteri".format( # noqa + DESCRIPTION_MAX_LEN + ) ) ) - ) - - for field in MANDATORY_RICH_TEXT_FIELDS: - if field not in data: - errors.append(new_error("Il campo {} è obbligatorio".format(field))) - elif field in data and not text_in_block(data.get(field)): - errors.append(new_error("Il campo {} è obbligatorio".format(field))) - - if is_patch: - # Title validation - if "title" in data and not title: - errors.append(new_error("Il titolo del servizio è obbligatorio")) - if title and len(title) > TITLE_MAX_LEN: - errors.append( - new_error( - "Il titolo può avere una lunghezza di massimo {} caratteri".format( # noqa - TITLE_MAX_LEN + + for field in MANDATORY_RICH_TEXT_FIELDS: + if field not in data: + errors.append( + new_error("Il campo {} è obbligatorio".format(field)) + ) + elif field in data and not text_in_block(data.get(field)): + errors.append( + new_error("Il campo {} è obbligatorio".format(field)) + ) + + if is_patch: + # Title validation + if "title" in data and not title: + errors.append(new_error("Il titolo del servizio è obbligatorio")) + if title and len(title) > TITLE_MAX_LEN: + errors.append( + new_error( + "Il titolo può avere una lunghezza di massimo {} caratteri".format( # noqa + TITLE_MAX_LEN + ) ) ) - ) - # description validation - if "description" in data and not description: - errors.append(new_error("La descrizione del servizio è obbligatorio")) - if description and len(description) > DESCRIPTION_MAX_LEN: - errors.append( - new_error( - "La descrizione del servizio deve avere una lunghezza di massimo {} caratteri".format( # noqa - DESCRIPTION_MAX_LEN + # description validation + if "description" in data and not description: + errors.append( + new_error("La descrizione del servizio è obbligatoria") + ) + if description and len(description) > DESCRIPTION_MAX_LEN: + errors.append( + new_error( + "La descrizione del servizio deve avere una lunghezza di massimo {} caratteri".format( # noqa + DESCRIPTION_MAX_LEN + ) ) ) - ) - if "description" not in data and not self.context.description: - errors.append(new_error("La descrizione del servizio è obbligatorio")) - - for field in MANDATORY_RICH_TEXT_FIELDS: - if field in data and not text_in_block(data.get(field)): - errors.append(new_error("Il campo {} è obbligatorio".format(field))) - # Se siamo nella patch siamo in modifica. Se siamo in modifica e siamo - # su un sito che ha avuto upgrade alla versione pnrr può essere che - # dei campi obbligatori un tempo non lo fossero e quindi arriviamo - # fino a qui - if field not in data and not text_in_block( - getattr(self.context, field) - ): - errors.append(new_error("Il campo {} è obbligatorio".format(field))) + if "description" not in data and not self.context.description: + errors.append( + new_error("La descrizione del servizio è obbligatoria") + ) + + for field in MANDATORY_RICH_TEXT_FIELDS: + if field in data and not text_in_block(data.get(field)): + errors.append( + new_error("Il campo {} è obbligatorio".format(field)) + ) + # Se siamo nella patch siamo in modifica. Se siamo in modifica e siamo + # su un sito che ha avuto upgrade alla versione pnrr può essere che + # dei campi obbligatori un tempo non lo fossero e quindi arriviamo + # fino a qui + if field not in data and not text_in_block( + getattr(self.context, field) + ): + errors.append( + new_error("Il campo {} è obbligatorio".format(field)) + ) if errors: raise BadRequest(errors) diff --git a/src/design/plone/contenttypes/restapi/deserializers/unitaorganizzativa.py b/src/design/plone/contenttypes/restapi/deserializers/unitaorganizzativa.py index 540a9822..bd04abd8 100644 --- a/src/design/plone/contenttypes/restapi/deserializers/unitaorganizzativa.py +++ b/src/design/plone/contenttypes/restapi/deserializers/unitaorganizzativa.py @@ -59,84 +59,99 @@ def __call__( is_patch = method == "PATCH" errors = [] - title = data.get("title") - description = data.get("description") - - if is_post: - # Title validation - if not title: - errors.append( - new_error("Il titolo dell'unità organizzativa è obbligatorio") - ) - elif len(title) > TITLE_MAX_LEN: - errors.append( - new_error( - "Il titolo può avere una lunghezza di massimo {} caratteri".format( # noqa - TITLE_MAX_LEN + if list(data.keys()) != ["ordering"]: + title = data.get("title") + description = data.get("description") + + if is_post: + # Title validation + if not title: + errors.append( + new_error("Il titolo dell'unità organizzativa è obbligatorio") + ) + elif len(title) > TITLE_MAX_LEN: + errors.append( + new_error( + "Il titolo può avere una lunghezza di massimo {} caratteri".format( # noqa + TITLE_MAX_LEN + ) ) ) - ) - - # description validation - if not description: - errors.append( - new_error("La descrizione dell'unità organizzativa è obbligatorio") - ) - elif len(description) > DESCRIPTION_MAX_LEN: - errors.append( - new_error( - "La descrizione deve avere una lunghezza di massimo {} caratteri".format( # noqa - DESCRIPTION_MAX_LEN + + # description validation + if not description: + errors.append( + new_error( + "La descrizione dell'unità organizzativa è obbligatorio" ) ) - ) - - for field in MANDATORY_RICH_TEXT_FIELDS: - if field not in data: - errors.append(new_error("Il campo {} è obbligatorio".format(field))) - elif field in data and not text_in_block(data.get(field)): - errors.append(new_error("Il campo {} è obbligatorio".format(field))) - - if is_patch: - # Title validation - if "title" in data and not title: - errors.append(new_error("Il titolo del servizio è obbligatorio")) - - if title and len(title) > TITLE_MAX_LEN: - errors.append( - new_error( - "Il titolo può avere una lunghezza di massimo {} caratteri".format( # noqa - TITLE_MAX_LEN + elif len(description) > DESCRIPTION_MAX_LEN: + errors.append( + new_error( + "La descrizione deve avere una lunghezza di massimo {} caratteri".format( # noqa + DESCRIPTION_MAX_LEN + ) ) ) - ) - # description validation - if "description" in data and not description: - errors.append(new_error("La descrizione del servizio è obbligatorio")) - if description and len(description) > DESCRIPTION_MAX_LEN: - errors.append( - new_error( - "La descrizione del servizio deve avere una lunghezza di massimo {} caratteri".format( # noqa - DESCRIPTION_MAX_LEN + + for field in MANDATORY_RICH_TEXT_FIELDS: + if field not in data: + errors.append( + new_error("Il campo {} è obbligatorio".format(field)) + ) + elif field in data and not text_in_block(data.get(field)): + errors.append( + new_error("Il campo {} è obbligatorio".format(field)) + ) + + if is_patch: + # Title validation + if "title" in data and not title: + errors.append(new_error("Il titolo del servizio è obbligatorio")) + + if title and len(title) > TITLE_MAX_LEN: + errors.append( + new_error( + "Il titolo può avere una lunghezza di massimo {} caratteri".format( # noqa + TITLE_MAX_LEN + ) ) ) - ) - - if "description" not in data and not self.context.description: - errors.append(new_error("La descrizione del servizio è obbligatorio")) - - for field in MANDATORY_RICH_TEXT_FIELDS: - if field in data and not text_in_block(data.get(field)): - errors.append(new_error("Il campo {} è obbligatorio".format(field))) - - # Se siamo nella patch siamo in modifica. Se siamo in modifica e siamo - # su un sito che ha avuto upgrade alla versione pnrr può essere che - # dei campi obbligatori un tempo non lo fossero e quindi arriviamo - # fino a qui - if field not in data and not text_in_block( - getattr(self.context, field) - ): - errors.append(new_error("Il campo {} è obbligatorio".format(field))) + # description validation + if "description" in data and not description: + errors.append( + new_error("La descrizione del servizio è obbligatoria") + ) + if description and len(description) > DESCRIPTION_MAX_LEN: + errors.append( + new_error( + "La descrizione del servizio deve avere una lunghezza di massimo {} caratteri".format( # noqa + DESCRIPTION_MAX_LEN + ) + ) + ) + + if "description" not in data and not self.context.description: + errors.append( + new_error("La descrizione del servizio è obbligatoria") + ) + + for field in MANDATORY_RICH_TEXT_FIELDS: + if field in data and not text_in_block(data.get(field)): + errors.append( + new_error("Il campo {} è obbligatorio".format(field)) + ) + + # Se siamo nella patch siamo in modifica. Se siamo in modifica e siamo + # su un sito che ha avuto upgrade alla versione pnrr può essere che + # dei campi obbligatori un tempo non lo fossero e quindi arriviamo + # fino a qui + if field not in data and not text_in_block( + getattr(self.context, field) + ): + errors.append( + new_error("Il campo {} è obbligatorio".format(field)) + ) if errors: raise BadRequest(errors) From 003d269e347a5c111e11a8977379276ab469cc8c Mon Sep 17 00:00:00 2001 From: Andrea Cecchi Date: Mon, 3 Apr 2023 16:04:14 +0200 Subject: [PATCH 273/487] add tests --- .../contenttypes/tests/test_ct_documento.py | 36 +++++++++++++++++ .../plone/contenttypes/tests/test_ct_news.py | 32 +++++++++++++++ .../contenttypes/tests/test_ct_servizio.py | 39 +++++++++++++++++++ .../tests/test_ct_unita_organizzativa.py | 35 +++++++++++++++++ 4 files changed, 142 insertions(+) diff --git a/src/design/plone/contenttypes/tests/test_ct_documento.py b/src/design/plone/contenttypes/tests/test_ct_documento.py index 15fd5d82..a92ea367 100644 --- a/src/design/plone/contenttypes/tests/test_ct_documento.py +++ b/src/design/plone/contenttypes/tests/test_ct_documento.py @@ -139,3 +139,39 @@ def test_post_image_will_convert_into_modulo(self): transaction.commit() self.assertEqual(self.documento["my-image"].portal_type, "Modulo") + + def test_cant_patch_document_that_has_no_required_fields(self): + + new_documento = api.content.create( + container=self.portal, type="Documento", title="Foo" + ) + transaction.commit() + resp = self.api_session.patch( + new_documento.absolute_url(), + json={ + "title": "Foo modified", + }, + ) + self.assertEqual(resp.status_code, 400) + self.assertIn( + "La descrizione del servizio è obbligatoria", resp.json()["message"] + ) + + def test_can_sort_document_that_has_no_required_fields(self): + new_documento = api.content.create( + container=self.portal, type="Documento", title="Foo" + ) + transaction.commit() + + self.assertEqual(self.documento, self.portal.listFolderContents()[0]) + self.assertEqual(new_documento, self.portal.listFolderContents()[1]) + + resp = self.api_session.patch( + self.portal_url, + json={"ordering": {"delta": -1, "obj_id": new_documento.getId()}}, + ) + transaction.commit() + + self.assertEqual(resp.status_code, 204) + self.assertEqual(self.documento, self.portal.listFolderContents()[1]) + self.assertEqual(new_documento, self.portal.listFolderContents()[0]) diff --git a/src/design/plone/contenttypes/tests/test_ct_news.py b/src/design/plone/contenttypes/tests/test_ct_news.py index 3a7b79c5..d633137b 100644 --- a/src/design/plone/contenttypes/tests/test_ct_news.py +++ b/src/design/plone/contenttypes/tests/test_ct_news.py @@ -185,3 +185,35 @@ def test_newsitem_substructure_created(self): # self.assertEqual( # news["documenti-allegati"].locally_allowed_types, ("File", "Image") # ) + + def test_cant_patch_news_that_has_no_required_fields(self): + + news = api.content.create(container=self.portal, type="News Item", title="Foo") + transaction.commit() + resp = self.api_session.patch( + news.absolute_url(), + json={ + "title": "Foo modified", + }, + ) + self.assertEqual(resp.status_code, 400) + self.assertIn( + "La descrizione del servizio è obbligatoria", resp.json()["message"] + ) + + def test_can_sort_news_that_has_no_required_fields(self): + news = api.content.create(container=self.portal, type="News Item", title="News") + transaction.commit() + + self.assertEqual(self.document, self.portal.listFolderContents()[0]) + self.assertEqual(news, self.portal.listFolderContents()[1]) + + resp = self.api_session.patch( + self.portal_url, + json={"ordering": {"delta": -1, "obj_id": news.getId()}}, + ) + transaction.commit() + + self.assertEqual(resp.status_code, 204) + self.assertEqual(self.document, self.portal.listFolderContents()[1]) + self.assertEqual(news, self.portal.listFolderContents()[0]) diff --git a/src/design/plone/contenttypes/tests/test_ct_servizio.py b/src/design/plone/contenttypes/tests/test_ct_servizio.py index 3ae3b668..005c0f4a 100644 --- a/src/design/plone/contenttypes/tests/test_ct_servizio.py +++ b/src/design/plone/contenttypes/tests/test_ct_servizio.py @@ -280,3 +280,42 @@ def test_canale_digitale_link_deserialized_as_plone_internal_url(self): servizio.canale_digitale_link, "${{portal_url}}/resolveuid/{}".format(page.UID()), ) + + def test_cant_patch_servizio_that_has_no_required_fields(self): + + service = api.content.create( + container=self.portal, type="Servizio", title="Foo" + ) + commit() + resp = self.api_session.patch( + service.absolute_url(), + json={ + "title": "Foo modified", + }, + ) + self.assertEqual(resp.status_code, 400) + self.assertIn( + "La descrizione del servizio è obbligatoria", resp.json()["message"] + ) + + def test_can_sort_service_that_has_no_required_fields(self): + document = api.content.create( + container=self.portal, type="Document", title="Document" + ) + service = api.content.create( + container=self.portal, type="Servizio", title="Foo" + ) + commit() + + self.assertEqual(document, self.portal.listFolderContents()[0]) + self.assertEqual(service, self.portal.listFolderContents()[1]) + + resp = self.api_session.patch( + self.portal_url, + json={"ordering": {"delta": -1, "obj_id": service.getId()}}, + ) + commit() + + self.assertEqual(resp.status_code, 204) + self.assertEqual(document, self.portal.listFolderContents()[1]) + self.assertEqual(service, self.portal.listFolderContents()[0]) diff --git a/src/design/plone/contenttypes/tests/test_ct_unita_organizzativa.py b/src/design/plone/contenttypes/tests/test_ct_unita_organizzativa.py index 79773194..266778ae 100644 --- a/src/design/plone/contenttypes/tests/test_ct_unita_organizzativa.py +++ b/src/design/plone/contenttypes/tests/test_ct_unita_organizzativa.py @@ -260,3 +260,38 @@ def test_backref_to_servizio_dove_rivolgersi(self): self.service.absolute_url(), [i["@id"] for i in response.json()["prestazioni"]], ) + + def test_cant_patch_uo_that_has_no_required_fields(self): + + uo = api.content.create( + container=self.portal, type="UnitaOrganizzativa", title="Foo" + ) + commit() + resp = self.api_session.patch( + uo.absolute_url(), + json={ + "title": "Foo modified", + }, + ) + self.assertEqual(resp.status_code, 400) + self.assertIn( + "La descrizione del servizio è obbligatoria", resp.json()["message"] + ) + + def test_can_sort_uo_that_has_no_required_fields(self): + uo = api.content.create( + container=self.portal, type="UnitaOrganizzativa", title="Foo" + ) + commit() + self.assertEqual(self.bando, self.portal.listFolderContents()[-2]) + self.assertEqual(uo, self.portal.listFolderContents()[-1]) + + resp = self.api_session.patch( + self.portal_url, + json={"ordering": {"delta": -1, "obj_id": uo.getId()}}, + ) + commit() + + self.assertEqual(resp.status_code, 204) + self.assertEqual(self.bando, self.portal.listFolderContents()[-1]) + self.assertEqual(uo, self.portal.listFolderContents()[-2]) From d39b79cf7762fe2ee7b4e486d347bfa45b8b9616 Mon Sep 17 00:00:00 2001 From: Andrea Cecchi Date: Mon, 3 Apr 2023 16:06:03 +0200 Subject: [PATCH 274/487] fix labels --- .../restapi/deserializers/documento.py | 20 +++++++------------ .../restapi/deserializers/news.py | 20 +++++++------------ .../restapi/deserializers/servizio.py | 20 +++++++------------ .../deserializers/unitaorganizzativa.py | 12 ++++------- .../contenttypes/tests/test_ct_documento.py | 4 +--- .../plone/contenttypes/tests/test_ct_news.py | 4 +--- .../contenttypes/tests/test_ct_servizio.py | 4 +--- .../tests/test_ct_unita_organizzativa.py | 4 +--- 8 files changed, 29 insertions(+), 59 deletions(-) diff --git a/src/design/plone/contenttypes/restapi/deserializers/documento.py b/src/design/plone/contenttypes/restapi/deserializers/documento.py index ab5505c9..df68efd2 100644 --- a/src/design/plone/contenttypes/restapi/deserializers/documento.py +++ b/src/design/plone/contenttypes/restapi/deserializers/documento.py @@ -68,7 +68,7 @@ def __call__( if is_post: # Title validation if not title: - errors.append(new_error("Il titolo del servizio è obbligatorio")) + errors.append(new_error("Il titolo è obbligatorio")) elif len(title) > TITLE_MAX_LEN: errors.append( new_error( @@ -80,13 +80,11 @@ def __call__( # description validation if not description: - errors.append( - new_error("La descrizione del servizio è obbligatoria") - ) + errors.append(new_error("La descrizione è obbligatoria")) elif len(description) > DESCRIPTION_MAX_LEN: errors.append( new_error( - "La descrizione del servizio deve avere una lunghezza di massimo {} caratteri".format( # noqa + "La descrizione deve avere una lunghezza di massimo {} caratteri".format( # noqa DESCRIPTION_MAX_LEN ) ) @@ -105,7 +103,7 @@ def __call__( if is_patch: # Title validation if "title" in data and not title: - errors.append(new_error("Il titolo del servizio è obbligatorio")) + errors.append(new_error("Il titolo è obbligatorio")) if title and len(title) > TITLE_MAX_LEN: errors.append( new_error( @@ -116,21 +114,17 @@ def __call__( ) # description validation if "description" in data and not description: - errors.append( - new_error("La descrizione del servizio è obbligatoria") - ) + errors.append(new_error("La descrizione è obbligatoria")) if description and len(description) > DESCRIPTION_MAX_LEN: errors.append( new_error( - "La descrizione del servizio deve avere una lunghezza di massimo {} caratteri".format( # noqa + "La descrizione deve avere una lunghezza di massimo {} caratteri".format( # noqa DESCRIPTION_MAX_LEN ) ) ) if "description" not in data and not self.context.description: - errors.append( - new_error("La descrizione del servizio è obbligatoria") - ) + errors.append(new_error("La descrizione è obbligatoria")) for field in MANDATORY_RICH_TEXT_FIELDS: if field in data and not text_in_block(data.get(field)): diff --git a/src/design/plone/contenttypes/restapi/deserializers/news.py b/src/design/plone/contenttypes/restapi/deserializers/news.py index 5ead25ba..51072a4a 100644 --- a/src/design/plone/contenttypes/restapi/deserializers/news.py +++ b/src/design/plone/contenttypes/restapi/deserializers/news.py @@ -68,7 +68,7 @@ def __call__( if is_post: # Title validation if not title: - errors.append(new_error("Il titolo del servizio è obbligatorio")) + errors.append(new_error("Il titolo è obbligatorio")) elif len(title) > TITLE_MAX_LEN: errors.append( new_error( @@ -80,13 +80,11 @@ def __call__( # description validation if not description: - errors.append( - new_error("La descrizione del servizio è obbligatoria") - ) + errors.append(new_error("La descrizione è obbligatoria")) elif len(description) > DESCRIPTION_MAX_LEN: errors.append( new_error( - "La descrizione del servizio deve avere una lunghezza di massimo {} caratteri".format( # noqa + "La descrizione deve avere una lunghezza di massimo {} caratteri".format( # noqa DESCRIPTION_MAX_LEN ) ) @@ -105,7 +103,7 @@ def __call__( if is_patch: # Title validation if "title" in data and not title: - errors.append(new_error("Il titolo del servizio è obbligatorio")) + errors.append(new_error("Il titolo è obbligatorio")) if title and len(title) > TITLE_MAX_LEN: errors.append( new_error( @@ -116,21 +114,17 @@ def __call__( ) # description validation if "description" in data and not description: - errors.append( - new_error("La descrizione del servizio è obbligatoria") - ) + errors.append(new_error("La descrizione è obbligatoria")) if description and len(description) > DESCRIPTION_MAX_LEN: errors.append( new_error( - "La descrizione del servizio deve avere una lunghezza di massimo {} caratteri".format( # noqa + "La descrizione deve avere una lunghezza di massimo {} caratteri".format( # noqa DESCRIPTION_MAX_LEN ) ) ) if "description" not in data and not self.context.description: - errors.append( - new_error("La descrizione del servizio è obbligatoria") - ) + errors.append(new_error("La descrizione è obbligatoria")) for field in MANDATORY_RICH_TEXT_FIELDS: if field in data and not text_in_block(data.get(field)): diff --git a/src/design/plone/contenttypes/restapi/deserializers/servizio.py b/src/design/plone/contenttypes/restapi/deserializers/servizio.py index bdbad7bf..0d62ef46 100644 --- a/src/design/plone/contenttypes/restapi/deserializers/servizio.py +++ b/src/design/plone/contenttypes/restapi/deserializers/servizio.py @@ -72,7 +72,7 @@ def __call__( if is_post: # Title validation if not title: - errors.append(new_error("Il titolo del servizio è obbligatorio")) + errors.append(new_error("Il titolo è obbligatorio")) elif len(title) > TITLE_MAX_LEN: errors.append( new_error( @@ -84,13 +84,11 @@ def __call__( # description validation if not description: - errors.append( - new_error("La descrizione del servizio è obbligatoria") - ) + errors.append(new_error("La descrizione è obbligatoria")) elif len(description) > DESCRIPTION_MAX_LEN: errors.append( new_error( - "La descrizione del servizio deve avere una lunghezza di massimo {} caratteri".format( # noqa + "La descrizione deve avere una lunghezza di massimo {} caratteri".format( # noqa DESCRIPTION_MAX_LEN ) ) @@ -109,7 +107,7 @@ def __call__( if is_patch: # Title validation if "title" in data and not title: - errors.append(new_error("Il titolo del servizio è obbligatorio")) + errors.append(new_error("Il titolo è obbligatorio")) if title and len(title) > TITLE_MAX_LEN: errors.append( new_error( @@ -120,21 +118,17 @@ def __call__( ) # description validation if "description" in data and not description: - errors.append( - new_error("La descrizione del servizio è obbligatoria") - ) + errors.append(new_error("La descrizione è obbligatoria")) if description and len(description) > DESCRIPTION_MAX_LEN: errors.append( new_error( - "La descrizione del servizio deve avere una lunghezza di massimo {} caratteri".format( # noqa + "La descrizione deve avere una lunghezza di massimo {} caratteri".format( # noqa DESCRIPTION_MAX_LEN ) ) ) if "description" not in data and not self.context.description: - errors.append( - new_error("La descrizione del servizio è obbligatoria") - ) + errors.append(new_error("La descrizione è obbligatoria")) for field in MANDATORY_RICH_TEXT_FIELDS: if field in data and not text_in_block(data.get(field)): diff --git a/src/design/plone/contenttypes/restapi/deserializers/unitaorganizzativa.py b/src/design/plone/contenttypes/restapi/deserializers/unitaorganizzativa.py index bd04abd8..c1d3d565 100644 --- a/src/design/plone/contenttypes/restapi/deserializers/unitaorganizzativa.py +++ b/src/design/plone/contenttypes/restapi/deserializers/unitaorganizzativa.py @@ -107,7 +107,7 @@ def __call__( if is_patch: # Title validation if "title" in data and not title: - errors.append(new_error("Il titolo del servizio è obbligatorio")) + errors.append(new_error("Il titolo è obbligatorio")) if title and len(title) > TITLE_MAX_LEN: errors.append( @@ -119,22 +119,18 @@ def __call__( ) # description validation if "description" in data and not description: - errors.append( - new_error("La descrizione del servizio è obbligatoria") - ) + errors.append(new_error("La descrizione è obbligatoria")) if description and len(description) > DESCRIPTION_MAX_LEN: errors.append( new_error( - "La descrizione del servizio deve avere una lunghezza di massimo {} caratteri".format( # noqa + "La descrizione deve avere una lunghezza di massimo {} caratteri".format( # noqa DESCRIPTION_MAX_LEN ) ) ) if "description" not in data and not self.context.description: - errors.append( - new_error("La descrizione del servizio è obbligatoria") - ) + errors.append(new_error("La descrizione è obbligatoria")) for field in MANDATORY_RICH_TEXT_FIELDS: if field in data and not text_in_block(data.get(field)): diff --git a/src/design/plone/contenttypes/tests/test_ct_documento.py b/src/design/plone/contenttypes/tests/test_ct_documento.py index a92ea367..ccc72a87 100644 --- a/src/design/plone/contenttypes/tests/test_ct_documento.py +++ b/src/design/plone/contenttypes/tests/test_ct_documento.py @@ -153,9 +153,7 @@ def test_cant_patch_document_that_has_no_required_fields(self): }, ) self.assertEqual(resp.status_code, 400) - self.assertIn( - "La descrizione del servizio è obbligatoria", resp.json()["message"] - ) + self.assertIn("La descrizione è obbligatoria", resp.json()["message"]) def test_can_sort_document_that_has_no_required_fields(self): new_documento = api.content.create( diff --git a/src/design/plone/contenttypes/tests/test_ct_news.py b/src/design/plone/contenttypes/tests/test_ct_news.py index d633137b..942c93c6 100644 --- a/src/design/plone/contenttypes/tests/test_ct_news.py +++ b/src/design/plone/contenttypes/tests/test_ct_news.py @@ -197,9 +197,7 @@ def test_cant_patch_news_that_has_no_required_fields(self): }, ) self.assertEqual(resp.status_code, 400) - self.assertIn( - "La descrizione del servizio è obbligatoria", resp.json()["message"] - ) + self.assertIn("La descrizione è obbligatoria", resp.json()["message"]) def test_can_sort_news_that_has_no_required_fields(self): news = api.content.create(container=self.portal, type="News Item", title="News") diff --git a/src/design/plone/contenttypes/tests/test_ct_servizio.py b/src/design/plone/contenttypes/tests/test_ct_servizio.py index 005c0f4a..0a3eb58b 100644 --- a/src/design/plone/contenttypes/tests/test_ct_servizio.py +++ b/src/design/plone/contenttypes/tests/test_ct_servizio.py @@ -294,9 +294,7 @@ def test_cant_patch_servizio_that_has_no_required_fields(self): }, ) self.assertEqual(resp.status_code, 400) - self.assertIn( - "La descrizione del servizio è obbligatoria", resp.json()["message"] - ) + self.assertIn("La descrizione è obbligatoria", resp.json()["message"]) def test_can_sort_service_that_has_no_required_fields(self): document = api.content.create( diff --git a/src/design/plone/contenttypes/tests/test_ct_unita_organizzativa.py b/src/design/plone/contenttypes/tests/test_ct_unita_organizzativa.py index 266778ae..1caf2e78 100644 --- a/src/design/plone/contenttypes/tests/test_ct_unita_organizzativa.py +++ b/src/design/plone/contenttypes/tests/test_ct_unita_organizzativa.py @@ -274,9 +274,7 @@ def test_cant_patch_uo_that_has_no_required_fields(self): }, ) self.assertEqual(resp.status_code, 400) - self.assertIn( - "La descrizione del servizio è obbligatoria", resp.json()["message"] - ) + self.assertIn("La descrizione è obbligatoria", resp.json()["message"]) def test_can_sort_uo_that_has_no_required_fields(self): uo = api.content.create( From d8d440c82bafd87ee33934f1873978346f401392 Mon Sep 17 00:00:00 2001 From: Andrea Cecchi Date: Mon, 3 Apr 2023 16:07:30 +0200 Subject: [PATCH 275/487] blacked --- src/design/plone/contenttypes/tests/test_ct_documento.py | 1 - src/design/plone/contenttypes/tests/test_ct_news.py | 1 - src/design/plone/contenttypes/tests/test_ct_servizio.py | 1 - .../plone/contenttypes/tests/test_ct_unita_organizzativa.py | 1 - 4 files changed, 4 deletions(-) diff --git a/src/design/plone/contenttypes/tests/test_ct_documento.py b/src/design/plone/contenttypes/tests/test_ct_documento.py index ccc72a87..996b4400 100644 --- a/src/design/plone/contenttypes/tests/test_ct_documento.py +++ b/src/design/plone/contenttypes/tests/test_ct_documento.py @@ -141,7 +141,6 @@ def test_post_image_will_convert_into_modulo(self): self.assertEqual(self.documento["my-image"].portal_type, "Modulo") def test_cant_patch_document_that_has_no_required_fields(self): - new_documento = api.content.create( container=self.portal, type="Documento", title="Foo" ) diff --git a/src/design/plone/contenttypes/tests/test_ct_news.py b/src/design/plone/contenttypes/tests/test_ct_news.py index 942c93c6..3c473028 100644 --- a/src/design/plone/contenttypes/tests/test_ct_news.py +++ b/src/design/plone/contenttypes/tests/test_ct_news.py @@ -187,7 +187,6 @@ def test_newsitem_substructure_created(self): # ) def test_cant_patch_news_that_has_no_required_fields(self): - news = api.content.create(container=self.portal, type="News Item", title="Foo") transaction.commit() resp = self.api_session.patch( diff --git a/src/design/plone/contenttypes/tests/test_ct_servizio.py b/src/design/plone/contenttypes/tests/test_ct_servizio.py index 0a3eb58b..31329b28 100644 --- a/src/design/plone/contenttypes/tests/test_ct_servizio.py +++ b/src/design/plone/contenttypes/tests/test_ct_servizio.py @@ -282,7 +282,6 @@ def test_canale_digitale_link_deserialized_as_plone_internal_url(self): ) def test_cant_patch_servizio_that_has_no_required_fields(self): - service = api.content.create( container=self.portal, type="Servizio", title="Foo" ) diff --git a/src/design/plone/contenttypes/tests/test_ct_unita_organizzativa.py b/src/design/plone/contenttypes/tests/test_ct_unita_organizzativa.py index 1caf2e78..ab1292e6 100644 --- a/src/design/plone/contenttypes/tests/test_ct_unita_organizzativa.py +++ b/src/design/plone/contenttypes/tests/test_ct_unita_organizzativa.py @@ -262,7 +262,6 @@ def test_backref_to_servizio_dove_rivolgersi(self): ) def test_cant_patch_uo_that_has_no_required_fields(self): - uo = api.content.create( container=self.portal, type="UnitaOrganizzativa", title="Foo" ) From 17504000c2426290469e56bcba825e4e7913b0b3 Mon Sep 17 00:00:00 2001 From: Andrea Cecchi Date: Tue, 4 Apr 2023 08:55:53 +0200 Subject: [PATCH 276/487] force redturtle.volto version --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 3478eb72..2dad5d04 100644 --- a/setup.py +++ b/setup.py @@ -60,7 +60,7 @@ "collective.volto.blocksfield", "collective.z3cform.datagridfield", "plone.formwidget.geolocation", - "redturtle.volto", + "redturtle.volto>=5.0.0", "redturtle.bandi", "z3c.unconfigure", "eea.api.taxonomy", From 1aaa32045955abd007ab2a99593add418d14dd74 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Wed, 5 Apr 2023 12:41:58 +0200 Subject: [PATCH 277/487] add atto di nomina link to incarico summary --- CHANGES.rst | 2 ++ .../restapi/serializers/summary.py | 10 +++++--- .../contenttypes/tests/test_ct_persona.py | 23 +++++++++++++++++++ 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 46b0ef75..38f13535 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -14,6 +14,8 @@ Changelog - Fix patch/post validations for required fields: do not return errors when sorting items. [cekk] +- Add "Atto di nomina" link in incarico summary serializer + [lucabel] 6.0.0 (2023-03-23) ------------------ diff --git a/src/design/plone/contenttypes/restapi/serializers/summary.py b/src/design/plone/contenttypes/restapi/serializers/summary.py index e55b0e96..cb86b283 100644 --- a/src/design/plone/contenttypes/restapi/serializers/summary.py +++ b/src/design/plone/contenttypes/restapi/serializers/summary.py @@ -15,9 +15,7 @@ from plone.restapi.interfaces import ISerializeToJsonSummary from plone.restapi.serializer.converters import json_compatible from Products.ZCatalog.interfaces import ICatalogBrain -from redturtle.volto.restapi.serializer.summary import ( - DefaultJSONSummarySerializer as BaseSerializer, -) +from redturtle.volto.restapi.serializer.summary import DefaultJSONSummarySerializer as BaseSerializer from zope.component import adapter from zope.component import getMultiAdapter from zope.component import getUtility @@ -240,6 +238,12 @@ def __call__(self, force_all_metadata=False): res["compensi"] = json_compatible(self.context.compensi) else: res["compensi"] = json_compatible([]) + if "atto_di_nomina" not in res: + res["atto_di_nomina"] = None + atto = getattr(self.context, "atto_nomina", None) + if atto and not atto[0].isBroken(): + atto = atto[0].to_object + res["atto_di_nomina"] = atto.absolute_url() return res diff --git a/src/design/plone/contenttypes/tests/test_ct_persona.py b/src/design/plone/contenttypes/tests/test_ct_persona.py index 540374ef..ec2473a6 100644 --- a/src/design/plone/contenttypes/tests/test_ct_persona.py +++ b/src/design/plone/contenttypes/tests/test_ct_persona.py @@ -126,3 +126,26 @@ def test_persona_assessore_di(self): self.assertIn("assessore_di", list(res.keys())) self.assertEqual(len(res["assessore_di"]), 1) self.assertEqual(res["assessore_di"][0]["title"], uo.title) + + def test_atto_di_nomina_incarico(self): + incarico = api.content.create( + container=self.persona.incarichi, + type="Incarico", + title="Sindaco" + ) + commit() + atto_nomina = api.content.create( + container=incarico, + type="Documento", + title="Atto di nomina" + ) + commit() + intids = getUtility(IIntIds) + self.persona.incarichi_persona = [RelationValue(intids.getId(incarico))] + incarico.atto_nomina = [RelationValue(intids.getId(atto_nomina))] + commit() + response = self.api_session.get(self.persona.absolute_url()) + res = response.json() + self.assertEqual(len(res['incarichi_persona']), 1) + self.assertEqual(res["incarichi_persona"][0]["title"], incarico.title) + self.assertIn("atto_di_nomina", list(res["incarichi_persona"][0].keys())) From 9a5ad751711fb5b45f16d189e986f8588d5ef364 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Wed, 5 Apr 2023 12:50:30 +0200 Subject: [PATCH 278/487] black --- src/design/plone/contenttypes/tests/test_ct_persona.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/design/plone/contenttypes/tests/test_ct_persona.py b/src/design/plone/contenttypes/tests/test_ct_persona.py index ec2473a6..f1083a0e 100644 --- a/src/design/plone/contenttypes/tests/test_ct_persona.py +++ b/src/design/plone/contenttypes/tests/test_ct_persona.py @@ -129,15 +129,11 @@ def test_persona_assessore_di(self): def test_atto_di_nomina_incarico(self): incarico = api.content.create( - container=self.persona.incarichi, - type="Incarico", - title="Sindaco" + container=self.persona.incarichi, type="Incarico", title="Sindaco" ) commit() atto_nomina = api.content.create( - container=incarico, - type="Documento", - title="Atto di nomina" + container=incarico, type="Documento", title="Atto di nomina" ) commit() intids = getUtility(IIntIds) @@ -146,6 +142,6 @@ def test_atto_di_nomina_incarico(self): commit() response = self.api_session.get(self.persona.absolute_url()) res = response.json() - self.assertEqual(len(res['incarichi_persona']), 1) + self.assertEqual(len(res["incarichi_persona"]), 1) self.assertEqual(res["incarichi_persona"][0]["title"], incarico.title) self.assertIn("atto_di_nomina", list(res["incarichi_persona"][0].keys())) From fd2db72e29cc78be5bc186881c237a247d267ae3 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Wed, 5 Apr 2023 12:52:15 +0200 Subject: [PATCH 279/487] black on restapi/serializers/summary.py --- src/design/plone/contenttypes/restapi/serializers/summary.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/design/plone/contenttypes/restapi/serializers/summary.py b/src/design/plone/contenttypes/restapi/serializers/summary.py index cb86b283..df58040c 100644 --- a/src/design/plone/contenttypes/restapi/serializers/summary.py +++ b/src/design/plone/contenttypes/restapi/serializers/summary.py @@ -15,7 +15,9 @@ from plone.restapi.interfaces import ISerializeToJsonSummary from plone.restapi.serializer.converters import json_compatible from Products.ZCatalog.interfaces import ICatalogBrain -from redturtle.volto.restapi.serializer.summary import DefaultJSONSummarySerializer as BaseSerializer +from redturtle.volto.restapi.serializer.summary import ( + DefaultJSONSummarySerializer as BaseSerializer, +) from zope.component import adapter from zope.component import getMultiAdapter from zope.component import getUtility From c2f4b0aafd63e2c23aed2d8f59f98c8c223d4ab1 Mon Sep 17 00:00:00 2001 From: Roman <72063601+foxtrot-dfm1@users.noreply.github.com> Date: Thu, 6 Apr 2023 12:12:36 +0200 Subject: [PATCH 280/487] Handle None case return (#173) --- .../plone/contenttypes/restapi/serializers/relationfield.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/design/plone/contenttypes/restapi/serializers/relationfield.py b/src/design/plone/contenttypes/restapi/serializers/relationfield.py index bb4a9e9c..239169f6 100644 --- a/src/design/plone/contenttypes/restapi/serializers/relationfield.py +++ b/src/design/plone/contenttypes/restapi/serializers/relationfield.py @@ -20,7 +20,7 @@ class RelationListFieldSerializer(DefaultRelationListFieldSerializer): def __call__(self): data = [] - for value in self.get_value(): + for value in self.get_value() or (): if not value: continue try: From 1b6e929a05cdfcaa6434ea44ce569ae8373f4e54 Mon Sep 17 00:00:00 2001 From: Roman <72063601+foxtrot-dfm1@users.noreply.github.com> Date: Thu, 6 Apr 2023 12:13:20 +0200 Subject: [PATCH 281/487] Update testing.py (#174) --- src/design/plone/contenttypes/testing.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/design/plone/contenttypes/testing.py b/src/design/plone/contenttypes/testing.py index 90d5fb8d..8b00b9f1 100644 --- a/src/design/plone/contenttypes/testing.py +++ b/src/design/plone/contenttypes/testing.py @@ -21,7 +21,6 @@ import kitconcept.seo import plone.app.caching import plone.formwidget.geolocation -import plone.restapi import redturtle.bandi import redturtle.prenotazioni import redturtle.volto From 4603b661111725d490306a317929dfc5a488afa1 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 6 Apr 2023 14:50:04 +0200 Subject: [PATCH 282/487] Update changelog --- CHANGES.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGES.rst b/CHANGES.rst index 38f13535..639ecaa9 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -5,6 +5,8 @@ Changelog 6.0.1 (unreleased) ------------------ +- Fix None type itereation attempt in relation field adapter + [foxtrot-dfm1] - Add serializer/deserializer for canale_digitale_link to handle internal/external links like remoteURL field. [cekk] - Force canale_digitale_link return `url` widget in Servizio schema. From bd52986d94aeb26841a455889b8a0a64d0d99883 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 6 Apr 2023 14:56:05 +0200 Subject: [PATCH 283/487] Preparing release 6.0.1 --- CHANGES.rst | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 639ecaa9..e40e77df 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -2,7 +2,7 @@ Changelog ========= -6.0.1 (unreleased) +6.0.1 (2023-04-06) ------------------ - Fix None type itereation attempt in relation field adapter diff --git a/setup.py b/setup.py index 2dad5d04..435d139c 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.0.1.dev0", + version="6.0.1", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 68d3facc5c16e8fe765dc1c705dbad0751135d13 Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 6 Apr 2023 14:56:28 +0200 Subject: [PATCH 284/487] Back to development: 6.0.2 --- CHANGES.rst | 6 ++++++ setup.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index e40e77df..45444575 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -2,6 +2,12 @@ Changelog ========= +6.0.2 (unreleased) +------------------ + +- Nothing changed yet. + + 6.0.1 (2023-04-06) ------------------ diff --git a/setup.py b/setup.py index 435d139c..cac5f131 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.0.1", + version="6.0.2.dev0", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From a353bd43510fb0c132f2cc4e3feb6001dd533ad0 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Fri, 7 Apr 2023 11:23:46 +0200 Subject: [PATCH 285/487] condizioni_di_servizio no more required --- CHANGES.rst | 3 ++- src/design/plone/contenttypes/interfaces/servizio.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 45444575..f2957574 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -5,7 +5,8 @@ Changelog 6.0.2 (unreleased) ------------------ -- Nothing changed yet. +- Fix condizioni_di_servizio field, no more required. + [eikichi18] 6.0.1 (2023-04-06) diff --git a/src/design/plone/contenttypes/interfaces/servizio.py b/src/design/plone/contenttypes/interfaces/servizio.py index 2cf12693..599de126 100644 --- a/src/design/plone/contenttypes/interfaces/servizio.py +++ b/src/design/plone/contenttypes/interfaces/servizio.py @@ -386,7 +386,7 @@ class IServizio(model.Schema, IDesignPloneContentType): condizioni_di_servizio = field.NamedBlobFile( title=_("condizioni_di_servizio", default="Condizioni di servizio"), - required=True, + required=False, ) servizi_collegati = RelationList( From 8e81d381c6ab3f7587c173a4f95e5b2f7777a621 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Tue, 11 Apr 2023 12:19:02 +0200 Subject: [PATCH 286/487] Preparing release 6.0.2 --- CHANGES.rst | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index f2957574..ffbe1dac 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -2,7 +2,7 @@ Changelog ========= -6.0.2 (unreleased) +6.0.2 (2023-04-11) ------------------ - Fix condizioni_di_servizio field, no more required. diff --git a/setup.py b/setup.py index cac5f131..7bb18a58 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.0.2.dev0", + version="6.0.2", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 321196f7861c095fbf5778c687c24cd7d8e8ea5a Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Tue, 11 Apr 2023 12:19:17 +0200 Subject: [PATCH 287/487] Back to development: 6.0.3 --- CHANGES.rst | 6 ++++++ setup.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index ffbe1dac..cbd88460 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -2,6 +2,12 @@ Changelog ========= +6.0.3 (unreleased) +------------------ + +- Nothing changed yet. + + 6.0.2 (2023-04-11) ------------------ diff --git a/setup.py b/setup.py index 7bb18a58..5d82e474 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.0.2", + version="6.0.3.dev0", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 9429e5022a6a7f691e9006e1b1cee9799275352d Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Thu, 13 Apr 2023 11:03:45 +0200 Subject: [PATCH 288/487] start changing check_servizi --- .../browser/manage_content/check_servizi.py | 26 ++++++++-------- .../manage_content/templates/check_servizi.pt | 30 ++++++++++--------- 2 files changed, 30 insertions(+), 26 deletions(-) diff --git a/src/design/plone/contenttypes/browser/manage_content/check_servizi.py b/src/design/plone/contenttypes/browser/manage_content/check_servizi.py index fd8f85cb..8cdeac2f 100644 --- a/src/design/plone/contenttypes/browser/manage_content/check_servizi.py +++ b/src/design/plone/contenttypes/browser/manage_content/check_servizi.py @@ -6,6 +6,8 @@ from zope.interface import implementer +FLAG = '' + FIELDS = [ "title", "description", @@ -74,55 +76,55 @@ def get_servizi(self): "title": servizio.title, "url": servizio.absolute_url().replace("/api/", "/"), "data": { - "title": getattr(servizio, "title") and "X" or "", + "title": getattr(servizio, "title") and FLAG or "", "description": getattr(servizio, "description", None) - and "X" + and FLAG or "", "condizioni_di_servizio": getattr( servizio, "condizioni_di_servizio", None ) - and "X" + and FLAG or "", "tassonomia_argomenti": getattr( servizio, "tassonomia_argomenti", None ) - and "X" + and FLAG or "", "a_chi_si_rivolge": text_in_block( getattr(servizio, "a_chi_si_rivolge", None) ) - and "X" + and FLAG or "", "come_si_fa": text_in_block( getattr(servizio, "come_si_fa", None) ) - and "X" + and FLAG or "", "cosa_si_ottiene": text_in_block( getattr(servizio, "cosa_si_ottiene", None) ) - and "X" + and FLAG or "", "canale_fisico": getattr(servizio, "canale_fisico", None) - and "X" + and FLAG or "", "cosa_serve": text_in_block( getattr(servizio, "cosa_serve", None) ) - and "X" + and FLAG or "", "tempi_e_scadenze": text_in_block( getattr(servizio, "tempi_e_scadenze", None) ) - and "X" + and FLAG or "", "ufficio_responsabile": getattr( servizio, "ufficio_responsabile", None ) - and "X" + and FLAG or "", "contact_info": getattr(servizio, "contact_info", None) - and "X" + and FLAG or "", }, } diff --git a/src/design/plone/contenttypes/browser/manage_content/templates/check_servizi.pt b/src/design/plone/contenttypes/browser/manage_content/templates/check_servizi.pt index 28292e77..607f900f 100644 --- a/src/design/plone/contenttypes/browser/manage_content/templates/check_servizi.pt +++ b/src/design/plone/contenttypes/browser/manage_content/templates/check_servizi.pt @@ -13,6 +13,7 @@ + @@ -88,8 +92,7 @@ - - + @@ -108,18 +111,17 @@ - - - - - - - - - - - - + + + + + + + + + + +
    TitoloTitolo Descrizione Condizioni di servizio Argomenti${servizio/title}
    From 8ae4dced073eb8a703874f6e14f01ebd330832b5 Mon Sep 17 00:00:00 2001 From: Andrea Cecchi Date: Mon, 17 Apr 2023 12:09:46 +0200 Subject: [PATCH 289/487] Remove redturtle.prenotazioni integration --- CHANGES.rst | 3 +- base.cfg | 4 -- setup.py | 4 -- .../plone/contenttypes/events/configure.zcml | 9 --- .../plone/contenttypes/events/servizio.py | 18 ------ .../profiles/default/types/Servizio.xml | 6 -- .../restapi/services/configure.zcml | 6 -- .../prenotazioni_folders_list/__init__.py | 0 .../prenotazioni_folders_list/configure.zcml | 19 ------ .../services/prenotazioni_folders_list/get.py | 27 -------- src/design/plone/contenttypes/testing.py | 8 --- .../test_service_prenotazioni_folders_list.py | 61 ------------------- .../plone/contenttypes/upgrades/upgrades.py | 23 ------- test_plone60.cfg | 12 ---- 14 files changed, 2 insertions(+), 198 deletions(-) delete mode 100644 src/design/plone/contenttypes/restapi/services/prenotazioni_folders_list/__init__.py delete mode 100644 src/design/plone/contenttypes/restapi/services/prenotazioni_folders_list/configure.zcml delete mode 100644 src/design/plone/contenttypes/restapi/services/prenotazioni_folders_list/get.py delete mode 100644 src/design/plone/contenttypes/tests/test_service_prenotazioni_folders_list.py diff --git a/CHANGES.rst b/CHANGES.rst index cbd88460..e5868aa3 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -5,7 +5,8 @@ Changelog 6.0.3 (unreleased) ------------------ -- Nothing changed yet. +- Remove redturtle.prenotazioni integration. + [cekk] 6.0.2 (2023-04-11) diff --git a/base.cfg b/base.cfg index ccc06c9e..ac8646cd 100644 --- a/base.cfg +++ b/base.cfg @@ -142,7 +142,3 @@ design.plone.contenttypes = #redturtle.volto = git https://github.com/RedTurtle/redturtle.volto.git pushurl=git@github.com:RedTurtle/redturtle.volto.git #redturtle.bandi = git https://github.com/RedTurtle/redturtle.bandi.git pushurl=git@github.com:RedTurtle/redturtle.bandi.git #plone.restapi = git https://github.com/plone/plone.restapi.git - -# use for integration development btw design.plone.contenttypes and redturtle.prenotazioni -redturtle.prenotazioni = git https://github.com/RedTurtle/redturtle.prenotazioni.git -# collective.contentrules.mailfromfield = git https://github.com/RedTurtle/collective.contentrules.mailfromfield.git diff --git a/setup.py b/setup.py index 5d82e474..8b10a740 100644 --- a/setup.py +++ b/setup.py @@ -76,10 +76,6 @@ "plone.app.contenttypes", "plone.app.robotframework[debug]", "collective.MockMailHost", - "redturtle.prenotazioni", - ], - "ioprenoto": [ - "redturtle.prenotazioni", ], }, entry_points=""" diff --git a/src/design/plone/contenttypes/events/configure.zcml b/src/design/plone/contenttypes/events/configure.zcml index e3efa3f6..b5b62c8c 100644 --- a/src/design/plone/contenttypes/events/configure.zcml +++ b/src/design/plone/contenttypes/events/configure.zcml @@ -77,13 +77,4 @@ handler=".common.onModify" /> - - - - - diff --git a/src/design/plone/contenttypes/events/servizio.py b/src/design/plone/contenttypes/events/servizio.py index 7f14a02d..eaa6d925 100644 --- a/src/design/plone/contenttypes/events/servizio.py +++ b/src/design/plone/contenttypes/events/servizio.py @@ -28,21 +28,3 @@ def servizioCreateHandler(servizio, event): childConstraints = ISelectableConstrainTypes(child) childConstraints.setConstrainTypesMode(1) childConstraints.setLocallyAllowedTypes(folder["contains"]) - - -# TODO: rivalutare se è necessario, o se i folder delle prenotazioni -# vanno creati manualmente al di fuori del servizio -def prenotazioni_folder_create(servizio, event): - """Create Prenotazioni folder inside of the created object, - but only if `redturtle.prenotazioni` is installed. - """ - if api.portal.get_tool("portal_types").get("PrenotazioniFolderContainer"): - if not api.portal.get_tool("portal_catalog")( - portal_type="PrenotazioniFolderContainer", - path="/".join(servizio.getPhysicalPath()), - ): - api.content.create( - type="PrenotazioniFolderContainer", - title=_("Cartella delle prenotazioni"), - container=servizio, - ) diff --git a/src/design/plone/contenttypes/profiles/default/types/Servizio.xml b/src/design/plone/contenttypes/profiles/default/types/Servizio.xml index 021eabde..6cffbeb4 100644 --- a/src/design/plone/contenttypes/profiles/default/types/Servizio.xml +++ b/src/design/plone/contenttypes/profiles/default/types/Servizio.xml @@ -22,12 +22,6 @@ - - design.plone.contenttypes.AddServizio diff --git a/src/design/plone/contenttypes/restapi/services/configure.zcml b/src/design/plone/contenttypes/restapi/services/configure.zcml index 853dda46..06d609df 100644 --- a/src/design/plone/contenttypes/restapi/services/configure.zcml +++ b/src/design/plone/contenttypes/restapi/services/configure.zcml @@ -10,12 +10,6 @@ - - - - - - - - - diff --git a/src/design/plone/contenttypes/restapi/services/prenotazioni_folders_list/get.py b/src/design/plone/contenttypes/restapi/services/prenotazioni_folders_list/get.py deleted file mode 100644 index 3dcb3821..00000000 --- a/src/design/plone/contenttypes/restapi/services/prenotazioni_folders_list/get.py +++ /dev/null @@ -1,27 +0,0 @@ -from plone import api -from plone.restapi.interfaces import ISerializeToJsonSummary -from plone.restapi.services import Service -from zope.component import getMultiAdapter - - -class PrenotazioniFoldersList(Service): - def reply(self): - """Lists the PrenotableFolders inside of Servizio - Returns: - list: List of PrenotableFolders serialized to JSON summary - """ - result = [] - - prenotazioni_folders = api.portal.get_tool("portal_catalog")( - portal_type="PrenotazioniFolder", - path="/".join(self.context.getPhysicalPath()), - ) - - for item in prenotazioni_folders: - result.append( - getMultiAdapter( - (item.getObject(), self.request), ISerializeToJsonSummary - )() - ) - - return result diff --git a/src/design/plone/contenttypes/testing.py b/src/design/plone/contenttypes/testing.py index 8b00b9f1..a8da2f47 100644 --- a/src/design/plone/contenttypes/testing.py +++ b/src/design/plone/contenttypes/testing.py @@ -22,7 +22,6 @@ import plone.app.caching import plone.formwidget.geolocation import redturtle.bandi -import redturtle.prenotazioni import redturtle.volto @@ -85,18 +84,11 @@ def setUpZope(self, app, configurationContext): self.loadZCML(package=redturtle.bandi) self.loadZCML(package=kitconcept.seo) - # TODO: valutare un layer a parte per i test di redturtle.prenotazioni - self.loadZCML(package=redturtle.prenotazioni) - self.loadZCML(package=collective.z3cform.datagridfield) - self.loadZCML(package=collective.contentrules.mailfromfield) - self.loadZCML(name="overrides.zcml", package=design.plone.contenttypes) def setUpPloneSite(self, portal): super().setUpPloneSite(portal) applyProfile(portal, "design.plone.contenttypes:default") - # TODO: valutare un layer a parte per i test di redturtle.prenotazioni - applyProfile(portal, "redturtle.prenotazioni:default") DESIGN_PLONE_CONTENTTYPES_API_FIXTURE = DesignPloneContenttypesRestApiLayer() diff --git a/src/design/plone/contenttypes/tests/test_service_prenotazioni_folders_list.py b/src/design/plone/contenttypes/tests/test_service_prenotazioni_folders_list.py deleted file mode 100644 index 83c8295c..00000000 --- a/src/design/plone/contenttypes/tests/test_service_prenotazioni_folders_list.py +++ /dev/null @@ -1,61 +0,0 @@ -# -*- coding: utf-8 -*- -# TODO: skip se redturtle.prenotazioni non è presente -from design.plone.contenttypes.testing import ( - DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING, -) -from plone import api -from plone.app.testing import setRoles -from plone.app.testing import SITE_OWNER_NAME -from plone.app.testing import SITE_OWNER_PASSWORD -from plone.app.testing import TEST_USER_ID -from plone.restapi.testing import RelativeSession - -import transaction -import unittest - - -class TestServicePrnotazioniFoldersList(unittest.TestCase): - layer = DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING - - def setUp(self): - self.app = self.layer["app"] - self.portal = self.layer["portal"] - self.portal_url = self.portal.absolute_url() - self.testing_view_name = "@prenotazioni_folders-list" - - self.api_session = RelativeSession(self.portal_url) - self.api_session.headers.update({"Accept": "application/json"}) - - self.api_session.auth = (SITE_OWNER_NAME, SITE_OWNER_PASSWORD) - - setRoles(self.portal, TEST_USER_ID, ["Manager"]) - - self.servizio = api.content.create( - type="Servizio", title="servizio", container=self.portal - ) - self.prenotazioni_folders_folder = api.content.create( - type="Folder", title="PrenotazioniFolders", container=self.servizio - ) - - transaction.commit() - - def test_no_prenotazioni_folders(self): - res = self.api_session.get( - self.servizio.absolute_url() + "/" + self.testing_view_name - ).json() - - self.assertFalse(res) - - def test_prenotazioni_folders(self): - prenotazione_folder = api.content.create( - type="PrenotazioniFolder", - title="prenotazioni_folder", - container=self.prenotazioni_folders_folder, - ) - transaction.commit() - - res = self.api_session.get( - self.servizio.absolute_url() + "/" + self.testing_view_name - ).json() - - self.assertIn(prenotazione_folder.absolute_url(), [item["@id"] for item in res]) diff --git a/src/design/plone/contenttypes/upgrades/upgrades.py b/src/design/plone/contenttypes/upgrades/upgrades.py index caf2715c..021d1867 100644 --- a/src/design/plone/contenttypes/upgrades/upgrades.py +++ b/src/design/plone/contenttypes/upgrades/upgrades.py @@ -1209,29 +1209,6 @@ class colors(object): YELLOW = "\033[93m" -# XXX: le prenotazioni non sono necessariamente all'interno del servizio -# def add_ioprenoto_folder(context): -# """Adds PrenotazioniFoldersContainer object to Servizio c.t. object""" -# catalog = api.portal.get_tool("portal_catalog") -# for servizio in catalog(portal_type="Servizio"): -# if not catalog( -# portal_type="PrenotazioniFolderContainer", path=servizio.getPath() -# ): -# container = servizio.getObject() -# if "PrenotazioniFolderContainer" in getattr( -# context, "allowedContentTypes", None -# ): -# api.content.create( -# type="PrenotazioniFolderContainer", -# title="Cartella delle prenotazioni", -# container=container, -# ) -# else: -# raise Exception( -# "Can not mirgate so as PrenotazioniFolderContainer is not allowed" -# ) - - def update_uo_contact_info(context): brains = api.portal.get_tool("portal_catalog")(portal_type="UnitaOrganizzativa") logger.info( diff --git a/test_plone60.cfg b/test_plone60.cfg index d81a5291..7207dc4a 100644 --- a/test_plone60.cfg +++ b/test_plone60.cfg @@ -42,10 +42,6 @@ zpretty = 2.4.1 # plone.recipe.codeanalysis==3.0.1 check-manifest = 0.49 -# Required by: -# redturtle.prenotazioni==1.6.2.dev0 -click = 8.1.3 - # Required by: # zest.releaser==6.22.2 colorama = 0.4.6 @@ -55,10 +51,6 @@ colorama = 0.4.6 # flake8-print==5.0.0 pycodestyle = 2.10.0 -# Required by: -# redturtle.prenotazioni==1.6.2.dev0 -pyinter = 0.2.0 - # Required by: # check-manifest==0.49 tomli = 2.0.1 @@ -68,7 +60,3 @@ tomli = 2.0.1 webencodings = 0.5.1 # Added by buildout at 2023-03-22 23:05:32.974075 - -# Required by: -# redturtle.prenotazioni==1.7.0.dev0 -collective.contentrules.mailfromfield = 1.1.0 From d289c967c3d23a8f5b79e488bc90b78a21d6c9eb Mon Sep 17 00:00:00 2001 From: Andrea Cecchi Date: Mon, 17 Apr 2023 12:22:39 +0200 Subject: [PATCH 290/487] fix import --- src/design/plone/contenttypes/events/servizio.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/design/plone/contenttypes/events/servizio.py b/src/design/plone/contenttypes/events/servizio.py index eaa6d925..1a37f81e 100644 --- a/src/design/plone/contenttypes/events/servizio.py +++ b/src/design/plone/contenttypes/events/servizio.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- -from design.plone.contenttypes import _ from design.plone.contenttypes.utils import create_default_blocks from plone import api from Products.CMFPlone.interfaces import ISelectableConstrainTypes From 18a7693003e47d12e889ec1764da7d56706ff3cd Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Mon, 17 Apr 2023 17:14:40 +0200 Subject: [PATCH 291/487] merge with stash --- .../browser/manage_content/check_servizi.py | 86 +++++++++++-------- .../manage_content/templates/check_servizi.pt | 38 +++++++- 2 files changed, 88 insertions(+), 36 deletions(-) diff --git a/src/design/plone/contenttypes/browser/manage_content/check_servizi.py b/src/design/plone/contenttypes/browser/manage_content/check_servizi.py index 8cdeac2f..3a982e5a 100644 --- a/src/design/plone/contenttypes/browser/manage_content/check_servizi.py +++ b/src/design/plone/contenttypes/browser/manage_content/check_servizi.py @@ -1,7 +1,6 @@ from plone import api from plone.restapi.behaviors import IBlocks from plone.restapi.indexers import SearchableText_blocks -from Products.CMFPlone.utils import safe_hasattr from Products.Five import BrowserView from zope.interface import implementer @@ -43,15 +42,38 @@ def __init__(self, blocks, blocks_layout): if not blocks: return None - fakeObj = FakeObject(blocks.get("blocks", ""), blocks.get("blocks_layout", "")) return SearchableText_blocks(fakeObj)() class CheckServizi(BrowserView): + cds = None + def is_anonymous(self): return api.user.is_anonymous() + def information_dict(self, servizio): + return { + "title": getattr(servizio, "title"), + "description": getattr(servizio, "description", None), + "condizioni_di_servizio": getattr(servizio, "condizioni_di_servizio", None), + "tassonomia_argomenti": getattr(servizio, "tassonomia_argomenti", None), + "a_chi_si_rivolge": text_in_block( + getattr(servizio, "a_chi_si_rivolge", None) + ), + "come_si_fa": text_in_block(getattr(servizio, "come_si_fa", None)), + "cosa_si_ottiene": text_in_block( + getattr(servizio, "cosa_si_ottiene", None) + ), + "canale_fisico": getattr(servizio, "canale_fisico", None), + "cosa_serve": text_in_block(getattr(servizio, "cosa_serve", None)), + "tempi_e_scadenze": text_in_block( + getattr(servizio, "tempi_e_scadenze", None) + ), + "ufficio_responsabile": getattr(servizio, "ufficio_responsabile", None), + "contact_info": getattr(servizio, "contact_info", None), + } + def get_servizi(self): if self.is_anonymous(): return [] @@ -60,10 +82,20 @@ def get_servizi(self): results = {} for brain in brains: servizio = brain.getObject() - if safe_hasattr(servizio, "condizioni_di_servizio") and getattr( - servizio, "condizioni_di_servizio" - ): + # if safe_hasattr(servizio, "condizioni_di_servizio") and getattr( + # servizio, "condizioni_di_servizio" + # ): + # continue + + # Se chiediamo di vedere anche le condizioni di servizio, lo teniamo + self.cds = self.request.get("condizioni_di_servizio", None) + information_dict = self.information_dict(servizio) + if not self.cds: + del information_dict["condizioni_di_servizio"] + + if all(information_dict.values()): continue + parent = servizio.aq_inner.aq_parent if parent.title not in results: results[parent.title] = { @@ -76,54 +108,40 @@ def get_servizi(self): "title": servizio.title, "url": servizio.absolute_url().replace("/api/", "/"), "data": { - "title": getattr(servizio, "title") and FLAG or "", - "description": getattr(servizio, "description", None) + "title": information_dict.get("title") and FLAG or "", + "description": information_dict.get("description") and FLAG or "", - "condizioni_di_servizio": getattr( - servizio, "condizioni_di_servizio", None + "condizioni_di_servizio": information_dict.get( + "condizioni_di_servizio" ) and FLAG or "", - "tassonomia_argomenti": getattr( - servizio, "tassonomia_argomenti", None + "tassonomia_argomenti": information_dict.get( + "tassonomia_argomenti" ) and FLAG or "", - "a_chi_si_rivolge": text_in_block( - getattr(servizio, "a_chi_si_rivolge", None) - ) + "a_chi_si_rivolge": information_dict.get("a_chi_si_rivolge") and FLAG or "", - "come_si_fa": text_in_block( - getattr(servizio, "come_si_fa", None) - ) + "come_si_fa": information_dict.get("come_si_fa") and FLAG or "", + "cosa_si_ottiene": information_dict.get("cosa_si_ottiene") and FLAG or "", - "cosa_si_ottiene": text_in_block( - getattr(servizio, "cosa_si_ottiene", None) - ) - and FLAG - or "", - "canale_fisico": getattr(servizio, "canale_fisico", None) + "canale_fisico": information_dict.get("canale_fisico") and FLAG or "", - "cosa_serve": text_in_block( - getattr(servizio, "cosa_serve", None) - ) - and FLAG - or "", - "tempi_e_scadenze": text_in_block( - getattr(servizio, "tempi_e_scadenze", None) - ) + "cosa_serve": information_dict.get("cosa_serve") and FLAG or "", + "tempi_e_scadenze": information_dict.get("tempi_e_scadenze") and FLAG or "", - "ufficio_responsabile": getattr( - servizio, "ufficio_responsabile", None + "ufficio_responsabile": information_dict.get( + "ufficio_responsabile" ) and FLAG or "", - "contact_info": getattr(servizio, "contact_info", None) + "contact_info": information_dict.get("contact_info") and FLAG or "", }, diff --git a/src/design/plone/contenttypes/browser/manage_content/templates/check_servizi.pt b/src/design/plone/contenttypes/browser/manage_content/templates/check_servizi.pt index 607f900f..fe71d8f7 100644 --- a/src/design/plone/contenttypes/browser/manage_content/templates/check_servizi.pt +++ b/src/design/plone/contenttypes/browser/manage_content/templates/check_servizi.pt @@ -45,6 +45,22 @@ table.services thead tr th.service_title{ width: 250px; } + .forms{ + margin-top: 1em; + margin-bottom: 1em; + text-align:center; + } + .forms input{ + border: none; /* Remove borders */ + color: white; /* Add a text color */ + padding: 14px 28px; /* Add some padding */ + cursor: pointer; /* Add a pointer cursor on mouse-over */ + background-color: #2196F3; + border-radius: 12px; + } + .forms input:hover{ + background: #0b7dda; + } @@ -56,6 +72,7 @@ che questo non sia corretto verifica di essere autenticato oppure rivolgiti agli amministratori del sito.
+
+
+
+ +
+
+
+
+ + +
+
+
+ +
From b6fc5815ad623c84920cd0f898d49213aef0d41b Mon Sep 17 00:00:00 2001 From: Daniele Andreotti Date: Mon, 27 Nov 2023 12:51:41 +0100 Subject: [PATCH 381/487] Preparing release 6.1.2 --- CHANGES.rst | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 1ed158dd..ecf7d8e8 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,7 +1,7 @@ Changelog ========= -6.1.2 (unreleased) +6.1.2 (2023-11-27) ------------------ - Added utility views: @@check-notizie and @@download-check-notizie. diff --git a/setup.py b/setup.py index 53124b15..8e6fc278 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.1.2.dev0", + version="6.1.2", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 5555ba3de7a71e6c6637c1d5c77e26b21c67ccf4 Mon Sep 17 00:00:00 2001 From: Daniele Andreotti Date: Mon, 27 Nov 2023 12:51:53 +0100 Subject: [PATCH 382/487] Back to development: 6.1.3 --- CHANGES.rst | 6 ++++++ setup.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index ecf7d8e8..2f3cda9c 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,6 +1,12 @@ Changelog ========= +6.1.3 (unreleased) +------------------ + +- Nothing changed yet. + + 6.1.2 (2023-11-27) ------------------ diff --git a/setup.py b/setup.py index 8e6fc278..2822cb8e 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.1.2", + version="6.1.3.dev0", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From bc77e3cb9a0eb57c342f344a00aac0b9bdd6376f Mon Sep 17 00:00:00 2001 From: daniele-andreotti Date: Tue, 28 Nov 2023 12:45:17 +0100 Subject: [PATCH 383/487] Fixed check on Competenze field. Excluding expired events and news (#222) * fixed check on Competenze field. Excluding expired events and news * updated CHANGES.rst * updated CHANGES.rst * updated query --- CHANGES.rst | 4 ++-- .../plone/contenttypes/browser/utils/check_eventi.py | 2 ++ .../plone/contenttypes/browser/utils/check_notizie.py | 2 ++ src/design/plone/contenttypes/browser/utils/check_uo.py | 7 ++++--- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 2f3cda9c..987afa53 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,8 +4,8 @@ Changelog 6.1.3 (unreleased) ------------------ -- Nothing changed yet. - +- "Buone pratiche" views: fixed check on Competenze field. Excluding expired events and news. + [daniele] 6.1.2 (2023-11-27) ------------------ diff --git a/src/design/plone/contenttypes/browser/utils/check_eventi.py b/src/design/plone/contenttypes/browser/utils/check_eventi.py index 190c42a6..9f4e67f6 100644 --- a/src/design/plone/contenttypes/browser/utils/check_eventi.py +++ b/src/design/plone/contenttypes/browser/utils/check_eventi.py @@ -1,3 +1,4 @@ +from DateTime import DateTime from openpyxl import Workbook from openpyxl.styles import Alignment from openpyxl.styles import Font @@ -49,6 +50,7 @@ def get_eventi(self): query = { "portal_type": "Event", "review_state": "published", + "effectiveRange": DateTime(), } brains = pc(query) results = {} diff --git a/src/design/plone/contenttypes/browser/utils/check_notizie.py b/src/design/plone/contenttypes/browser/utils/check_notizie.py index dbe64486..779fd858 100644 --- a/src/design/plone/contenttypes/browser/utils/check_notizie.py +++ b/src/design/plone/contenttypes/browser/utils/check_notizie.py @@ -1,3 +1,4 @@ +from DateTime import DateTime from openpyxl import Workbook from openpyxl.styles import Alignment from openpyxl.styles import Font @@ -48,6 +49,7 @@ def get_notizie(self): query = { "portal_type": "News Item", "review_state": "published", + "effectiveRange": DateTime(), } brains = pc(query) diff --git a/src/design/plone/contenttypes/browser/utils/check_uo.py b/src/design/plone/contenttypes/browser/utils/check_uo.py index 6903ab15..6e548ce6 100644 --- a/src/design/plone/contenttypes/browser/utils/check_uo.py +++ b/src/design/plone/contenttypes/browser/utils/check_uo.py @@ -46,9 +46,10 @@ def information_dict(self, uo): sede_ref = sede_ref[0] competenze = getattr(uo, "competenze", "") - res = [x.get("text", "") for x in competenze["blocks"].values()] - if not [x for x in res if x]: - competenze = "" + if competenze: + res = [x.get("text", "") for x in competenze["blocks"].values()] + if not [x for x in res if x]: + competenze = "" return { "description": getattr(uo, "description", "").strip(), "competenze": competenze, From 39b71b985dfc628191e5baf43c0d4e714bf1b342 Mon Sep 17 00:00:00 2001 From: Daniele Andreotti Date: Tue, 28 Nov 2023 12:57:28 +0100 Subject: [PATCH 384/487] Preparing release 6.1.3 --- CHANGES.rst | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 987afa53..ca401468 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,7 +1,7 @@ Changelog ========= -6.1.3 (unreleased) +6.1.3 (2023-11-28) ------------------ - "Buone pratiche" views: fixed check on Competenze field. Excluding expired events and news. diff --git a/setup.py b/setup.py index 2822cb8e..a8090201 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.1.3.dev0", + version="6.1.3", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From bdb2e34090da70ba20fea0985bca9a79a324d373 Mon Sep 17 00:00:00 2001 From: Daniele Andreotti Date: Tue, 28 Nov 2023 12:57:36 +0100 Subject: [PATCH 385/487] Back to development: 6.1.4 --- CHANGES.rst | 6 ++++++ setup.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index ca401468..f48cb1c5 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,6 +1,12 @@ Changelog ========= +6.1.4 (unreleased) +------------------ + +- Nothing changed yet. + + 6.1.3 (2023-11-28) ------------------ diff --git a/setup.py b/setup.py index a8090201..4fa9d87d 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.1.3", + version="6.1.4.dev0", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From f3729ea63ff3bc0ef80317d46dcb77b53ac81773 Mon Sep 17 00:00:00 2001 From: Mauro Amico Date: Mon, 4 Dec 2023 12:39:20 +0100 Subject: [PATCH 386/487] Fix check_persone. When there are no relation --- CHANGES.rst | 3 ++- .../contenttypes/browser/utils/check_persone.py | 17 +++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index f48cb1c5..797e533f 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,7 +4,8 @@ Changelog 6.1.4 (unreleased) ------------------ -- Nothing changed yet. +- Fix check_persone. When there are no relation. + [mamico] 6.1.3 (2023-11-28) diff --git a/src/design/plone/contenttypes/browser/utils/check_persone.py b/src/design/plone/contenttypes/browser/utils/check_persone.py index fff003d5..9298c8a8 100644 --- a/src/design/plone/contenttypes/browser/utils/check_persone.py +++ b/src/design/plone/contenttypes/browser/utils/check_persone.py @@ -70,14 +70,15 @@ def information_dict(self, persona): if persona.incarichi_persona: relations = self.get_related_objects(persona, "incarichi_persona") - rel_data = relations[0] - - if ( - rel_data["data_inizio_incarico"] - and rel_data["title"].strip() - and rel_data["tipologia_incarico"] - ): - incarichi_persona = FLAG + if relations: + rel_data = relations[0] + + if ( + rel_data["data_inizio_incarico"] + and rel_data["title"].strip() + and rel_data["tipologia_incarico"] + ): + incarichi_persona = FLAG return { "incarichi_persona": incarichi_persona, From 3289801833a81b5a189afe51d87463b38a97c27d Mon Sep 17 00:00:00 2001 From: Mauro Amico Date: Mon, 4 Dec 2023 12:45:58 +0100 Subject: [PATCH 387/487] Preparing release 6.1.4 --- CHANGES.rst | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 797e533f..e301868d 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,7 +1,7 @@ Changelog ========= -6.1.4 (unreleased) +6.1.4 (2023-12-04) ------------------ - Fix check_persone. When there are no relation. diff --git a/setup.py b/setup.py index 4fa9d87d..a94f712b 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.1.4.dev0", + version="6.1.4", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From cc4b9615dbaee62c2f84fae5ce8a84228f6dbd91 Mon Sep 17 00:00:00 2001 From: Mauro Amico Date: Mon, 4 Dec 2023 12:46:16 +0100 Subject: [PATCH 388/487] Back to development: 6.1.5 --- CHANGES.rst | 6 ++++++ setup.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index e301868d..8de32401 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,6 +1,12 @@ Changelog ========= +6.1.5 (unreleased) +------------------ + +- Nothing changed yet. + + 6.1.4 (2023-12-04) ------------------ diff --git a/setup.py b/setup.py index a94f712b..d663b573 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.1.4", + version="6.1.5.dev0", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From e7bad208454fdff07acf1b6f5f94b08d912453b4 Mon Sep 17 00:00:00 2001 From: Piero Nicolli Date: Wed, 13 Dec 2023 10:13:48 +0100 Subject: [PATCH 389/487] Allow reorder of data grid fields (#224) * [chg] allow reorder of data grid fields * [fix] widget props --- CHANGES.rst | 3 ++- .../plone/contenttypes/interfaces/punto_di_contatto.py | 7 ++++++- src/design/plone/contenttypes/interfaces/servizio.py | 7 ++++++- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 8de32401..936ef1a1 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,7 +4,8 @@ Changelog 6.1.5 (unreleased) ------------------ -- Nothing changed yet. +- Allow reorder of data grid fields. + [pnicolli] 6.1.4 (2023-12-04) diff --git a/src/design/plone/contenttypes/interfaces/punto_di_contatto.py b/src/design/plone/contenttypes/interfaces/punto_di_contatto.py index 84296528..1071241f 100644 --- a/src/design/plone/contenttypes/interfaces/punto_di_contatto.py +++ b/src/design/plone/contenttypes/interfaces/punto_di_contatto.py @@ -65,7 +65,12 @@ class IPuntoDiContatto(model.Schema, IDesignPloneContentType): form.widget( "value_punto_contatto", DataGridFieldFactory, - frontendOptions={"widget": "data_grid"}, + frontendOptions={ + "widget": "data_grid", + "widgetProps": { + "allow_reorder": True, + }, + }, ) form.widget( diff --git a/src/design/plone/contenttypes/interfaces/servizio.py b/src/design/plone/contenttypes/interfaces/servizio.py index 8d18fc9a..1f53ff8a 100644 --- a/src/design/plone/contenttypes/interfaces/servizio.py +++ b/src/design/plone/contenttypes/interfaces/servizio.py @@ -464,7 +464,12 @@ class IServizio(model.Schema, IDesignPloneContentType): form.widget( "timeline_tempi_scadenze", DataGridFieldFactory, - frontendOptions={"widget": "data_grid"}, + frontendOptions={ + "widget": "data_grid", + "widgetProps": { + "allow_reorder": True, + }, + }, ) form.widget("canale_digitale_link", LinkFieldWidget) From 40c21524946a496186ec1aa75682eee04616b411 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Wed, 13 Dec 2023 10:20:36 +0100 Subject: [PATCH 390/487] Preparing release 6.1.5 --- CHANGES.rst | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 936ef1a1..be1792b6 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,7 +1,7 @@ Changelog ========= -6.1.5 (unreleased) +6.1.5 (2023-12-13) ------------------ - Allow reorder of data grid fields. diff --git a/setup.py b/setup.py index d663b573..08e3efa6 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.1.5.dev0", + version="6.1.5", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 6b8e0f7e94353bddc010152aed3a4ae8c022bf06 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Wed, 13 Dec 2023 10:20:52 +0100 Subject: [PATCH 391/487] Back to development: 6.1.6 --- CHANGES.rst | 6 ++++++ setup.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index be1792b6..feb8f7e7 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,6 +1,12 @@ Changelog ========= +6.1.6 (unreleased) +------------------ + +- Nothing changed yet. + + 6.1.5 (2023-12-13) ------------------ diff --git a/setup.py b/setup.py index 08e3efa6..09dfc80b 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.1.5", + version="6.1.6.dev0", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 1ede6441715bebd1517bad39a67ba609b18b171c Mon Sep 17 00:00:00 2001 From: daniele-andreotti Date: Fri, 15 Dec 2023 14:56:56 +0100 Subject: [PATCH 392/487] Improved "Buone pratiche" view for Event - US #49677 (#225) * Improved "Buone pratiche" view for Event: checking both for relation with Evenue and coordinates. * fixed typo * blacked --- CHANGES.rst | 3 ++- .../plone/contenttypes/browser/utils/check_eventi.py | 11 ++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index feb8f7e7..4f70afe4 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,7 +4,8 @@ Changelog 6.1.6 (unreleased) ------------------ -- Nothing changed yet. +- Improved "Buone pratiche" view for Event: checking both for relation with Venue and coordinates. + [daniele] 6.1.5 (2023-12-13) diff --git a/src/design/plone/contenttypes/browser/utils/check_eventi.py b/src/design/plone/contenttypes/browser/utils/check_eventi.py index 9f4e67f6..a5997fb6 100644 --- a/src/design/plone/contenttypes/browser/utils/check_eventi.py +++ b/src/design/plone/contenttypes/browser/utils/check_eventi.py @@ -25,10 +25,19 @@ def information_dict(self, evento): if not [x for x in res if x]: prezzo = "" + luoghi_correlati = False + if getattr(evento, "luoghi_correlati", None): + luoghi_correlati = True + elif getattr(evento, "geolocation", None): + if getattr(evento.geolocation, "latitude", "") and getattr( + evento.geolocation, "longitude", "" + ): + luoghi_correlati = True + return { "description": getattr(evento, "description", "").strip(), "effective_date": getattr(evento, "effective_date", None), - "luoghi_correlati": getattr(evento, "luoghi_correlati", None), + "luoghi_correlati": luoghi_correlati, "prezzo": prezzo, "contact_info": getattr(evento, "contact_info", None), } From 7169ee43509c1f2a6635b36909f4abe757c4e27a Mon Sep 17 00:00:00 2001 From: Daniele Andreotti Date: Fri, 15 Dec 2023 15:02:16 +0100 Subject: [PATCH 393/487] Preparing release 6.1.6 --- CHANGES.rst | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 4f70afe4..be8407bc 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,7 +1,7 @@ Changelog ========= -6.1.6 (unreleased) +6.1.6 (2023-12-15) ------------------ - Improved "Buone pratiche" view for Event: checking both for relation with Venue and coordinates. diff --git a/setup.py b/setup.py index 09dfc80b..2ad08095 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.1.6.dev0", + version="6.1.6", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 2e71373d169f4880a914afc6edb708dfaf2d56b2 Mon Sep 17 00:00:00 2001 From: Daniele Andreotti Date: Fri, 15 Dec 2023 15:02:25 +0100 Subject: [PATCH 394/487] Back to development: 6.1.7 --- CHANGES.rst | 6 ++++++ setup.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index be8407bc..79a687c7 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,6 +1,12 @@ Changelog ========= +6.1.7 (unreleased) +------------------ + +- Nothing changed yet. + + 6.1.6 (2023-12-15) ------------------ diff --git a/setup.py b/setup.py index 2ad08095..98d107ca 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.1.6", + version="6.1.7.dev0", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 2dee466b2296c09ac1bc498ffc2cabe120b4021e Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Tue, 19 Dec 2023 13:58:08 +0100 Subject: [PATCH 395/487] Fixed label for tassonomia_evento taxonomies + updated CHANGES (#227) --- CHANGES.rst | 3 ++- .../profiles/behaviors/taxonomies/tipologia_evento.xml | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 79a687c7..f6fe8683 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,7 +4,8 @@ Changelog 6.1.7 (unreleased) ------------------ -- Nothing changed yet. +- Fixed label for tassonomia_evento taxonomies. + [eikichi18] 6.1.6 (2023-12-15) diff --git a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_evento.xml b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_evento.xml index 8935654c..d8a091ea 100644 --- a/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_evento.xml +++ b/src/design/plone/contenttypes/profiles/behaviors/taxonomies/tipologia_evento.xml @@ -167,7 +167,7 @@ concorso_competizione - Concorco/competizione + Concorso/competizione @@ -293,7 +293,7 @@ santificazione - Sanntificazione + Santificazione From 214d45c45171270c997cda61a8fa10efa4c09d5d Mon Sep 17 00:00:00 2001 From: Luca Date: Tue, 19 Dec 2023 15:20:41 +0100 Subject: [PATCH 396/487] Improved "Check notizie" view adding a way to set "a cura di" field (#226) --- CHANGES.rst | 2 + .../browser/utils/check_notizie.py | 62 +++++++++++++++- .../contenttypes/browser/utils/configure.zcml | 6 ++ .../browser/utils/templates/check_notizie.pt | 74 ++++++++++++++++++- 4 files changed, 139 insertions(+), 5 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index f6fe8683..61870f40 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,6 +4,8 @@ Changelog 6.1.7 (unreleased) ------------------ +- Improved "Check notizie" view adding a way to set "a cura di" field + [lucabel] - Fixed label for tassonomia_evento taxonomies. [eikichi18] diff --git a/src/design/plone/contenttypes/browser/utils/check_notizie.py b/src/design/plone/contenttypes/browser/utils/check_notizie.py index 779fd858..40c0dc5f 100644 --- a/src/design/plone/contenttypes/browser/utils/check_notizie.py +++ b/src/design/plone/contenttypes/browser/utils/check_notizie.py @@ -6,8 +6,12 @@ from openpyxl.utils import get_column_letter from plone import api from Products.Five import BrowserView +from z3c.relationfield import RelationValue +from zope.component import getUtility +from zope.intid.interfaces import IIntIds import io +import transaction FLAG = '' @@ -20,7 +24,6 @@ def is_anonymous(self): return api.user.is_anonymous() def information_dict(self, notizia): - descrizione_estesa = getattr(notizia, "descrizione_estesa", "") res = [x.get("text", "") for x in descrizione_estesa["blocks"].values()] if not [x for x in res if x]: @@ -66,6 +69,7 @@ def get_notizie(self): if parent.title not in results: results[parent.title] = { "url": self.plone2volto(parent.absolute_url()), + "path": "/".join(parent.getPhysicalPath()), "children": [], } @@ -76,6 +80,7 @@ def get_notizie(self): and FLAG or "", "url": self.plone2volto(notizia.absolute_url()), + "UID": notizia.UID(), "data": { "effective_date": information_dict.get("effective_date") and FLAG @@ -92,6 +97,61 @@ def get_notizie(self): return results +class SetACuraDi(CheckNotizie): + def __call__(self): + # news_folder = self.request.get("path") + came_from = self.request.get("came_from") + uids = self.request.get("uids") + news_folder = self.request.get("path") + portal_id = api.portal.get().id + path_ufficio = f"/{portal_id}" + self.request.get("path_ufficio") + ufficio = api.content.get(path=path_ufficio) + + if not ufficio: + self.context.plone_utils.addPortalMessage( + f"Impossibile trovare l'ufficio {self.request.get('path_ufficio')}", + "error", + ) + + self.request.RESPONSE.redirect(came_from) + return + + # same query above, plus news UIDS; use UIDS 'cause trying to get brains + # by path give me strange results + query = { + "portal_type": "News Item", + "review_state": "published", + "effectiveRange": DateTime(), + "UID": uids, + } + pc = api.portal.get_tool("portal_catalog") + brains = pc(query) + intids = getUtility(IIntIds) + ufficio = api.content.get(path=path_ufficio) + + for idx, brain in enumerate(brains): + notizia = brain.getObject() + + information_dict = self.information_dict(notizia) + if all(information_dict.values()): + continue + + if not getattr(notizia, "a_cura_di", None): + notizia.a_cura_di = [RelationValue(intids.getId(ufficio))] + notizia.reindexObject() + + if idx % 10 == 0: + transaction.commit() + + office_path = "/".join(ufficio.getPhysicalPath()) + self.context.plone_utils.addPortalMessage( + f'Impostato l\'ufficio "{ufficio.title}" ({office_path}) nelle news della cartella {news_folder}', # noqa + "info", + ) + self.request.RESPONSE.redirect(came_from) + return + + class DownloadCheckNotizie(CheckNotizie): CT = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" diff --git a/src/design/plone/contenttypes/browser/utils/configure.zcml b/src/design/plone/contenttypes/browser/utils/configure.zcml index fed77926..7cc4ab2f 100644 --- a/src/design/plone/contenttypes/browser/utils/configure.zcml +++ b/src/design/plone/contenttypes/browser/utils/configure.zcml @@ -69,6 +69,12 @@ template="templates/check_notizie.pt" permission="cmf.ManagePortal" /> + @@ -130,6 +161,7 @@

${categoria}

+
  • ${evento/title}
+ +
+ Imposta 'A cura di' per le notizie di questa cartella +
+

Imposta il path dell'ufficio che vuoi assegnare alle news e premi "Imposta 'A cura di'" per assegnare l'ufficio alle news con dato mancante in questa cartella.

+

L'ufficio deve essere impostato con path relativo alla radice del sito, esempio: /amministrazione/uffici/comunicazione

+
+ + + + + + + +
+
+
+ From bcae868587ee2eb16ad7e4a695011524bdb523fe Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Wed, 20 Dec 2023 09:18:42 +0100 Subject: [PATCH 397/487] Preparing release 6.1.7 --- CHANGES.rst | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 61870f40..3a6ba413 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,7 +1,7 @@ Changelog ========= -6.1.7 (unreleased) +6.1.7 (2023-12-20) ------------------ - Improved "Check notizie" view adding a way to set "a cura di" field diff --git a/setup.py b/setup.py index 98d107ca..a67bf86f 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.1.7.dev0", + version="6.1.7", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 21349b869e2510452f054a160200be24d98ad401 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Wed, 20 Dec 2023 09:19:43 +0100 Subject: [PATCH 398/487] Back to development: 6.1.8 --- CHANGES.rst | 6 ++++++ setup.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 3a6ba413..2a8323ee 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,6 +1,12 @@ Changelog ========= +6.1.8 (unreleased) +------------------ + +- Nothing changed yet. + + 6.1.7 (2023-12-20) ------------------ diff --git a/setup.py b/setup.py index a67bf86f..845c131b 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.1.7", + version="6.1.8.dev0", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 0d484a4548b1793b9d00432e1dd07b9542a6edf7 Mon Sep 17 00:00:00 2001 From: Luca Date: Wed, 20 Dec 2023 16:02:17 +0100 Subject: [PATCH 399/487] [feat] behavior to add field argomenti in Link CT (#228) --- CHANGES.rst | 3 +- .../plone/contenttypes/behaviors/argomenti.py | 42 +++++++++++++++++++ .../contenttypes/behaviors/configure.zcml | 10 +++++ .../profiles/default/metadata.xml | 2 +- .../profiles/default/types/Link.xml | 1 + .../contenttypes/upgrades/configure.zcml | 11 +++++ 6 files changed, 67 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 2a8323ee..28f5ece7 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,7 +4,8 @@ Changelog 6.1.8 (unreleased) ------------------ -- Nothing changed yet. +- Add behavior aromento to Link CT + [lucabel] 6.1.7 (2023-12-20) diff --git a/src/design/plone/contenttypes/behaviors/argomenti.py b/src/design/plone/contenttypes/behaviors/argomenti.py index c35caa97..427410bd 100644 --- a/src/design/plone/contenttypes/behaviors/argomenti.py +++ b/src/design/plone/contenttypes/behaviors/argomenti.py @@ -4,6 +4,7 @@ from design.plone.contenttypes.interfaces.documento import IDocumento from design.plone.contenttypes.interfaces.servizio import IServizio from plone.app.contenttypes.interfaces import IDocument +from plone.app.contenttypes.interfaces import ILink from plone.app.dexterity import textindexer from plone.app.z3cform.widget import RelatedItemsFieldWidget from plone.autoform import directives as form @@ -68,6 +69,38 @@ class IArgomentiSchema(model.Schema): textindexer.searchable("tassonomia_argomenti") +@provider(IFormFieldProvider) +class IArgomentiLink(model.Schema): + """Marker interface for Argomenti""" + + tassonomia_argomenti = RelationList( + title=_("tassonomia_argomenti_label", default="Argomenti"), + description=_( + "tassonomia_argomenti_help", + default="Seleziona una lista di argomenti d'interesse per questo" + " contenuto.", + ), + value_type=RelationChoice( + title=_("Argomenti correlati"), + vocabulary="plone.app.vocabularies.Catalog", + ), + required=False, + default=[], + ) + + form.widget( + "tassonomia_argomenti", + RelatedItemsFieldWidget, + vocabulary="plone.app.vocabularies.Catalog", + pattern_options={ + "maximumSelectionSize": 20, + "selectableTypes": ["Pagina Argomento"], + }, + ) + + textindexer.searchable("tassonomia_argomenti") + + @provider(IFormFieldProvider) class IArgomenti(IArgomentiSchema): """ """ @@ -273,3 +306,12 @@ class ArgomentiEvento(object): def __init__(self, context): self.context = context + + +@implementer(IArgomentiLink) +@adapter(ILink) +class ArgomentiLink(object): + """""" + + def __init__(self, context): + self.context = context diff --git a/src/design/plone/contenttypes/behaviors/configure.zcml b/src/design/plone/contenttypes/behaviors/configure.zcml index 204c1e03..9d00c5cb 100644 --- a/src/design/plone/contenttypes/behaviors/configure.zcml +++ b/src/design/plone/contenttypes/behaviors/configure.zcml @@ -101,6 +101,16 @@ for="plone.dexterity.interfaces.IDexterityContent" marker=".argomenti.IArgomentiServizio" /> + + - 7020 + 7021 profile-redturtle.bandi:default profile-collective.venue:default diff --git a/src/design/plone/contenttypes/profiles/default/types/Link.xml b/src/design/plone/contenttypes/profiles/default/types/Link.xml index 8aea89da..49cb09a4 100644 --- a/src/design/plone/contenttypes/profiles/default/types/Link.xml +++ b/src/design/plone/contenttypes/profiles/default/types/Link.xml @@ -12,5 +12,6 @@ + diff --git a/src/design/plone/contenttypes/upgrades/configure.zcml b/src/design/plone/contenttypes/upgrades/configure.zcml index 75f8fced..3cfeb960 100644 --- a/src/design/plone/contenttypes/upgrades/configure.zcml +++ b/src/design/plone/contenttypes/upgrades/configure.zcml @@ -784,4 +784,15 @@ handler=".upgrades.update_actions" /> + + + + From 94af5305a2a3647d98393e055de54dc1ca472db3 Mon Sep 17 00:00:00 2001 From: Piero Nicolli Date: Fri, 22 Dec 2023 13:01:51 +0100 Subject: [PATCH 400/487] Removed maximumSelectionSize from all fields that had it greater than 0 (#229) --- CHANGES.rst | 4 +++- src/design/plone/contenttypes/behaviors/argomenti.py | 2 -- src/design/plone/contenttypes/behaviors/contatti.py | 5 ----- .../plone/contenttypes/behaviors/dataset_correlati.py | 1 - src/design/plone/contenttypes/behaviors/evento.py | 3 --- .../plone/contenttypes/behaviors/luoghi_correlati.py | 2 -- src/design/plone/contenttypes/behaviors/luogo.py | 1 - .../plone/contenttypes/behaviors/news_additional_fields.py | 3 --- .../plone/contenttypes/behaviors/servizi_correlati.py | 1 - .../plone/contenttypes/behaviors/strutture_correlate.py | 1 - src/design/plone/contenttypes/behaviors/trasparenza.py | 2 -- src/design/plone/contenttypes/interfaces/documento.py | 7 +++---- .../plone/contenttypes/interfaces/pagina_argomento.py | 1 - src/design/plone/contenttypes/interfaces/persona.py | 2 -- .../plone/contenttypes/interfaces/punto_di_contatto.py | 1 - src/design/plone/contenttypes/interfaces/servizio.py | 4 ---- .../plone/contenttypes/interfaces/unita_organizzativa.py | 5 +---- src/design/plone/contenttypes/tests/test_ct_servizio.py | 4 ---- 18 files changed, 7 insertions(+), 42 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 28f5ece7..2137f927 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,8 +4,10 @@ Changelog 6.1.8 (unreleased) ------------------ -- Add behavior aromento to Link CT +- Add behavior argomento to Link CT [lucabel] +- Removed maximumSelectionSize from all fields that had it greater than 0 + [pnicolli] 6.1.7 (2023-12-20) diff --git a/src/design/plone/contenttypes/behaviors/argomenti.py b/src/design/plone/contenttypes/behaviors/argomenti.py index 427410bd..7678ab49 100644 --- a/src/design/plone/contenttypes/behaviors/argomenti.py +++ b/src/design/plone/contenttypes/behaviors/argomenti.py @@ -55,7 +55,6 @@ class IArgomentiSchema(model.Schema): RelatedItemsFieldWidget, vocabulary="plone.app.vocabularies.Catalog", pattern_options={ - "maximumSelectionSize": 20, "selectableTypes": ["Pagina Argomento"], }, ) @@ -93,7 +92,6 @@ class IArgomentiLink(model.Schema): RelatedItemsFieldWidget, vocabulary="plone.app.vocabularies.Catalog", pattern_options={ - "maximumSelectionSize": 20, "selectableTypes": ["Pagina Argomento"], }, ) diff --git a/src/design/plone/contenttypes/behaviors/contatti.py b/src/design/plone/contenttypes/behaviors/contatti.py index f33be26f..5d76e374 100644 --- a/src/design/plone/contenttypes/behaviors/contatti.py +++ b/src/design/plone/contenttypes/behaviors/contatti.py @@ -49,7 +49,6 @@ class IContattiUnitaOrganizzativa(model.Schema): RelatedItemsFieldWidget, vocabulary="plone.app.vocabularies.Catalog", pattern_options={ - "maximumSelectionSize": 10, "selectableTypes": ["PuntoDiContatto"], }, ) @@ -86,7 +85,6 @@ class IContattiPersona(model.Schema): RelatedItemsFieldWidget, vocabulary="plone.app.vocabularies.Catalog", pattern_options={ - "maximumSelectionSize": 10, "selectableTypes": ["PuntoDiContatto"], }, ) @@ -120,7 +118,6 @@ class IContattiServizio(model.Schema): RelatedItemsFieldWidget, vocabulary="plone.app.vocabularies.Catalog", pattern_options={ - "maximumSelectionSize": 10, "selectableTypes": ["PuntoDiContatto"], }, ) @@ -154,7 +151,6 @@ class IContattiVenue(model.Schema): RelatedItemsFieldWidget, vocabulary="plone.app.vocabularies.Catalog", pattern_options={ - "maximumSelectionSize": 10, "selectableTypes": ["PuntoDiContatto"], }, ) @@ -188,7 +184,6 @@ class IContattiEvent(model.Schema): RelatedItemsFieldWidget, vocabulary="plone.app.vocabularies.Catalog", pattern_options={ - "maximumSelectionSize": 10, "selectableTypes": ["PuntoDiContatto"], }, ) diff --git a/src/design/plone/contenttypes/behaviors/dataset_correlati.py b/src/design/plone/contenttypes/behaviors/dataset_correlati.py index ac2fe90e..fdf71d8f 100644 --- a/src/design/plone/contenttypes/behaviors/dataset_correlati.py +++ b/src/design/plone/contenttypes/behaviors/dataset_correlati.py @@ -32,7 +32,6 @@ class IDatasetCorrelati(model.Schema): vocabulary="plone.app.vocabularies.Catalog", pattern_options={ "selectableTypes": ["Dataset"], - "maximumSelectionSize": 50, }, ) diff --git a/src/design/plone/contenttypes/behaviors/evento.py b/src/design/plone/contenttypes/behaviors/evento.py index 2a280e31..65fb13ad 100644 --- a/src/design/plone/contenttypes/behaviors/evento.py +++ b/src/design/plone/contenttypes/behaviors/evento.py @@ -127,7 +127,6 @@ class IEvento(model.Schema): RelatedItemsFieldWidget, vocabulary="plone.app.vocabularies.Catalog", pattern_options={ - "maximumSelectionSize": 10, "selectableTypes": ["UnitaOrganizzativa"], }, ) @@ -136,7 +135,6 @@ class IEvento(model.Schema): RelatedItemsFieldWidget, vocabulary="plone.app.vocabularies.Catalog", pattern_options={ - "maximumSelectionSize": 10, "selectableTypes": ["Persona", "UnitaOrganizzativa", "Servizio"], }, ) @@ -145,7 +143,6 @@ class IEvento(model.Schema): RelatedItemsFieldWidget, vocabulary="plone.app.vocabularies.Catalog", pattern_options={ - "maximumSelectionSize": 10, "selectableTypes": ["Persona"], }, ) diff --git a/src/design/plone/contenttypes/behaviors/luoghi_correlati.py b/src/design/plone/contenttypes/behaviors/luoghi_correlati.py index da545131..0f171c71 100644 --- a/src/design/plone/contenttypes/behaviors/luoghi_correlati.py +++ b/src/design/plone/contenttypes/behaviors/luoghi_correlati.py @@ -30,7 +30,6 @@ class ILuoghiCorrelatiSchema(model.Schema): vocabulary="plone.app.vocabularies.Catalog", pattern_options={ "selectableTypes": ["Venue"], - "maximumSelectionSize": 50, }, ) @@ -66,7 +65,6 @@ class ILuoghiCorrelatiEvento(model.Schema): vocabulary="plone.app.vocabularies.Catalog", pattern_options={ "selectableTypes": ["Venue"], - "maximumSelectionSize": 50, }, ) diff --git a/src/design/plone/contenttypes/behaviors/luogo.py b/src/design/plone/contenttypes/behaviors/luogo.py index 753bdfd0..e36e9d22 100644 --- a/src/design/plone/contenttypes/behaviors/luogo.py +++ b/src/design/plone/contenttypes/behaviors/luogo.py @@ -171,7 +171,6 @@ class ILuogo(model.Schema): RelatedItemsFieldWidget, vocabulary="plone.app.vocabularies.Catalog", pattern_options={ - "maximumSelectionSize": 10, "selectableTypes": ["UnitaOrganizzativa"], }, ) diff --git a/src/design/plone/contenttypes/behaviors/news_additional_fields.py b/src/design/plone/contenttypes/behaviors/news_additional_fields.py index 0a20c31e..149879b1 100644 --- a/src/design/plone/contenttypes/behaviors/news_additional_fields.py +++ b/src/design/plone/contenttypes/behaviors/news_additional_fields.py @@ -97,7 +97,6 @@ class INewsAdditionalFields(model.Schema): vocabulary="plone.app.vocabularies.Catalog", pattern_options={ "selectableTypes": ["Persona"], - "maximumSelectionSize": 50, }, ) form.widget( @@ -105,7 +104,6 @@ class INewsAdditionalFields(model.Schema): RelatedItemsFieldWidget, vocabulary="plone.app.vocabularies.Catalog", pattern_options={ - "maximumSelectionSize": 10, "selectableTypes": ["News Item"], }, ) @@ -115,7 +113,6 @@ class INewsAdditionalFields(model.Schema): vocabulary="plone.app.vocabularies.Catalog", pattern_options={ "selectableTypes": ["Venue"], - "maximumSelectionSize": 50, }, ) model.fieldset( diff --git a/src/design/plone/contenttypes/behaviors/servizi_correlati.py b/src/design/plone/contenttypes/behaviors/servizi_correlati.py index 74828cbf..b7446dbe 100644 --- a/src/design/plone/contenttypes/behaviors/servizi_correlati.py +++ b/src/design/plone/contenttypes/behaviors/servizi_correlati.py @@ -34,7 +34,6 @@ class IServiziCorrelati(model.Schema): RelatedItemsFieldWidget, vocabulary="plone.app.vocabularies.Catalog", pattern_options={ - "maximumSelectionSize": 10, "selectableTypes": ["Servizio"], }, ) diff --git a/src/design/plone/contenttypes/behaviors/strutture_correlate.py b/src/design/plone/contenttypes/behaviors/strutture_correlate.py index 14c21654..63d752b6 100644 --- a/src/design/plone/contenttypes/behaviors/strutture_correlate.py +++ b/src/design/plone/contenttypes/behaviors/strutture_correlate.py @@ -33,7 +33,6 @@ class IStruttureCorrelate(model.Schema): RelatedItemsFieldWidget, vocabulary="plone.app.vocabularies.Catalog", pattern_options={ - "maximumSelectionSize": 10, "selectableTypes": ["UnitaOrganizzativa"], }, ) diff --git a/src/design/plone/contenttypes/behaviors/trasparenza.py b/src/design/plone/contenttypes/behaviors/trasparenza.py index 90b93fde..31dafdc5 100644 --- a/src/design/plone/contenttypes/behaviors/trasparenza.py +++ b/src/design/plone/contenttypes/behaviors/trasparenza.py @@ -274,7 +274,6 @@ class ITrasparenza(model.Schema): RelatedItemsFieldWidget, vocabulary="plone.app.vocabularies.Catalog", pattern_options={ - "maximumSelectionSize": 10, "selectableTypes": ["Persona"], }, ) @@ -283,7 +282,6 @@ class ITrasparenza(model.Schema): RelatedItemsFieldWidget, vocabulary="plone.app.vocabularies.Catalog", pattern_options={ - "maximumSelectionSize": 10, "selectableTypes": ["Persona"], }, ) diff --git a/src/design/plone/contenttypes/interfaces/documento.py b/src/design/plone/contenttypes/interfaces/documento.py index 3e89a07d..58979951 100644 --- a/src/design/plone/contenttypes/interfaces/documento.py +++ b/src/design/plone/contenttypes/interfaces/documento.py @@ -161,7 +161,7 @@ class IDocumento(model.Schema, IDesignPloneContentType): "dataset", RelatedItemsFieldWidget, vocabulary="plone.app.vocabularies.Catalog", - pattern_options={"maximumSelectionSize": 10, "selectableTypes": ["Dataset"]}, + pattern_options={"selectableTypes": ["Dataset"]}, ) # servizi = RelationList( @@ -183,7 +183,7 @@ class IDocumento(model.Schema, IDesignPloneContentType): # "servizi", # RelatedItemsFieldWidget, # vocabulary="plone.app.vocabularies.Catalog", - # pattern_options={"maximumSelectionSize": 20, "selectableTypes": ["Servizio"]}, + # pattern_options={"selectableTypes": ["Servizio"]}, # ) documenti_allegati = RelationList( @@ -217,7 +217,6 @@ class IDocumento(model.Schema, IDesignPloneContentType): RelatedItemsFieldWidget, vocabulary="plone.app.vocabularies.Catalog", pattern_options={ - "maximumSelectionSize": 10, "selectableTypes": ["Persona", "UnitaOrganizzativa"], }, ) @@ -234,7 +233,7 @@ class IDocumento(model.Schema, IDesignPloneContentType): "documenti_allegati", RelatedItemsFieldWidget, vocabulary="plone.app.vocabularies.Catalog", - pattern_options={"maximumSelectionSize": 10, "selectableTypes": ["Documento"]}, + pattern_options={"selectableTypes": ["Documento"]}, ) #  custom fieldsets diff --git a/src/design/plone/contenttypes/interfaces/pagina_argomento.py b/src/design/plone/contenttypes/interfaces/pagina_argomento.py index f2621ea7..9a455493 100644 --- a/src/design/plone/contenttypes/interfaces/pagina_argomento.py +++ b/src/design/plone/contenttypes/interfaces/pagina_argomento.py @@ -56,7 +56,6 @@ class IPaginaArgomento(model.Schema, IDesignPloneContentType): RelatedItemsFieldWidget, vocabulary="plone.app.vocabularies.Catalog", pattern_options={ - "maximumSelectionSize": 10, "selectableTypes": ["UnitaOrganizzativa"], }, ) diff --git a/src/design/plone/contenttypes/interfaces/persona.py b/src/design/plone/contenttypes/interfaces/persona.py index 021d96e3..2b7e5020 100644 --- a/src/design/plone/contenttypes/interfaces/persona.py +++ b/src/design/plone/contenttypes/interfaces/persona.py @@ -116,7 +116,6 @@ class IPersona(model.Schema, IDesignPloneContentType): RelatedItemsFieldWidget, vocabulary="plone.app.vocabularies.Catalog", pattern_options={ - "maximumSelectionSize": 10, "selectableTypes": ["UnitaOrganizzativa"], }, ) @@ -126,7 +125,6 @@ class IPersona(model.Schema, IDesignPloneContentType): RelatedItemsFieldWidget, vocabulary="plone.app.vocabularies.Catalog", pattern_options={ - "maximumSelectionSize": 10, "selectableTypes": ["Incarico"], }, ) diff --git a/src/design/plone/contenttypes/interfaces/punto_di_contatto.py b/src/design/plone/contenttypes/interfaces/punto_di_contatto.py index 1071241f..0639904b 100644 --- a/src/design/plone/contenttypes/interfaces/punto_di_contatto.py +++ b/src/design/plone/contenttypes/interfaces/punto_di_contatto.py @@ -78,7 +78,6 @@ class IPuntoDiContatto(model.Schema, IDesignPloneContentType): RelatedItemsFieldWidget, vocabulary="plone.app.vocabularies.Catalog", pattern_options={ - "maximumSelectionSize": 10, "selectableTypes": ["Persona"], }, ) diff --git a/src/design/plone/contenttypes/interfaces/servizio.py b/src/design/plone/contenttypes/interfaces/servizio.py index 1f53ff8a..740e1695 100644 --- a/src/design/plone/contenttypes/interfaces/servizio.py +++ b/src/design/plone/contenttypes/interfaces/servizio.py @@ -408,7 +408,6 @@ class IServizio(model.Schema, IDesignPloneContentType): RelatedItemsFieldWidget, vocabulary="plone.app.vocabularies.Catalog", pattern_options={ - "maximumSelectionSize": 10, "selectableTypes": ["UnitaOrganizzativa"], }, ) @@ -417,7 +416,6 @@ class IServizio(model.Schema, IDesignPloneContentType): RelatedItemsFieldWidget, vocabulary="plone.app.vocabularies.Catalog", pattern_options={ - "maximumSelectionSize": 10, "selectableTypes": ["Venue", "UnitaOrganizzativa"], }, ) @@ -446,7 +444,6 @@ class IServizio(model.Schema, IDesignPloneContentType): RelatedItemsFieldWidget, vocabulary="plone.app.vocabularies.Catalog", pattern_options={ - "maximumSelectionSize": 10, "selectableTypes": ["Documento", "CartellaModulistica"], # "basePath": "/", }, @@ -456,7 +453,6 @@ class IServizio(model.Schema, IDesignPloneContentType): RelatedItemsFieldWidget, vocabulary="plone.app.vocabularies.Catalog", pattern_options={ - "maximumSelectionSize": 10, "selectableTypes": ["Servizio"], # "basePath": "/", }, diff --git a/src/design/plone/contenttypes/interfaces/unita_organizzativa.py b/src/design/plone/contenttypes/interfaces/unita_organizzativa.py index 21c0dc8d..12e1bfad 100644 --- a/src/design/plone/contenttypes/interfaces/unita_organizzativa.py +++ b/src/design/plone/contenttypes/interfaces/unita_organizzativa.py @@ -144,7 +144,6 @@ class IUnitaOrganizzativa(model.Schema, IDesignPloneContentType): RelatedItemsFieldWidget, vocabulary="plone.app.vocabularies.Catalog", pattern_options={ - "maximumSelectionSize": 10, "selectableTypes": ["Documento"], }, ) @@ -152,14 +151,13 @@ class IUnitaOrganizzativa(model.Schema, IDesignPloneContentType): "persone_struttura", RelatedItemsFieldWidget, vocabulary="plone.app.vocabularies.Catalog", - pattern_options={"selectableTypes": ["Persona"], "maximumSelectionSize": 50}, + pattern_options={"selectableTypes": ["Persona"]}, ) form.widget( "legami_con_altre_strutture", RelatedItemsFieldWidget, vocabulary="plone.app.vocabularies.Catalog", pattern_options={ - "maximumSelectionSize": 10, "selectableTypes": ["UnitaOrganizzativa"], }, ) @@ -194,7 +192,6 @@ class IUnitaOrganizzativa(model.Schema, IDesignPloneContentType): RelatedItemsFieldWidget, vocabulary="plone.app.vocabularies.Catalog", pattern_options={ - "maximumSelectionSize": 10, "selectableTypes": ["Venue"], # "basePath": "/servizi", }, diff --git a/src/design/plone/contenttypes/tests/test_ct_servizio.py b/src/design/plone/contenttypes/tests/test_ct_servizio.py index 0b8935fc..884b0dca 100644 --- a/src/design/plone/contenttypes/tests/test_ct_servizio.py +++ b/src/design/plone/contenttypes/tests/test_ct_servizio.py @@ -19,7 +19,6 @@ WIDGET_PROPERTY_CHECKS = { "tassonomia_argomenti": { - "maximumSelectionSize": 20, "selectableTypes": ["Pagina Argomento"], }, "ufficio_responsabile": { @@ -30,15 +29,12 @@ "selectableTypes": ["UnitaOrganizzativa"], }, "altri_documenti": { - "maximumSelectionSize": 10, "selectableTypes": ["Documento", "CartellaModulistica"], }, "servizi_collegati": { - "maximumSelectionSize": 10, "selectableTypes": ["Servizio"], }, "dove_rivolgersi": { - "maximumSelectionSize": 10, "selectableTypes": ["Venue", "UnitaOrganizzativa"], }, } From 7a4c92d9d45ade80f61f06e00ca34f974d5c76f4 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Fri, 22 Dec 2023 15:26:30 +0100 Subject: [PATCH 401/487] Preparing release 6.1.8 --- CHANGES.rst | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 2137f927..99381af0 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,7 +1,7 @@ Changelog ========= -6.1.8 (unreleased) +6.1.8 (2023-12-22) ------------------ - Add behavior argomento to Link CT diff --git a/setup.py b/setup.py index 845c131b..23f3fcbc 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.1.8.dev0", + version="6.1.8", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 4124f5550a4067c675a81c78b7b375e2481437ee Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Fri, 22 Dec 2023 15:26:43 +0100 Subject: [PATCH 402/487] Back to development: 6.1.9 --- CHANGES.rst | 6 ++++++ setup.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 99381af0..671f3049 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,6 +1,12 @@ Changelog ========= +6.1.9 (unreleased) +------------------ + +- Nothing changed yet. + + 6.1.8 (2023-12-22) ------------------ diff --git a/setup.py b/setup.py index 23f3fcbc..292820b7 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.1.8", + version="6.1.9.dev0", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 910885d6d36caaa0fd145b67d6a88a40ab643946 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Wed, 10 Jan 2024 17:22:34 +0100 Subject: [PATCH 403/487] Add UID to UOJSONSummarySerializer (#230) --- CHANGES.rst | 3 ++- .../contenttypes/restapi/serializers/unita_organizzativa.py | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 671f3049..862466f8 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,7 +4,8 @@ Changelog 6.1.9 (unreleased) ------------------ -- Nothing changed yet. +- Add UID to UOJSONSummarySerializer + [eikichi18] 6.1.8 (2023-12-22) diff --git a/src/design/plone/contenttypes/restapi/serializers/unita_organizzativa.py b/src/design/plone/contenttypes/restapi/serializers/unita_organizzativa.py index 17445379..aa573de8 100644 --- a/src/design/plone/contenttypes/restapi/serializers/unita_organizzativa.py +++ b/src/design/plone/contenttypes/restapi/serializers/unita_organizzativa.py @@ -105,6 +105,7 @@ def __call__(self, version=None, include_items=True): result = super(UOSerializer, self).__call__( version=version, include_items=include_items ) + result["servizi_offerti"] = json_compatible(self.get_services()) result["uo_parent"] = json_compatible(self.getParentUo()) result["uo_children"] = json_compatible(self.getChildrenUo()) @@ -132,6 +133,7 @@ def __call__(self, force_images=True, **kwargs): data[field] = getattr(self.context, field, "") data["geolocation"] = self.getGeolocation() + data["UID"] = self.context.UID() get_taxonomy_information("tipologia_organizzazione", self.context, data) From d5ba8c271913d57b77dab83c8d98b2941cfa5a19 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Thu, 11 Jan 2024 10:34:39 +0100 Subject: [PATCH 404/487] Preparing release 6.1.9 --- CHANGES.rst | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 862466f8..205661cd 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,7 +1,7 @@ Changelog ========= -6.1.9 (unreleased) +6.1.9 (2024-01-11) ------------------ - Add UID to UOJSONSummarySerializer diff --git a/setup.py b/setup.py index 292820b7..6857bd2a 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.1.9.dev0", + version="6.1.9", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 3aa36c9b6b603ea2f5ea9705b52d882814f3a96b Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Thu, 11 Jan 2024 10:34:53 +0100 Subject: [PATCH 405/487] Back to development: 6.1.10 --- CHANGES.rst | 6 ++++++ setup.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 205661cd..1ac2bb4c 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,6 +1,12 @@ Changelog ========= +6.1.10 (unreleased) +------------------- + +- Nothing changed yet. + + 6.1.9 (2024-01-11) ------------------ diff --git a/setup.py b/setup.py index 6857bd2a..c0989d8b 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.1.9", + version="6.1.10.dev0", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 9b4d7573df3279c167f9ed0c8456d4bc9b45c504 Mon Sep 17 00:00:00 2001 From: Piero Nicolli Date: Mon, 15 Jan 2024 11:34:42 +0100 Subject: [PATCH 406/487] [new] added pdc description (#231) * [new] added pdc description * add upgrade step for pdc_desc field --------- Co-authored-by: Luca Bellenghi --- CHANGES.rst | 5 ++++- .../contenttypes/interfaces/punto_di_contatto.py | 10 ++++++++++ .../plone/contenttypes/upgrades/configure.zcml | 11 ++++++++++- src/design/plone/contenttypes/upgrades/upgrades.py | 14 ++++++++++++++ 4 files changed, 38 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 1ac2bb4c..9d4d57f7 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,7 +4,10 @@ Changelog 6.1.10 (unreleased) ------------------- -- Nothing changed yet. +- Added description to PDC fields + [pnicolli] + Added upgrade step to update PDC fields description + [lucabel] 6.1.9 (2024-01-11) diff --git a/src/design/plone/contenttypes/interfaces/punto_di_contatto.py b/src/design/plone/contenttypes/interfaces/punto_di_contatto.py index 0639904b..38964d36 100644 --- a/src/design/plone/contenttypes/interfaces/punto_di_contatto.py +++ b/src/design/plone/contenttypes/interfaces/punto_di_contatto.py @@ -22,6 +22,16 @@ class IPDCValueSchema(model.Schema): required=True, default="", ) + pdc_desc = schema.TextLine( + title=_("pdc_desc_label", default="Descrizione"), + description=_( + "pdc_desc_help", + default="Descrizione", + ), + required=False, + default="", + max_length=255, + ) pdc_value = schema.TextLine( title=_("pdc_value_label", default="Contatto"), description=_( diff --git a/src/design/plone/contenttypes/upgrades/configure.zcml b/src/design/plone/contenttypes/upgrades/configure.zcml index 3cfeb960..e8fc5e60 100644 --- a/src/design/plone/contenttypes/upgrades/configure.zcml +++ b/src/design/plone/contenttypes/upgrades/configure.zcml @@ -794,5 +794,14 @@ handler=".upgrades.update_types" /> - + + + diff --git a/src/design/plone/contenttypes/upgrades/upgrades.py b/src/design/plone/contenttypes/upgrades/upgrades.py index 18ba85b1..6019d520 100644 --- a/src/design/plone/contenttypes/upgrades/upgrades.py +++ b/src/design/plone/contenttypes/upgrades/upgrades.py @@ -1559,3 +1559,17 @@ def has_empty_prezzo(value): "blocks_layout": {"items": [uid]}, } logger.info(f"Fixed {len(fixed)} Events.") + + +def update_pdc_with_pdc_desc(context): + brains = api.content.find(portal_type="PuntoDiContatto") + logger.info(f"Found {len(brains)} PuntoDiContatto content type") + for brain in brains: + pdc = brain.getObject() + value_punto_contatto = getattr(pdc, "value_punto_contatto", []) + if value_punto_contatto: + for v in value_punto_contatto: + if not v.get("pdc_desc", None): + v["pdc_desc"] = None + logger.info(f"Set pdc_desc for {pdc.absolute_url()}") + logger.info("Ends of update") From d567d83b41dfa949e756d099ac8649ede3a4956e Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Mon, 15 Jan 2024 17:08:12 +0100 Subject: [PATCH 407/487] added UID for all summary obj (#232) * added UID for all summary obj * fixed for callable UID * black --- CHANGES.rst | 4 +++- src/design/plone/contenttypes/restapi/serializers/summary.py | 3 +++ .../contenttypes/restapi/serializers/unita_organizzativa.py | 1 - 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 9d4d57f7..f6bf14f6 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -6,8 +6,10 @@ Changelog - Added description to PDC fields [pnicolli] - Added upgrade step to update PDC fields description +- Added upgrade step to update PDC fields description [lucabel] +- Added UID for all summary obj + [eikichi18] 6.1.9 (2024-01-11) diff --git a/src/design/plone/contenttypes/restapi/serializers/summary.py b/src/design/plone/contenttypes/restapi/serializers/summary.py index da59564c..930c9387 100644 --- a/src/design/plone/contenttypes/restapi/serializers/summary.py +++ b/src/design/plone/contenttypes/restapi/serializers/summary.py @@ -165,6 +165,9 @@ def __call__(self, force_all_metadata=False, force_images=False): res["geolocation"] = extract_geolocation(self.context, res) res["id"] = self.context.id + res["UID"] = ( + self.context.UID() if callable(self.context.UID) else self.context.UID + ) # meta_type res["design_italia_meta_type"] = self.get_design_meta_type() diff --git a/src/design/plone/contenttypes/restapi/serializers/unita_organizzativa.py b/src/design/plone/contenttypes/restapi/serializers/unita_organizzativa.py index aa573de8..38a7a022 100644 --- a/src/design/plone/contenttypes/restapi/serializers/unita_organizzativa.py +++ b/src/design/plone/contenttypes/restapi/serializers/unita_organizzativa.py @@ -133,7 +133,6 @@ def __call__(self, force_images=True, **kwargs): data[field] = getattr(self.context, field, "") data["geolocation"] = self.getGeolocation() - data["UID"] = self.context.UID() get_taxonomy_information("tipologia_organizzazione", self.context, data) From 0fc34feb831cdb49183604edd4fd42a1a3751660 Mon Sep 17 00:00:00 2001 From: Piero Nicolli Date: Tue, 16 Jan 2024 13:08:36 +0100 Subject: [PATCH 408/487] [new] use new widget for event luoghi_correlati (#233) * [new] use new widget for event luoghi_correlati * updated changelog --- CHANGES.rst | 2 ++ src/design/plone/contenttypes/behaviors/luoghi_correlati.py | 3 +++ 2 files changed, 5 insertions(+) diff --git a/CHANGES.rst b/CHANGES.rst index f6bf14f6..d7d2e7ce 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -8,6 +8,8 @@ Changelog [pnicolli] - Added upgrade step to update PDC fields description [lucabel] +- Added new widget for event luoghi_correlati + [pnicolli] - Added UID for all summary obj [eikichi18] diff --git a/src/design/plone/contenttypes/behaviors/luoghi_correlati.py b/src/design/plone/contenttypes/behaviors/luoghi_correlati.py index 0f171c71..65cb1ea8 100644 --- a/src/design/plone/contenttypes/behaviors/luoghi_correlati.py +++ b/src/design/plone/contenttypes/behaviors/luoghi_correlati.py @@ -66,6 +66,9 @@ class ILuoghiCorrelatiEvento(model.Schema): pattern_options={ "selectableTypes": ["Venue"], }, + frontendOptions={ + "widget": "luoghi_correlati_evento", + }, ) model.fieldset( From 46385d15057a3b2a6137a97ea39186895e9fd83f Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Tue, 16 Jan 2024 13:59:30 +0100 Subject: [PATCH 409/487] Preparing release 6.1.10 --- CHANGES.rst | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index d7d2e7ce..4871ff0f 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,7 +1,7 @@ Changelog ========= -6.1.10 (unreleased) +6.1.10 (2024-01-16) ------------------- - Added description to PDC fields diff --git a/setup.py b/setup.py index c0989d8b..187b8d4c 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.1.10.dev0", + version="6.1.10", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 53b014d9ea987ceae8a11bcc60888060367c718d Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Tue, 16 Jan 2024 13:59:43 +0100 Subject: [PATCH 410/487] Back to development: 6.1.11 --- CHANGES.rst | 6 ++++++ setup.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 4871ff0f..27756c9d 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,6 +1,12 @@ Changelog ========= +6.1.11 (unreleased) +------------------- + +- Nothing changed yet. + + 6.1.10 (2024-01-16) ------------------- diff --git a/setup.py b/setup.py index 187b8d4c..032f6104 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.1.10", + version="6.1.11.dev0", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From c58f3cd20aac4f89fcdb2ef28a5b1c9bc719c51f Mon Sep 17 00:00:00 2001 From: Andrea Cecchi Date: Thu, 25 Jan 2024 21:15:47 +0100 Subject: [PATCH 411/487] Add getObjSize info in File field serializer (#236) --- CHANGES.rst | 3 ++- .../contenttypes/restapi/serializers/dxfields.py | 11 +++++++++-- .../tests/test_filefield_view_mode_serializer.py | 5 ++++- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 27756c9d..4306f573 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,7 +4,8 @@ Changelog 6.1.11 (unreleased) ------------------- -- Nothing changed yet. +- Add getObjSize info in File field serializer. + [cekk] 6.1.10 (2024-01-16) diff --git a/src/design/plone/contenttypes/restapi/serializers/dxfields.py b/src/design/plone/contenttypes/restapi/serializers/dxfields.py index 1cf1ab10..133351c6 100644 --- a/src/design/plone/contenttypes/restapi/serializers/dxfields.py +++ b/src/design/plone/contenttypes/restapi/serializers/dxfields.py @@ -5,6 +5,7 @@ from design.plone.contenttypes.interfaces.servizio import IServizio from plone import api from plone.app.contenttypes.utils import replace_link_variables_by_paths +from plone.base.utils import human_readable_size from plone.dexterity.interfaces import IDexterityContent from plone.namedfile.interfaces import INamedFileField from plone.outputfilters.browser.resolveuid import uuidToURL @@ -56,7 +57,11 @@ def __call__(self): @adapter(INamedFileField, IDexterityContent, IDesignPloneContenttypesLayer) class FileFieldViewModeSerializer(DefaultFieldSerializer): - """Ovveride the basic DX serializer to handle the visualize file functionality""" + """ + Ovveride the basic DX serializer to: + - handle the visualize file functionality + - add getObjSize info + """ def __call__(self): namedfile = self.field.get(self.context) @@ -70,10 +75,12 @@ def __call__(self): self.field.__name__, ) ) + size = namedfile.getSize() result = { "filename": namedfile.filename, "content-type": namedfile.contentType, - "size": namedfile.getSize(), + "size": size, + "getObjSize": human_readable_size(size), "download": url, } diff --git a/src/design/plone/contenttypes/tests/test_filefield_view_mode_serializer.py b/src/design/plone/contenttypes/tests/test_filefield_view_mode_serializer.py index c0fb9737..b1532b2d 100644 --- a/src/design/plone/contenttypes/tests/test_filefield_view_mode_serializer.py +++ b/src/design/plone/contenttypes/tests/test_filefield_view_mode_serializer.py @@ -59,5 +59,8 @@ def test_if_visualize_files_true_so_dsiplay(self): commit() response = self.api_session.get(self.modulo.absolute_url()).json() - self.assertIn("@@display-file", response["file_principale"]["download"]) + + def test_human_readable_obj_size_in_data(self): + response = self.api_session.get(self.modulo.absolute_url()).json() + self.assertEqual("1 KB", response["file_principale"]["getObjSize"]) From 60a899bb4dde370fee47b602e62d45d420b618d3 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Fri, 26 Jan 2024 12:09:58 +0100 Subject: [PATCH 412/487] Us51048 modifie old pdc (#235) * fixed upgrade step for add desc to pdc * updated CHANGES --- CHANGES.rst | 2 ++ .../plone/contenttypes/profiles/default/metadata.xml | 2 +- src/design/plone/contenttypes/upgrades/configure.zcml | 7 ++++--- src/design/plone/contenttypes/upgrades/upgrades.py | 4 ++++ 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 4306f573..e0b2077f 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,6 +4,8 @@ Changelog 6.1.11 (unreleased) ------------------- +- Fixed script to update pdc with description + [eikichi18] - Add getObjSize info in File field serializer. [cekk] diff --git a/src/design/plone/contenttypes/profiles/default/metadata.xml b/src/design/plone/contenttypes/profiles/default/metadata.xml index bd728141..24726ddb 100644 --- a/src/design/plone/contenttypes/profiles/default/metadata.xml +++ b/src/design/plone/contenttypes/profiles/default/metadata.xml @@ -1,6 +1,6 @@ - 7021 + 7023 profile-redturtle.bandi:default profile-collective.venue:default diff --git a/src/design/plone/contenttypes/upgrades/configure.zcml b/src/design/plone/contenttypes/upgrades/configure.zcml index e8fc5e60..8e88bee8 100644 --- a/src/design/plone/contenttypes/upgrades/configure.zcml +++ b/src/design/plone/contenttypes/upgrades/configure.zcml @@ -796,12 +796,13 @@ + diff --git a/src/design/plone/contenttypes/upgrades/upgrades.py b/src/design/plone/contenttypes/upgrades/upgrades.py index 6019d520..e3837fd7 100644 --- a/src/design/plone/contenttypes/upgrades/upgrades.py +++ b/src/design/plone/contenttypes/upgrades/upgrades.py @@ -1572,4 +1572,8 @@ def update_pdc_with_pdc_desc(context): if not v.get("pdc_desc", None): v["pdc_desc"] = None logger.info(f"Set pdc_desc for {pdc.absolute_url()}") + + pdc.value_punto_contatto = value_punto_contatto + + commit() logger.info("Ends of update") From f328cb6ada38e96ba89bc844924310747cb4f683 Mon Sep 17 00:00:00 2001 From: Martina Bustacchini <41484878+deodorhunter@users.noreply.github.com> Date: Fri, 26 Jan 2024 14:21:15 +0100 Subject: [PATCH 413/487] US 50839 filtro canale digitale link servizi (#234) * feat: added new indexer, catalog index and query operation for canale_digitale_link field of Servizio CT * chore: changelog * black --------- Co-authored-by: Filippo Campi --- CHANGES.rst | 3 +++ .../plone/contenttypes/indexers/configure.zcml | 4 ++++ .../plone/contenttypes/indexers/servizio.py | 6 ++++++ .../contenttypes/profiles/default/catalog.xml | 3 +++ .../profiles/default/registry/criteria.xml | 14 ++++++++++++++ .../plone/contenttypes/upgrades/configure.zcml | 4 ++++ .../plone/contenttypes/upgrades/upgrades.py | 16 +++++++++++++++- 7 files changed, 49 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index e0b2077f..0171ba0c 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,6 +4,9 @@ Changelog 6.1.11 (unreleased) ------------------- +- Added new indexer, catalog index and query operation for canale_digitale_link field of Servizio CT +[deodorhunter] + - Fixed script to update pdc with description [eikichi18] - Add getObjSize info in File field serializer. diff --git a/src/design/plone/contenttypes/indexers/configure.zcml b/src/design/plone/contenttypes/indexers/configure.zcml index 3160fd2a..bcab069a 100644 --- a/src/design/plone/contenttypes/indexers/configure.zcml +++ b/src/design/plone/contenttypes/indexers/configure.zcml @@ -28,6 +28,10 @@ factory=".servizio.service_venue" name="service_venue" /> + + + + diff --git a/src/design/plone/contenttypes/profiles/default/registry/criteria.xml b/src/design/plone/contenttypes/profiles/default/registry/criteria.xml index 2ca97f8e..32972a24 100644 --- a/src/design/plone/contenttypes/profiles/default/registry/criteria.xml +++ b/src/design/plone/contenttypes/profiles/default/registry/criteria.xml @@ -450,6 +450,20 @@ i18n:translate="" >Metadata + + Link al Canale Digitale + Link al Canale Digitale è compilato o meno + True + False + + plone.app.querystring.operation.boolean.isTrue + plone.app.querystring.operation.boolean.isFalse + + Metadata + + + diff --git a/src/design/plone/contenttypes/upgrades/upgrades.py b/src/design/plone/contenttypes/upgrades/upgrades.py index e3837fd7..709d931b 100644 --- a/src/design/plone/contenttypes/upgrades/upgrades.py +++ b/src/design/plone/contenttypes/upgrades/upgrades.py @@ -1439,7 +1439,9 @@ def to_7010(context): # import the new interface logger.info(f"{colors.DARKCYAN} Setup new interface in the registry {colors.ENDC}") context.runImportStepFromProfile( - "profile-design.plone.contenttypes:fix_syndication", "plone.app.registry", False + "profile-design.plone.contenttypes:fix_syndication", + "plone.app.registry", + False, ) logger.info( f"{colors.DARKCYAN} Set the old values into the new registry records{colors.ENDC}" # noqa @@ -1577,3 +1579,15 @@ def update_pdc_with_pdc_desc(context): commit() logger.info("Ends of update") + + +def add_canale_digitale_link_index(context): + update_catalog(context) + update_registry(context) + brains = api.content.find(portal_type="Servizio") + logger.info(f"Found {len(brains)} Servizio content type to reindex") + for brain in brains: + service = brain.getObject() + service.reindexObject(idxs=["canale_digitale_link"]) + logger.info(f"Reindexed {service.absolute_url()}") + logger.info("End of update, added index canale_digitale_link") From 8019d362eb5d30c07ac4a47c21bb61916d0f6c3d Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Mon, 29 Jan 2024 14:57:07 +0100 Subject: [PATCH 414/487] Preparing release 6.1.11 --- CHANGES.rst | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 0171ba0c..b29819e6 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,7 +1,7 @@ Changelog ========= -6.1.11 (unreleased) +6.1.11 (2024-01-29) ------------------- - Added new indexer, catalog index and query operation for canale_digitale_link field of Servizio CT diff --git a/setup.py b/setup.py index 032f6104..94af5d76 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.1.11.dev0", + version="6.1.11", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 841905814fce6105fa4757643e9e5e970b1afdb6 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Mon, 29 Jan 2024 14:57:55 +0100 Subject: [PATCH 415/487] Back to development: 6.1.12 --- CHANGES.rst | 6 ++++++ setup.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index b29819e6..a3a1e92b 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,6 +1,12 @@ Changelog ========= +6.1.12 (unreleased) +------------------- + +- Nothing changed yet. + + 6.1.11 (2024-01-29) ------------------- diff --git a/setup.py b/setup.py index 94af5d76..1780e17d 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.1.11", + version="6.1.12.dev0", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 75e0822db7f9a3827fbe19ef6f34b7d7775673bc Mon Sep 17 00:00:00 2001 From: Andrea Cecchi Date: Fri, 2 Feb 2024 10:34:02 +0100 Subject: [PATCH 416/487] remove commit in upgrade-step (#239) --- CHANGES.rst | 3 ++- src/design/plone/contenttypes/upgrades/upgrades.py | 2 -- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index a3a1e92b..1696e49f 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,7 +4,8 @@ Changelog 6.1.12 (unreleased) ------------------- -- Nothing changed yet. +- Remove un-needed commit in upgrade-step. + [cekk] 6.1.11 (2024-01-29) diff --git a/src/design/plone/contenttypes/upgrades/upgrades.py b/src/design/plone/contenttypes/upgrades/upgrades.py index 709d931b..20eb5d7e 100644 --- a/src/design/plone/contenttypes/upgrades/upgrades.py +++ b/src/design/plone/contenttypes/upgrades/upgrades.py @@ -1576,8 +1576,6 @@ def update_pdc_with_pdc_desc(context): logger.info(f"Set pdc_desc for {pdc.absolute_url()}") pdc.value_punto_contatto = value_punto_contatto - - commit() logger.info("Ends of update") From 5d769f657db07bf9e4297c0eb26271afb21e5bb6 Mon Sep 17 00:00:00 2001 From: Andrea Cecchi Date: Fri, 2 Feb 2024 10:35:08 +0100 Subject: [PATCH 417/487] Make footer columns auto-generation optional (#238) * initial work * Add new flag in settings needed to choose to show or not auto-generated footer columns and Customize @navigation endpoint to expose also the new flag for frontend * zpretty * update readme --- CHANGES.rst | 5 +- README.md | 9 +- .../contenttypes/controlpanels/settings.py | 10 +++ .../restapi/services/configure.zcml | 4 +- .../restapi/services/navigation/__init__.py | 0 .../services/navigation/configure.zcml | 22 +++++ .../restapi/services/navigation/get.py | 29 +++++++ .../tests/test_custom_service_navigation.py | 82 +++++++++++++++++++ .../contenttypes/upgrades/configure.zcml | 11 ++- 9 files changed, 167 insertions(+), 5 deletions(-) create mode 100644 src/design/plone/contenttypes/restapi/services/navigation/__init__.py create mode 100644 src/design/plone/contenttypes/restapi/services/navigation/configure.zcml create mode 100644 src/design/plone/contenttypes/restapi/services/navigation/get.py create mode 100644 src/design/plone/contenttypes/tests/test_custom_service_navigation.py diff --git a/CHANGES.rst b/CHANGES.rst index 1696e49f..aaf37836 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -18,7 +18,10 @@ Changelog [eikichi18] - Add getObjSize info in File field serializer. [cekk] - +- Add new flag in settings needed to choose to show or not auto-generated footer columns. + [cekk] +- Customize @navigation endpoint to expose also the new flag for frontend. + [cekk] 6.1.10 (2024-01-16) ------------------- diff --git a/README.md b/README.md index c1580770..ab5124c1 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ - [Design Plone Content-types](#design-plone-content-types) - [Features](#features) -- [Compatibilità](#compatibilit%C3%A0) +- [Compatibilità](#compatibilità) - [Tipi di contenuto](#tipi-di-contenuto) - [Elenco tipi implementati](#elenco-tipi-implementati) - [Bando](#bando) @@ -30,10 +30,11 @@ - [Campi indicizzati nel SearchableText](#campi-indicizzati-nel-searchabletext-2) - [Servizio](#servizio) - [Campi indicizzati nel SearchableText](#campi-indicizzati-nel-searchabletext-3) - - [Unità Organizzativa](#unit%C3%A0-organizzativa) + - [Unità Organizzativa](#unità-organizzativa) - [Campi indicizzati nel SearchableText](#campi-indicizzati-nel-searchabletext-4) - [Pannello di controllo](#pannello-di-controllo) - [Gestione modulistica](#gestione-modulistica) +- [Viste verifica contentuti](#viste-verifica-contentuti) - [Data di modifica](#data-di-modifica) - [Endpoint restapi](#endpoint-restapi) - [Customizzazione dati relation field](#customizzazione-dati-relation-field) @@ -421,6 +422,10 @@ Endpoint ed expansion per la modulistica. Nei content-type CartellaModulistica, tra i vari expansion c'è anche `@modulistica_items`. Questo è utile per la vista di frontend, in quanto se richiamato, ritorna la struttura di dati da mostrare in visualizzazione. +## @navigation + +Endpoint customizzato da plone.restapi per esporre anche il valore show_in_footer per decidere se disegnare o meno le colonne dinamiche nel footer. + # Installazione Questo prodotto non è stato pensato per funzionare da solo, ma fa parte della suite "design.plone". diff --git a/src/design/plone/contenttypes/controlpanels/settings.py b/src/design/plone/contenttypes/controlpanels/settings.py index 60beed41..365b8135 100644 --- a/src/design/plone/contenttypes/controlpanels/settings.py +++ b/src/design/plone/contenttypes/controlpanels/settings.py @@ -88,6 +88,16 @@ class IDesignPloneSettings(Interface): default=True, required=False, ) + show_dynamic_folders_in_footer = Bool( + title=_("show_dynamic_folders_in_footer_label", default="Footer dinamico"), + description=_( + "show_dynamic_folders_in_footer_help", + default="Se selezionato, il footer verrà popolato automaticamente " + "con i contenuti di primo livello non esclusi dalla navigazione.", + ), + default=True, + required=False, + ) class DesignPloneControlPanelForm(RegistryEditForm): diff --git a/src/design/plone/contenttypes/restapi/services/configure.zcml b/src/design/plone/contenttypes/restapi/services/configure.zcml index 06d609df..e93dcc9d 100644 --- a/src/design/plone/contenttypes/restapi/services/configure.zcml +++ b/src/design/plone/contenttypes/restapi/services/configure.zcml @@ -6,9 +6,11 @@ + - + + + + + + + + diff --git a/src/design/plone/contenttypes/restapi/services/navigation/get.py b/src/design/plone/contenttypes/restapi/services/navigation/get.py new file mode 100644 index 00000000..70e42e12 --- /dev/null +++ b/src/design/plone/contenttypes/restapi/services/navigation/get.py @@ -0,0 +1,29 @@ +from design.plone.contenttypes.controlpanels.settings import IDesignPloneSettings +from design.plone.contenttypes.interfaces import IDesignPloneContenttypesLayer +from plone import api +from plone.restapi.interfaces import IExpandableElement +from plone.restapi.services import Service +from plone.restapi.services.navigation.get import Navigation as BaseNavigation +from zope.component import adapter +from zope.interface import implementer +from zope.interface import Interface + + +@implementer(IExpandableElement) +@adapter(Interface, IDesignPloneContenttypesLayer) +class Navigation(BaseNavigation): + def __call__(self, expand=False): + result = super().__call__(expand=expand) + show_dynamic_folders_in_footer = api.portal.get_registry_record( + "show_dynamic_folders_in_footer", + interface=IDesignPloneSettings, + default=False, + ) + result["navigation"]["show_in_footer"] = show_dynamic_folders_in_footer + return result + + +class NavigationGet(Service): + def reply(self): + navigation = Navigation(self.context, self.request) + return navigation(expand=True)["navigation"] diff --git a/src/design/plone/contenttypes/tests/test_custom_service_navigation.py b/src/design/plone/contenttypes/tests/test_custom_service_navigation.py new file mode 100644 index 00000000..014ad580 --- /dev/null +++ b/src/design/plone/contenttypes/tests/test_custom_service_navigation.py @@ -0,0 +1,82 @@ +# -*- coding: utf-8 -*- +from design.plone.contenttypes.controlpanels.settings import IDesignPloneSettings +from design.plone.contenttypes.testing import ( + DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING, +) +from plone import api +from plone.app.testing import setRoles +from plone.app.testing import SITE_OWNER_NAME +from plone.app.testing import SITE_OWNER_PASSWORD +from plone.app.testing import TEST_USER_ID +from plone.dexterity.utils import createContentInContainer +from plone.restapi.testing import RelativeSession +from transaction import commit + +import unittest + + +class CustomNavigationTest(unittest.TestCase): + layer = DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING + + def setUp(self): + self.app = self.layer["app"] + self.portal = self.layer["portal"] + self.portal_url = self.portal.absolute_url() + self.api_session = RelativeSession(self.portal_url) + self.api_session.headers.update({"Accept": "application/json"}) + self.api_session.auth = (SITE_OWNER_NAME, SITE_OWNER_PASSWORD) + setRoles(self.portal, TEST_USER_ID, ["Manager"]) + + self.folder = createContentInContainer( + self.portal, "Folder", id="folder", title="Some Folder" + ) + self.folder2 = createContentInContainer( + self.portal, "Folder", id="folder2", title="Some Folder 2" + ) + self.subfolder1 = createContentInContainer( + self.folder, "Folder", id="subfolder1", title="SubFolder 1" + ) + self.subfolder2 = createContentInContainer( + self.folder, "Folder", id="subfolder2", title="SubFolder 2" + ) + self.thirdlevelfolder = createContentInContainer( + self.subfolder1, + "Folder", + id="thirdlevelfolder", + title="Third Level Folder", + ) + self.fourthlevelfolder = createContentInContainer( + self.thirdlevelfolder, + "Folder", + id="fourthlevelfolder", + title="Fourth Level Folder", + ) + createContentInContainer(self.folder, "Document", id="doc1", title="A document") + commit() + + def tearDown(self): + self.api_session.close() + + def test_return_show_in_footer_info_based_on_registry(self): + # by default is True + response = self.api_session.get( + "/@navigation", params={"expand.navigation.depth": 2} + ).json() + + self.assertIn("show_in_footer", response) + self.assertTrue(response["show_in_footer"]) + + # change it + api.portal.set_registry_record( + "show_dynamic_folders_in_footer", + False, + interface=IDesignPloneSettings, + ) + commit() + + response = self.api_session.get( + "/@navigation", params={"expand.navigation.depth": 2} + ).json() + + self.assertIn("show_in_footer", response) + self.assertFalse(response["show_in_footer"]) diff --git a/src/design/plone/contenttypes/upgrades/configure.zcml b/src/design/plone/contenttypes/upgrades/configure.zcml index f824c5c3..f7c06cd8 100644 --- a/src/design/plone/contenttypes/upgrades/configure.zcml +++ b/src/design/plone/contenttypes/upgrades/configure.zcml @@ -808,5 +808,14 @@ handler=".upgrades.add_canale_digitale_link_index" /> - + + + From 57239d42e1f2c571b85a4a21c4803eac610b594b Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Tue, 6 Feb 2024 12:32:32 +0100 Subject: [PATCH 418/487] Preparing release 6.1.12 --- CHANGES.rst | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index aaf37836..ddf53243 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,7 +1,7 @@ Changelog ========= -6.1.12 (unreleased) +6.1.12 (2024-02-06) ------------------- - Remove un-needed commit in upgrade-step. diff --git a/setup.py b/setup.py index 1780e17d..dba40f06 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.1.12.dev0", + version="6.1.12", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 72aa179af162023ec5314cc13e69a19d8e106c0e Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Tue, 6 Feb 2024 12:32:47 +0100 Subject: [PATCH 419/487] Back to development: 6.1.13 --- CHANGES.rst | 6 ++++++ setup.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index ddf53243..7d4bc397 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,6 +1,12 @@ Changelog ========= +6.1.13 (unreleased) +------------------- + +- Nothing changed yet. + + 6.1.12 (2024-02-06) ------------------- diff --git a/setup.py b/setup.py index dba40f06..de31b7cd 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.1.12", + version="6.1.13.dev0", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From c9739e7eee94a365340444e298eada699fad2274 Mon Sep 17 00:00:00 2001 From: Andrea Cecchi Date: Thu, 8 Feb 2024 10:49:44 +0100 Subject: [PATCH 420/487] Handle missing new footer navigation option in registry entry (#240) --- CHANGES.rst | 3 ++- .../contenttypes/restapi/services/navigation/get.py | 13 ++++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 7d4bc397..3001c818 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,7 +4,8 @@ Changelog 6.1.13 (unreleased) ------------------- -- Nothing changed yet. +- Handle missing `show_dynamic_folders_in_footer` in registry entry. + [cekk] 6.1.12 (2024-02-06) diff --git a/src/design/plone/contenttypes/restapi/services/navigation/get.py b/src/design/plone/contenttypes/restapi/services/navigation/get.py index 70e42e12..73550281 100644 --- a/src/design/plone/contenttypes/restapi/services/navigation/get.py +++ b/src/design/plone/contenttypes/restapi/services/navigation/get.py @@ -14,11 +14,14 @@ class Navigation(BaseNavigation): def __call__(self, expand=False): result = super().__call__(expand=expand) - show_dynamic_folders_in_footer = api.portal.get_registry_record( - "show_dynamic_folders_in_footer", - interface=IDesignPloneSettings, - default=False, - ) + try: + show_dynamic_folders_in_footer = api.portal.get_registry_record( + "show_dynamic_folders_in_footer", + interface=IDesignPloneSettings, + default=True, + ) + except KeyError: + show_dynamic_folders_in_footer = True result["navigation"]["show_in_footer"] = show_dynamic_folders_in_footer return result From 054d7d3db656d0a39896057f3e18afa5bbdcb41b Mon Sep 17 00:00:00 2001 From: Piero Nicolli Date: Thu, 8 Feb 2024 10:52:48 +0100 Subject: [PATCH 421/487] Preparing release 6.1.13 --- CHANGES.rst | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 3001c818..1010ecc5 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,7 +1,7 @@ Changelog ========= -6.1.13 (unreleased) +6.1.13 (2024-02-08) ------------------- - Handle missing `show_dynamic_folders_in_footer` in registry entry. diff --git a/setup.py b/setup.py index de31b7cd..980ceefb 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.1.13.dev0", + version="6.1.13", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 903161aaf71670f497b195e62a7ebe173675150e Mon Sep 17 00:00:00 2001 From: Piero Nicolli Date: Thu, 8 Feb 2024 10:53:09 +0100 Subject: [PATCH 422/487] Back to development: 6.1.14 --- CHANGES.rst | 6 ++++++ setup.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 1010ecc5..c0d5ecc2 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,6 +1,12 @@ Changelog ========= +6.1.14 (unreleased) +------------------- + +- Nothing changed yet. + + 6.1.13 (2024-02-08) ------------------- diff --git a/setup.py b/setup.py index 980ceefb..56dd1887 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.1.13", + version="6.1.14.dev0", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 02afdaf920a597a525a66323f8cd82fc013c4eff Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Tue, 20 Feb 2024 10:15:33 +0100 Subject: [PATCH 423/487] updated CHANGES + fixed typo in update_note field description (#245) --- CHANGES.rst | 3 ++- src/design/plone/contenttypes/behaviors/update_note.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index c0d5ecc2..8c868dfe 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,7 +4,8 @@ Changelog 6.1.14 (unreleased) ------------------- -- Nothing changed yet. +- Fixed typo in update_note field description. + [eikichi18] 6.1.13 (2024-02-08) diff --git a/src/design/plone/contenttypes/behaviors/update_note.py b/src/design/plone/contenttypes/behaviors/update_note.py index 113fe7f1..9e1d6f5b 100644 --- a/src/design/plone/contenttypes/behaviors/update_note.py +++ b/src/design/plone/contenttypes/behaviors/update_note.py @@ -18,7 +18,7 @@ class IUpdateNote(model.Schema): description=_( "help_update_note", default="Inserisci una nota per indicare che il contenuto corrente è stato aggiornato." # noqa - "Questo testo può essere visualizzato nei blocchi elenco con determinati layout per informare " # noqa + " Questo testo può essere visualizzato nei blocchi elenco con determinati layout per informare " # noqa "gli utenti che un determinato contenuto è stato aggiornato. " "Ad esempio se in un bando sono stati aggiunti dei documenti.", ), From 0c69406000d788b5e376af11c1a507614376f22f Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Tue, 20 Feb 2024 11:01:22 +0100 Subject: [PATCH 424/487] update description of sede field in UnitaOrganizzativa CT (#241) * updated CHANGES + update description of sede field in UnitaOrganizzativa CT --- CHANGES.rst | 1 + .../plone/contenttypes/interfaces/unita_organizzativa.py | 6 ++---- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 8c868dfe..d551913c 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,6 +4,7 @@ Changelog 6.1.14 (unreleased) ------------------- +- Change description for field sede in UnitaOrganizzativa CT. - Fixed typo in update_note field description. [eikichi18] diff --git a/src/design/plone/contenttypes/interfaces/unita_organizzativa.py b/src/design/plone/contenttypes/interfaces/unita_organizzativa.py index 12e1bfad..b54570f1 100644 --- a/src/design/plone/contenttypes/interfaces/unita_organizzativa.py +++ b/src/design/plone/contenttypes/interfaces/unita_organizzativa.py @@ -97,10 +97,8 @@ class IUnitaOrganizzativa(model.Schema, IDesignPloneContentType): description=_( "sede_help", default="Seleziona il Luogo in cui questa struttura ha sede. " - "Se non è presente un contenuto di tipo Luogo a cui far " - "riferimento, puoi compilare i campi seguenti. Se selezioni un " - "Luogo, puoi usare comunque i campi seguenti per sovrascrivere " - "alcune informazioni.", + "Se non è presente creare il Luogo nella sezione dedicata " + "nell'alberatura del sito.", ), value_type=RelationChoice( title=_("Sede"), vocabulary="plone.app.vocabularies.Catalog" From 3801755c9b3adcbf4aa543676bbdccb63d3dfaec Mon Sep 17 00:00:00 2001 From: Andrea Cecchi Date: Tue, 20 Feb 2024 11:02:51 +0100 Subject: [PATCH 425/487] Fix news item view to not break on classic plone (#243) * set base views to ct with blocks * only set News view --- CHANGES.rst | 2 ++ ...contenttypes.browser.templates.newsitem.pt | 30 ------------------- .../profiles/default/metadata.xml | 2 +- .../profiles/default/types/Document.xml | 1 + .../profiles/default/types/Event.xml | 1 + .../profiles/default/types/News_Item.xml | 5 ++++ .../contenttypes/upgrades/configure.zcml | 10 +++++++ .../plone/contenttypes/upgrades/upgrades.py | 7 +++++ 8 files changed, 27 insertions(+), 31 deletions(-) delete mode 100644 src/design/plone/contenttypes/browser/overrides/plone.app.contenttypes.browser.templates.newsitem.pt diff --git a/CHANGES.rst b/CHANGES.rst index d551913c..0b2d5189 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,6 +4,8 @@ Changelog 6.1.14 (unreleased) ------------------- +- Set base view to News Item, to do not break on Classic Plone. + [cekk] - Change description for field sede in UnitaOrganizzativa CT. - Fixed typo in update_note field description. [eikichi18] diff --git a/src/design/plone/contenttypes/browser/overrides/plone.app.contenttypes.browser.templates.newsitem.pt b/src/design/plone/contenttypes/browser/overrides/plone.app.contenttypes.browser.templates.newsitem.pt deleted file mode 100644 index 53d14271..00000000 --- a/src/design/plone/contenttypes/browser/overrides/plone.app.contenttypes.browser.templates.newsitem.pt +++ /dev/null @@ -1,30 +0,0 @@ - - - - - -
-
-
- - - diff --git a/src/design/plone/contenttypes/profiles/default/metadata.xml b/src/design/plone/contenttypes/profiles/default/metadata.xml index 24726ddb..02602d3b 100644 --- a/src/design/plone/contenttypes/profiles/default/metadata.xml +++ b/src/design/plone/contenttypes/profiles/default/metadata.xml @@ -1,6 +1,6 @@ - 7023 + 7031 profile-redturtle.bandi:default profile-collective.venue:default diff --git a/src/design/plone/contenttypes/profiles/default/types/Document.xml b/src/design/plone/contenttypes/profiles/default/types/Document.xml index 56036477..30e528d3 100644 --- a/src/design/plone/contenttypes/profiles/default/types/Document.xml +++ b/src/design/plone/contenttypes/profiles/default/types/Document.xml @@ -4,6 +4,7 @@ name="Document" i18n:domain="plone" > + diff --git a/src/design/plone/contenttypes/profiles/default/types/Event.xml b/src/design/plone/contenttypes/profiles/default/types/Event.xml index 412101c9..5edb1552 100644 --- a/src/design/plone/contenttypes/profiles/default/types/Event.xml +++ b/src/design/plone/contenttypes/profiles/default/types/Event.xml @@ -14,6 +14,7 @@ + diff --git a/src/design/plone/contenttypes/profiles/default/types/News_Item.xml b/src/design/plone/contenttypes/profiles/default/types/News_Item.xml index 1c0f6d9b..0da6ce08 100644 --- a/src/design/plone/contenttypes/profiles/default/types/News_Item.xml +++ b/src/design/plone/contenttypes/profiles/default/types/News_Item.xml @@ -17,6 +17,11 @@ + view + + + + diff --git a/src/design/plone/contenttypes/upgrades/configure.zcml b/src/design/plone/contenttypes/upgrades/configure.zcml index f7c06cd8..cbb18bef 100644 --- a/src/design/plone/contenttypes/upgrades/configure.zcml +++ b/src/design/plone/contenttypes/upgrades/configure.zcml @@ -818,4 +818,14 @@ handler=".upgrades.update_registry" /> + + + diff --git a/src/design/plone/contenttypes/upgrades/upgrades.py b/src/design/plone/contenttypes/upgrades/upgrades.py index 20eb5d7e..bffa9c19 100644 --- a/src/design/plone/contenttypes/upgrades/upgrades.py +++ b/src/design/plone/contenttypes/upgrades/upgrades.py @@ -1589,3 +1589,10 @@ def add_canale_digitale_link_index(context): service.reindexObject(idxs=["canale_digitale_link"]) logger.info(f"Reindexed {service.absolute_url()}") logger.info("End of update, added index canale_digitale_link") + + +def to_7031(context): + portal_types = api.portal.get_tool(name="portal_types") + for ptype in ["News Item"]: + portal_types[ptype].default_view = "view" + portal_types[ptype].view_methods = ["view"] From 8695c3210d6c6ef040d2a506eb71c84b0d004a02 Mon Sep 17 00:00:00 2001 From: Andrea Cecchi Date: Tue, 20 Feb 2024 11:08:07 +0100 Subject: [PATCH 426/487] Fix in @scadenziario endpoint: return future events if afterToday criteria is set (#242) --- CHANGES.rst | 3 + .../restapi/services/scadenziario/post.py | 8 +- .../tests/test_service_scadenziario.py | 89 +++++++++++++++++++ 3 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 src/design/plone/contenttypes/tests/test_service_scadenziario.py diff --git a/CHANGES.rst b/CHANGES.rst index 0b2d5189..5f08e5fe 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,6 +4,8 @@ Changelog 6.1.14 (unreleased) ------------------- +- Fix in @scadenziario endpoint: return future events if afterToday criteria is set. + [cekk] - Set base view to News Item, to do not break on Classic Plone. [cekk] - Change description for field sede in UnitaOrganizzativa CT. @@ -11,6 +13,7 @@ Changelog [eikichi18] + 6.1.13 (2024-02-08) ------------------- diff --git a/src/design/plone/contenttypes/restapi/services/scadenziario/post.py b/src/design/plone/contenttypes/restapi/services/scadenziario/post.py index 07ba6299..e19720c1 100644 --- a/src/design/plone/contenttypes/restapi/services/scadenziario/post.py +++ b/src/design/plone/contenttypes/restapi/services/scadenziario/post.py @@ -158,7 +158,13 @@ def reply(self): if "start" in query_for_catalog: start = query_for_catalog["start"]["query"] if "end" in query_for_catalog: - end = query_for_catalog["end"]["query"] + if query_for_catalog["end"].get("range", "") != "min": + # per esempio, è impostato il filtro "con fine evento da domani". + # se impostiamo un'end (la data di domani), poi nella generazione delle ricorrenze, + # vengono scartati tutti gli eventi che hanno una data di inizio nel futuro + # (https://github.com/plone/plone.event/blob/master/plone/event/recurrence.py#L141) + # perché la data della ricorrenza è maggiore di "until", che è quello che qui inviamo come end. + end = query_for_catalog["end"]["query"] expanded_events = self.expand_events(events, 3, start, end) all_results = not_events + expanded_events diff --git a/src/design/plone/contenttypes/tests/test_service_scadenziario.py b/src/design/plone/contenttypes/tests/test_service_scadenziario.py new file mode 100644 index 00000000..bdc56425 --- /dev/null +++ b/src/design/plone/contenttypes/tests/test_service_scadenziario.py @@ -0,0 +1,89 @@ +# -*- coding: utf-8 -*- +from datetime import datetime +from datetime import timedelta +from design.plone.contenttypes.testing import ( + DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING, +) +from plone import api +from plone.app.testing import setRoles +from plone.app.testing import SITE_OWNER_NAME +from plone.app.testing import SITE_OWNER_PASSWORD +from plone.app.testing import TEST_USER_ID +from plone.restapi.testing import RelativeSession +from transaction import commit + +import unittest + + +class ScadenziarioTest(unittest.TestCase): + layer = DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING + + def setUp(self): + self.app = self.layer["app"] + self.portal = self.layer["portal"] + self.request = self.layer["request"] + self.portal_url = self.portal.absolute_url() + + self.api_session = RelativeSession(self.portal_url) + self.api_session.headers.update({"Accept": "application/json"}) + self.api_session.auth = (SITE_OWNER_NAME, SITE_OWNER_PASSWORD) + + setRoles(self.portal, TEST_USER_ID, ["Manager"]) + + commit() + + def tearDown(self): + self.api_session.close() + + def test_return_future_events_if_query_is_end_after_today(self): + now = datetime.now() + + # past event + api.content.create( + container=self.portal, + type="Event", + title="Past event", + start=now.replace(hour=8) + timedelta(days=-2), + end=now.replace(hour=18) + timedelta(days=-2), + ) + + future_event_1 = api.content.create( + container=self.portal, + type="Event", + title="Future event", + start=now.replace(hour=8) + timedelta(days=2), + end=now.replace(hour=18) + timedelta(days=4), + ) + future_event_2 = api.content.create( + container=self.portal, + type="Event", + title="Future event that starts in the past", + start=now.replace(hour=8) + timedelta(days=-4), + end=now.replace(hour=18) + timedelta(days=4), + ) + + commit() + + response = self.api_session.post( + f"{self.portal_url}/@scadenziario", + json={ + "query": [ + { + "i": "end", + "o": "plone.app.querystring.operation.date.afterToday", + "v": "", + } + ] + }, + ).json() + self.assertEqual(len(response["items"]), 2) + + # results are in asc order + self.assertEqual( + response["items"][0], + future_event_2.start.strftime("%Y/%m/%d"), + ) + self.assertEqual( + response["items"][1], + future_event_1.start.strftime("%Y/%m/%d"), + ) From 20bcdab869db46ff103b97cf7d7eee8278947a73 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Tue, 20 Feb 2024 11:23:10 +0100 Subject: [PATCH 427/487] Preparing release 6.1.14 --- CHANGES.rst | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 5f08e5fe..a7f4777e 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,7 +1,7 @@ Changelog ========= -6.1.14 (unreleased) +6.1.14 (2024-02-20) ------------------- - Fix in @scadenziario endpoint: return future events if afterToday criteria is set. diff --git a/setup.py b/setup.py index 56dd1887..7926b850 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.1.14.dev0", + version="6.1.14", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 96a9e8ade686a5a8bbb2307d9170871199ce4c46 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Tue, 20 Feb 2024 11:23:37 +0100 Subject: [PATCH 428/487] Back to development: 6.1.15 --- CHANGES.rst | 6 ++++++ setup.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index a7f4777e..23247d69 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,6 +1,12 @@ Changelog ========= +6.1.15 (unreleased) +------------------- + +- Nothing changed yet. + + 6.1.14 (2024-02-20) ------------------- diff --git a/setup.py b/setup.py index 7926b850..b487d5c3 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.1.14", + version="6.1.15.dev0", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 1bfdba446a1b1f6571a1bef6f264e42d9a059ea9 Mon Sep 17 00:00:00 2001 From: Andrea Cecchi Date: Tue, 5 Mar 2024 11:50:11 +0100 Subject: [PATCH 429/487] Code improvements (#247) * improved tests * make package more extensible * Do not show fieldsets with no visible fields in @types endpoint. * lower log level * fix test * Add getObjSize info in File field serializer * add collective.volto.enhancedlinks dependency (needed for slate integration) * initial work * remove customizations * Add new flag in settings needed to choose to show or not auto-generated footer columns and Customize @navigation endpoint to expose also the new flag for frontend * zpretty * update readme * add info also for image fields * fix imports * enhance Bandi serializer for enhancedlinks features * fix check * Fix in @scadenziario endpoint: return future events if afterToday criteria is set * fix upgrade-steps * removed unused logger * fix tests * standardize subfolders creation in events * update changelog * zpretty --------- Co-authored-by: Mauro Amico --- CHANGES.rst | 11 +- base.cfg | 1 + setup.py | 1 + .../contenttypes/adapters/configure.zcml | 1 + .../contenttypes/behaviors/configure.zcml | 8 - src/design/plone/contenttypes/events/bando.py | 19 -- .../plone/contenttypes/events/common.py | 169 +++++++++++ .../plone/contenttypes/events/configure.zcml | 56 +--- .../plone/contenttypes/events/documento.py | 36 --- .../plone/contenttypes/events/evento.py | 85 ------ .../plone/contenttypes/events/incarico.py | 32 -- src/design/plone/contenttypes/events/luogo.py | 30 -- .../events/notizie_e_comunicati_stampa.py | 33 --- .../plone/contenttypes/events/persona.py | 52 ---- .../plone/contenttypes/events/pratica.py | 20 -- .../plone/contenttypes/events/servizio.py | 29 -- .../events/unita_organizzativa.py | 35 --- .../profiles/default/metadata.xml | 3 +- .../profiles/default/types/Modulo.xml | 1 + .../contenttypes/restapi/serializers/bando.py | 5 + .../restapi/serializers/configure.zcml | 1 + .../restapi/serializers/dxcontent.py | 59 ++-- .../restapi/serializers/dxfields.py | 28 +- .../restapi/serializers/summary.py | 5 - .../restapi/services/types/get.py | 20 +- src/design/plone/contenttypes/testing.py | 3 + .../plone/contenttypes/tests/test_ct_bando.py | 174 +++++++++++ .../tests/test_ct_cartella_modulistica.py | 135 ++++++++- .../contenttypes/tests/test_ct_document.py | 160 +++++++++- .../contenttypes/tests/test_ct_documento.py | 184 +++++++++++- .../tests/test_ct_documento_personale.py | 39 --- .../plone/contenttypes/tests/test_ct_event.py | 276 +++++++++++++++++- .../plone/contenttypes/tests/test_ct_luogo.py | 213 +++++++++++++- .../contenttypes/tests/test_ct_modulo.py | 109 ++++++- .../plone/contenttypes/tests/test_ct_news.py | 154 +++++++++- .../tests/test_ct_pagina_argomento.py | 147 +++++++++- .../contenttypes/tests/test_ct_persona.py | 174 +++++++++-- .../contenttypes/tests/test_ct_servizio.py | 273 ++++++++++++++++- .../tests/test_ct_unita_organizzativa.py | 269 ++++++++++++++--- ...py => test_filefield_custom_serializer.py} | 9 +- .../contenttypes/upgrades/configure.zcml | 10 + .../plone/contenttypes/upgrades/upgrades.py | 20 ++ .../contenttypes/vocabularies/configure.zcml | 5 - .../vocabularies/reference_vocabularies.py | 2 +- .../vocabularies/tags_vocabulary.py | 131 +++++---- 45 files changed, 2515 insertions(+), 712 deletions(-) delete mode 100644 src/design/plone/contenttypes/events/bando.py delete mode 100644 src/design/plone/contenttypes/events/documento.py delete mode 100644 src/design/plone/contenttypes/events/evento.py delete mode 100644 src/design/plone/contenttypes/events/luogo.py delete mode 100644 src/design/plone/contenttypes/events/notizie_e_comunicati_stampa.py delete mode 100644 src/design/plone/contenttypes/events/persona.py delete mode 100644 src/design/plone/contenttypes/events/pratica.py delete mode 100644 src/design/plone/contenttypes/events/servizio.py delete mode 100644 src/design/plone/contenttypes/events/unita_organizzativa.py delete mode 100644 src/design/plone/contenttypes/tests/test_ct_documento_personale.py rename src/design/plone/contenttypes/tests/{test_filefield_view_mode_serializer.py => test_filefield_custom_serializer.py} (83%) diff --git a/CHANGES.rst b/CHANGES.rst index 23247d69..bc479736 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,8 +4,14 @@ Changelog 6.1.15 (unreleased) ------------------- -- Nothing changed yet. - +- Remove unused behavior (design.plone.contenttypes.behavior.geolocation_uo). + [cekk] +- Standardize subfolders creations in events. + [cekk] +- Do not return a fieldset if it has all fields hidden (maybe after a schema tweak). + [cekk] +- Improve types test for their schema, required fields, fieldsets. + [cekk] 6.1.14 (2024-02-20) ------------------- @@ -19,7 +25,6 @@ Changelog [eikichi18] - 6.1.13 (2024-02-08) ------------------- diff --git a/base.cfg b/base.cfg index 7aaa4b1b..20b969de 100644 --- a/base.cfg +++ b/base.cfg @@ -143,3 +143,4 @@ design.plone.contenttypes = #redturtle.volto = git https://github.com/RedTurtle/redturtle.volto.git pushurl=git@github.com:RedTurtle/redturtle.volto.git #redturtle.bandi = git https://github.com/RedTurtle/redturtle.bandi.git pushurl=git@github.com:RedTurtle/redturtle.bandi.git #plone.restapi = git https://github.com/plone/plone.restapi.git +collective.volto.enhancedlinks = git https://github.com/RegioneER/collective.volto.enhancedlinks.git pushurl=git@github.com:RegioneER/collective.volto.enhancedlinks.git branch=main diff --git a/setup.py b/setup.py index b487d5c3..02c87c81 100644 --- a/setup.py +++ b/setup.py @@ -66,6 +66,7 @@ "z3c.unconfigure", "eea.api.taxonomy", "openpyxl", + "collective.volto.enhancedlinks", ], extras_require={ "test": [ diff --git a/src/design/plone/contenttypes/adapters/configure.zcml b/src/design/plone/contenttypes/adapters/configure.zcml index 8f7a3224..7e7188fd 100644 --- a/src/design/plone/contenttypes/adapters/configure.zcml +++ b/src/design/plone/contenttypes/adapters/configure.zcml @@ -20,4 +20,5 @@ factory=".searchabletext_indexers.TextBlockSearchableText" name="text" /> + diff --git a/src/design/plone/contenttypes/behaviors/configure.zcml b/src/design/plone/contenttypes/behaviors/configure.zcml index 9d00c5cb..4cfdb19b 100644 --- a/src/design/plone/contenttypes/behaviors/configure.zcml +++ b/src/design/plone/contenttypes/behaviors/configure.zcml @@ -261,14 +261,6 @@ provides=".contatti.IContattiEvent" marker=".contatti.IContattiEvent" /> - - - - - - - - - - - - + diff --git a/src/design/plone/contenttypes/events/documento.py b/src/design/plone/contenttypes/events/documento.py deleted file mode 100644 index e8cc971d..00000000 --- a/src/design/plone/contenttypes/events/documento.py +++ /dev/null @@ -1,36 +0,0 @@ -# -*- coding: utf-8 -*- -from design.plone.contenttypes.utils import create_default_blocks -from plone import api -from Products.CMFPlone.interfaces import ISelectableConstrainTypes - - -def documentoCreateHandler(documento, event): - """ - Complete content type Documento setup on added event, generating - missing folders, fields, etc. - - @param documento: Content item - - @param event: Event that triggers the method (onAdded event) - """ - if "multimedia" in documento.keys(): - # we are copying or moving it - return - - documentoConstraints = ISelectableConstrainTypes(documento) - documentoConstraints.setConstrainTypesMode(1) - documentoConstraints.setLocallyAllowedTypes(("Document",)) - - # create support folder - multimedia = api.content.create( - type="Document", title="Multimedia", container=documento - ) - create_default_blocks(context=multimedia) - - multimediaConstraints = ISelectableConstrainTypes(multimedia) - multimediaConstraints.setConstrainTypesMode(1) - multimediaConstraints.setLocallyAllowedTypes(("Image",)) - - documentoConstraints = ISelectableConstrainTypes(documento) - documentoConstraints.setConstrainTypesMode(1) - documentoConstraints.setLocallyAllowedTypes(("Modulo", "Link")) diff --git a/src/design/plone/contenttypes/events/evento.py b/src/design/plone/contenttypes/events/evento.py deleted file mode 100644 index aa67f6c6..00000000 --- a/src/design/plone/contenttypes/events/evento.py +++ /dev/null @@ -1,85 +0,0 @@ -# -*- coding: utf-8 -*- -from design.plone.contenttypes.interfaces import IDesignPloneContenttypesLayer -from design.plone.contenttypes.utils import create_default_blocks -from plone import api -from Products.CMFPlone.interfaces import ISelectableConstrainTypes - - -def eventoCreateHandler(evento, event): - """ - Complete content type evento setup on added event, generating - missing folders, fields, etc. - - @param evento: Content item - - @param event: Event that triggers the method (onAdded event) - """ - if not IDesignPloneContenttypesLayer.providedBy(evento.REQUEST): - return - if "immagini" not in evento.keys(): - galleria = api.content.create( - container=evento, - type="Document", - title="Immagini", - id="immagini", - ) - create_default_blocks(context=galleria) - - # select constraints - constraintsGalleria = ISelectableConstrainTypes(galleria) - constraintsGalleria.setConstrainTypesMode(1) - constraintsGalleria.setLocallyAllowedTypes(("Image", "Link")) - - with api.env.adopt_roles(["Reviewer"]): - api.content.transition(obj=galleria, transition="publish") - - if not IDesignPloneContenttypesLayer.providedBy(evento.REQUEST): - return - if "video" not in evento.keys(): - galleria_video = api.content.create( - container=evento, - type="Document", - title="Video", - id="video", - ) - create_default_blocks(context=galleria_video) - - # select constraints - constraintsGalleriaVideo = ISelectableConstrainTypes(galleria_video) - constraintsGalleriaVideo.setConstrainTypesMode(1) - constraintsGalleriaVideo.setLocallyAllowedTypes(("Link",)) - - with api.env.adopt_roles(["Reviewer"]): - api.content.transition(obj=galleria_video, transition="publish") - - if "sponsor_evento" not in evento.keys(): - sponsor = api.content.create( - container=evento, - type="Document", - title="Sponsor Evento", - id="sponsor_evento", - ) - create_default_blocks(context=sponsor) - - constraintsSponsor = ISelectableConstrainTypes(sponsor) - constraintsSponsor.setConstrainTypesMode(1) - constraintsSponsor.setLocallyAllowedTypes(("Link",)) - - with api.env.adopt_roles(["Reviewer"]): - api.content.transition(obj=sponsor, transition="publish") - - if "documenti" not in evento.keys(): - documenti = api.content.create( - container=evento, - type="Document", - title="Allegati", - id="documenti", - ) - create_default_blocks(context=documenti) - - constraintsDocumenti = ISelectableConstrainTypes(documenti) - constraintsDocumenti.setConstrainTypesMode(1) - constraintsDocumenti.setLocallyAllowedTypes(("File",)) - - with api.env.adopt_roles(["Reviewer"]): - api.content.transition(obj=documenti, transition="publish") diff --git a/src/design/plone/contenttypes/events/incarico.py b/src/design/plone/contenttypes/events/incarico.py index 6b077b49..34368b77 100644 --- a/src/design/plone/contenttypes/events/incarico.py +++ b/src/design/plone/contenttypes/events/incarico.py @@ -1,37 +1,5 @@ # -*- coding: utf-8 -*- -from design.plone.contenttypes.utils import create_default_blocks from plone import api -from Products.CMFPlone.interfaces import ISelectableConstrainTypes - - -def incaricoCreateHandler(incarico, event): - """ - Complete content type incarico setup on added event, generating - missing folders, fields, etc. - - @param incarico: Content item - - @param event: Event that triggers the method (onAdded event) - """ - - FOLDERS = [ - {"id": "compensi-file", "title": "Compensi", "contains": ("File",)}, - { - "id": "importi-di-viaggio-e-o-servizi", - "title": "Importi di viaggio e/o servizi", - "contains": ("File",), - }, - ] - for folder in FOLDERS: - if folder["id"] in incarico: - continue - suboject = api.content.create( - type="Document", id=folder["id"], title=folder["title"], container=incarico - ) - create_default_blocks(context=suboject) - subobjectConstraints = ISelectableConstrainTypes(suboject) - subobjectConstraints.setConstrainTypesMode(1) - subobjectConstraints.setLocallyAllowedTypes(folder["contains"]) def modify_incarico(obj, event): diff --git a/src/design/plone/contenttypes/events/luogo.py b/src/design/plone/contenttypes/events/luogo.py deleted file mode 100644 index 42bf0e47..00000000 --- a/src/design/plone/contenttypes/events/luogo.py +++ /dev/null @@ -1,30 +0,0 @@ -# -*- coding: utf-8 -*- -from Products.CMFPlone.interfaces import ISelectableConstrainTypes -from Products.CMFPlone.utils import _createObjectByType - - -def luogoCreateHandler(luogo, event): - """ - Complete content type luogo setup on added event, generating - missing folders, fields, etc. - - @param luogo: Content item - - @param event: Event that triggers the method (onAdded event) - """ - folder_id = "multimedia" - if folder_id in luogo: - return - folder = _createObjectByType("Folder", luogo, "multimedia") - folder.title = "Multimedia" - folder.reindexObject(idxs=["Title"]) - constraints = ISelectableConstrainTypes(folder) - constraints.setConstrainTypesMode(1) - constraints.setLocallyAllowedTypes( - ( - "Image", - "Link", - ) - ) - - # non dovrebbe essere cancellabile diff --git a/src/design/plone/contenttypes/events/notizie_e_comunicati_stampa.py b/src/design/plone/contenttypes/events/notizie_e_comunicati_stampa.py deleted file mode 100644 index 053928e3..00000000 --- a/src/design/plone/contenttypes/events/notizie_e_comunicati_stampa.py +++ /dev/null @@ -1,33 +0,0 @@ -# -*- coding: utf-8 -*- -from design.plone.contenttypes.utils import create_default_blocks -from plone import api -from Products.CMFPlone.interfaces import ISelectableConstrainTypes - - -def notiziaCreateHandler(notizia, event): - """ - Complete content type notizia setup on added event, generating - missing folders, fields, etc. - - @param notizia: Content item - - @param event: Event that triggers the method (onAdded event) - """ - - if "multimedia" not in notizia.keys(): - multimedia = api.content.create( - type="Document", title="Multimedia", container=notizia - ) - create_default_blocks(context=multimedia) - constraintsMultimedia = ISelectableConstrainTypes(multimedia) - constraintsMultimedia.setConstrainTypesMode(1) - constraintsMultimedia.setLocallyAllowedTypes(("Link", "Image")) - - if "documenti-allegati" not in notizia.keys(): - documenti = api.content.create( - type="Document", title="Documenti allegati", container=notizia - ) - create_default_blocks(context=documenti) - constraintsDocumenti = ISelectableConstrainTypes(documenti) - constraintsDocumenti.setConstrainTypesMode(1) - constraintsDocumenti.setLocallyAllowedTypes(("File", "Image")) diff --git a/src/design/plone/contenttypes/events/persona.py b/src/design/plone/contenttypes/events/persona.py deleted file mode 100644 index 0da34496..00000000 --- a/src/design/plone/contenttypes/events/persona.py +++ /dev/null @@ -1,52 +0,0 @@ -# -*- coding: utf-8 -*- -from design.plone.contenttypes.utils import create_default_blocks -from plone import api -from Products.CMFPlone.interfaces import ISelectableConstrainTypes - - -def personaCreateHandler(persona, event): - """ - Complete content type Persona setup on added event, generating - missing folders, fields, etc. - - @param persona: Content item - - @param event: Event that triggers the method (onAdded event) - """ - - FOLDERS = [ - { - "id": "foto-e-attivita-politica", - "title": "Foto e attività politica", - "contains": ("Image",), - }, - {"id": "curriculum-vitae", "title": "Curriculum vitae", "contains": ("File",)}, - { - "id": "situazione-patrimoniale", - "title": "Situazione patrimoniale", - "contains": ("File",), - }, - { - "id": "dichiarazione-dei-redditi", - "title": "Dichiarazione dei redditi", - "contains": ("File",), - }, - {"id": "spese-elettorali", "title": "Spese elettorali", "contains": ("File",)}, - { - "id": "variazione-situazione-patrimoniale", - "title": "Variazione situazione patrimoniale", - "contains": ("File",), - }, - {"id": "altre-cariche", "title": "Altre cariche", "contains": ("File",)}, - {"id": "incarichi", "title": "Incarichi", "contains": ("Incarico",)}, - ] - for folder in FOLDERS: - if folder["id"] in persona: - continue - suboject = api.content.create( - type="Document", id=folder["id"], title=folder["title"], container=persona - ) - create_default_blocks(context=suboject) - subobjectConstraints = ISelectableConstrainTypes(suboject) - subobjectConstraints.setConstrainTypesMode(1) - subobjectConstraints.setLocallyAllowedTypes(folder["contains"]) diff --git a/src/design/plone/contenttypes/events/pratica.py b/src/design/plone/contenttypes/events/pratica.py deleted file mode 100644 index bf44dda7..00000000 --- a/src/design/plone/contenttypes/events/pratica.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -from plone import api -from Products.CMFPlone.interfaces import ISelectableConstrainTypes - - -def praticaCreateHandler(pratica, event): - """ - Complete content type Pratica setup on added event, generating - missing folders, fields, etc. - - @param pratica: Content item - - @param event: Event that triggers the method (onAdded event) - """ - - allegati = api.content.create(type="Folder", title="Allegati", container=pratica) - - allegatiConstraints = ISelectableConstrainTypes(allegati) - allegatiConstraints.setConstrainTypesMode(1) - allegatiConstraints.setLocallyAllowedTypes(("File",)) diff --git a/src/design/plone/contenttypes/events/servizio.py b/src/design/plone/contenttypes/events/servizio.py deleted file mode 100644 index 1a37f81e..00000000 --- a/src/design/plone/contenttypes/events/servizio.py +++ /dev/null @@ -1,29 +0,0 @@ -# -*- coding: utf-8 -*- -from design.plone.contenttypes.utils import create_default_blocks -from plone import api -from Products.CMFPlone.interfaces import ISelectableConstrainTypes - - -def servizioCreateHandler(servizio, event): - """ - Complete content type Servizio setup on added event, generating - missing folders, fields, etc. - - @param servizio: Content item - - @param event: Event that triggers the method (onAdded event) - """ - - for folder in [ - {"id": "modulistica", "title": "Modulistica", "contains": ("File", "Link")}, - {"id": "allegati", "title": "Allegati", "contains": ("File", "Link")}, - ]: - if folder["id"] not in servizio.keys(): - child = api.content.create( - type="Document", title=folder["title"], container=servizio - ) - create_default_blocks(context=child) - - childConstraints = ISelectableConstrainTypes(child) - childConstraints.setConstrainTypesMode(1) - childConstraints.setLocallyAllowedTypes(folder["contains"]) diff --git a/src/design/plone/contenttypes/events/unita_organizzativa.py b/src/design/plone/contenttypes/events/unita_organizzativa.py deleted file mode 100644 index ec11a746..00000000 --- a/src/design/plone/contenttypes/events/unita_organizzativa.py +++ /dev/null @@ -1,35 +0,0 @@ -# -*- coding: utf-8 -*- -from design.plone.contenttypes.utils import create_default_blocks -from plone import api -from Products.CMFPlone.interfaces import ISelectableConstrainTypes - -import logging - - -logger = logging.getLogger(__name__) - - -def unitaOrganizzativaCreateHandler(unitaOrganizzativa, event): - """ - Complete content type UnitaOrganizzativa setup on added event, generating - missing folders, fields, etc. - - @param unitaOrganizzativa: Content item - - @param event: Event that triggers the method (onAdded event) - """ - if "allegati" in unitaOrganizzativa.keys(): - return - try: - allegati = api.content.create( - type="Document", title="Allegati", container=unitaOrganizzativa - ) - except AttributeError as e: - # problems with tests in design.plone.policy - logger.exception(e) - return - - create_default_blocks(context=allegati) - allegatiConstraints = ISelectableConstrainTypes(allegati) - allegatiConstraints.setConstrainTypesMode(1) - allegatiConstraints.setLocallyAllowedTypes(("File",)) diff --git a/src/design/plone/contenttypes/profiles/default/metadata.xml b/src/design/plone/contenttypes/profiles/default/metadata.xml index 02602d3b..a1d80769 100644 --- a/src/design/plone/contenttypes/profiles/default/metadata.xml +++ b/src/design/plone/contenttypes/profiles/default/metadata.xml @@ -1,6 +1,6 @@ - 7031 + 7100 profile-redturtle.bandi:default profile-collective.venue:default @@ -8,5 +8,6 @@ profile-eea.api.taxonomy:default profile-collective.z3cform.datagridfield:default profile-design.plone.contenttypes:taxonomy + profile-collective.volto.enhancedlinks:default diff --git a/src/design/plone/contenttypes/profiles/default/types/Modulo.xml b/src/design/plone/contenttypes/profiles/default/types/Modulo.xml index fe0ea9c1..1978e988 100644 --- a/src/design/plone/contenttypes/profiles/default/types/Modulo.xml +++ b/src/design/plone/contenttypes/profiles/default/types/Modulo.xml @@ -43,6 +43,7 @@ + diff --git a/src/design/plone/contenttypes/restapi/serializers/bando.py b/src/design/plone/contenttypes/restapi/serializers/bando.py index 9e463ad0..c3354e70 100644 --- a/src/design/plone/contenttypes/restapi/serializers/bando.py +++ b/src/design/plone/contenttypes/restapi/serializers/bando.py @@ -19,6 +19,11 @@ def get_approfondimenti(self, bando_view): contents = bando_view.retrieveContentsOfFolderDeepening(folder["path"]) if not contents: continue + # fix results for enhancedlinks + for content in contents: + content["getObjSize"] = content.get("filesize", "") + content["mime_type"] = content.get("content-type", "") + content["enhanced_links_enabled"] = "filesize" in content folder.update({"children": contents}) results.append(folder) return results diff --git a/src/design/plone/contenttypes/restapi/serializers/configure.zcml b/src/design/plone/contenttypes/restapi/serializers/configure.zcml index d5c46918..e81c934a 100644 --- a/src/design/plone/contenttypes/restapi/serializers/configure.zcml +++ b/src/design/plone/contenttypes/restapi/serializers/configure.zcml @@ -22,6 +22,7 @@ + diff --git a/src/design/plone/contenttypes/restapi/serializers/dxcontent.py b/src/design/plone/contenttypes/restapi/serializers/dxcontent.py index c499da46..bae57370 100644 --- a/src/design/plone/contenttypes/restapi/serializers/dxcontent.py +++ b/src/design/plone/contenttypes/restapi/serializers/dxcontent.py @@ -16,59 +16,46 @@ from zope.interface import implementer +class MetaTypeSerializer(object): + def get_design_meta_type(self): + ttool = api.portal.get_tool("portal_types") + if self.context.portal_type == "News Item" and self.context.tipologia_notizia: + taxonomy = getUtility( + ITaxonomy, name="collective.taxonomy.tipologia_notizia" + ) + taxonomy_voc = taxonomy.makeVocabulary(self.request.get("LANGUAGE")) + if isinstance(self.context.tipologia_notizia, list): + token = self.context.tipologia_notizia[0] + else: + token = self.context.tipologia_notizia + title = taxonomy_voc.inv_data.get(token, None) + + if title and title.startswith(PATH_SEPARATOR): + return title.replace(PATH_SEPARATOR, "", 1) + return translate(ttool[self.context.portal_type].Title(), context=self.request) + + @implementer(ISerializeToJson) @adapter(IDexterityContent, IDesignPloneContenttypesLayer) -class SerializeToJson(BaseSerializer): +class SerializeToJson(BaseSerializer, MetaTypeSerializer): def __call__(self, version=None, include_items=True): result = super(SerializeToJson, self).__call__( version=version, include_items=include_items ) - ttool = api.portal.get_tool("portal_types") - result["design_italia_meta_type"] = translate( - ttool[self.context.portal_type].Title(), context=self.request - ) - if self.context.portal_type == "News Item": - if self.context.tipologia_notizia: - taxonomy = getUtility( - ITaxonomy, name="collective.taxonomy.tipologia_notizia" - ) - taxonomy_voc = taxonomy.makeVocabulary(self.request.get("LANGUAGE")) - - title = taxonomy_voc.inv_data.get(self.context.tipologia_notizia, None) - - if title and title.startswith(PATH_SEPARATOR): - result["design_italia_meta_type"] = title.replace( - PATH_SEPARATOR, "", 1 - ) + result["design_italia_meta_type"] = self.get_design_meta_type() return result @implementer(ISerializeToJson) @adapter(IDexterityContainer, IDesignPloneContenttypesLayer) -class SerializeFolderToJson(BaseFolderSerializer): +class SerializeFolderToJson(BaseFolderSerializer, MetaTypeSerializer): def __call__(self, version=None, include_items=True): result = super(SerializeFolderToJson, self).__call__( version=version, include_items=include_items ) result["@id"] = self.context.absolute_url() - ttool = api.portal.get_tool("portal_types") - - result["design_italia_meta_type"] = translate( - ttool[self.context.portal_type].Title(), context=self.request - ) - if self.context.portal_type == "News Item": - if self.context.tipologia_notizia: - taxonomy = getUtility( - ITaxonomy, name="collective.taxonomy.tipologia_notizia" - ) - taxonomy_voc = taxonomy.makeVocabulary(self.request.get("LANGUAGE")) - - title = taxonomy_voc.inv_data.get(self.context.tipologia_notizia, None) + result["design_italia_meta_type"] = self.get_design_meta_type() - if title and title.startswith(PATH_SEPARATOR): - result["design_italia_meta_type"] = title.replace( - PATH_SEPARATOR, "", 1 - ) if "items_total" not in result: # siamo in un sotto-elemento di quello richiesto dalla query. #  ritorniamo il numero di elementi totale, senza doverli ritornare diff --git a/src/design/plone/contenttypes/restapi/serializers/dxfields.py b/src/design/plone/contenttypes/restapi/serializers/dxfields.py index 133351c6..fb11bef5 100644 --- a/src/design/plone/contenttypes/restapi/serializers/dxfields.py +++ b/src/design/plone/contenttypes/restapi/serializers/dxfields.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- from AccessControl.unauthorized import Unauthorized from Acquisition import aq_inner +from collective.volto.enhancedlinks.interfaces import IEnhancedLinksEnabled from design.plone.contenttypes.interfaces import IDesignPloneContenttypesLayer from design.plone.contenttypes.interfaces.servizio import IServizio from plone import api @@ -8,12 +9,16 @@ from plone.base.utils import human_readable_size from plone.dexterity.interfaces import IDexterityContent from plone.namedfile.interfaces import INamedFileField +from plone.namedfile.interfaces import INamedImageField from plone.outputfilters.browser.resolveuid import uuidToURL from plone.restapi.interfaces import IBlockFieldSerializationTransformer from plone.restapi.interfaces import IFieldSerializer from plone.restapi.interfaces import ISerializeToJsonSummary from plone.restapi.serializer.converters import json_compatible from plone.restapi.serializer.dxfields import DefaultFieldSerializer +from plone.restapi.serializer.dxfields import ( + ImageFieldSerializer as BaseImageFieldSerializer, +) from zope.component import adapter from zope.component import getMultiAdapter from zope.component import subscribers @@ -23,6 +28,7 @@ from zope.schema.interfaces import ISourceText from zope.schema.interfaces import ITextLine + import json import re @@ -80,9 +86,15 @@ def __call__(self): "filename": namedfile.filename, "content-type": namedfile.contentType, "size": size, - "getObjSize": human_readable_size(size), "download": url, } + if IEnhancedLinksEnabled.providedBy(self.context): + result.update( + { + "getObjSize": human_readable_size(size), + "enhanced_links_enabled": True, + } + ) return json_compatible(result) @@ -95,6 +107,20 @@ def get_file_view_mode(self, content_type): return "@@download" +@adapter(INamedImageField, IDexterityContent, IDesignPloneContenttypesLayer) +class ImageFieldSerializer(BaseImageFieldSerializer): + def __call__(self): + result = super().__call__() + if result and IEnhancedLinksEnabled.providedBy(self.context): + result.update( + { + "getObjSize": human_readable_size(result["size"]), + "enhanced_links_enabled": True, + } + ) + return result + + def serialize_data(context, json_data, show_children=False): request = getRequest() if not json_data: diff --git a/src/design/plone/contenttypes/restapi/serializers/summary.py b/src/design/plone/contenttypes/restapi/serializers/summary.py index 930c9387..055ba38e 100644 --- a/src/design/plone/contenttypes/restapi/serializers/summary.py +++ b/src/design/plone/contenttypes/restapi/serializers/summary.py @@ -239,11 +239,6 @@ def get_design_meta_type(self): ttool[self.context.portal_type].Title(), context=self.request ) else: - logger.error( - "missing portal_type %s for %s", - self.context.portal_type, - self.context.absolute_url(), - ) return self.context.portal_type def expand_tassonomia_argomenti(self): diff --git a/src/design/plone/contenttypes/restapi/services/types/get.py b/src/design/plone/contenttypes/restapi/services/types/get.py index f74dc8a0..c68697d4 100644 --- a/src/design/plone/contenttypes/restapi/services/types/get.py +++ b/src/design/plone/contenttypes/restapi/services/types/get.py @@ -276,9 +276,8 @@ def customize_documento_schema(self, result): def reply(self): result = super(TypesGet, self).reply() - if "fieldsets" in result: - result["fieldsets"] = self.reorder_fieldsets(original=result["fieldsets"]) + result["fieldsets"] = self.reorder_fieldsets(schema=result) pt = self.request.PATH_INFO.split("/")[-1] # be careful: result could be dict or list. If list it will not @@ -308,7 +307,8 @@ def reply(self): def get_order_by_type(self, portal_type): return [x for x in FIELDSETS_ORDER.get(portal_type, [])] - def reorder_fieldsets(self, original): + def reorder_fieldsets(self, schema): + original = schema["fieldsets"] pt = self.request.PATH_INFO.split("/")[-1] order = self.get_order_by_type(portal_type=pt) if not order: @@ -326,9 +326,21 @@ def reorder_fieldsets(self, original): new = [] for id in order: for fieldset in original: - if fieldset["id"] == id: + if fieldset["id"] == id and self.fieldset_has_fields(fieldset, schema): new.append(fieldset) if not new: # no match return original return new + + def fieldset_has_fields(self, fieldset, schema): + """ + If a fieldset has all hidden fields (maybe after a schema tweak), + these are not in the schema data, but are still in fieldset data. + This happens only in add, because the schema is generate with the parent's context. + """ + fieldset_fields = fieldset["fields"] + + schema_fields = [x for x in fieldset_fields if x in schema["properties"].keys()] + + return len(schema_fields) > 0 diff --git a/src/design/plone/contenttypes/testing.py b/src/design/plone/contenttypes/testing.py index 035a1fec..f7284719 100644 --- a/src/design/plone/contenttypes/testing.py +++ b/src/design/plone/contenttypes/testing.py @@ -14,6 +14,7 @@ import collective.venue import collective.volto.blocksfield import collective.volto.cookieconsent +import collective.volto.enhancedlinks import collective.z3cform.datagridfield import design.plone.contenttypes import eea.api.taxonomy @@ -32,6 +33,7 @@ def setUpZope(self, app, configurationContext): super().setUpZope(app, configurationContext) self.loadZCML(package=collective.venue) self.loadZCML(package=collective.volto.blocksfield) + self.loadZCML(package=collective.volto.enhancedlinks) self.loadZCML(package=design.plone.contenttypes, context=configurationContext) self.loadZCML(package=plone.formwidget.geolocation) self.loadZCML(name="overrides.zcml", package=design.plone.contenttypes) @@ -71,6 +73,7 @@ def setUpZope(self, app, configurationContext): super().setUpZope(app, configurationContext) self.loadZCML(package=collective.venue) self.loadZCML(package=collective.volto.blocksfield) + self.loadZCML(package=collective.volto.enhancedlinks) self.loadZCML(package=design.plone.contenttypes, context=configurationContext) self.loadZCML(package=plone.formwidget.geolocation) self.loadZCML(package=eea.api.taxonomy) diff --git a/src/design/plone/contenttypes/tests/test_ct_bando.py b/src/design/plone/contenttypes/tests/test_ct_bando.py index a11587df..ddb628c4 100644 --- a/src/design/plone/contenttypes/tests/test_ct_bando.py +++ b/src/design/plone/contenttypes/tests/test_ct_bando.py @@ -1,15 +1,189 @@ # -*- coding: utf-8 -*- from design.plone.contenttypes.testing import ( DESIGN_PLONE_CONTENTTYPES_INTEGRATION_TESTING, + DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING, ) from plone import api from plone.app.testing import setRoles from plone.app.testing import TEST_USER_ID +from plone.app.testing import SITE_OWNER_NAME +from plone.app.testing import SITE_OWNER_PASSWORD +from plone.restapi.testing import RelativeSession from redturtle.bandi.interfaces.settings import IBandoSettings import unittest +class TestBandoSchema(unittest.TestCase): + layer = DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING + + def setUp(self): + self.app = self.layer["app"] + self.portal = self.layer["portal"] + self.request = self.layer["request"] + self.portal_url = self.portal.absolute_url() + setRoles(self.portal, TEST_USER_ID, ["Manager"]) + + self.api_session = RelativeSession(self.portal_url) + self.api_session.headers.update({"Accept": "application/json"}) + self.api_session.auth = (SITE_OWNER_NAME, SITE_OWNER_PASSWORD) + + def tearDown(self): + self.api_session.close() + + def test_behaviors_enabled_for_bando(self): + portal_types = api.portal.get_tool(name="portal_types") + self.assertEqual( + portal_types["Bando"].behaviors, + ( + "plone.app.content.interfaces.INameFromTitle", + "plone.app.dexterity.behaviors.discussion.IAllowDiscussion", + "plone.app.dexterity.behaviors.exclfromnav.IExcludeFromNavigation", + "plone.app.dexterity.behaviors.id.IShortName", + "plone.app.dexterity.behaviors.metadata.IDublinCore", + "plone.app.relationfield.behavior.IRelatedItems", + "plone.app.versioningbehavior.behaviors.IVersionable", + "plone.app.contenttypes.behaviors.tableofcontents.ITableOfContents", + "plone.app.lockingbehavior.behaviors.ILocking", + "Products.CMFPlone.interfaces.constrains.ISelectableConstrainTypes", + "plone.versioning", + "design.plone.contenttypes.behavior.argomenti_bando", + "plone.textindexer", + "plone.translatable", + "kitconcept.seo", + "design.plone.contenttypes.behavior.update_note", + "volto.preview_image", + ), + ) + + def test_bando_fieldsets(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Bando").json() + self.assertEqual(len(resp["fieldsets"]), 7) + self.assertEqual( + [x.get("id") for x in resp["fieldsets"]], + [ + "default", + "correlati", + "settings", + "categorization", + "dates", + "ownership", + "seo", + ], + ) + + def test_bando_required_fields(self): + resp = self.api_session.get("@types/Bando").json() + self.assertEqual( + sorted(resp["required"]), + sorted(["title", "tipologia_bando"]), + ) + + def test_bando_fields_default_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Bando").json() + self.assertEqual( + resp["fieldsets"][0]["fields"], + [ + "title", + "description", + "text", + "tipologia_bando", + "destinatari", + "ente_bando", + "apertura_bando", + "scadenza_domande_bando", + "scadenza_bando", + "chiusura_procedimento_bando", + "riferimenti_bando", + "update_note", + "preview_image", + "preview_caption", + ], + ) + + def test_bando_fields_correlati_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Bando").json() + self.assertEqual( + resp["fieldsets"][1]["fields"], + [ + "area_responsabile", + "ufficio_responsabile", + "tassonomia_argomenti", + "correlato_in_evidenza", + ], + ) + + def test_bando_fields_settings_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Bando").json() + self.assertEqual( + resp["fieldsets"][2]["fields"], + [ + "allow_discussion", + "exclude_from_nav", + "id", + "versioning_enabled", + "table_of_contents", + "changeNote", + ], + ) + + def test_bando_fields_categorization_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Bando").json() + self.assertEqual( + resp["fieldsets"][3]["fields"], + ["subjects", "language", "relatedItems"], + ) + + def test_bando_fields_dates_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Bando").json() + self.assertEqual(resp["fieldsets"][4]["fields"], ["effective", "expires"]) + + def test_bando_fields_ownership_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Bando").json() + self.assertEqual( + resp["fieldsets"][5]["fields"], ["creators", "contributors", "rights"] + ) + + def test_bando_fields_seo_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Bando").json() + self.assertEqual( + resp["fieldsets"][6]["fields"], + [ + "seo_title", + "seo_description", + "seo_noindex", + "seo_canonical_url", + "opengraph_title", + "opengraph_description", + "opengraph_image", + ], + ) + + class TestBando(unittest.TestCase): layer = DESIGN_PLONE_CONTENTTYPES_INTEGRATION_TESTING diff --git a/src/design/plone/contenttypes/tests/test_ct_cartella_modulistica.py b/src/design/plone/contenttypes/tests/test_ct_cartella_modulistica.py index fe0047e7..69c19a9a 100644 --- a/src/design/plone/contenttypes/tests/test_ct_cartella_modulistica.py +++ b/src/design/plone/contenttypes/tests/test_ct_cartella_modulistica.py @@ -1,21 +1,36 @@ # -*- coding: utf-8 -*- from design.plone.contenttypes.testing import ( - DESIGN_PLONE_CONTENTTYPES_INTEGRATION_TESTING, + DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING, ) from plone import api +from plone.app.testing import setRoles +from plone.app.testing import TEST_USER_ID +from plone.app.testing import SITE_OWNER_NAME +from plone.app.testing import SITE_OWNER_PASSWORD +from plone.restapi.testing import RelativeSession import unittest -class TestCartellaModulistica(unittest.TestCase): - layer = DESIGN_PLONE_CONTENTTYPES_INTEGRATION_TESTING +class TestCartellaModulisticaSchema(unittest.TestCase): + layer = DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING def setUp(self): - """Custom shared utility setup for tests.""" + self.app = self.layer["app"] self.portal = self.layer["portal"] + self.request = self.layer["request"] + self.portal_url = self.portal.absolute_url() + setRoles(self.portal, TEST_USER_ID, ["Manager"]) - def test_behaviors_enabled_for_documento(self): + self.api_session = RelativeSession(self.portal_url) + self.api_session.headers.update({"Accept": "application/json"}) + self.api_session.auth = (SITE_OWNER_NAME, SITE_OWNER_PASSWORD) + + def tearDown(self): + self.api_session.close() + + def test_behaviors_enabled_for_cartella_modulistica(self): portal_types = api.portal.get_tool(name="portal_types") self.assertEqual( portal_types["CartellaModulistica"].behaviors, @@ -38,9 +53,117 @@ def test_behaviors_enabled_for_documento(self): ), ) - def test_event_addable_types(self): + def test_cartella_modulistica_addable_types(self): portal_types = api.portal.get_tool(name="portal_types") self.assertEqual( ("Document", "Documento", "Link", "Image", "File"), portal_types["CartellaModulistica"].allowed_content_types, ) + + def test_cartella_modulistica_fieldsets(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/CartellaModulistica").json() + self.assertEqual(len(resp["fieldsets"]), 7) + self.assertEqual( + [x.get("id") for x in resp["fieldsets"]], + [ + "default", + "settings", + "ownership", + "dates", + "categorization", + "layout", + "seo", + ], + ) + + def test_cartella_modulistica_required_fields(self): + resp = self.api_session.get("@types/CartellaModulistica").json() + self.assertEqual( + sorted(resp["required"]), + sorted(["title"]), + ) + + def test_cartella_modulistica_fields_default_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/CartellaModulistica").json() + self.assertEqual( + resp["fieldsets"][0]["fields"], + [ + "title", + "description", + "visualize_files", + "image", + "image_caption", + "preview_image", + "preview_caption", + ], + ) + + def test_cartella_modulistica_fields_settings_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/CartellaModulistica").json() + self.assertEqual( + resp["fieldsets"][1]["fields"], + [ + "allow_discussion", + "exclude_from_nav", + "id", + "versioning_enabled", + "changeNote", + ], + ) + + def test_cartella_modulistica_fields_ownership_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/CartellaModulistica").json() + self.assertEqual( + resp["fieldsets"][2]["fields"], ["creators", "contributors", "rights"] + ) + + def test_cartella_modulistica_fields_dates_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/CartellaModulistica").json() + self.assertEqual(resp["fieldsets"][3]["fields"], ["effective", "expires"]) + + def test_cartella_modulistica_fields_categorization_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/CartellaModulistica").json() + self.assertEqual(resp["fieldsets"][4]["fields"], ["subjects", "language"]) + + def test_cartella_modulistica_fields_layout_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/CartellaModulistica").json() + self.assertEqual(resp["fieldsets"][5]["fields"], ["blocks", "blocks_layout"]) + + def test_cartella_modulistica_fields_seo_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/CartellaModulistica").json() + self.assertEqual( + resp["fieldsets"][6]["fields"], + [ + "seo_title", + "seo_description", + "seo_noindex", + "seo_canonical_url", + "opengraph_title", + "opengraph_description", + "opengraph_image", + ], + ) diff --git a/src/design/plone/contenttypes/tests/test_ct_document.py b/src/design/plone/contenttypes/tests/test_ct_document.py index 162a3459..3262761c 100644 --- a/src/design/plone/contenttypes/tests/test_ct_document.py +++ b/src/design/plone/contenttypes/tests/test_ct_document.py @@ -1,19 +1,34 @@ # -*- coding: utf-8 -*- from design.plone.contenttypes.testing import ( - DESIGN_PLONE_CONTENTTYPES_INTEGRATION_TESTING, + DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING, ) from plone import api +from plone.app.testing import setRoles +from plone.app.testing import TEST_USER_ID +from plone.app.testing import SITE_OWNER_NAME +from plone.app.testing import SITE_OWNER_PASSWORD +from plone.restapi.testing import RelativeSession import unittest -class TestDocument(unittest.TestCase): - layer = DESIGN_PLONE_CONTENTTYPES_INTEGRATION_TESTING +class TestDocumentSchema(unittest.TestCase): + layer = DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING def setUp(self): - """Custom shared utility setup for tests.""" + self.app = self.layer["app"] self.portal = self.layer["portal"] + self.request = self.layer["request"] + self.portal_url = self.portal.absolute_url() + setRoles(self.portal, TEST_USER_ID, ["Manager"]) + + self.api_session = RelativeSession(self.portal_url) + self.api_session.headers.update({"Accept": "application/json"}) + self.api_session.auth = (SITE_OWNER_NAME, SITE_OWNER_PASSWORD) + + def tearDown(self): + self.api_session.close() def test_behaviors_enabled_for_document(self): portal_types = api.portal.get_tool(name="portal_types") @@ -39,3 +54,140 @@ def test_behaviors_enabled_for_document(self): "volto.preview_image", ), ) + + def test_document_fieldsets(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Document").json() + self.assertEqual(len(resp["fieldsets"]), 9) + self.assertEqual( + [x.get("id") for x in resp["fieldsets"]], + [ + "default", + "testata", + "settings", + "correlati", + "categorization", + "dates", + "ownership", + "layout", + "seo", + ], + ) + + def test_document_required_fields(self): + resp = self.api_session.get("@types/Document").json() + self.assertEqual( + sorted(resp["required"]), + sorted(["title"]), + ) + + def test_document_fields_default_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Document").json() + self.assertEqual( + resp["fieldsets"][0]["fields"], + [ + "title", + "description", + ], + ) + + def test_document_fields_testata_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Document").json() + self.assertEqual( + resp["fieldsets"][1]["fields"], + [ + "image", + "image_caption", + "preview_image", + "ricerca_in_testata", + "mostra_bottoni_condivisione", + "info_testata", + "mostra_navigazione", + "tassonomia_argomenti", + ], + ) + + def test_document_fields_settings_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Document").json() + self.assertEqual( + resp["fieldsets"][2]["fields"], + [ + "allow_discussion", + "exclude_from_nav", + "id", + "versioning_enabled", + "show_modified", + "changeNote", + ], + ) + + def test_document_fields_correlati_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Document").json() + self.assertEqual( + resp["fieldsets"][3]["fields"], + ["correlato_in_evidenza"], + ) + + def test_document_fields_categorization_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Document").json() + self.assertEqual( + resp["fieldsets"][4]["fields"], ["subjects", "language", "relatedItems"] + ) + + def test_document_fields_dates_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Document").json() + self.assertEqual(resp["fieldsets"][5]["fields"], ["effective", "expires"]) + + def test_document_fields_ownership_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Document").json() + self.assertEqual( + resp["fieldsets"][6]["fields"], ["creators", "contributors", "rights"] + ) + + def test_document_fields_layout_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Document").json() + self.assertEqual(resp["fieldsets"][7]["fields"], ["blocks", "blocks_layout"]) + + def test_document_fields_seo_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Document").json() + self.assertEqual( + resp["fieldsets"][8]["fields"], + [ + "seo_title", + "seo_description", + "seo_noindex", + "seo_canonical_url", + "opengraph_title", + "opengraph_description", + "opengraph_image", + ], + ) diff --git a/src/design/plone/contenttypes/tests/test_ct_documento.py b/src/design/plone/contenttypes/tests/test_ct_documento.py index 996b4400..d5d7f207 100644 --- a/src/design/plone/contenttypes/tests/test_ct_documento.py +++ b/src/design/plone/contenttypes/tests/test_ct_documento.py @@ -3,9 +3,6 @@ from design.plone.contenttypes.testing import ( DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING, ) -from design.plone.contenttypes.testing import ( - DESIGN_PLONE_CONTENTTYPES_INTEGRATION_TESTING, -) from plone import api from plone.app.testing import setRoles from plone.app.testing import SITE_OWNER_NAME @@ -19,13 +16,23 @@ import unittest -class TestDocument(unittest.TestCase): - layer = DESIGN_PLONE_CONTENTTYPES_INTEGRATION_TESTING +class TestDocumentoSchema(unittest.TestCase): + layer = DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING maxDiff = None def setUp(self): - """Custom shared utility setup for tests.""" + self.app = self.layer["app"] self.portal = self.layer["portal"] + self.request = self.layer["request"] + self.portal_url = self.portal.absolute_url() + setRoles(self.portal, TEST_USER_ID, ["Manager"]) + + self.api_session = RelativeSession(self.portal_url) + self.api_session.headers.update({"Accept": "application/json"}) + self.api_session.auth = (SITE_OWNER_NAME, SITE_OWNER_PASSWORD) + + def tearDown(self): + self.api_session.close() def test_behaviors_enabled_for_documento(self): portal_types = api.portal.get_tool(name="portal_types") @@ -43,7 +50,7 @@ def test_behaviors_enabled_for_documento(self): "plone.leadimage", "volto.preview_image", "design.plone.contenttypes.behavior.argomenti_documento", - "design.plone.contenttypes.behavior.descrizione_estesa_documento", # noqa + "design.plone.contenttypes.behavior.descrizione_estesa_documento", "design.plone.contenttypes.behavior.additional_help_infos", "plone.textindexer", "plone.translatable", @@ -57,13 +64,174 @@ def test_behaviors_enabled_for_documento(self): ), ) - def test_event_addable_types(self): + def test_documento_addable_types(self): portal_types = api.portal.get_tool(name="portal_types") self.assertEqual( ("Document", "Modulo", "Link"), portal_types["Documento"].allowed_content_types, ) + def test_documento_fieldsets(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Documento").json() + self.assertEqual(len(resp["fieldsets"]), 9) + self.assertEqual( + [x.get("id") for x in resp["fieldsets"]], + [ + "default", + "descrizione", + "informazioni", + "settings", + "correlati", + "categorization", + "dates", + "ownership", + "seo", + ], + ) + + def test_documento_required_fields(self): + resp = self.api_session.get("@types/Documento").json() + self.assertEqual( + sorted(resp["required"]), + sorted( + [ + "title", + "formati_disponibili", + "tassonomia_argomenti", + "tipologia_documento", + "ufficio_responsabile", + "tipologia_licenze", + "description", + ] + ), + ) + + def test_documento_fields_default_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Documento").json() + self.assertEqual( + resp["fieldsets"][0]["fields"], + [ + "title", + "description", + "identificativo", + "protocollo", + "data_protocollo", + "formati_disponibili", + "dataset", + "image", + "image_caption", + "preview_image", + "preview_caption", + "tassonomia_argomenti", + "person_life_events", + "business_events", + "tipologia_documenti_albopretorio", + "tipologia_documento", + ], + ) + + def test_documento_fields_descrizione_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Documento").json() + self.assertEqual( + resp["fieldsets"][1]["fields"], + [ + "ufficio_responsabile", + "area_responsabile", + "autori", + "licenza_distribuzione", + "descrizione_estesa", + "tipologia_licenze", + ], + ) + + def test_documento_fields_informazioni_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Documento").json() + self.assertEqual( + resp["fieldsets"][2]["fields"], + ["riferimenti_normativi", "documenti_allegati", "ulteriori_informazioni"], + ) + + def test_documento_fields_settings_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Documento").json() + self.assertEqual( + resp["fieldsets"][3]["fields"], + [ + "allow_discussion", + "exclude_from_nav", + "id", + "versioning_enabled", + "changeNote", + ], + ) + + def test_documento_fields_correlati_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Documento").json() + self.assertEqual( + resp["fieldsets"][4]["fields"], + ["correlato_in_evidenza"], + ) + + def test_documento_fields_categorization_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Documento").json() + self.assertEqual( + resp["fieldsets"][5]["fields"], ["subjects", "language", "relatedItems"] + ) + + def test_documento_fields_dates_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Documento").json() + self.assertEqual(resp["fieldsets"][6]["fields"], ["effective", "expires"]) + + def test_documento_fields_ownership_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Documento").json() + self.assertEqual( + resp["fieldsets"][7]["fields"], ["creators", "contributors", "rights"] + ) + + def test_documento_fields_seo_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Documento").json() + self.assertEqual( + resp["fieldsets"][8]["fields"], + [ + "seo_title", + "seo_description", + "seo_noindex", + "seo_canonical_url", + "opengraph_title", + "opengraph_description", + "opengraph_image", + ], + ) + class TestDocumentoApi(unittest.TestCase): layer = DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING diff --git a/src/design/plone/contenttypes/tests/test_ct_documento_personale.py b/src/design/plone/contenttypes/tests/test_ct_documento_personale.py deleted file mode 100644 index 75e0fa56..00000000 --- a/src/design/plone/contenttypes/tests/test_ct_documento_personale.py +++ /dev/null @@ -1,39 +0,0 @@ -# -*- coding: utf-8 -*- - -from design.plone.contenttypes.testing import ( - DESIGN_PLONE_CONTENTTYPES_INTEGRATION_TESTING, -) -from plone import api - -import unittest - - -class TestDocument(unittest.TestCase): - layer = DESIGN_PLONE_CONTENTTYPES_INTEGRATION_TESTING - - def setUp(self): - """Custom shared utility setup for tests.""" - self.portal = self.layer["portal"] - - def test_behaviors_enabled_for_documento_personale(self): - portal_types = api.portal.get_tool(name="portal_types") - self.assertEqual( - portal_types["Documento Personale"].behaviors, - ( - "plone.namefromtitle", - "plone.allowdiscussion", - "plone.excludefromnavigation", - "plone.shortname", - "plone.ownership", - "plone.publication", - "plone.categorization", - "plone.basic", - "design.plone.contenttypes.behavior.descrizione_estesa", - "design.plone.contenttypes.behavior.additional_help_infos", - "plone.locking", - ), - ) - - def test_document_ct_title(self): - portal_types = api.portal.get_tool(name="portal_types") - self.assertEqual("Documento", portal_types["Documento"].title) diff --git a/src/design/plone/contenttypes/tests/test_ct_event.py b/src/design/plone/contenttypes/tests/test_ct_event.py index b675f551..ebc063fe 100644 --- a/src/design/plone/contenttypes/tests/test_ct_event.py +++ b/src/design/plone/contenttypes/tests/test_ct_event.py @@ -4,9 +4,6 @@ from design.plone.contenttypes.testing import ( DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING, ) -from design.plone.contenttypes.testing import ( - DESIGN_PLONE_CONTENTTYPES_INTEGRATION_TESTING, -) from plone import api from plone.app.testing import setRoles from plone.app.testing import SITE_OWNER_NAME @@ -20,13 +17,23 @@ import unittest -class TestEvent(unittest.TestCase): - layer = DESIGN_PLONE_CONTENTTYPES_INTEGRATION_TESTING +class TestEventSchema(unittest.TestCase): + layer = DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING maxDiff = None def setUp(self): - """Custom shared utility setup for tests.""" + self.app = self.layer["app"] self.portal = self.layer["portal"] + self.request = self.layer["request"] + self.portal_url = self.portal.absolute_url() + setRoles(self.portal, TEST_USER_ID, ["Manager"]) + + self.api_session = RelativeSession(self.portal_url) + self.api_session.headers.update({"Accept": "application/json"}) + self.api_session.auth = (SITE_OWNER_NAME, SITE_OWNER_PASSWORD) + + def tearDown(self): + self.api_session.close() def test_behaviors_enabled_for_event(self): portal_types = api.portal.get_tool(name="portal_types") @@ -73,6 +80,263 @@ def test_event_provide_design_pct_marker_interface(self): event = api.content.create(container=self.portal, type="Event", title="Evento") self.assertTrue(IDesignPloneContentType.providedBy(event)) + def test_event_fieldsets(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Event").json() + self.assertEqual(len(resp["fieldsets"]), 12) + # should be 13 but SchemaTweaks does not work in tests + # self.assertEqual(len(resp["fieldsets"]), 13) + self.assertEqual( + [x.get("id") for x in resp["fieldsets"]], + [ + "default", + "cose", + "luogo", + "date_e_orari", + "costi", + "contatti", + "informazioni", + # "correlati", see SchemaTweaks problem in tests + "categorization", + "dates", + "settings", + "ownership", + "seo", + ], + ) + + def test_event_required_fields(self): + resp = self.api_session.get("@types/Event").json() + self.assertEqual( + sorted(resp["required"]), + sorted( + [ + "title", + "tassonomia_argomenti", + "tipologia_evento", + "start", + "prezzo", + "end", + "descrizione_estesa", + "descrizione_destinatari", + "contact_info", + "description", + ] + ), + ) + + def test_event_fields_default_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Event").json() + self.assertEqual( + resp["fieldsets"][0]["fields"], + [ + "title", + "description", + "start", + "end", + "whole_day", + "open_end", + "sync_uid", + "image", + "image_caption", + "preview_image", + "preview_caption", + "correlato_in_evidenza", + "tassonomia_argomenti", + "recurrence", + "sottotitolo", + "tipologia_evento", + ], + # should be like this with SchemaTweaks + # [ + # "title", + # "description", + # "image", + # "image_caption", + # "preview_image", + # "preview_caption", + # "correlato_in_evidenza", + # "tassonomia_argomenti", + # "sottotitolo", + # "tipologia_evento", + # ], + ) + + def test_event_fields_cose_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Event").json() + self.assertEqual( + resp["fieldsets"][1]["fields"], + [ + "descrizione_estesa", + "descrizione_destinatari", + "persone_amministrazione", + ], + ) + + def test_event_fields_luogo_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Event").json() + self.assertEqual( + resp["fieldsets"][2]["fields"], + [ + "luoghi_correlati", + "nome_sede", + "street", + "zip_code", + "city", + "quartiere", + "circoscrizione", + "country", + "geolocation", + ], + ) + + def test_event_fields_date_e_orari_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Event").json() + self.assertEqual( + resp["fieldsets"][3]["fields"], + [ + "orari", + ], + # with SchemaTweaks should be like this + # [ + # "start", + # "end", + # "whole_day", + # "open_end", + # "sync_uid", + # "recurrence", + # "orari", + # ], + ) + + def test_event_fields_costi_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Event").json() + self.assertEqual( + resp["fieldsets"][4]["fields"], + [ + "prezzo", + ], + # should be like this with SchemaTweaks + # [ + # "costi", + # ], + ) + + def test_event_fields_contatti_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Event").json() + self.assertEqual( + resp["fieldsets"][5]["fields"], + [ + "organizzato_da_interno", + "organizzato_da_esterno", + "supportato_da", + "patrocinato_da", + "contact_info", + ], + ) + + def test_event_fields_informazioni_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Event").json() + self.assertEqual( + resp["fieldsets"][6]["fields"], + ["ulteriori_informazioni", "strutture_politiche"], + ) + + # def test_event_fields_correlati_fieldset(self): + # """ + # Get the list from restapi + # """ + # resp = self.api_session.get("@types/Event").json() + # self.assertEqual( + # resp["fieldsets"][7]["fields"], + # ["relatedItems"], + # ) + + def test_event_fields_categorization_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Event").json() + self.assertEqual( + resp["fieldsets"][7]["fields"], + ["subjects", "language", "relatedItems"], + # should be like this with SchemaTweaks + # ["subjects", "language"], + ) + + def test_event_fields_dates_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Event").json() + self.assertEqual(resp["fieldsets"][8]["fields"], ["effective", "expires"]) + + def test_event_fields_settings_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Event").json() + self.assertEqual( + resp["fieldsets"][9]["fields"], + [ + "allow_discussion", + "exclude_from_nav", + "id", + "versioning_enabled", + "changeNote", + ], + ) + + def test_event_fields_ownership_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Event").json() + self.assertEqual( + resp["fieldsets"][10]["fields"], ["creators", "contributors", "rights"] + ) + + def test_event_fields_seo_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Event").json() + self.assertEqual( + resp["fieldsets"][11]["fields"], + [ + "seo_title", + "seo_description", + "seo_noindex", + "seo_canonical_url", + "opengraph_title", + "opengraph_description", + "opengraph_image", + ], + ) + class TestEventApi(unittest.TestCase): layer = DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING diff --git a/src/design/plone/contenttypes/tests/test_ct_luogo.py b/src/design/plone/contenttypes/tests/test_ct_luogo.py index 2827e1fc..75f9e66a 100644 --- a/src/design/plone/contenttypes/tests/test_ct_luogo.py +++ b/src/design/plone/contenttypes/tests/test_ct_luogo.py @@ -3,9 +3,6 @@ from design.plone.contenttypes.testing import ( DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING, ) -from design.plone.contenttypes.testing import ( - DESIGN_PLONE_CONTENTTYPES_INTEGRATION_TESTING, -) from plone import api from plone.app.testing import setRoles from plone.app.testing import SITE_OWNER_NAME @@ -23,13 +20,22 @@ import unittest -class TestLuogo(unittest.TestCase): - layer = DESIGN_PLONE_CONTENTTYPES_INTEGRATION_TESTING - maxDiff = None +class TestLuogoSchema(unittest.TestCase): + layer = DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING def setUp(self): - """Custom shared utility setup for tests.""" + self.app = self.layer["app"] self.portal = self.layer["portal"] + self.request = self.layer["request"] + self.portal_url = self.portal.absolute_url() + setRoles(self.portal, TEST_USER_ID, ["Manager"]) + + self.api_session = RelativeSession(self.portal_url) + self.api_session.headers.update({"Accept": "application/json"}) + self.api_session.auth = (SITE_OWNER_NAME, SITE_OWNER_PASSWORD) + + def tearDown(self): + self.api_session.close() def test_behaviors_enabled_for_luogo(self): portal_types = api.portal.get_tool(name="portal_types") @@ -63,6 +69,199 @@ def test_luogo_ct_title(self): portal_types = api.portal.get_tool(name="portal_types") self.assertEqual("Luogo", portal_types["Venue"].title) + def test_luogo_fieldsets(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Venue").json() + self.assertEqual(len(resp["fieldsets"]), 11) + self.assertEqual( + [x.get("id") for x in resp["fieldsets"]], + [ + "default", + "descrizione", + "accesso", + "dove", + "orari", + "contatti", + "informazioni", + "settings", + "correlati", + "categorization", + "seo", + ], + ) + + def test_luogo_required_fields(self): + resp = self.api_session.get("@types/Venue").json() + self.assertEqual( + sorted(resp["required"]), + sorted( + [ + "title", + "contact_info", + "modalita_accesso", + "description", + "image", + "street", + "city", + "zip_code", + "geolocation", + ] + ), + ) + + def test_luogo_fields_default_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Venue").json() + self.assertEqual( + resp["fieldsets"][0]["fields"], + [ + "title", + "description", + "image", + "image_caption", + "preview_image", + "preview_caption", + "nome_alternativo", + "tassonomia_argomenti", + "luoghi_correlati", + "tipologia_luogo", + ], + ) + + def test_luogo_fields_descrizione_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Venue").json() + self.assertEqual( + resp["fieldsets"][1]["fields"], + ["descrizione_completa", "elementi_di_interesse"], + ) + + def test_luogo_fields_accesso_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Venue").json() + self.assertEqual( + resp["fieldsets"][2]["fields"], + ["modalita_accesso"], + ) + + def test_luogo_fields_dove_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Venue").json() + self.assertEqual( + resp["fieldsets"][3]["fields"], + [ + "street", + "zip_code", + "city", + "quartiere", + "circoscrizione", + "country", + "geolocation", + "notes", + ], + ) + + def test_luogo_fields_orari_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Venue").json() + self.assertEqual( + resp["fieldsets"][4]["fields"], + ["orario_pubblico"], + ) + + def test_luogo_fields_contatti_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Venue").json() + self.assertEqual( + resp["fieldsets"][5]["fields"], + [ + "contact_info", + "struttura_responsabile_correlati", + "struttura_responsabile", + ], + ) + + def test_luogo_fields_informazioni_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Venue").json() + self.assertEqual( + resp["fieldsets"][6]["fields"], + [ + "ulteriori_informazioni", + ], + ) + + def test_luogo_fields_settings_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Venue").json() + self.assertEqual( + resp["fieldsets"][7]["fields"], + [ + "id", + "exclude_from_nav", + "versioning_enabled", + "changeNote", + ], + ) + + def test_luogo_fields_correlati_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Venue").json() + self.assertEqual( + resp["fieldsets"][8]["fields"], + ["correlato_in_evidenza"], + ) + + def test_luogo_fields_categorization_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Venue").json() + self.assertEqual( + resp["fieldsets"][9]["fields"], + # ["subjects", "language", "identificativo_mibac"] BBB dovrebbe essere così + # ma nei test esce così perché non viene vista la patch di SchemaTweaks + ["subjects", "language", "relatedItems", "identificativo_mibac"], + ) + + def test_luogo_fields_seo_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Venue").json() + self.assertEqual( + resp["fieldsets"][10]["fields"], + [ + "seo_title", + "seo_description", + "seo_noindex", + "seo_canonical_url", + "opengraph_title", + "opengraph_description", + "opengraph_image", + ], + ) + class TestLuogoApi(unittest.TestCase): layer = DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING diff --git a/src/design/plone/contenttypes/tests/test_ct_modulo.py b/src/design/plone/contenttypes/tests/test_ct_modulo.py index e12bf364..329c9da8 100644 --- a/src/design/plone/contenttypes/tests/test_ct_modulo.py +++ b/src/design/plone/contenttypes/tests/test_ct_modulo.py @@ -1,21 +1,36 @@ # -*- coding: utf-8 -*- from design.plone.contenttypes.testing import ( - DESIGN_PLONE_CONTENTTYPES_INTEGRATION_TESTING, + DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING, ) from plone import api +from plone.app.testing import setRoles +from plone.app.testing import TEST_USER_ID +from plone.app.testing import SITE_OWNER_NAME +from plone.app.testing import SITE_OWNER_PASSWORD +from plone.restapi.testing import RelativeSession import unittest -class TestDocument(unittest.TestCase): - layer = DESIGN_PLONE_CONTENTTYPES_INTEGRATION_TESTING +class TestModuloSchema(unittest.TestCase): + layer = DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING def setUp(self): - """Custom shared utility setup for tests.""" + self.app = self.layer["app"] self.portal = self.layer["portal"] + self.request = self.layer["request"] + self.portal_url = self.portal.absolute_url() + setRoles(self.portal, TEST_USER_ID, ["Manager"]) - def test_behaviors_enabled_for_documento(self): + self.api_session = RelativeSession(self.portal_url) + self.api_session.headers.update({"Accept": "application/json"}) + self.api_session.auth = (SITE_OWNER_NAME, SITE_OWNER_PASSWORD) + + def tearDown(self): + self.api_session.close() + + def test_behaviors_enabled_for_modulo(self): portal_types = api.portal.get_tool(name="portal_types") self.assertEqual( portal_types["Modulo"].behaviors, @@ -29,5 +44,89 @@ def test_behaviors_enabled_for_documento(self): "plone.locking", "design.plone.contenttypes.behavior.multi_file", "plone.translatable", + "volto.enhanced_links_enabled", ), ) + + def test_modulo_fieldsets(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Modulo").json() + self.assertEqual(len(resp["fieldsets"]), 5) + self.assertEqual( + [x.get("id") for x in resp["fieldsets"]], + [ + "default", + "settings", + # "correlati", + "categorization", + "dates", + "ownership", + ], + ) + + def test_modulo_required_fields(self): + resp = self.api_session.get("@types/Modulo").json() + self.assertEqual( + sorted(resp["required"]), + sorted(["title", "file_principale"]), + ) + + def test_modulo_fields_default_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Modulo").json() + self.assertEqual( + resp["fieldsets"][0]["fields"], + [ + "title", + "description", + "file_principale", + "formato_alternativo_1", + "formato_alternativo_2", + ], + ) + + def test_modulo_fields_settings_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Modulo").json() + self.assertEqual( + resp["fieldsets"][1]["fields"], + [ + "allow_discussion", + "exclude_from_nav", + "id", + ], + ) + + def test_modulo_fields_categorization_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Modulo").json() + self.assertEqual( + resp["fieldsets"][2]["fields"], + # ["subjects", "language"] BBB dovrebbe essere così + # ma nei test esce così perché non viene vista la patch di SchemaTweaks + ["subjects", "language", "relatedItems"], + ) + + def test_modulo_fields_dates_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Modulo").json() + self.assertEqual(resp["fieldsets"][3]["fields"], ["effective", "expires"]) + + def test_modulo_fields_ownership_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Modulo").json() + self.assertEqual( + resp["fieldsets"][4]["fields"], ["creators", "contributors", "rights"] + ) diff --git a/src/design/plone/contenttypes/tests/test_ct_news.py b/src/design/plone/contenttypes/tests/test_ct_news.py index 764b3212..4239d9c2 100644 --- a/src/design/plone/contenttypes/tests/test_ct_news.py +++ b/src/design/plone/contenttypes/tests/test_ct_news.py @@ -1,12 +1,8 @@ # -*- coding: utf-8 -*- -from design.plone.contenttypes.controlpanels.settings import IDesignPloneSettings from design.plone.contenttypes.interfaces import IDesignPloneContentType from design.plone.contenttypes.testing import ( DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING, ) -from design.plone.contenttypes.testing import ( - DESIGN_PLONE_CONTENTTYPES_INTEGRATION_TESTING, -) from plone import api from plone.app.testing import setRoles from plone.app.testing import SITE_OWNER_NAME @@ -20,13 +16,23 @@ import unittest -class TestNews(unittest.TestCase): - layer = DESIGN_PLONE_CONTENTTYPES_INTEGRATION_TESTING +class TestNewsSchema(unittest.TestCase): + layer = DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING maxDiff = None def setUp(self): - """Custom shared utility setup for tests.""" + self.app = self.layer["app"] self.portal = self.layer["portal"] + self.request = self.layer["request"] + self.portal_url = self.portal.absolute_url() + setRoles(self.portal, TEST_USER_ID, ["Manager"]) + + self.api_session = RelativeSession(self.portal_url) + self.api_session.headers.update({"Accept": "application/json"}) + self.api_session.auth = (SITE_OWNER_NAME, SITE_OWNER_PASSWORD) + + def tearDown(self): + self.api_session.close() def test_behaviors_enabled_for_news(self): portal_types = api.portal.get_tool(name="portal_types") @@ -70,6 +76,134 @@ def test_news_provide_design_pct_marker_interface(self): news = api.content.create(container=self.portal, type="News Item", title="News") self.assertTrue(IDesignPloneContentType.providedBy(news)) + def test_news_item_fieldsets(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/News%20Item").json() + self.assertEqual(len(resp["fieldsets"]), 7) + self.assertEqual( + [x.get("id") for x in resp["fieldsets"]], + [ + "default", + "dates", + "correlati", + "categorization", + "settings", + "ownership", + "seo", + ], + ) + + def test_news_item_required_fields(self): + resp = self.api_session.get("@types/News%20Item").json() + self.assertEqual( + sorted(resp["required"]), + sorted( + [ + "title", + "descrizione_estesa", + "a_cura_di", + "tassonomia_argomenti", + "tipologia_notizia", + "description", + ] + ), + ) + + def test_news_item_fields_default_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/News%20Item").json() + self.assertEqual( + resp["fieldsets"][0]["fields"], + [ + "title", + "description", + "image", + "image_caption", + "preview_image", + "preview_caption", + "descrizione_estesa", + "numero_progressivo_cs", + "a_cura_di", + "a_cura_di_persone", + "luoghi_correlati", + "tassonomia_argomenti", + "tipologia_notizia", + ], + ) + + def test_news_item_fields_dates_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/News%20Item").json() + self.assertEqual(resp["fieldsets"][1]["fields"], ["effective", "expires"]) + + def test_news_item_fields_correlati_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/News%20Item").json() + self.assertEqual( + resp["fieldsets"][2]["fields"], + ["notizie_correlate", "correlato_in_evidenza"], + ) + + def test_news_item_fields_categorization_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/News%20Item").json() + self.assertEqual( + resp["fieldsets"][3]["fields"], ["subjects", "language", "relatedItems"] + ) + + def test_news_item_fields_settings_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/News%20Item").json() + self.assertEqual( + resp["fieldsets"][4]["fields"], + [ + "allow_discussion", + "id", + "exclude_from_nav", + "versioning_enabled", + "changeNote", + ], + ) + + def test_news_item_fields_ownership_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/News%20Item").json() + self.assertEqual( + resp["fieldsets"][5]["fields"], ["creators", "contributors", "rights"] + ) + + def test_news_item_fields_seo_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/News%20Item").json() + self.assertEqual( + resp["fieldsets"][6]["fields"], + [ + "seo_title", + "seo_description", + "seo_noindex", + "seo_canonical_url", + "opengraph_title", + "opengraph_description", + "opengraph_image", + ], + ) + class TestNewsApi(unittest.TestCase): layer = DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING @@ -89,12 +223,6 @@ def setUp(self): container=self.portal, type="Document", title="Document" ) - # we need it because of vocabularies - api.portal.set_registry_record( - "tipologie_notizia", - json.dumps({"en": ["foo", "bar"]}), - interface=IDesignPloneSettings, - ) transaction.commit() def tearDown(self): diff --git a/src/design/plone/contenttypes/tests/test_ct_pagina_argomento.py b/src/design/plone/contenttypes/tests/test_ct_pagina_argomento.py index e598271d..35ceb755 100644 --- a/src/design/plone/contenttypes/tests/test_ct_pagina_argomento.py +++ b/src/design/plone/contenttypes/tests/test_ct_pagina_argomento.py @@ -1,19 +1,34 @@ # -*- coding: utf-8 -*- """Setup tests for this package.""" from design.plone.contenttypes.testing import ( - DESIGN_PLONE_CONTENTTYPES_INTEGRATION_TESTING, + DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING, ) from plone import api +from plone.app.testing import setRoles +from plone.app.testing import SITE_OWNER_NAME +from plone.app.testing import SITE_OWNER_PASSWORD +from plone.app.testing import TEST_USER_ID +from plone.restapi.testing import RelativeSession import unittest -class TestPaginaArgomento(unittest.TestCase): - layer = DESIGN_PLONE_CONTENTTYPES_INTEGRATION_TESTING +class TestPaginaArgomentoSchema(unittest.TestCase): + layer = DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING def setUp(self): - """Custom shared utility setup for tests.""" + self.app = self.layer["app"] self.portal = self.layer["portal"] + self.request = self.layer["request"] + self.portal_url = self.portal.absolute_url() + setRoles(self.portal, TEST_USER_ID, ["Manager"]) + + self.api_session = RelativeSession(self.portal_url) + self.api_session.headers.update({"Accept": "application/json"}) + self.api_session.auth = (SITE_OWNER_NAME, SITE_OWNER_PASSWORD) + + def tearDown(self): + self.api_session.close() def test_behaviors_enabled_for_pagina_argomento(self): portal_types = api.portal.get_tool(name="portal_types") @@ -39,3 +54,127 @@ def test_behaviors_enabled_for_pagina_argomento(self): "plone.versioning", ), ) + + def test_pagina_argomento_fieldsets(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Pagina%20Argomento").json() + self.assertEqual(len(resp["fieldsets"]), 8) + self.assertEqual( + [x.get("id") for x in resp["fieldsets"]], + [ + "default", + "informazioni", + # "correlati", questo non viene fuori nei test + "categorization", + "dates", + "settings", + "layout", + "ownership", + "seo", + ], + ) + + def test_pagina_argomento_required_fields(self): + resp = self.api_session.get("@types/Pagina%20Argomento").json() + self.assertEqual( + sorted(resp["required"]), + sorted( + [ + "title", + ] + ), + ) + + def test_pagina_argomento_fields_default_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Pagina%20Argomento").json() + self.assertEqual( + resp["fieldsets"][0]["fields"], + [ + "title", + "description", + "icona", + "unita_amministrative_responsabili", + "image", + "image_caption", + "preview_image", + "preview_caption", + ], + ) + + def test_pagina_argomento_fields_informazioni_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Pagina%20Argomento").json() + self.assertEqual(resp["fieldsets"][1]["fields"], ["ulteriori_informazioni"]) + + def test_pagina_argomento_fields_categorization_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Pagina%20Argomento").json() + self.assertEqual( + resp["fieldsets"][2]["fields"], ["relatedItems", "subjects", "language"] + ) + + def test_pagina_argomento_fields_dates_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Pagina%20Argomento").json() + self.assertEqual(resp["fieldsets"][3]["fields"], ["effective", "expires"]) + + def test_pagina_argomento_fields_settings_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Pagina%20Argomento").json() + self.assertEqual( + resp["fieldsets"][4]["fields"], + [ + "allow_discussion", + "exclude_from_nav", + "id", + "versioning_enabled", + "changeNote", + ], + ) + + def test_pagina_argomento_fields_layout_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Pagina%20Argomento").json() + self.assertEqual(resp["fieldsets"][5]["fields"], ["blocks", "blocks_layout"]) + + def test_pagina_argomento_fields_ownership_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Pagina%20Argomento").json() + self.assertEqual( + resp["fieldsets"][6]["fields"], ["creators", "contributors", "rights"] + ) + + def test_pagina_argomento_fields_seo_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Pagina%20Argomento").json() + self.assertEqual( + resp["fieldsets"][7]["fields"], + [ + "seo_title", + "seo_description", + "seo_noindex", + "seo_canonical_url", + "opengraph_title", + "opengraph_description", + "opengraph_image", + ], + ) diff --git a/src/design/plone/contenttypes/tests/test_ct_persona.py b/src/design/plone/contenttypes/tests/test_ct_persona.py index 5d76519a..fdaea25f 100644 --- a/src/design/plone/contenttypes/tests/test_ct_persona.py +++ b/src/design/plone/contenttypes/tests/test_ct_persona.py @@ -3,9 +3,6 @@ from design.plone.contenttypes.testing import ( DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING, ) -from design.plone.contenttypes.testing import ( - DESIGN_PLONE_CONTENTTYPES_INTEGRATION_TESTING, -) from plone import api from plone.app.testing import helpers from plone.app.testing import setRoles @@ -23,12 +20,29 @@ import unittest -class TestPersona(unittest.TestCase): - layer = DESIGN_PLONE_CONTENTTYPES_INTEGRATION_TESTING +class TestPersonaSchema(unittest.TestCase): + layer = DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING def setUp(self): - """Custom shared utility setup for tests.""" + self.app = self.layer["app"] self.portal = self.layer["portal"] + self.request = self.layer["request"] + self.portal_url = self.portal.absolute_url() + setRoles(self.portal, TEST_USER_ID, ["Manager"]) + + self.api_session = RelativeSession(self.portal_url) + self.api_session.headers.update({"Accept": "application/json"}) + self.api_session.auth = (SITE_OWNER_NAME, SITE_OWNER_PASSWORD) + self.persona = api.content.create( + container=self.portal, type="Persona", title="John Doe" + ) + intids = getUtility(IIntIds) + + self.persona_ref = RelationValue(intids.getId(self.persona)) + commit() + + def tearDown(self): + self.api_session.close() def test_behaviors_enabled_for_persona(self): portal_types = api.portal.get_tool(name="portal_types") @@ -58,33 +72,143 @@ def test_persona_ct_title(self): portal_types = api.portal.get_tool(name="portal_types") self.assertEqual("Persona pubblica", portal_types["Persona"].title) + def test_persona_fieldsets(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Persona").json() + self.assertEqual(len(resp["fieldsets"]), 10) + self.assertEqual( + [x.get("id") for x in resp["fieldsets"]], + [ + "default", + "ruolo", + "contatti", + "documenti", + "informazioni", + # "correlati", questo non viene fuori nei test + "categorization", + "dates", + "ownership", + "settings", + "seo", + ], + ) -class TestPersonaEndpoint(unittest.TestCase): - """""" + def test_persona_required_fields(self): + resp = self.api_session.get("@types/Persona").json() + self.assertEqual( + sorted(resp["required"]), + sorted( + [ + "title", + "contact_info", + ] + ), + ) - layer = DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING + def test_persona_fields_default_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Persona").json() + self.assertEqual( + resp["fieldsets"][0]["fields"], + ["title", "description", "foto_persona"], + ) - def setUp(self): - self.app = self.layer["app"] - self.portal = self.layer["portal"] - self.request = self.layer["request"] - self.portal_url = self.portal.absolute_url() - setRoles(self.portal, TEST_USER_ID, ["Manager"]) + def test_persona_fields_ruolo_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Persona").json() + self.assertEqual( + resp["fieldsets"][1]["fields"], + ["incarichi_persona", "competenze", "deleghe", "biografia"], + ) - self.api_session = RelativeSession(self.portal_url) - self.api_session.headers.update({"Accept": "application/json"}) - self.api_session.auth = (SITE_OWNER_NAME, SITE_OWNER_PASSWORD) + def test_persona_fields_contatti_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Persona").json() + self.assertEqual(resp["fieldsets"][2]["fields"], ["contact_info"]) - self.persona = api.content.create( - container=self.portal, type="Persona", title="John Doe" + def test_persona_fields_documenti_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Persona").json() + self.assertEqual(resp["fieldsets"][3]["fields"], ["curriculum_vitae"]) + + def test_persona_fields_informazioni_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Persona").json() + self.assertEqual( + resp["fieldsets"][4]["fields"], + ["ulteriori_informazioni"], ) - intids = getUtility(IIntIds) - self.persona_ref = RelationValue(intids.getId(self.persona)) - commit() + def test_persona_fields_categorization_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Persona").json() + self.assertEqual( + resp["fieldsets"][5]["fields"], ["relatedItems", "subjects", "language"] + ) - def tearDown(self): - self.api_session.close() + def test_persona_fields_dates_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Persona").json() + self.assertEqual(resp["fieldsets"][6]["fields"], ["effective", "expires"]) + + def test_persona_fields_ownership_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Persona").json() + self.assertEqual( + resp["fieldsets"][7]["fields"], ["creators", "contributors", "rights"] + ) + + def test_persona_fields_settings_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Persona").json() + self.assertEqual( + resp["fieldsets"][8]["fields"], + [ + "allow_discussion", + "exclude_from_nav", + "id", + "versioning_enabled", + "changeNote", + ], + ) + + def test_persona_fields_seo_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Persona").json() + self.assertEqual( + resp["fieldsets"][9]["fields"], + [ + "seo_title", + "seo_description", + "seo_noindex", + "seo_canonical_url", + "opengraph_title", + "opengraph_description", + "opengraph_image", + ], + ) def test_atto_di_nomina_incarico(self): incarico = api.content.create( diff --git a/src/design/plone/contenttypes/tests/test_ct_servizio.py b/src/design/plone/contenttypes/tests/test_ct_servizio.py index 884b0dca..b170b827 100644 --- a/src/design/plone/contenttypes/tests/test_ct_servizio.py +++ b/src/design/plone/contenttypes/tests/test_ct_servizio.py @@ -1,11 +1,8 @@ # -*- coding: utf-8 -*- """Setup tests for this package.""" -from design.plone.contenttypes.testing import ( # noqa +from design.plone.contenttypes.testing import ( DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING, ) -from design.plone.contenttypes.testing import ( # noqa - DESIGN_PLONE_CONTENTTYPES_INTEGRATION_TESTING, -) from plone import api from plone.app.testing import setRoles from plone.app.testing import SITE_OWNER_NAME @@ -40,15 +37,24 @@ } -class TestServizio(unittest.TestCase): - layer = DESIGN_PLONE_CONTENTTYPES_INTEGRATION_TESTING +class TestServizioSchema(unittest.TestCase): + layer = DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING maxDiff = None def setUp(self): - """Custom shared utility setup for tests.""" + self.app = self.layer["app"] self.portal = self.layer["portal"] + self.request = self.layer["request"] + self.portal_url = self.portal.absolute_url() setRoles(self.portal, TEST_USER_ID, ["Manager"]) + self.api_session = RelativeSession(self.portal_url) + self.api_session.headers.update({"Accept": "application/json"}) + self.api_session.auth = (SITE_OWNER_NAME, SITE_OWNER_PASSWORD) + + def tearDown(self): + self.api_session.close() + def test_behaviors_enabled_for_servizio(self): portal_types = api.portal.get_tool(name="portal_types") self.assertEqual( @@ -79,6 +85,259 @@ def test_behaviors_enabled_for_servizio(self): ), ) + def test_servizio_fieldsets(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Servizio").json() + self.assertEqual(len(resp["fieldsets"]), 18) + self.assertEqual( + [x.get("id") for x in resp["fieldsets"]], + [ + "default", + "cose", + "a_chi_si_rivolge", + "accedi_al_servizio", + "cosa_serve", + "costi_e_vincoli", + "tempi_e_scadenze", + "casi_particolari", + "contatti", + "documenti", + "link_utili", + "informazioni", + "correlati", + "categorization", + "settings", + "ownership", + "dates", + "seo", + ], + ) + + def test_servizio_required_fields(self): + resp = self.api_session.get("@types/Servizio").json() + self.assertEqual( + sorted(resp["required"]), + sorted( + [ + "title", + "tassonomia_argomenti", + "a_chi_si_rivolge", + "come_si_fa", + "cosa_si_ottiene", + "cosa_serve", + "tempi_e_scadenze", + "ufficio_responsabile", + "contact_info", + "description", + ] + ), + ) + + def test_servizio_fields_default_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Servizio").json() + self.assertEqual( + resp["fieldsets"][0]["fields"], + [ + "title", + "description", + "sottotitolo", + "stato_servizio", + "motivo_stato_servizio", + "condizioni_di_servizio", + "image", + "image_caption", + "preview_image", + "preview_caption", + "correlato_in_evidenza", + "tassonomia_argomenti", + "person_life_events", + "business_events", + ], + ) + + def test_servizio_fields_cose_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Servizio").json() + self.assertEqual( + resp["fieldsets"][1]["fields"], + ["descrizione_estesa"], + ) + + def test_servizio_fields_a_chi_si_rivolge_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Servizio").json() + self.assertEqual( + resp["fieldsets"][2]["fields"], + ["a_chi_si_rivolge", "chi_puo_presentare", "copertura_geografica"], + ) + + def test_servizio_fields_accedi_al_servizio_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Servizio").json() + self.assertEqual( + resp["fieldsets"][3]["fields"], + [ + "come_si_fa", + "cosa_si_ottiene", + "procedure_collegate", + "canale_digitale", + "canale_digitale_link", + "canale_fisico", + "dove_rivolgersi", + "dove_rivolgersi_extra", + "prenota_appuntamento", + ], + ) + + def test_servizio_fields_cosa_serve_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Servizio").json() + self.assertEqual( + resp["fieldsets"][4]["fields"], + ["cosa_serve"], + ) + + def test_servizio_fields_costi_e_vincoli_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Servizio").json() + self.assertEqual(resp["fieldsets"][5]["fields"], ["costi", "vincoli"]) + + def test_servizio_fields_tempi_e_scadenze_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Servizio").json() + self.assertEqual( + resp["fieldsets"][6]["fields"], + ["tempi_e_scadenze", "timeline_tempi_scadenze"], + ) + + def test_servizio_fields_casi_particolari_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Servizio").json() + self.assertEqual(resp["fieldsets"][7]["fields"], ["casi_particolari"]) + + def test_servizio_fields_contatti_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Servizio").json() + self.assertEqual( + resp["fieldsets"][8]["fields"], + ["ufficio_responsabile", "area", "contact_info"], + ) + + def test_servizio_fields_documenti_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Servizio").json() + self.assertEqual(resp["fieldsets"][9]["fields"], ["altri_documenti"]) + + def test_servizio_fields_link_utili_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Servizio").json() + self.assertEqual(resp["fieldsets"][10]["fields"], ["link_siti_esterni"]) + + def test_servizio_fields_informazioni_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Servizio").json() + self.assertEqual( + resp["fieldsets"][11]["fields"], + ["codice_ipa", "settore_merceologico", "ulteriori_informazioni"], + ) + + def test_servizio_fields_correlati_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Servizio").json() + self.assertEqual( + resp["fieldsets"][12]["fields"], + ["servizi_collegati"], + ) + + def test_servizio_fields_categorization_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Servizio").json() + self.assertEqual( + resp["fieldsets"][13]["fields"], + ["identificativo", "subjects", "language", "relatedItems"], + ) + + def test_servizio_fields_settings_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Servizio").json() + self.assertEqual( + resp["fieldsets"][14]["fields"], + [ + "allow_discussion", + "exclude_from_nav", + "id", + "versioning_enabled", + "changeNote", + ], + ) + + def test_servizio_fields_ownership_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Servizio").json() + self.assertEqual( + resp["fieldsets"][15]["fields"], ["creators", "contributors", "rights"] + ) + + def test_servizio_fields_dates_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Servizio").json() + self.assertEqual(resp["fieldsets"][16]["fields"], ["effective", "expires"]) + + def test_servizio_fields_seo_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/Servizio").json() + self.assertEqual( + resp["fieldsets"][17]["fields"], + [ + "seo_title", + "seo_description", + "seo_noindex", + "seo_canonical_url", + "opengraph_title", + "opengraph_description", + "opengraph_image", + ], + ) + class TestServizioApi(unittest.TestCase): """Test that design.plone.contenttypes is properly installed.""" diff --git a/src/design/plone/contenttypes/tests/test_ct_unita_organizzativa.py b/src/design/plone/contenttypes/tests/test_ct_unita_organizzativa.py index ab1292e6..9e05347f 100644 --- a/src/design/plone/contenttypes/tests/test_ct_unita_organizzativa.py +++ b/src/design/plone/contenttypes/tests/test_ct_unita_organizzativa.py @@ -21,6 +21,239 @@ import unittest +class TestUOSchema(unittest.TestCase): + layer = DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING + + def setUp(self): + self.app = self.layer["app"] + self.portal = self.layer["portal"] + self.request = self.layer["request"] + self.portal_url = self.portal.absolute_url() + setRoles(self.portal, TEST_USER_ID, ["Manager"]) + + self.api_session = RelativeSession(self.portal_url) + self.api_session.headers.update({"Accept": "application/json"}) + self.api_session.auth = (SITE_OWNER_NAME, SITE_OWNER_PASSWORD) + + def tearDown(self): + self.api_session.close() + + def test_behaviors_enabled_for_uo(self): + portal_types = api.portal.get_tool(name="portal_types") + self.assertEqual( + portal_types["UnitaOrganizzativa"].behaviors, + ( + "plone.namefromtitle", + "plone.allowdiscussion", + "plone.excludefromnavigation", + "plone.shortname", + "plone.ownership", + "plone.publication", + "plone.categorization", + "plone.basic", + "plone.locking", + "plone.leadimage", + "volto.preview_image", + "plone.relateditems", + "design.plone.contenttypes.behavior.contatti_uo", + "design.plone.contenttypes.behavior.argomenti", + "plone.textindexer", + "design.plone.contenttypes.behavior.additional_help_infos", + "plone.translatable", + "kitconcept.seo", + "plone.versioning", + "collective.taxonomy.generated.tipologia_organizzazione", + ), + ) + + def test_uo_ct_title(self): + portal_types = api.portal.get_tool(name="portal_types") + self.assertEqual( + "Unita Organizzativa", portal_types["UnitaOrganizzativa"].title + ) + + def test_uo_fieldsets(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/UnitaOrganizzativa").json() + self.assertEqual(len(resp["fieldsets"]), 12) + self.assertEqual( + [x.get("id") for x in resp["fieldsets"]], + [ + "default", + "cosa_fa", + "struttura", + "persone", + "contatti", + "correlati", + "categorization", + "informazioni", + "settings", + "ownership", + "dates", + "seo", + ], + ) + + def test_uo_required_fields(self): + resp = self.api_session.get("@types/UnitaOrganizzativa").json() + self.assertEqual( + sorted(resp["required"]), + sorted( + [ + "title", + "competenze", + "tipologia_organizzazione", + "sede", + "contact_info", + "description", + ] + ), + ) + + def test_uo_fields_default_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/UnitaOrganizzativa").json() + self.assertEqual( + resp["fieldsets"][0]["fields"], + [ + "title", + "description", + "image", + "image_caption", + "preview_image", + "preview_caption", + "tassonomia_argomenti", + ], + ) + + def test_uo_fields_cosa_fa_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/UnitaOrganizzativa").json() + self.assertEqual(resp["fieldsets"][1]["fields"], ["competenze"]) + + def test_uo_fields_struttura_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/UnitaOrganizzativa").json() + self.assertEqual( + resp["fieldsets"][2]["fields"], + [ + "legami_con_altre_strutture", + "responsabile", + "assessore_riferimento", + "tipologia_organizzazione", + ], + ) + + def test_uo_fields_persone_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/UnitaOrganizzativa").json() + self.assertEqual( + resp["fieldsets"][3]["fields"], + ["persone_struttura"], + ) + + def test_uo_fields_contatti_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/UnitaOrganizzativa").json() + self.assertEqual( + resp["fieldsets"][4]["fields"], + ["contact_info", "sede", "sedi_secondarie", "orario_pubblico"], + ) + + def test_uo_fields_correlati_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/UnitaOrganizzativa").json() + self.assertEqual( + resp["fieldsets"][5]["fields"], + # ["documenti_pubblici", "correlato_in_evidenza"], # BBB dovrebbe essere così + # ma viene fuori così nei test perché non viene vista la patch SchemaTweaks + ["correlato_in_evidenza"], + ) + + def test_uo_fields_categorization_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/UnitaOrganizzativa").json() + self.assertEqual( + resp["fieldsets"][6]["fields"], + # ["subjects", "language"] BBB dovrebbe essere così + # ma nei test esce così perché non viene vista la patch di SchemaTweaks + ["subjects", "language", "relatedItems", "documenti_pubblici"], + ) + + def test_uo_fields_informazioni_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/UnitaOrganizzativa").json() + self.assertEqual(resp["fieldsets"][7]["fields"], ["ulteriori_informazioni"]) + + def test_uo_fields_settings_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/UnitaOrganizzativa").json() + self.assertEqual( + resp["fieldsets"][8]["fields"], + [ + "allow_discussion", + "exclude_from_nav", + "id", + "versioning_enabled", + "changeNote", + ], + ) + + def test_uo_fields_ownership_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/UnitaOrganizzativa").json() + self.assertEqual( + resp["fieldsets"][9]["fields"], ["creators", "contributors", "rights"] + ) + + def test_uo_fields_dates_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/UnitaOrganizzativa").json() + self.assertEqual(resp["fieldsets"][10]["fields"], ["effective", "expires"]) + + def test_uo_fields_seo_fieldset(self): + """ + Get the list from restapi + """ + resp = self.api_session.get("@types/UnitaOrganizzativa").json() + self.assertEqual( + resp["fieldsets"][11]["fields"], + [ + "seo_title", + "seo_description", + "seo_noindex", + "seo_canonical_url", + "opengraph_title", + "opengraph_description", + "opengraph_image", + ], + ) + + class TestUO(unittest.TestCase): """Test that design.plone.contenttypes is properly installed.""" @@ -91,42 +324,6 @@ def setUp(self): def tearDown(self): self.api_session.close() - def test_behaviors_enabled_for_uo(self): - portal_types = api.portal.get_tool(name="portal_types") - self.assertEqual( - portal_types["UnitaOrganizzativa"].behaviors, - ( - "plone.namefromtitle", - "plone.allowdiscussion", - "plone.excludefromnavigation", - "plone.shortname", - "plone.ownership", - "plone.publication", - "plone.categorization", - "plone.basic", - "plone.locking", - "plone.leadimage", - "volto.preview_image", - "plone.relateditems", - # "design.plone.contenttypes.behavior.address_uo", - # "design.plone.contenttypes.behavior.geolocation_uo", - "design.plone.contenttypes.behavior.contatti_uo", - "design.plone.contenttypes.behavior.argomenti", - "plone.textindexer", - "design.plone.contenttypes.behavior.additional_help_infos", - "plone.translatable", - "kitconcept.seo", - "plone.versioning", - "collective.taxonomy.generated.tipologia_organizzazione", - ), - ) - - def test_uo_ct_title(self): - portal_types = api.portal.get_tool(name="portal_types") - self.assertEqual( - "Unita Organizzativa", portal_types["UnitaOrganizzativa"].title - ) - def test_uo_service_related_service_show_only_services(self): response = self.api_session.get(self.uo.absolute_url() + "?fullobjects") self.assertEqual( diff --git a/src/design/plone/contenttypes/tests/test_filefield_view_mode_serializer.py b/src/design/plone/contenttypes/tests/test_filefield_custom_serializer.py similarity index 83% rename from src/design/plone/contenttypes/tests/test_filefield_view_mode_serializer.py rename to src/design/plone/contenttypes/tests/test_filefield_custom_serializer.py index b1532b2d..2f478e86 100644 --- a/src/design/plone/contenttypes/tests/test_filefield_view_mode_serializer.py +++ b/src/design/plone/contenttypes/tests/test_filefield_custom_serializer.py @@ -14,7 +14,7 @@ import unittest -class SummarySerializerTest(unittest.TestCase): +class FileFieldSerializerTest(unittest.TestCase): layer = DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING def setUp(self): @@ -61,6 +61,11 @@ def test_if_visualize_files_true_so_dsiplay(self): response = self.api_session.get(self.modulo.absolute_url()).json() self.assertIn("@@display-file", response["file_principale"]["download"]) - def test_human_readable_obj_size_in_data(self): + def test_if_enhancedlinks_behavior_active_has_human_readable_obj_size_in_data(self): response = self.api_session.get(self.modulo.absolute_url()).json() self.assertEqual("1 KB", response["file_principale"]["getObjSize"]) + + def test_if_enhancedlinks_behavior_active_has_flag_in_data(self): + response = self.api_session.get(self.modulo.absolute_url()).json() + self.assertIn("enhanced_links_enabled", response["file_principale"]) + self.assertTrue(response["file_principale"]["enhanced_links_enabled"]) diff --git a/src/design/plone/contenttypes/upgrades/configure.zcml b/src/design/plone/contenttypes/upgrades/configure.zcml index cbb18bef..53231884 100644 --- a/src/design/plone/contenttypes/upgrades/configure.zcml +++ b/src/design/plone/contenttypes/upgrades/configure.zcml @@ -828,4 +828,14 @@ handler=".upgrades.to_7031" /> + + + diff --git a/src/design/plone/contenttypes/upgrades/upgrades.py b/src/design/plone/contenttypes/upgrades/upgrades.py index bffa9c19..af7bbfa6 100644 --- a/src/design/plone/contenttypes/upgrades/upgrades.py +++ b/src/design/plone/contenttypes/upgrades/upgrades.py @@ -1596,3 +1596,23 @@ def to_7031(context): for ptype in ["News Item"]: portal_types[ptype].default_view = "view" portal_types[ptype].view_methods = ["view"] + + +def to_7100(context): + installOrReinstallProduct(api.portal.get(), "collective.volto.enhancedlinks") + # add behavior to modulo + portal_types = api.portal.get_tool(name="portal_types") + modulo_behaviors = [x for x in portal_types["Modulo"].behaviors] + if "volto.enhanced_links_enabled" not in modulo_behaviors: + modulo_behaviors.append("volto.enhanced_links_enabled") + portal_types["Modulo"].behaviors = tuple(modulo_behaviors) + + # update index/metadata + brains = api.content.find(portal_type=["File", "Image", "Modulo"]) + tot = len(brains) + i = 0 + for brain in brains: + i += 1 + if i % 100 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + brain.getObject().reindexObject(idxs=["enhanced_links_enabled"]) diff --git a/src/design/plone/contenttypes/vocabularies/configure.zcml b/src/design/plone/contenttypes/vocabularies/configure.zcml index 2928f5a8..3550dc13 100644 --- a/src/design/plone/contenttypes/vocabularies/configure.zcml +++ b/src/design/plone/contenttypes/vocabularies/configure.zcml @@ -60,9 +60,4 @@ component=".reference_vocabularies.UOLocationVocabularyFactory" /> - - diff --git a/src/design/plone/contenttypes/vocabularies/reference_vocabularies.py b/src/design/plone/contenttypes/vocabularies/reference_vocabularies.py index cc46d8ba..bfa2ef40 100644 --- a/src/design/plone/contenttypes/vocabularies/reference_vocabularies.py +++ b/src/design/plone/contenttypes/vocabularies/reference_vocabularies.py @@ -12,7 +12,7 @@ from zope.schema.interfaces import IVocabularyFactory from zope.schema.vocabulary import SimpleTerm from zope.schema.vocabulary import SimpleVocabulary -from zope.site.hooks import getSite +from zope.component.hooks import getSite class ReferencesVocabulary(object): diff --git a/src/design/plone/contenttypes/vocabularies/tags_vocabulary.py b/src/design/plone/contenttypes/vocabularies/tags_vocabulary.py index 4df59b1a..23f71883 100644 --- a/src/design/plone/contenttypes/vocabularies/tags_vocabulary.py +++ b/src/design/plone/contenttypes/vocabularies/tags_vocabulary.py @@ -14,6 +14,72 @@ def __init__(self, token, value): self.value = value +TAGS_MAPPING = [ + ("accesso_all_informazione", _("Accesso all'informazione")), + ("acqua", _("Acqua")), + ("agricoltura", _("Agricoltura")), + ("animale_domestico", _("Animale domestico")), + ("aria", _("Aria")), + ("assistenza_agli_anziani", _("Assistenza agli invalidi")), + ("assistenza_sociale", _("Assistenza sociale")), + ("associazioni", _("Associazioni")), + ("bilancio", _("Bilancio")), + ("commercio_all_ingresso", _("Commercio all'ingrosso")), + ("commercio_al_minuto", _("Commercio al minuto")), + ("commercio_ambulante", _("Commercio ambulante")), + ("comunicazione_istituzionale", _("Comunicazione istituzionale")), + ("comunicazione_politica", _("Comunicazione politica")), + ("concordi", _("Concorsi")), + ("covid_19", _("Covid - 19")), + ("elezioni", _("Elezioni")), + ("energie_rinnovabili", _("Energie rinnovabili")), + ("estero", _("Estero")), + ("foreste", _("Foreste")), + ("formazione_professionale", _("Formazione professionale")), + ("gemellaggi", _("Gemellaggi")), + ("gestione_rifiuti", _("Gestione rifiuti")), + ("giustizia", _("Giustizia")), + ("igiene_pubblica", _("Igiene pubblica")), + ("immigrazione", _("Immigrazione")), + ("imposte", _("Imposte")), + ("imprese", _("Imprese")), + ("inquinamento", _("Inquinamento")), + ("integrazione_sociale", _("Integrazione sociale")), + ("isolamento_termico", _("Isolamento termico")), + ("istruzione", _("Istruzione")), + ("lavoro", _("Lavoro")), + ("matrimonio", _("Matrimonio")), + ("mercato", _("Mercato")), + ("mobilita_sostenibile", _("Mobilità sostenibile")), + ("morte", _("Morte")), + ("nascita", _("Nascita")), + ("parcheggi", _("Parcheggi")), + ("patrimonio_culturale", _("Patrimonio culturale")), + ("pesca", _("Pesca")), + ("piano_di_sviluppo", _("Piano di sviluppo")), + ("pista_ciclabile", _("Pista ciclabile")), + ("politica_commerciale", _("Politica commerciale")), + ("polizia", _("Polizia")), + ("prodotti_alimentari", _("Prodotti alimentari")), + ("protezione_civile", _("Protezione civile")), + ("residenza", _("Residenza")), + ("risposta_alle_emergenze", _("Risposta alle emergenze")), + ("sistema_giuridico", _("Sistema giuridico")), + ("spazio_verde", _("Spazio Verde")), + ("sport", _("Sport")), + ("sviluppo_sostenibile", _("Sviluppo sostenibile")), + ("tassa_sui_servizi", _("Tassa sui servizi")), + ("tempo_libero", _("Tempo libero")), + ("trasparenza_amministrativa", _("Trasparenza amministrativa")), + ("trasporto_pubblico", _("Trasporto pubblico")), + ("turismo", _("Turismo")), + ("urbanizzazione", _("Urbanizzazione")), + ("viaggi", _("Viaggi")), + ("zone_pedonali", _("Zone pedonali")), + ("ztl", _("ZTL")), +] + + @implementer(IVocabularyFactory) class TagsVocabulary(object): """ """ @@ -21,70 +87,7 @@ class TagsVocabulary(object): def __call__(self, context): # Just an example list of content for our vocabulary, # this can be any static or dynamic data, a catalog result for example. - items = [ - VocabItem("accesso_all_informazione", _("Accesso all'informazione")), - VocabItem("acqua", _("Acqua")), - VocabItem("agricoltura", _("Agricoltura")), - VocabItem("animale_domestico", _("Animale domestico")), - VocabItem("aria", _("Aria")), - VocabItem("assistenza_agli_anziani", _("Assistenza agli invalidi")), - VocabItem("assistenza_sociale", _("Assistenza sociale")), - VocabItem("associazioni", _("Associazioni")), - VocabItem("bilancio", _("Bilancio")), - VocabItem("commercio_all_ingresso", _("Commercio all'ingrosso")), - VocabItem("commercio_al_minuto", _("Commercio al minuto")), - VocabItem("commercio_ambulante", _("Commercio ambulante")), - VocabItem("comunicazione_istituzionale", _("Comunicazione istituzionale")), - VocabItem("comunicazione_politica", _("Comunicazione politica")), - VocabItem("concordi", _("Concorsi")), - VocabItem("covid_19", _("Covid - 19")), - VocabItem("elezioni", _("Elezioni")), - VocabItem("energie_rinnovabili", _("Energie rinnovabili")), - VocabItem("estero", _("Estero")), - VocabItem("foreste", _("Foreste")), - VocabItem("formazione_professionale", _("Formazione professionale")), - VocabItem("gemellaggi", _("Gemellaggi")), - VocabItem("gestione_rifiuti", _("Gestione rifiuti")), - VocabItem("giustizia", _("Giustizia")), - VocabItem("igiene_pubblica", _("Igiene pubblica")), - VocabItem("immigrazione", _("Immigrazione")), - VocabItem("imposte", _("Imposte")), - VocabItem("imprese", _("Imprese")), - VocabItem("inquinamento", _("Inquinamento")), - VocabItem("integrazione_sociale", _("Integrazione sociale")), - VocabItem("isolamento_termico", _("Isolamento termico")), - VocabItem("istruzione", _("Istruzione")), - VocabItem("lavoro", _("Lavoro")), - VocabItem("matrimonio", _("Matrimonio")), - VocabItem("mercato", _("Mercato")), - VocabItem("mobilita_sostenibile", _("Mobilità sostenibile")), - VocabItem("morte", _("Morte")), - VocabItem("nascita", _("Nascita")), - VocabItem("parcheggi", _("Parcheggi")), - VocabItem("patrimonio_culturale", _("Patrimonio culturale")), - VocabItem("pesca", _("Pesca")), - VocabItem("piano_di_sviluppo", _("Piano di sviluppo")), - VocabItem("pista_ciclabile", _("Pista ciclabile")), - VocabItem("politica_commerciale", _("Politica commerciale")), - VocabItem("polizia", _("Polizia")), - VocabItem("prodotti_alimentari", _("Prodotti alimentari")), - VocabItem("protezione_civile", _("Protezione civile")), - VocabItem("residenza", _("Residenza")), - VocabItem("risposta_alle_emergenze", _("Risposta alle emergenze")), - VocabItem("sistema_giuridico", _("Sistema giuridico")), - VocabItem("spazio_verde", _("Spazio Verde")), - VocabItem("sport", _("Sport")), - VocabItem("sviluppo_sostenibile", _("Sviluppo sostenibile")), - VocabItem("tassa_sui_servizi", _("Tassa sui servizi")), - VocabItem("tempo_libero", _("Tempo libero")), - VocabItem("trasparenza_amministrativa", _("Trasparenza amministrativa")), - VocabItem("trasporto_pubblico", _("Trasporto pubblico")), - VocabItem("turismo", _("Turismo")), - VocabItem("urbanizzazione", _("Urbanizzazione")), - VocabItem("viaggi", _("Viaggi")), - VocabItem("zone_pedonali", _("Zone pedonali")), - VocabItem("ztl", _("ZTL")), - ] + items = [VocabItem(token=token, value=value) for token, value in TAGS_MAPPING] # Fix context if you are using the vocabulary in DataGridField. # See https://github.com/collective/collective.z3cform.datagridfield/issues/31: # NOQA: 501 From fc01b61b221c98bc09de2aeddff8794b5fe3af21 Mon Sep 17 00:00:00 2001 From: Andrea Cecchi Date: Wed, 6 Mar 2024 09:42:06 +0100 Subject: [PATCH 430/487] Exclude some folders from search (#248) * add new behavior + indexer + adapter for @search queries and exclude from search some folders by default * fix variable name * comments * do not fix restapi version * handle also old-style persona folders --------- Co-authored-by: Mauro Amico --- CHANGES.rst | 7 + base.cfg | 1 + .../contenttypes/adapters/configure.zcml | 2 + .../plone/contenttypes/adapters/query.py | 26 ++ .../contenttypes/behaviors/configure.zcml | 8 + .../behaviors/exclude_from_search.py | 37 ++ .../plone/contenttypes/events/common.py | 19 +- .../plone/contenttypes/indexers/common.py | 5 + .../contenttypes/indexers/configure.zcml | 4 + .../contenttypes/profiles/default/catalog.xml | 3 + .../profiles/default/metadata.xml | 2 +- .../profiles/default/types/Document.xml | 1 + .../profiles/default/types/Folder.xml | 13 + .../test_behavior_exclude_from_search.py | 123 ++++++ .../contenttypes/tests/test_ct_document.py | 2 + .../contenttypes/tests/test_ct_folder.py | 48 +++ .../tests/test_substructure_creation.py | 369 ++++++++++++++++++ .../contenttypes/upgrades/configure.zcml | 10 + .../plone/contenttypes/upgrades/upgrades.py | 64 +++ 19 files changed, 738 insertions(+), 6 deletions(-) create mode 100644 src/design/plone/contenttypes/adapters/query.py create mode 100644 src/design/plone/contenttypes/behaviors/exclude_from_search.py create mode 100644 src/design/plone/contenttypes/profiles/default/types/Folder.xml create mode 100644 src/design/plone/contenttypes/tests/test_behavior_exclude_from_search.py create mode 100644 src/design/plone/contenttypes/tests/test_ct_folder.py create mode 100644 src/design/plone/contenttypes/tests/test_substructure_creation.py diff --git a/CHANGES.rst b/CHANGES.rst index bc479736..f3d2b321 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -12,6 +12,13 @@ Changelog [cekk] - Improve types test for their schema, required fields, fieldsets. [cekk] +- Add *exclude_from_search* indexer and behavior, and enable for Document and Folder. + [cekk] +- Add custom adapter for IZCatalogCompatibleQuery to force all anonymous @search calls to skip items excluded from search. + [cekk] +- Set *exclude_from_search* to True in all Documents/Folders automatically created in createSubfolders event handler, + and add an upgrade-step that fix already created ones. + [cekk] 6.1.14 (2024-02-20) ------------------- diff --git a/base.cfg b/base.cfg index 20b969de..7a9ad1c4 100644 --- a/base.cfg +++ b/base.cfg @@ -137,6 +137,7 @@ eggs = createcoverage [versions] # Don't use a released version of design.plone.contenttypes design.plone.contenttypes = +plone.restapi = [sources] #collective.volto.blocksfield = git https://github.com/collective/collective.volto.blocksfield.git pushurl=git@github.com:collective/collective.volto.blocksfield.git branch=main diff --git a/src/design/plone/contenttypes/adapters/configure.zcml b/src/design/plone/contenttypes/adapters/configure.zcml index 7e7188fd..ebbd9de7 100644 --- a/src/design/plone/contenttypes/adapters/configure.zcml +++ b/src/design/plone/contenttypes/adapters/configure.zcml @@ -21,4 +21,6 @@ name="text" /> + + diff --git a/src/design/plone/contenttypes/adapters/query.py b/src/design/plone/contenttypes/adapters/query.py new file mode 100644 index 00000000..d3b0e924 --- /dev/null +++ b/src/design/plone/contenttypes/adapters/query.py @@ -0,0 +1,26 @@ +from design.plone.contenttypes.interfaces import IDesignPloneContenttypesLayer +from plone.restapi.interfaces import IZCatalogCompatibleQuery +from plone.restapi.search.query import ZCatalogCompatibleQueryAdapter as BaseAdapter +from zope.component import adapter +from zope.interface import implementer +from zope.interface import Interface +from plone import api + + +@implementer(IZCatalogCompatibleQuery) +@adapter(Interface, IDesignPloneContenttypesLayer) +class ZCatalogCompatibleQueryAdapter(BaseAdapter): + """ """ + + def __call__(self, query): + """ + Do not show excluded from search items when anonymous are performing + some catalog searches + """ + query = super().__call__(query=query) + + if api.user.is_anonymous(): + # For the anonymous user, only content that is not "excluded from the search" is found + query["exclude_from_search"] = False + + return query diff --git a/src/design/plone/contenttypes/behaviors/configure.zcml b/src/design/plone/contenttypes/behaviors/configure.zcml index 4cfdb19b..10d55afa 100644 --- a/src/design/plone/contenttypes/behaviors/configure.zcml +++ b/src/design/plone/contenttypes/behaviors/configure.zcml @@ -314,4 +314,12 @@ marker=".update_note.IUpdateNote" /> + diff --git a/src/design/plone/contenttypes/behaviors/exclude_from_search.py b/src/design/plone/contenttypes/behaviors/exclude_from_search.py new file mode 100644 index 00000000..54d18a8b --- /dev/null +++ b/src/design/plone/contenttypes/behaviors/exclude_from_search.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +from design.plone.contenttypes import _ +from plone.autoform.interfaces import IFormFieldProvider +from plone.dexterity.interfaces import IDexterityContent +from plone.supermodel import model +from zope import schema +from zope.component import adapter +from zope.interface import implementer +from zope.interface import provider + + +@provider(IFormFieldProvider) +class IExcludeFromSearch(model.Schema): + """ """ + + exclude_from_search = schema.Bool( + title=_("exclude_from_search_label", default="Escludi dalla ricerca"), + description=_( + "help_exclude_from_search", + default="Se selezionato, questo contenuto non verrà mostrato nelle ricerche del sito per gli utenti anonimi.", + ), + required=False, + default=False, + ) + model.fieldset( + "settings", + fields=["exclude_from_search"], + ) + + +@implementer(IExcludeFromSearch) +@adapter(IDexterityContent) +class ExcludeFromSearch(object): + """ """ + + def __init__(self, context): + self.context = context diff --git a/src/design/plone/contenttypes/events/common.py b/src/design/plone/contenttypes/events/common.py index 51b7c49c..9295226a 100644 --- a/src/design/plone/contenttypes/events/common.py +++ b/src/design/plone/contenttypes/events/common.py @@ -130,11 +130,15 @@ } ], "Servizio": [ - {"id": "modulistica", "title": "Modulistica", "contains": ("File", "Link")}, - {"id": "allegati", "title": "Allegati", "contains": ("File", "Link")}, + { + "id": "modulistica", + "title": "Modulistica", + "allowed_types": ("File", "Link"), + }, + {"id": "allegati", "title": "Allegati", "allowed_types": ("File", "Link")}, ], "UnitaOrganizzativa": [ - {"id": "allegati", "title": "Allegati", "contains": ("File",)}, + {"id": "allegati", "title": "Allegati", "allowed_types": ("File",)}, ], } @@ -160,14 +164,19 @@ def createSubfolders(context, event): return for mapping in subfolders_mapping: if mapping["id"] not in context.keys(): + portal_type = mapping.get("type", "Document") child = api.content.create( container=context, - type=mapping.get("type", "Document"), + type=portal_type, title=mapping["title"], id=mapping["id"], ) - create_default_blocks(context=child) + if portal_type == "Document": + create_default_blocks(context=child) + if portal_type in ["Folder", "Document"]: + child.exclude_from_search = True + child.reindexObject(idxs=["exclude_from_search"]) # select constraints if mapping.get("allowed_types", ()): constraintsChild = ISelectableConstrainTypes(child) diff --git a/src/design/plone/contenttypes/indexers/common.py b/src/design/plone/contenttypes/indexers/common.py index bf23ab58..802c76d2 100644 --- a/src/design/plone/contenttypes/indexers/common.py +++ b/src/design/plone/contenttypes/indexers/common.py @@ -35,3 +35,8 @@ def parent(context): "UID": obj_parent.UID(), "@id": obj_parent.absolute_url(), } + + +@indexer(IDexterityContent) +def exclude_from_search(context): + return getattr(context.aq_base, "exclude_from_search", False) diff --git a/src/design/plone/contenttypes/indexers/configure.zcml b/src/design/plone/contenttypes/indexers/configure.zcml index bcab069a..76f35000 100644 --- a/src/design/plone/contenttypes/indexers/configure.zcml +++ b/src/design/plone/contenttypes/indexers/configure.zcml @@ -73,6 +73,10 @@ factory=".punto_di_contatto.PuntoDiContattoMoreTextToIndex" name="IPuntoDiContatto" /> + diff --git a/src/design/plone/contenttypes/profiles/default/catalog.xml b/src/design/plone/contenttypes/profiles/default/catalog.xml index 4e481d5e..a37b9a79 100644 --- a/src/design/plone/contenttypes/profiles/default/catalog.xml +++ b/src/design/plone/contenttypes/profiles/default/catalog.xml @@ -55,6 +55,9 @@ + + + diff --git a/src/design/plone/contenttypes/profiles/default/metadata.xml b/src/design/plone/contenttypes/profiles/default/metadata.xml index a1d80769..f6ba447d 100644 --- a/src/design/plone/contenttypes/profiles/default/metadata.xml +++ b/src/design/plone/contenttypes/profiles/default/metadata.xml @@ -1,6 +1,6 @@ - 7100 + 7200 profile-redturtle.bandi:default profile-collective.venue:default diff --git a/src/design/plone/contenttypes/profiles/default/types/Document.xml b/src/design/plone/contenttypes/profiles/default/types/Document.xml index 30e528d3..a4b27027 100644 --- a/src/design/plone/contenttypes/profiles/default/types/Document.xml +++ b/src/design/plone/contenttypes/profiles/default/types/Document.xml @@ -17,6 +17,7 @@ + diff --git a/src/design/plone/contenttypes/profiles/default/types/Folder.xml b/src/design/plone/contenttypes/profiles/default/types/Folder.xml new file mode 100644 index 00000000..2ea54936 --- /dev/null +++ b/src/design/plone/contenttypes/profiles/default/types/Folder.xml @@ -0,0 +1,13 @@ + + + + + + + diff --git a/src/design/plone/contenttypes/tests/test_behavior_exclude_from_search.py b/src/design/plone/contenttypes/tests/test_behavior_exclude_from_search.py new file mode 100644 index 00000000..f07296d9 --- /dev/null +++ b/src/design/plone/contenttypes/tests/test_behavior_exclude_from_search.py @@ -0,0 +1,123 @@ +# -*- coding: utf-8 -*- +from design.plone.contenttypes.testing import ( + DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING, +) + +from plone import api +from plone.app.testing import setRoles +from plone.app.testing import SITE_OWNER_NAME +from plone.app.testing import SITE_OWNER_PASSWORD +from plone.app.testing import TEST_USER_ID +from plone.app.testing.helpers import logout +from plone.indexer.interfaces import IIndexableObject +from plone.restapi.interfaces import IZCatalogCompatibleQuery +from plone.restapi.testing import RelativeSession +from transaction import commit +from zope.component import getMultiAdapter +from zope.component import queryMultiAdapter +import unittest + + +class ExcludeFromSearchFunctionalTest(unittest.TestCase): + layer = DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING + maxDiff = None + + def setUp(self): + self.portal = self.layer["portal"] + self.request = self.layer["request"] + self.portal_url = self.portal.absolute_url() + self.catalog = api.portal.get_tool("portal_catalog") + setRoles(self.portal, TEST_USER_ID, ["Manager"]) + + api.user.create( + email="foo@example.com", + username="foo", + password="secret!!!", + ) + + self.news = api.content.create( + container=self.portal, + type="News Item", + title="Test News", + ) + + self.document = api.content.create( + container=self.portal, + type="Document", + title="Test Document", + ) + + api.content.transition(obj=self.news, transition="publish") + api.content.transition(obj=self.news["multimedia"], transition="publish") + api.content.transition(obj=self.document, transition="publish") + + commit() + + self.api_session = RelativeSession(self.portal_url) + self.api_session.headers.update({"Accept": "application/json"}) + self.api_session.auth = (SITE_OWNER_NAME, SITE_OWNER_PASSWORD) + + self.api_session_foo = RelativeSession(self.portal_url) + self.api_session_foo.headers.update({"Accept": "application/json"}) + self.api_session_foo.auth = ("foo", "secret!!!") + + self.api_session_anon = RelativeSession(self.portal_url) + self.api_session_anon.headers.update({"Accept": "application/json"}) + + def tearDown(self): + self.api_session.close() + self.api_session_anon.close() + + def test_exclude_from_search_indexer_for_item_without_behavior(self): + """ + news item does not have the behavior, so it has False by default + """ + self.assertRaises(AttributeError, getattr, self.news, "exclude_from_search") + adapter = queryMultiAdapter((self.news, self.catalog), IIndexableObject) + self.assertFalse(adapter.exclude_from_search) + + def test_exclude_from_search_indexer_for_item_with_behavior_enabled(self): + """ """ + self.assertFalse(self.document.exclude_from_search) + adapter = queryMultiAdapter((self.document, self.catalog), IIndexableObject) + self.assertFalse(adapter.exclude_from_search) + + def test_exclude_from_search_indexer_for_item_with_behavior_enabled_and_set(self): + """ """ + self.assertTrue(self.news["multimedia"].exclude_from_search) + adapter = queryMultiAdapter( + (self.news["multimedia"], self.catalog), IIndexableObject + ) + self.assertTrue(adapter.exclude_from_search) + + def test_adapter_do_not_append_anything_to_query_for_auth_users(self): + catalog_compatible_query = getMultiAdapter( + (self.portal, self.request), IZCatalogCompatibleQuery + )({}) + self.assertEqual({}, catalog_compatible_query) + + def test_adapter_append_exclude_from_search_to_query_for_anon_users(self): + logout() + catalog_compatible_query = getMultiAdapter( + (self.portal, self.request), IZCatalogCompatibleQuery + )({}) + self.assertEqual(catalog_compatible_query, {"exclude_from_search": False}) + + def test_search_return_excluded_contents_for_logged_users(self): + """ """ + resp = self.api_session.get( + "/@search", params={"SearchableText": "multimedia"} + ).json() + self.assertEqual(resp["items_total"], 1) + + resp = self.api_session_foo.get( + "/@search", params={"SearchableText": "multimedia"} + ).json() + self.assertEqual(resp["items_total"], 1) + + def test_search_do_not_return_excluded_contents_for_anon_users(self): + """ """ + resp = self.api_session_anon.get( + "/@search", params={"SearchableText": "multimedia"} + ).json() + self.assertEqual(resp["items_total"], 0) diff --git a/src/design/plone/contenttypes/tests/test_ct_document.py b/src/design/plone/contenttypes/tests/test_ct_document.py index 3262761c..814e1c18 100644 --- a/src/design/plone/contenttypes/tests/test_ct_document.py +++ b/src/design/plone/contenttypes/tests/test_ct_document.py @@ -50,6 +50,7 @@ def test_behaviors_enabled_for_document(self): "design.plone.contenttypes.behavior.show_modified", "kitconcept.seo", "plone.constraintypes", + "design.plone.contenttypes.behavior.exclude_from_search", "plone.leadimage", "volto.preview_image", ), @@ -128,6 +129,7 @@ def test_document_fields_settings_fieldset(self): "id", "versioning_enabled", "show_modified", + "exclude_from_search", "changeNote", ], ) diff --git a/src/design/plone/contenttypes/tests/test_ct_folder.py b/src/design/plone/contenttypes/tests/test_ct_folder.py new file mode 100644 index 00000000..2c71fed0 --- /dev/null +++ b/src/design/plone/contenttypes/tests/test_ct_folder.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- + +from design.plone.contenttypes.testing import ( + DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING, +) +from plone import api +from plone.app.testing import setRoles +from plone.app.testing import TEST_USER_ID +from plone.app.testing import SITE_OWNER_NAME +from plone.app.testing import SITE_OWNER_PASSWORD +from plone.restapi.testing import RelativeSession + +import unittest + + +class TestFolderSchema(unittest.TestCase): + layer = DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING + + def setUp(self): + self.app = self.layer["app"] + self.portal = self.layer["portal"] + self.request = self.layer["request"] + self.portal_url = self.portal.absolute_url() + setRoles(self.portal, TEST_USER_ID, ["Manager"]) + + self.api_session = RelativeSession(self.portal_url) + self.api_session.headers.update({"Accept": "application/json"}) + self.api_session.auth = (SITE_OWNER_NAME, SITE_OWNER_PASSWORD) + + def tearDown(self): + self.api_session.close() + + def test_behaviors_enabled_for_folder(self): + portal_types = api.portal.get_tool(name="portal_types") + self.assertEqual( + portal_types["Folder"].behaviors, + ( + "plone.dublincore", + "plone.namefromtitle", + "plone.allowdiscussion", + "plone.excludefromnavigation", + "plone.shortname", + "plone.constraintypes", + "plone.relateditems", + "plone.nextprevioustoggle", + "design.plone.contenttypes.behavior.exclude_from_search", + ), + ) diff --git a/src/design/plone/contenttypes/tests/test_substructure_creation.py b/src/design/plone/contenttypes/tests/test_substructure_creation.py new file mode 100644 index 00000000..991bc753 --- /dev/null +++ b/src/design/plone/contenttypes/tests/test_substructure_creation.py @@ -0,0 +1,369 @@ +# -*- coding: utf-8 -*- +from design.plone.contenttypes.testing import ( + DESIGN_PLONE_CONTENTTYPES_FUNCTIONAL_TESTING, +) +from plone import api +from plone.app.testing import setRoles +from plone.app.testing import TEST_USER_ID + +import unittest + + +class TestEventCreation(unittest.TestCase): + layer = DESIGN_PLONE_CONTENTTYPES_FUNCTIONAL_TESTING + + def setUp(self): + self.app = self.layer["app"] + self.portal = self.layer["portal"] + self.request = self.layer["request"] + self.portal_url = self.portal.absolute_url() + setRoles(self.portal, TEST_USER_ID, ["Manager"]) + + def test_bando_substructure_created(self): + """ + Should have: + - documenti + - comunicazioni + - esiti + """ + item = api.content.create( + container=self.portal, + type="Bando", + title="Test Bando", + ) + + self.assertEqual( + list(item.keys()), + ["documenti", "comunicazioni", "esiti"], + ) + + self.assertEqual(item["documenti"].portal_type, "Bando Folder Deepening") + self.assertEqual(api.content.get_state(item["documenti"]), "private") + + self.assertEqual(item["comunicazioni"].portal_type, "Bando Folder Deepening") + self.assertEqual(api.content.get_state(item["comunicazioni"]), "private") + + self.assertEqual(item["esiti"].portal_type, "Bando Folder Deepening") + self.assertEqual(api.content.get_state(item["esiti"]), "private") + + def test_documento_substructure_created(self): + """ + Should have: + - multimedia + """ + item = api.content.create( + container=self.portal, + type="Documento", + title="Test", + ) + + self.assertEqual( + list(item.keys()), + ["multimedia"], + ) + + self.assertEqual(item["multimedia"].portal_type, "Document") + self.assertEqual(api.content.get_state(item["multimedia"]), "private") + self.assertEqual(item["multimedia"].constrain_types_mode, 1) + self.assertEqual( + item["multimedia"].locally_allowed_types, + ("Image",), + ) + self.assertTrue(item["multimedia"].exclude_from_search) + + def test_event_substructure_created(self): + """ + Should have: + - immagini + - video + - sponsor_evento + - documenti + """ + item = api.content.create( + container=self.portal, + type="Event", + title="Test", + ) + + self.assertEqual( + list(item.keys()), + ["immagini", "video", "sponsor_evento", "documenti"], + ) + + self.assertEqual(item["immagini"].portal_type, "Document") + self.assertEqual(api.content.get_state(item["immagini"]), "published") + self.assertEqual(item["immagini"].constrain_types_mode, 1) + self.assertEqual( + item["immagini"].locally_allowed_types, + ("Image", "Link"), + ) + self.assertTrue(item["immagini"].exclude_from_search) + + self.assertEqual(item["video"].portal_type, "Document") + self.assertEqual(api.content.get_state(item["video"]), "published") + self.assertEqual(item["video"].constrain_types_mode, 1) + self.assertEqual( + item["video"].locally_allowed_types, + ("Link",), + ) + self.assertTrue(item["video"].exclude_from_search) + + self.assertEqual(item["sponsor_evento"].portal_type, "Document") + self.assertEqual(api.content.get_state(item["sponsor_evento"]), "published") + self.assertEqual(item["sponsor_evento"].constrain_types_mode, 1) + self.assertEqual( + item["sponsor_evento"].locally_allowed_types, + ("Link",), + ) + self.assertTrue(item["sponsor_evento"].exclude_from_search) + + self.assertEqual(item["documenti"].portal_type, "Document") + self.assertEqual(api.content.get_state(item["documenti"]), "published") + self.assertEqual(item["documenti"].constrain_types_mode, 1) + self.assertEqual(item["documenti"].locally_allowed_types, ("File",)) + self.assertTrue(item["documenti"].exclude_from_search) + + def test_incarico_substructure_created(self): + """ + Should have: + - compensi-file + - importi-di-viaggio-e-o-servizi + """ + item = api.content.create( + container=self.portal, + type="Incarico", + title="Test", + ) + + self.assertEqual( + list(item.keys()), + ["compensi-file", "importi-di-viaggio-e-o-servizi"], + ) + + self.assertEqual(item["compensi-file"].portal_type, "Document") + self.assertEqual(api.content.get_state(item["compensi-file"]), "private") + self.assertTrue(item["compensi-file"].exclude_from_search) + + self.assertEqual(item["importi-di-viaggio-e-o-servizi"].portal_type, "Document") + self.assertEqual( + api.content.get_state(item["importi-di-viaggio-e-o-servizi"]), "private" + ) + self.assertTrue(item["importi-di-viaggio-e-o-servizi"].exclude_from_search) + + def test_news_substructure_created(self): + """ + Should have: + - multimedia + - documenti allegati + """ + item = api.content.create( + container=self.portal, + type="News Item", + title="Test News", + ) + + self.assertEqual( + list(item.keys()), + ["multimedia", "documenti-allegati"], + ) + + self.assertEqual(item["multimedia"].portal_type, "Document") + self.assertEqual(api.content.get_state(item["multimedia"]), "private") + self.assertEqual(item["multimedia"].constrain_types_mode, 1) + self.assertEqual( + item["multimedia"].locally_allowed_types, + ("Image", "Link"), + ) + self.assertTrue(item["multimedia"].exclude_from_search) + + self.assertEqual(item["documenti-allegati"].portal_type, "Document") + self.assertEqual(api.content.get_state(item["documenti-allegati"]), "private") + self.assertEqual(item["documenti-allegati"].constrain_types_mode, 1) + self.assertEqual( + item["documenti-allegati"].locally_allowed_types, + ("File", "Image"), + ) + self.assertTrue(item["multimedia"].exclude_from_search) + + def test_venue_substructure_created(self): + """ + Should have: + - multimedia + """ + item = api.content.create( + container=self.portal, + type="Venue", + title="Test", + ) + + self.assertEqual( + list(item.keys()), + ["multimedia"], + ) + + self.assertEqual(item["multimedia"].portal_type, "Folder") + self.assertEqual(api.content.get_state(item["multimedia"]), "published") + self.assertEqual(item["multimedia"].constrain_types_mode, 1) + self.assertEqual( + item["multimedia"].locally_allowed_types, + ("Image", "Link"), + ) + self.assertTrue(item["multimedia"].exclude_from_search) + + def test_persona_substructure_created(self): + """ + Should have: + - foto-e-attivita-politica + - curriculum-vitae + - situazione-patrimoniale + - dichiarazione-dei-redditi + - spese-elettorali + - spese-elettorali + - variazione-situazione-patrimoniale" "altre-cariche + - incarichi + """ + item = api.content.create( + container=self.portal, + type="Persona", + title="Test", + ) + + self.assertEqual( + list(item.keys()), + [ + "foto-e-attivita-politica", + "curriculum-vitae", + "situazione-patrimoniale", + "dichiarazione-dei-redditi", + "spese-elettorali", + "variazione-situazione-patrimoniale", + "altre-cariche", + "incarichi", + ], + ) + + self.assertEqual(item["foto-e-attivita-politica"].portal_type, "Document") + self.assertEqual( + api.content.get_state(item["foto-e-attivita-politica"]), "private" + ) + self.assertEqual(item["foto-e-attivita-politica"].constrain_types_mode, 1) + self.assertEqual( + item["foto-e-attivita-politica"].locally_allowed_types, + ("Image",), + ) + self.assertTrue(item["foto-e-attivita-politica"].exclude_from_search) + + self.assertEqual(item["curriculum-vitae"].portal_type, "Document") + self.assertEqual(api.content.get_state(item["curriculum-vitae"]), "private") + self.assertEqual(item["curriculum-vitae"].constrain_types_mode, 1) + self.assertEqual(item["curriculum-vitae"].locally_allowed_types, ("File",)) + self.assertTrue(item["curriculum-vitae"].exclude_from_search) + + self.assertEqual(item["situazione-patrimoniale"].portal_type, "Document") + self.assertEqual( + api.content.get_state(item["situazione-patrimoniale"]), "private" + ) + self.assertEqual(item["situazione-patrimoniale"].constrain_types_mode, 1) + self.assertEqual( + item["situazione-patrimoniale"].locally_allowed_types, ("File",) + ) + self.assertTrue(item["situazione-patrimoniale"].exclude_from_search) + + self.assertEqual(item["dichiarazione-dei-redditi"].portal_type, "Document") + self.assertEqual( + api.content.get_state(item["dichiarazione-dei-redditi"]), "private" + ) + self.assertEqual(item["dichiarazione-dei-redditi"].constrain_types_mode, 1) + self.assertEqual( + item["dichiarazione-dei-redditi"].locally_allowed_types, ("File",) + ) + self.assertTrue(item["dichiarazione-dei-redditi"].exclude_from_search) + + self.assertEqual(item["spese-elettorali"].portal_type, "Document") + self.assertEqual(api.content.get_state(item["spese-elettorali"]), "private") + self.assertEqual(item["spese-elettorali"].constrain_types_mode, 1) + self.assertEqual(item["spese-elettorali"].locally_allowed_types, ("File",)) + self.assertTrue(item["spese-elettorali"].exclude_from_search) + + self.assertEqual(item["curriculum-vitae"].portal_type, "Document") + self.assertEqual(api.content.get_state(item["curriculum-vitae"]), "private") + self.assertEqual(item["curriculum-vitae"].constrain_types_mode, 1) + self.assertEqual(item["curriculum-vitae"].locally_allowed_types, ("File",)) + self.assertTrue(item["curriculum-vitae"].exclude_from_search) + + self.assertEqual( + item["variazione-situazione-patrimoniale"].portal_type, "Document" + ) + self.assertEqual( + api.content.get_state(item["variazione-situazione-patrimoniale"]), "private" + ) + self.assertEqual( + item["variazione-situazione-patrimoniale"].constrain_types_mode, 1 + ) + self.assertEqual( + item["variazione-situazione-patrimoniale"].locally_allowed_types, ("File",) + ) + self.assertTrue(item["variazione-situazione-patrimoniale"].exclude_from_search) + + self.assertEqual(item["altre-cariche"].portal_type, "Document") + self.assertEqual(api.content.get_state(item["altre-cariche"]), "private") + self.assertEqual(item["altre-cariche"].constrain_types_mode, 1) + self.assertEqual(item["altre-cariche"].locally_allowed_types, ("File",)) + self.assertTrue(item["altre-cariche"].exclude_from_search) + + self.assertEqual(item["incarichi"].portal_type, "Document") + self.assertEqual(api.content.get_state(item["incarichi"]), "private") + self.assertEqual(item["incarichi"].constrain_types_mode, 1) + self.assertEqual(item["incarichi"].locally_allowed_types, ("Incarico",)) + self.assertTrue(item["incarichi"].exclude_from_search) + + def test_servizio_substructure_created(self): + """ + Should have: + - modulistica + - allegati + """ + item = api.content.create( + container=self.portal, + type="Servizio", + title="Test", + ) + + self.assertEqual( + list(item.keys()), + ["modulistica", "allegati"], + ) + + self.assertEqual(item["modulistica"].portal_type, "Document") + self.assertEqual(api.content.get_state(item["modulistica"]), "private") + self.assertEqual(item["modulistica"].constrain_types_mode, 1) + self.assertEqual(item["modulistica"].locally_allowed_types, ("File", "Link")) + self.assertTrue(item["modulistica"].exclude_from_search) + + self.assertEqual(item["allegati"].portal_type, "Document") + self.assertEqual(api.content.get_state(item["allegati"]), "private") + self.assertEqual(item["allegati"].constrain_types_mode, 1) + self.assertEqual(item["allegati"].locally_allowed_types, ("File", "Link")) + self.assertTrue(item["allegati"].exclude_from_search) + + def test_uo_substructure_created(self): + """ + Should have: + - allegati + """ + item = api.content.create( + container=self.portal, + type="UnitaOrganizzativa", + title="Test", + ) + + self.assertEqual( + list(item.keys()), + ["allegati"], + ) + + self.assertEqual(item["allegati"].portal_type, "Document") + self.assertEqual(api.content.get_state(item["allegati"]), "private") + self.assertEqual(item["allegati"].constrain_types_mode, 1) + self.assertEqual(item["allegati"].locally_allowed_types, ("File",)) + self.assertTrue(item["allegati"].exclude_from_search) diff --git a/src/design/plone/contenttypes/upgrades/configure.zcml b/src/design/plone/contenttypes/upgrades/configure.zcml index 53231884..7d4fbff9 100644 --- a/src/design/plone/contenttypes/upgrades/configure.zcml +++ b/src/design/plone/contenttypes/upgrades/configure.zcml @@ -838,4 +838,14 @@ handler=".upgrades.to_7100" /> + + + diff --git a/src/design/plone/contenttypes/upgrades/upgrades.py b/src/design/plone/contenttypes/upgrades/upgrades.py index af7bbfa6..0702a58b 100644 --- a/src/design/plone/contenttypes/upgrades/upgrades.py +++ b/src/design/plone/contenttypes/upgrades/upgrades.py @@ -22,6 +22,7 @@ from zope.intid.interfaces import IIntIds from zope.lifecycleevent import ObjectModifiedEvent from zope.schema import getFields +from design.plone.contenttypes.events.common import SUBFOLDERS_MAPPING import json import logging @@ -1616,3 +1617,66 @@ def to_7100(context): if i % 100 == 0: logger.info("Progress: {}/{}".format(i, tot)) brain.getObject().reindexObject(idxs=["enhanced_links_enabled"]) + + +def to_7200(context): + update_catalog(context) + # add behavior to Document and Folder + bhv = "design.plone.contenttypes.behavior.exclude_from_search" + portal_types = api.portal.get_tool(name="portal_types") + for ptype in ["Document", "Folder"]: + behaviors = [x for x in portal_types[ptype].behaviors] + if bhv not in behaviors: + behaviors.append(bhv) + portal_types[ptype].behaviors = tuple(behaviors) + + # set True to all of already created children + # update index/metadata + brains = api.content.find(portal_type=[x for x in SUBFOLDERS_MAPPING.keys()]) + tot = len(brains) + i = 0 + for brain in brains: + i += 1 + if i % 100 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + container = brain.getObject() + mappings = SUBFOLDERS_MAPPING.get(container.portal_type, []) + persona_old_mapping = [ + { + "id": "foto-e-attivita-politica", + }, + {"id": "curriculum-vitae"}, + {"id": "compensi"}, + { + "id": "importi-di-viaggio-e-o-servizi", + }, + { + "id": "situazione-patrimoniale", + }, + { + "id": "dichiarazione-dei-redditi", + }, + { + "id": "spese-elettorali", + }, + { + "id": "variazione-situazione-patrimoniale", + }, + { + "id": "altre-cariche", + }, + ] + if container.portal_type == "Persona": + # cleanup also some old-style (v2) folders + mappings.extend(persona_old_mapping) + + for mapping in mappings: + child = container.get(mapping["id"], None) + if not child: + continue + if child.portal_type not in ["Folder", "Document"]: + continue + child.exclude_from_search = True + + catalog = api.portal.get_tool(name="portal_catalog") + catalog.manage_reindexIndex(ids=["exclude_from_search"]) From 9ab381ce818ef1dcffb9b1987fef89453488ed52 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Wed, 6 Mar 2024 10:11:14 +0100 Subject: [PATCH 431/487] fix version --- CHANGES.rst | 4 ++-- setup.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index f3d2b321..49e6a266 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,8 +1,8 @@ Changelog ========= -6.1.15 (unreleased) -------------------- +6.2.0 (unreleased) +------------------ - Remove unused behavior (design.plone.contenttypes.behavior.geolocation_uo). [cekk] diff --git a/setup.py b/setup.py index 02c87c81..0251fb93 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.1.15.dev0", + version="6.2.0.dev0", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 389c2d7ed8b44afc3c73fd261aa9ee4bc853ffe8 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Wed, 6 Mar 2024 10:11:58 +0100 Subject: [PATCH 432/487] Preparing release 6.2.0 --- CHANGES.rst | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 49e6a266..4a6767d8 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,7 +1,7 @@ Changelog ========= -6.2.0 (unreleased) +6.2.0 (2024-03-06) ------------------ - Remove unused behavior (design.plone.contenttypes.behavior.geolocation_uo). diff --git a/setup.py b/setup.py index 0251fb93..41ce6c9e 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.2.0.dev0", + version="6.2.0", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From fd90d8be5c78f8c2c7fe8db4482aece18094cd5c Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Wed, 6 Mar 2024 10:12:30 +0100 Subject: [PATCH 433/487] Back to development: 6.2.1 --- CHANGES.rst | 6 ++++++ setup.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 4a6767d8..48dbb8d2 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,6 +1,12 @@ Changelog ========= +6.2.1 (unreleased) +------------------ + +- Nothing changed yet. + + 6.2.0 (2024-03-06) ------------------ diff --git a/setup.py b/setup.py index 41ce6c9e..776ecec4 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.2.0", + version="6.2.1.dev0", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 64ba5147aa9b243057705eaf2172ff93b0ca8b6d Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Thu, 7 Mar 2024 10:20:41 +0100 Subject: [PATCH 434/487] Added check for blocks field in check_luoghi view + updated CHANGES + black (#249) --- CHANGES.rst | 3 ++- .../contenttypes/browser/utils/check_documenti.py | 2 -- .../plone/contenttypes/browser/utils/check_luoghi.py | 11 +++++++---- .../plone/contenttypes/browser/utils/check_persone.py | 3 --- .../plone/contenttypes/browser/utils/check_uo.py | 1 - 5 files changed, 9 insertions(+), 11 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 48dbb8d2..be5afd2b 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,7 +4,8 @@ Changelog 6.2.1 (unreleased) ------------------ -- Nothing changed yet. +- Added check for blocks field in check_luoghi view. + [eikichi18] 6.2.0 (2024-03-06) diff --git a/src/design/plone/contenttypes/browser/utils/check_documenti.py b/src/design/plone/contenttypes/browser/utils/check_documenti.py index be91864c..bbea1c7c 100644 --- a/src/design/plone/contenttypes/browser/utils/check_documenti.py +++ b/src/design/plone/contenttypes/browser/utils/check_documenti.py @@ -40,7 +40,6 @@ def get_related_objects(self, obj, field): return sorted(items, key=lambda k: k["title"]) def has_module(self, documento): - if [ x for x in documento.listFolderContents() @@ -74,7 +73,6 @@ def plone2volto(self, url): return url def get_documenti(self): - if self.is_anonymous(): return [] pc = api.portal.get_tool("portal_catalog") diff --git a/src/design/plone/contenttypes/browser/utils/check_luoghi.py b/src/design/plone/contenttypes/browser/utils/check_luoghi.py index 03970fbc..2bc7ff48 100644 --- a/src/design/plone/contenttypes/browser/utils/check_luoghi.py +++ b/src/design/plone/contenttypes/browser/utils/check_luoghi.py @@ -26,10 +26,14 @@ def information_dict(self, luogo): if getattr(luogo, "zip_code", "") and luogo.zip_code.strip(): indirizzo = True - modalita_accesso = getattr(luogo, "modalita_accesso", "") - res = [x.get("text", "") for x in modalita_accesso["blocks"].values()] - if not [x for x in res if x]: + modalita_accesso = getattr(luogo, "modalita_accesso", {}) + if not isinstance(modalita_accesso, dict): modalita_accesso = "" + else: + modalita_accesso_blocks = modalita_accesso.get("blocks", {}) + res = [x.get("text", "") for x in modalita_accesso_blocks.values()] + if not [x for x in res if x]: + modalita_accesso = "" return { "description": getattr(luogo, "description", "").strip(), @@ -49,7 +53,6 @@ def plone2volto(self, url): return url def get_luoghi(self): - if self.is_anonymous(): return [] pc = api.portal.get_tool("portal_catalog") diff --git a/src/design/plone/contenttypes/browser/utils/check_persone.py b/src/design/plone/contenttypes/browser/utils/check_persone.py index 9298c8a8..4b5ea6ba 100644 --- a/src/design/plone/contenttypes/browser/utils/check_persone.py +++ b/src/design/plone/contenttypes/browser/utils/check_persone.py @@ -46,7 +46,6 @@ def get_related_objects(self, obj, field): return sorted(items, key=lambda k: k["title"]) def back_references(self, source_object, attribute_name): - catalog = getUtility(ICatalog) intids = getUtility(IIntIds) result = [] @@ -68,7 +67,6 @@ def information_dict(self, persona): incarichi_persona = "" if persona.incarichi_persona: - relations = self.get_related_objects(persona, "incarichi_persona") if relations: rel_data = relations[0] @@ -96,7 +94,6 @@ def plone2volto(self, url): return url def get_persone(self): - if self.is_anonymous(): return [] pc = api.portal.get_tool("portal_catalog") diff --git a/src/design/plone/contenttypes/browser/utils/check_uo.py b/src/design/plone/contenttypes/browser/utils/check_uo.py index 6e548ce6..a28947a7 100644 --- a/src/design/plone/contenttypes/browser/utils/check_uo.py +++ b/src/design/plone/contenttypes/browser/utils/check_uo.py @@ -67,7 +67,6 @@ def plone2volto(self, url): return url def get_uos(self): - if self.is_anonymous(): return [] pc = api.portal.get_tool("portal_catalog") From 0960b5ff16775a6d0e2524d357bbc705db48ba5f Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Thu, 7 Mar 2024 15:37:19 +0100 Subject: [PATCH 435/487] Preparing release 6.2.1 --- CHANGES.rst | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index be5afd2b..c5617dc4 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,7 +1,7 @@ Changelog ========= -6.2.1 (unreleased) +6.2.1 (2024-03-07) ------------------ - Added check for blocks field in check_luoghi view. diff --git a/setup.py b/setup.py index 776ecec4..878f10c6 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.2.1.dev0", + version="6.2.1", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From ad64b993bb29f9842b0a3ee075219a22854fe95e Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Thu, 7 Mar 2024 15:37:36 +0100 Subject: [PATCH 436/487] Back to development: 6.2.2 --- CHANGES.rst | 6 ++++++ setup.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index c5617dc4..09eacc7c 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,6 +1,12 @@ Changelog ========= +6.2.2 (unreleased) +------------------ + +- Nothing changed yet. + + 6.2.1 (2024-03-07) ------------------ diff --git a/setup.py b/setup.py index 878f10c6..97aa5cd1 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.2.1", + version="6.2.2.dev0", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From b35a15eee6c81d0973ee64559d5b6267fa013351 Mon Sep 17 00:00:00 2001 From: Roman <72063601+folix-01@users.noreply.github.com> Date: Mon, 18 Mar 2024 14:30:54 +0100 Subject: [PATCH 437/487] Internationalize title (#251) * UnitaOrganizzativa.assesore_riferimento title internationalize * Changelog * Locales --- CHANGES.rst | 3 +- .../interfaces/unita_organizzativa.py | 2 +- .../LC_MESSAGES/design.plone.contenttypes.po | 1769 ++++++++-------- .../locales/design.plone.contenttypes.pot | 1769 ++++++++-------- .../LC_MESSAGES/design.plone.contenttypes.po | 1771 ++++++++-------- .../LC_MESSAGES/design.plone.contenttypes.po | 1779 ++++++++--------- 6 files changed, 3533 insertions(+), 3560 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 09eacc7c..c3bd33df 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,7 +4,8 @@ Changelog 6.2.2 (unreleased) ------------------ -- Nothing changed yet. +- UnitaOrganizzativa.assessore_riferimento title internationalize. + [folix-01] 6.2.1 (2024-03-07) diff --git a/src/design/plone/contenttypes/interfaces/unita_organizzativa.py b/src/design/plone/contenttypes/interfaces/unita_organizzativa.py index b54570f1..a1615a27 100644 --- a/src/design/plone/contenttypes/interfaces/unita_organizzativa.py +++ b/src/design/plone/contenttypes/interfaces/unita_organizzativa.py @@ -58,7 +58,7 @@ class IUnitaOrganizzativa(model.Schema, IDesignPloneContentType): ) assessore_riferimento = RelationList( - title="Assessore di riferimento", + title=_("assessore_riferimento_title", default="Assessore di riferimento"), # vocabolario di riferimento sara' dinamico con i content type # persona presenti all'interno della macro Amministrazione" value_type=RelationChoice( diff --git a/src/design/plone/contenttypes/locales/__pycache__/LC_MESSAGES/design.plone.contenttypes.po b/src/design/plone/contenttypes/locales/__pycache__/LC_MESSAGES/design.plone.contenttypes.po index 38113beb..36f17b52 100644 --- a/src/design/plone/contenttypes/locales/__pycache__/LC_MESSAGES/design.plone.contenttypes.po +++ b/src/design/plone/contenttypes/locales/__pycache__/LC_MESSAGES/design.plone.contenttypes.po @@ -4,7 +4,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2023-01-13 13:15+0000\n" +"POT-Creation-Date: 2024-03-18 13:30+0000\n" "PO-Revision-Date: 2023-01-03 18:01+0100\n" "Last-Translator: Roman Kysil \n" "Language-Team: Language\n" @@ -18,39 +18,23 @@ msgstr "" "Domain: design.plone.contenttypes\n" "Language: __pycache__\n" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:32 -msgid "Abitazione" -msgstr "" - -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:36 -msgid "Accesso al trasporto pubblico" -msgstr "" - -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:59 -msgid "Accesso luoghi della cultura" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:18 +msgid "Accesso all'informazione" msgstr "" #: design/plone/contenttypes/vocabularies/lista_azioni_pratica.py:33 msgid "Accettare" msgstr "" -#: design/plone/contenttypes/vocabularies/document_types_vocabulary.py:34 -msgid "Accordo tra enti" -msgstr "" - -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:52 +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:19 msgid "Acqua" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:194 +#: design/plone/contenttypes/behaviors/configure.zcml:223 msgid "Address Event" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:178 -msgid "Address UO" -msgstr "" - -#: design/plone/contenttypes/behaviors/configure.zcml:186 +#: design/plone/contenttypes/behaviors/configure.zcml:215 msgid "Address Venue" msgstr "" @@ -58,57 +42,53 @@ msgstr "" msgid "Adds fields." msgstr "" -#: design/plone/contenttypes/vocabularies/dataset.py:28 -msgid "Agricoltura, pesca, silvicoltura e prodotti alimentari" +#: design/plone/contenttypes/configure.zcml:66 +msgid "After Plone6 migration syndication is broken" msgstr "" -#: design/plone/contenttypes/browser/manage_content/templates/change_news_type.pt:22 -msgid "All the already existing News Types" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:20 +msgid "Agricoltura" msgstr "" -#: design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt:63 -msgid "All the selected items will be moved to indicated path" +#: design/plone/contenttypes/browser/utils/templates/change_news_type.pt:30 +msgid "All the already existing News Types" msgstr "" -#: design/plone/contenttypes/vocabularies/dataset.py:36 -msgid "Ambiente" +#: design/plone/contenttypes/browser/utils/templates/move_news_items.pt:113 +msgid "All the selected items will be moved to indicated path" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:33 +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:21 msgid "Animale domestico" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:25 -msgid "Anziano" -msgstr "" - -#: design/plone/contenttypes/interfaces/bando.py:134 -#: design/plone/contenttypes/interfaces/documento.py:67 -#: design/plone/contenttypes/interfaces/servizio.py:239 +#: design/plone/contenttypes/interfaces/bando.py:135 +#: design/plone/contenttypes/interfaces/documento.py:97 +#: design/plone/contenttypes/interfaces/servizio.py:328 msgid "Area" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:50 -msgid "Area di parcheggio" -msgstr "" - #: design/plone/contenttypes/behaviors/configure.zcml:49 msgid "Argomenti" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:76 +#: design/plone/contenttypes/behaviors/configure.zcml:94 msgid "Argomenti Bando" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:58 +#: design/plone/contenttypes/behaviors/configure.zcml:76 msgid "Argomenti Document" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:67 +#: design/plone/contenttypes/behaviors/configure.zcml:85 msgid "Argomenti Documento" msgstr "" -#: design/plone/contenttypes/behaviors/argomenti.py:28 +#: design/plone/contenttypes/behaviors/configure.zcml:112 +msgid "Argomenti Link" +msgstr "" + +#: design/plone/contenttypes/behaviors/argomenti.py:32 msgid "Argomenti correlati" msgstr "" @@ -116,20 +96,36 @@ msgstr "" msgid "Argomento" msgstr "" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:73 +#: design/plone/contenttypes/behaviors/configure.zcml:103 +msgid "Argomento Servizio" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:22 +msgid "Aria" +msgstr "" + +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:65 msgid "Assessore di riferimento" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:30 -msgid "Associazione" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:23 +msgid "Assistenza agli invalidi" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:24 +msgid "Assistenza sociale" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:25 +msgid "Associazioni" msgstr "" #: design/plone/contenttypes/vocabularies/lista_azioni_pratica.py:29 msgid "Attivare" msgstr "" -#: design/plone/contenttypes/vocabularies/document_types_vocabulary.py:33 -msgid "Atto normativo" +#: design/plone/contenttypes/interfaces/incarico.py:121 +msgid "Atto di nomina" msgstr "" #: design/plone/contenttypes/interfaces/documento_personale.py:86 @@ -140,70 +136,66 @@ msgstr "" msgid "Autorizzare" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:65 -msgid "Avvio impresa" -msgstr "" - -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:66 -msgid "Avvio nuova attività professionale" -msgstr "" - -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:69 -msgid "Avvio/registrazione filiale" +#: design/plone/contenttypes/behaviors/configure.zcml:223 +msgid "Behavior address per Event." msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:78 -msgid "Bancarotta" +#: design/plone/contenttypes/behaviors/configure.zcml:215 +msgid "Behavior address per Venue." msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:194 -msgid "Behavior address per Event." +#: design/plone/contenttypes/behaviors/configure.zcml:263 +msgid "Behavior contatti per Event." msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:178 -msgid "Behavior address per UO." +#: design/plone/contenttypes/behaviors/configure.zcml:255 +msgid "Behavior contatti per Persona." msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:186 -msgid "Behavior address per Venue." +#: design/plone/contenttypes/behaviors/configure.zcml:247 +msgid "Behavior contatti per Servizio." msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:202 +#: design/plone/contenttypes/behaviors/configure.zcml:231 msgid "Behavior contatti per UO." msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:210 +#: design/plone/contenttypes/behaviors/configure.zcml:239 msgid "Behavior contatti per Venue." msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:234 +#: design/plone/contenttypes/behaviors/configure.zcml:279 msgid "Behavior geolocatable per Event." msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:218 -msgid "Behavior geolocatable per UO." +#: design/plone/contenttypes/behaviors/configure.zcml:271 +msgid "Behavior geolocatable per Venue." msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:226 -msgid "Behavior geolocatable per Venue." +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:26 +msgid "Bilancio" msgstr "" #: design/plone/contenttypes/controlpanels/geolocation_defaults.py:18 msgid "CAP" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:43 -msgid "Cambio di residenza/domicilio" +#: design/plone/contenttypes/behaviors/configure.zcml:306 +msgid "Campi aggiuntivi per la sezione amministrazione trasparente." msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:261 -msgid "Campi aggiuntivi per la sezione amministrazione trasparente." +#: design/plone/contenttypes/behaviors/configure.zcml:324 +msgid "Campo per escludere un contenuto dalle ricerche del sito." msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:270 +#: design/plone/contenttypes/behaviors/configure.zcml:315 msgid "Campo per le note di aggiornamento." msgstr "" +#: design/plone/contenttypes/interfaces/servizio.py:183 +msgid "Canale fisico" +msgstr "" + #: design/plone/contenttypes/vocabularies/mockup.py:26 msgid "Canon 5D IV" msgstr "" @@ -212,39 +204,44 @@ msgstr "" msgid "Cartella Modulistica" msgstr "" -#: design/plone/contenttypes/browser/manage_content/templates/change_news_type.pt:11 +#: design/plone/contenttypes/browser/utils/templates/change_news_type.pt:13 msgid "Change News Type" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:75 -msgid "Chiusura filiale" +#: design/plone/contenttypes/controlpanels/geolocation_defaults.py:23 +msgid "Città" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:74 -msgid "Chiusura impresa e attività professionale" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:28 +msgid "Commercio al minuto" msgstr "" -#: design/plone/contenttypes/controlpanels/geolocation_defaults.py:23 -msgid "Città" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:27 +msgid "Commercio all'ingrosso" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:39 -msgid "Compravendita/affitto casa/edifici/terreni, costruzione o ristrutturazione casa/edificio " +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:29 +msgid "Commercio ambulante" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:36 -msgid "Comunicazione" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:30 +msgid "Comunicazione istituzionale" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:41 -msgid "Condizioni e organizzazione del lavoro" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:31 +msgid "Comunicazione politica" msgstr "" -#: design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt:57 +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:32 +msgid "Concorsi" +msgstr "" + +#: design/plone/contenttypes/browser/utils/templates/move_news_items.pt:104 msgid "Contained by" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:202 +#: design/plone/contenttypes/behaviors/configure.zcml:231 +#: design/plone/contenttypes/behaviors/contatti.py:112 msgid "Contatti" msgstr "" @@ -252,12 +249,12 @@ msgstr "" msgid "Coordinate" msgstr "" -#: design/plone/contenttypes/behaviors/argomenti.py:42 +#: design/plone/contenttypes/behaviors/argomenti.py:46 msgid "Correlato in evidenza" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:47 -msgid "Cultura" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:33 +msgid "Covid - 19" msgstr "" #: design/plone/contenttypes/interfaces/documento_personale.py:130 @@ -269,7 +266,7 @@ msgstr "" msgid "Dataset collegato" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:104 +#: design/plone/contenttypes/behaviors/configure.zcml:141 msgid "Dataset correlati" msgstr "" @@ -277,115 +274,102 @@ msgstr "" msgid "Delegare" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:52 -msgid "Denuncia crimini" -msgstr "" - -#: design/plone/contenttypes/behaviors/configure.zcml:143 +#: design/plone/contenttypes/behaviors/configure.zcml:180 msgid "Descrizione estesa" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:160 +#: design/plone/contenttypes/behaviors/configure.zcml:197 msgid "Descrizione estesa documento" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:152 +#: design/plone/contenttypes/behaviors/configure.zcml:189 msgid "Descrizione estesa servizio" msgstr "" -#: design/plone/contenttypes/configure.zcml:36 +#: design/plone/contenttypes/configure.zcml:32 msgid "Design Plone: Content-types" msgstr "" -#: design/plone/contenttypes/configure.zcml:45 +#: design/plone/contenttypes/configure.zcml:41 +msgid "Design Plone: Content-types (behaviors)" +msgstr "" + +#: design/plone/contenttypes/configure.zcml:50 msgid "Design Plone: Content-types (uninstall)" msgstr "" -#: design/plone/contenttypes/configure.zcml:52 +#: design/plone/contenttypes/configure.zcml:58 msgid "Design Plone: Content-types to 3000" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:55 -msgid "Dichiarazione dei redditi, versamento e riscossione tributi/imposte e contributi" +#: design/plone/contenttypes/configure.zcml:66 +msgid "Design Plone: Fix Syndication after Plone6 Migration" msgstr "" -#: design/plone/contenttypes/behaviors/trasparenza.py:145 +#: design/plone/contenttypes/behaviors/trasparenza.py:146 msgid "Dirigente" msgstr "" -#: design/plone/contenttypes/vocabularies/document_types_vocabulary.py:27 -msgid "Documenti albo pretorio" +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:134 +msgid "Documenti pubblici" msgstr "" -#: design/plone/contenttypes/interfaces/servizio.py:252 +#: design/plone/contenttypes/interfaces/servizio.py:341 #: design/plone/contenttypes/profiles/default/types/Documento.xml msgid "Documento" msgstr "" -#: design/plone/contenttypes/vocabularies/document_types_vocabulary.py:41 -msgid "Documento (tecnico) di supporto" -msgstr "" - #: design/plone/contenttypes/profiles/default/types/Documento_Personale.xml msgid "Documento Personale" msgstr "" -#: design/plone/contenttypes/vocabularies/document_types_vocabulary.py:37 -msgid "Documento attivita politica" -msgstr "" - -#: design/plone/contenttypes/vocabularies/document_types_vocabulary.py:31 -msgid "Documento funzionamento interno" -msgstr "" - -#: design/plone/contenttypes/vocabularies/dataset.py:30 -msgid "Economia e Finanze" -msgstr "" - #: design/plone/contenttypes/profiles/default/types/CartellaModulistica.xml #: design/plone/contenttypes/profiles/default/types/Dataset.xml #: design/plone/contenttypes/profiles/default/types/Documento.xml msgid "Edit" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:45 -msgid "Elezione" -msgstr "" - -#: design/plone/contenttypes/vocabularies/dataset.py:35 -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:61 -msgid "Energia" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:34 +msgid "Elezioni" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:28 -msgid "Famiglia" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:35 +msgid "Energie rinnovabili" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:26 -msgid "Fanciullo" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:36 +msgid "Estero" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:70 -msgid "Finanziamento impresa" +#: design/plone/contenttypes/behaviors/configure.zcml:324 +msgid "Exclude from search" msgstr "" -#: design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt:28 +#: design/plone/contenttypes/browser/utils/templates/move_news_items.pt:51 msgid "Find news with the indicated Path, put attention than generaly sites have the root name \"/Plone/\"" msgstr "" -#: design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt:21 +#: design/plone/contenttypes/browser/utils/templates/move_news_items.pt:29 msgid "Find news with this News Type" msgstr "" -#: design/plone/contenttypes/configure.zcml:52 +#: design/plone/contenttypes/configure.zcml:58 msgid "Fix control panel of design.plone.contenttypes add-on." msgstr "" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:37 +msgid "Foreste" +msgstr "" + #: design/plone/contenttypes/vocabularies/tags_vocabulary.py:38 msgid "Formazione professionale" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:218 +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:39 +msgid "Gemellaggi" +msgstr "" + +#: design/plone/contenttypes/behaviors/configure.zcml:271 msgid "Geolocatable" msgstr "" @@ -394,44 +378,57 @@ msgstr "" msgid "Geolocation default" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:53 -msgid "Gestione dei rifiuti" -msgstr "" - -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:71 -msgid "Gestione personale" -msgstr "" - -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:27 -msgid "Giovane" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:40 +msgid "Gestione rifiuti" msgstr "" #: design/plone/contenttypes/vocabularies/mockup.py:30 msgid "Giovanni" msgstr "" -#: design/plone/contenttypes/vocabularies/dataset.py:42 -msgid "Giustizia, sistema giuridico e sicurezza pubblica" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:41 +msgid "Giustizia" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:42 +msgid "Igiene pubblica" msgstr "" -#: design/plone/contenttypes/vocabularies/dataset.py:37 -msgid "Governo e settore pubblico" +#: design/plone/contenttypes/browser/utils/change_news_type.py:32 +#: design/plone/contenttypes/browser/utils/move_news_items.py:74 +msgid "Il vocabolario dei valori non è stato trovato" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:48 +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:43 msgid "Immigrazione" msgstr "" -#: design/plone/contenttypes/controlpanels/settings.py:154 +#: design/plone/contenttypes/controlpanels/settings.py:106 #: design/plone/contenttypes/profiles/default/controlpanel.xml msgid "Impostazioni Design Plone" msgstr "" -#: design/plone/contenttypes/browser/manage_content/move_news_items.py:33 +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:44 +msgid "Imposte" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:45 +msgid "Imprese" +msgstr "" + +#: design/plone/contenttypes/interfaces/persona.py:68 +msgid "Incarichi" +msgstr "" + +#: design/plone/contenttypes/profiles/default/types/Incarico.xml +msgid "Incarico" +msgstr "" + +#: design/plone/contenttypes/browser/utils/move_news_items.py:34 msgid "Indicated path is not valid" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:170 +#: design/plone/contenttypes/behaviors/configure.zcml:207 msgid "Info per la testata" msgstr "" @@ -439,64 +436,56 @@ msgstr "" msgid "Informare" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:64 -msgid "Informatica e trattamento dei dati" +#: design/plone/contenttypes/behaviors/contatti.py:34 +msgid "Informazioni di contatto" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:49 +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:46 msgid "Inquinamento" msgstr "" -#: design/plone/contenttypes/configure.zcml:36 +#: design/plone/contenttypes/configure.zcml:32 msgid "Installs the design.plone.contenttypes add-on." msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:34 +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:47 msgid "Integrazione sociale" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:28 -msgid "Invalidità" -msgstr "" - #: design/plone/contenttypes/vocabularies/lista_azioni_pratica.py:26 msgid "Iscriversi" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:26 -msgid "Iscrizione scuola/università e/o richiesta borsa di studio" -msgstr "" - -#: design/plone/contenttypes/vocabularies/document_types_vocabulary.py:43 -msgid "Istanza" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:48 +msgid "Isolamento termico" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:31 +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:49 msgid "Istruzione" msgstr "" -#: design/plone/contenttypes/vocabularies/dataset.py:33 -msgid "Istruzione, cultura e sport" +#: design/plone/contenttypes/browser/utils/move_news_items.py:48 +msgid "Items moved with success" msgstr "" -#: design/plone/contenttypes/browser/manage_content/move_news_items.py:47 -msgid "Items moved with success" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:50 +msgid "Lavoro" msgstr "" #: design/plone/contenttypes/vocabularies/lista_azioni_pratica.py:28 msgid "Leggere" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:85 +#: design/plone/contenttypes/behaviors/configure.zcml:122 msgid "Luoghi correlati" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:44 +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:51 msgid "Matrimonio" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:49 -msgid "Matrimonio e/o cambio stato civile" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:52 +msgid "Mercato" msgstr "" #: design/plone/contenttypes/profiles/default/types/Messaggio.xml @@ -515,72 +504,64 @@ msgstr "" msgid "Metadati news" msgstr "" -#: design/plone/contenttypes/vocabularies/document_types_vocabulary.py:28 -msgid "Modulistica" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:53 +msgid "Mobilità sostenibile" msgstr "" #: design/plone/contenttypes/profiles/default/types/Modulo.xml msgid "Modulo" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:50 -msgid "Morte ed eredità" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:54 +msgid "Morte" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:252 +#: design/plone/contenttypes/behaviors/configure.zcml:297 msgid "Mostra la data di modifica." msgstr "" -#: design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt:70 +#: design/plone/contenttypes/browser/utils/templates/move_news_items.pt:124 msgid "Move" msgstr "" -#: design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt:11 +#: design/plone/contenttypes/browser/utils/templates/move_news_items.pt:13 msgid "Move News Items" msgstr "" -#: design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt:62 +#: design/plone/contenttypes/browser/utils/templates/move_news_items.pt:110 msgid "Move to Path" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:243 +#: design/plone/contenttypes/behaviors/configure.zcml:288 msgid "Multi File" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:48 -msgid "Nascita di un bambino, richiesta adozioni" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:55 +msgid "Nascita" msgstr "" #: design/plone/contenttypes/controlpanels/geolocation_defaults.py:28 msgid "Nazione" msgstr "" -#: design/plone/contenttypes/browser/manage_content/templates/change_news_type.pt:21 -#: design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt:20 +#: design/plone/contenttypes/browser/utils/templates/change_news_type.pt:27 +#: design/plone/contenttypes/browser/utils/templates/move_news_items.pt:26 msgid "News Type" msgstr "" -#: design/plone/contenttypes/browser/manage_content/templates/change_news_type.pt:30 +#: design/plone/contenttypes/browser/utils/templates/change_news_type.pt:48 msgid "News Type to substitute" msgstr "" #. Default: "Nome e cognome" -#: design/plone/contenttypes/restapi/services/types/get.py:152 +#: design/plone/contenttypes/restapi/services/types/get.py:163 msgid "Nome e Cognome" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:73 -msgid "Notifiche autorità" -msgstr "" - -#: design/plone/contenttypes/interfaces/persona.py:48 +#: design/plone/contenttypes/interfaces/persona.py:51 msgid "Organizzazione di riferimento" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:72 -msgid "Pagamento tasse, iva e dogane" -msgstr "" - #: design/plone/contenttypes/vocabularies/lista_azioni_pratica.py:25 msgid "Pagare" msgstr "" @@ -589,84 +570,100 @@ msgstr "" msgid "Paperino" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:81 -msgid "Partecipazione ad appalti pubblici nazionali e trasfrontalieri" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:56 +msgid "Parcheggi" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:33 -msgid "Pensionamento" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:57 +msgid "Patrimonio culturale" msgstr "" -#: design/plone/contenttypes/profiles/default/types/Persona.xml +#: design/plone/contenttypes/interfaces/incarico.py:54 msgid "Persona" msgstr "" -#: design/plone/contenttypes/behaviors/evento.py:50 -msgid "Persona dell'amministrazione" +#: design/plone/contenttypes/profiles/default/types/Persona.xml +msgid "Persona pubblica" msgstr "" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:92 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:84 msgid "Persone della struttura" msgstr "" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:58 +msgid "Pesca" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:59 +msgid "Piano di sviluppo" +msgstr "" + #: design/plone/contenttypes/vocabularies/mockup.py:27 msgid "Pippo" msgstr "" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:60 +msgid "Pista ciclabile" +msgstr "" + #: design/plone/contenttypes/vocabularies/mockup.py:28 msgid "Pluto" msgstr "" -#: design/plone/contenttypes/vocabularies/dataset.py:45 -msgid "Popolazione e società" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:61 +msgid "Politica commerciale" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:60 -msgid "Possesso, cura, smarrimento animale da compagnia" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:62 +msgid "Polizia" msgstr "" #: design/plone/contenttypes/profiles/default/types/Pratica.xml msgid "Pratica" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:51 -msgid "Prenotazione e disdetta visite/esami" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:63 +msgid "Prodotti alimentari" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:35 -msgid "Protezione sociale" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:64 +msgid "Protezione civile" msgstr "" -#: design/plone/contenttypes/browser/manage_content/templates/change_news_type.pt:13 -msgid "Questo tool viene usato per cambiare il valore del campo 'Tipologia Notizia' in tutte le notizie che hanno il valore del campo selezionato. Fa anche il giro su tutti i blocchi elenco" +#: design/plone/contenttypes/behaviors/contatti.py:78 +msgid "Punti di contatto" msgstr "" -#: design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt:13 -msgid "Questo tool viene usato per trovare e spostare le Notizie con una Tipologia Notizia determinata." +#: design/plone/contenttypes/profiles/default/types/PuntoDiContatto.xml +msgid "Punto di Contatto" +msgstr "" + +#: design/plone/contenttypes/browser/utils/templates/change_news_type.pt:15 +msgid "Questo tool viene usato per cambiare il valore del campo 'Tipologia Notizia' in tutte le notizie che hanno il valore del campo selezionato. Fa anche il giro su tutti i blocchi elenco" msgstr "" -#: design/plone/contenttypes/vocabularies/dataset.py:44 -msgid "Regioni e città" +#: design/plone/contenttypes/browser/utils/templates/move_news_items.pt:15 +msgid "Questo tool viene usato per trovare e spostare le Notizie con una Tipologia Notizia determinata." msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:68 -msgid "Registrazione impresa transfrontalier" +#: design/plone/contenttypes/configure.zcml:41 +msgid "Registers taxonomies." msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:35 -msgid "Registrazione/possesso veicolo" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:65 +msgid "Residenza" msgstr "" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:45 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:49 msgid "Responsabile" msgstr "" -#: design/plone/contenttypes/behaviors/trasparenza.py:129 -msgid "Responsabile procedimento" +#: design/plone/contenttypes/interfaces/incarico.py:89 +msgid "Responsabile della struttura" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:31 -msgid "Ricerca di lavoro, avvio nuovo lavoro, disoccupazione" +#: design/plone/contenttypes/behaviors/trasparenza.py:130 +msgid "Responsabile procedimento" msgstr "" #: design/plone/contenttypes/profiles/default/types/RicevutaPagamento.xml @@ -677,40 +674,19 @@ msgstr "" msgid "Richiedere" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:67 -msgid "Richiesta licenze/permessi/certificati" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:66 +msgid "Risposta alle emergenze" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:34 -msgid "Richiesta o rinnovo patente" -msgstr "" - -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:46 -msgid "Richiesta passaporto, visto e assistenza viaggi internazionali" -msgstr "" - -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:76 -msgid "Ristrutturazione impresa" -msgstr "" - -#: design/plone/contenttypes/vocabularies/dataset.py:38 -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:54 -msgid "Salute" -msgstr "" - -#: design/plone/contenttypes/vocabularies/dataset.py:46 -msgid "Scienza e tecnologia" -msgstr "" - -#: design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt:27 +#: design/plone/contenttypes/browser/utils/templates/move_news_items.pt:47 msgid "Search Path" msgstr "" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:114 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:104 msgid "Sede" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:114 +#: design/plone/contenttypes/behaviors/configure.zcml:151 msgid "Servizi correlati" msgstr "" @@ -722,129 +698,128 @@ msgstr "" msgid "Servizio collegato" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:252 +#: design/plone/contenttypes/behaviors/configure.zcml:297 msgid "Show modified" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:56 -msgid "Sicurezza internazionale" -msgstr "" - -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:55 -msgid "Sicurezza pubblica" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:67 +msgid "Sistema giuridico" msgstr "" #: design/plone/contenttypes/vocabularies/mockup.py:25 msgid "Sony Aplha 7R III" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:57 -msgid "Spazio verde" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:68 +msgid "Spazio Verde" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:58 +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:69 msgid "Sport" msgstr "" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:37 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:41 msgid "Struttura" msgstr "" -#: design/plone/contenttypes/behaviors/strutture_correlate.py:20 +#: design/plone/contenttypes/behaviors/strutture_correlate.py:21 msgid "Struttura politica coinvolta" msgstr "" -#: design/plone/contenttypes/behaviors/luogo.py:74 +#: design/plone/contenttypes/behaviors/luogo.py:75 msgid "Struttura responsabile" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:124 +#: design/plone/contenttypes/behaviors/configure.zcml:161 msgid "Strutture correlate" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:29 -msgid "Studente" +#: design/plone/contenttypes/browser/utils/templates/change_news_type.pt:74 +msgid "Substitute" msgstr "" -#: design/plone/contenttypes/browser/manage_content/templates/change_news_type.pt:43 -msgid "Substitute" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:70 +msgid "Sviluppo sostenibile" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:71 +msgid "Tassa sui servizi" msgstr "" #: design/plone/contenttypes/behaviors/configure.zcml:49 msgid "Tassonomia argomenti" msgstr "" +#: design/plone/contenttypes/behaviors/configure.zcml:67 +msgid "Tassonomia argomenti evento" +msgstr "" + #: design/plone/contenttypes/behaviors/configure.zcml:58 -msgid "Tassonomia argomenti per i Document" +msgid "Tassonomia argomenti news" msgstr "" -#: design/plone/contenttypes/vocabularies/dataset.py:39 -msgid "Tematiche internazionali" +#: design/plone/contenttypes/behaviors/configure.zcml:76 +msgid "Tassonomia argomenti per i Document" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:46 +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:72 msgid "Tempo libero" msgstr "" -#: design/plone/contenttypes/browser/manage_content/templates/change_news_type.pt:31 +#: design/plone/contenttypes/browser/utils/templates/change_news_type.pt:52 msgid "The News Type selected above will be substituted by the selected value" msgstr "" -#: design/plone/contenttypes/browser/manage_content/change_news_type.py:97 +#: design/plone/contenttypes/browser/utils/change_news_type.py:108 msgid "The News Types was changed with success" msgstr "" -#: design/plone/contenttypes/browser/manage_content/change_news_type.py:55 +#: design/plone/contenttypes/browser/utils/change_news_type.py:64 msgid "The new News Type was not found between available values" msgstr "" -#: design/plone/contenttypes/browser/manage_content/change_news_type.py:49 +#: design/plone/contenttypes/browser/utils/change_news_type.py:58 msgid "The new type field was not populated" msgstr "" -#: design/plone/contenttypes/browser/manage_content/change_news_type.py:61 +#: design/plone/contenttypes/browser/utils/change_news_type.py:70 msgid "The old News Type was not found between available values" msgstr "" -#: design/plone/contenttypes/browser/manage_content/change_news_type.py:43 +#: design/plone/contenttypes/browser/utils/change_news_type.py:52 msgid "The old type field was not populated" msgstr "" -#: design/plone/contenttypes/browser/manage_content/move_news_items.py:51 +#: design/plone/contenttypes/browser/utils/move_news_items.py:52 msgid "The path was not indicated" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:51 -msgid "Traffico urbano" -msgstr "" - -#: design/plone/contenttypes/behaviors/configure.zcml:261 +#: design/plone/contenttypes/behaviors/configure.zcml:306 msgid "Trasparenza" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:43 -msgid "Trasporto" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:73 +msgid "Trasparenza amministrativa" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:59 -msgid "Trasporto stradale" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:74 +msgid "Trasporto pubblico" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:243 +#: design/plone/contenttypes/behaviors/configure.zcml:288 msgid "Tre campi file aggiuntivi." msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:60 +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:75 msgid "Turismo" msgstr "" -#: design/plone/contenttypes/interfaces/bando.py:117 -#: design/plone/contenttypes/interfaces/documento.py:50 -#: design/plone/contenttypes/interfaces/servizio.py:225 +#: design/plone/contenttypes/interfaces/bando.py:118 +#: design/plone/contenttypes/interfaces/documento.py:80 msgid "Ufficio responsabile" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:134 +#: design/plone/contenttypes/behaviors/configure.zcml:171 msgid "Ulteriori campi aiuto testuali" msgstr "" @@ -852,7 +827,11 @@ msgstr "" msgid "Un modulo compilabile." msgstr "" -#: design/plone/contenttypes/configure.zcml:45 +#: design/plone/contenttypes/browser/utils/templates/utils.pt:15 +msgid "Una raccolta di utility per i contenuti agid" +msgstr "" + +#: design/plone/contenttypes/configure.zcml:50 msgid "Uninstalls the design.plone.contenttypes add-on." msgstr "" @@ -864,65 +843,87 @@ msgstr "" msgid "Unità amministrative responsabili" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:270 -msgid "Update note" +#: design/plone/contenttypes/interfaces/incarico.py:71 +msgid "Unità organizzativa" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:37 -msgid "Urbanistica ed edilizia" +#: design/plone/contenttypes/interfaces/servizio.py:314 +msgid "Unità organizzativa responsabile" +msgstr "" + +#: design/plone/contenttypes/behaviors/configure.zcml:315 +msgid "Update note" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:77 -msgid "Vendita impresa" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:76 +msgid "Urbanizzazione" msgstr "" #: design/plone/contenttypes/controlpanels/geolocation_defaults.py:13 msgid "Via" msgstr "" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:77 +msgid "Viaggi" +msgstr "" + #: design/plone/contenttypes/profiles/default/types/CartellaModulistica.xml #: design/plone/contenttypes/profiles/default/types/Dataset.xml #: design/plone/contenttypes/profiles/default/types/Documento.xml msgid "View" msgstr "" -#. Default: "A chi si rivolge questo servizio e chi può usufruirne." -#: design/plone/contenttypes/interfaces/servizio.py:53 +#: design/plone/contenttypes/browser/utils/templates/utils.pt:13 +msgid "Viste di utility per Design Plone Contenttypes" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:79 +msgid "ZTL" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:78 +msgid "Zone pedonali" +msgstr "" + +#. Default: "Descrizione testuale dei principali destinatari dell'Evento" +#: design/plone/contenttypes/behaviors/evento.py:43 +#: design/plone/contenttypes/interfaces/servizio.py:98 msgid "a_chi_si_rivolge_help" msgstr "" -#. Default: "A chi si rivolge" -#: design/plone/contenttypes/interfaces/servizio.py:51 +#. Default: "A chi è rivolto" +#: design/plone/contenttypes/behaviors/evento.py:41 +#: design/plone/contenttypes/interfaces/servizio.py:96 msgid "a_chi_si_rivolge_label" msgstr "" #. Default: "Seleziona l'ufficio di comunicazione responsabile di questa notizia/comunicato stampa." -#: design/plone/contenttypes/behaviors/news_additional_fields.py:47 +#: design/plone/contenttypes/behaviors/news_additional_fields.py:39 msgid "a_cura_di_help" msgstr "" #. Default: "A cura di" -#: design/plone/contenttypes/behaviors/news_additional_fields.py:46 +#: design/plone/contenttypes/behaviors/news_additional_fields.py:38 msgid "a_cura_di_label" msgstr "" #. Default: "Seleziona una lista di persone dell'amministrazione citate in questa notizia/comunicato stampa. Questa informazione verrà mostrata nella sezione \"A cura di\"." -#: design/plone/contenttypes/behaviors/news_additional_fields.py:59 +#: design/plone/contenttypes/behaviors/news_additional_fields.py:51 msgid "a_cura_di_persone_help" msgstr "" #. Default: "Persone" -#: design/plone/contenttypes/behaviors/news_additional_fields.py:58 +#: design/plone/contenttypes/behaviors/news_additional_fields.py:50 msgid "a_cura_di_persone_label" msgstr "" #. Default: "Accedere al servizio" -#: design/plone/contenttypes/interfaces/servizio.py:370 +#: design/plone/contenttypes/interfaces/servizio.py:481 msgid "accedi_al_servizio_label" msgstr "" #. Default: "Modalità di accesso" -#: design/plone/contenttypes/behaviors/luogo.py:171 +#: design/plone/contenttypes/behaviors/luogo.py:140 msgid "accesso_label" msgstr "" @@ -932,37 +933,37 @@ msgid "allegato" msgstr "" #. Default: "Indicare, se esistono, altre modalità di invio." -#: design/plone/contenttypes/behaviors/trasparenza.py:189 +#: design/plone/contenttypes/behaviors/trasparenza.py:190 msgid "altre_modalita_invio_help" msgstr "" #. Default: "Altre modalità di invio" -#: design/plone/contenttypes/behaviors/trasparenza.py:185 +#: design/plone/contenttypes/behaviors/trasparenza.py:186 msgid "altre_modalita_invio_label" msgstr "" #. Default: "Seleziona la lista dei documenti di supporto collegati a questo servizio." -#: design/plone/contenttypes/interfaces/servizio.py:246 +#: design/plone/contenttypes/interfaces/servizio.py:335 msgid "altri_documenti_help" msgstr "" #. Default: "Date and time of the opening of the announcement. Use this field if you want to set a specific opening date. If not set, the announcement will be open immediately." -#: design/plone/contenttypes/interfaces/bando.py:56 +#: design/plone/contenttypes/interfaces/bando.py:57 msgid "apertura_bando_help" msgstr "" #. Default: "Opening date" -#: design/plone/contenttypes/interfaces/bando.py:55 +#: design/plone/contenttypes/interfaces/bando.py:56 msgid "apertura_bando_label" msgstr "" #. Default: "Area" -#: design/plone/contenttypes/interfaces/servizio.py:231 +#: design/plone/contenttypes/interfaces/servizio.py:320 msgid "area" msgstr "" #. Default: "Seleziona l'area da cui dipende questo servizio." -#: design/plone/contenttypes/interfaces/servizio.py:234 +#: design/plone/contenttypes/interfaces/servizio.py:323 msgid "area_help" msgstr "" @@ -972,14 +973,14 @@ msgid "area_responsabile_documento_personale" msgstr "" #. Default: "Seleziona l'area amministrativa responsabile del documento." -#: design/plone/contenttypes/interfaces/bando.py:127 -#: design/plone/contenttypes/interfaces/documento.py:60 +#: design/plone/contenttypes/interfaces/bando.py:128 +#: design/plone/contenttypes/interfaces/documento.py:90 msgid "area_responsabile_help" msgstr "" #. Default: "Area responsabile del documento" -#: design/plone/contenttypes/interfaces/bando.py:123 -#: design/plone/contenttypes/interfaces/documento.py:56 +#: design/plone/contenttypes/interfaces/bando.py:124 +#: design/plone/contenttypes/interfaces/documento.py:86 msgid "area_responsabile_label" msgstr "" @@ -989,47 +990,42 @@ msgid "argomenti_utenti" msgstr "" #. Default: "Inserire l'assessore di riferimento della struttura, se esiste." -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:76 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:68 msgid "assessore_riferimento_help" msgstr "" +#. Default: "Assessore di riferimento" +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:61 +msgid "assessore_riferimento_title" +msgstr "" + #. Default: "Indicare, se la esistono, atti e documenti a corredo dell'istanza." -#: design/plone/contenttypes/behaviors/trasparenza.py:200 +#: design/plone/contenttypes/behaviors/trasparenza.py:201 msgid "atti_documenti_corredo_help" msgstr "" #. Default: "Atti e documenti a corredo dell'istanza" -#: design/plone/contenttypes/behaviors/trasparenza.py:196 +#: design/plone/contenttypes/behaviors/trasparenza.py:197 msgid "atti_documenti_corredo_label" msgstr "" -#. Default: "Inserire un file contenente l'atto di nomina della persona." -#: design/plone/contenttypes/interfaces/persona.py:160 -msgid "atto_nomina_help" +#. Default: "Inserire riferimento all'atto di nomina della persona" +#: design/plone/contenttypes/interfaces/incarico.py:114 +msgid "atto_nomina_incarico_help" msgstr "" #. Default: "Atto di nomina" -#: design/plone/contenttypes/interfaces/persona.py:158 -msgid "atto_nomina_label" -msgstr "" - -#. Default: "Autenticazione" -#: design/plone/contenttypes/interfaces/servizio.py:121 -msgid "autenticazione" -msgstr "" - -#. Default: "Indicare, se previste, le modalità di autenticazione necessarie per poter accedere al servizio." -#: design/plone/contenttypes/interfaces/servizio.py:122 -msgid "autenticazione_help" +#: design/plone/contenttypes/interfaces/incarico.py:110 +msgid "atto_nomina_incarico_label" msgstr "" #. Default: "Seleziona una lista di autori che hanno pubblicato il documento. Possono essere Persone o Unità Organizzative." -#: design/plone/contenttypes/interfaces/documento.py:76 +#: design/plone/contenttypes/interfaces/documento.py:106 msgid "autori_help" msgstr "" #. Default: "Autore/i" -#: design/plone/contenttypes/interfaces/documento.py:72 +#: design/plone/contenttypes/interfaces/documento.py:102 msgid "autori_label" msgstr "" @@ -1049,52 +1045,72 @@ msgid "azioni_utente" msgstr "" #. Default: "Solo per persona politica: testo descrittivo che riporta la biografia della persona." -#: design/plone/contenttypes/interfaces/persona.py:107 +#: design/plone/contenttypes/interfaces/persona.py:94 msgid "biografia_help" msgstr "" #. Default: "Biografia" -#: design/plone/contenttypes/interfaces/persona.py:106 +#: design/plone/contenttypes/interfaces/persona.py:93 msgid "biografia_label" msgstr "" #. Default: "Canale digitale" -#: design/plone/contenttypes/interfaces/servizio.py:111 +#: design/plone/contenttypes/interfaces/servizio.py:156 msgid "canale_digitale" msgstr "" -#. Default: "Collegamento con l'eventuale canale digitale di attivazione del servizio." -#: design/plone/contenttypes/interfaces/servizio.py:112 +#. Default: "Testo di introduzione del canale digitale" +#: design/plone/contenttypes/interfaces/servizio.py:157 msgid "canale_digitale_help" msgstr "" +#. Default: "Link al canale digitale" +#: design/plone/contenttypes/interfaces/servizio.py:165 +msgid "canale_digitale_link" +msgstr "" + +#. Default: "Collegamento con l'eventuale canale digitale di attivazione del servizio." +#: design/plone/contenttypes/interfaces/servizio.py:166 +msgid "canale_digitale_link_help" +msgstr "" + #. Default: "Canale digitale servizio collegato" #: design/plone/contenttypes/interfaces/documento_personale.py:108 msgid "canale_digitale_servizio" msgstr "" +#. Default: "Canale fisico" +#: design/plone/contenttypes/interfaces/servizio.py:175 +msgid "canale_fisico" +msgstr "" + +#. Default: "Unità organizzative per la fruizione del servizio" +#: design/plone/contenttypes/interfaces/servizio.py:176 +msgid "canale_fisico_help" +msgstr "" + #. Default: "Casi particolari" -#: design/plone/contenttypes/interfaces/servizio.py:205 +#: design/plone/contenttypes/interfaces/servizio.py:291 msgid "casi_particolari" msgstr "" #. Default: "Descrizione degli evetuali casi particolari riferiti alla fruibilità di questo servizio." -#: design/plone/contenttypes/interfaces/servizio.py:207 +#: design/plone/contenttypes/interfaces/servizio.py:293 msgid "casi_particolari_help" msgstr "" #. Default: "Casi particolari" -#: design/plone/contenttypes/interfaces/servizio.py:401 +#: design/plone/contenttypes/interfaces/servizio.py:514 msgid "casi_particolari_label" msgstr "" #. Default: "Descrizione di chi può presentare domanda per usufruire del servizio e delle diverse casistiche." -#: design/plone/contenttypes/interfaces/servizio.py:62 +#: design/plone/contenttypes/interfaces/servizio.py:107 msgid "chi_puo_presentare_help" msgstr "" #. Default: "Chi può presentare" -#: design/plone/contenttypes/interfaces/servizio.py:60 +#: design/plone/contenttypes/interfaces/servizio.py:105 msgid "chi_puo_presentare_label" msgstr "" @@ -1104,37 +1120,57 @@ msgid "circoscrizione" msgstr "" #. Default: "Codice dell'ente erogatore (ipa)" -#: design/plone/contenttypes/interfaces/servizio.py:268 +#: design/plone/contenttypes/interfaces/servizio.py:357 msgid "codice_ipa" msgstr "" #. Default: "Specificare il nome dell’organizzazione, come indicato nell’Indice della Pubblica Amministrazione (IPA), che esercita uno specifico ruolo sul Servizio." -#: design/plone/contenttypes/interfaces/servizio.py:270 +#: design/plone/contenttypes/interfaces/servizio.py:359 msgid "codice_ipa_help" msgstr "" -#. Default: "Come si fa" -#: design/plone/contenttypes/interfaces/servizio.py:80 +#. Default: "Come fare" +#: design/plone/contenttypes/interfaces/servizio.py:125 msgid "come_si_fa" msgstr "" #. Default: "Descrizione della procedura da seguire per poter usufruire del servizio." -#: design/plone/contenttypes/interfaces/servizio.py:82 +#: design/plone/contenttypes/interfaces/servizio.py:127 msgid "come_si_fa_help" msgstr "" +#. Default: "Solo per incarico politico: compensi di qualsiasi natura connessi all'assunzione della carica." +#: design/plone/contenttypes/interfaces/incarico.py:21 +msgid "compensi_incarico_help" +msgstr "" + +#. Default: "Compensi" +#: design/plone/contenttypes/interfaces/incarico.py:17 +msgid "compensi_incarico_label" +msgstr "" + #. Default: "Descrizione del ruolo e dei compiti della persona." -#: design/plone/contenttypes/interfaces/persona.py:69 +#: design/plone/contenttypes/interfaces/persona.py:77 msgid "competenze_help" msgstr "" #. Default: "Competenze" -#: design/plone/contenttypes/interfaces/persona.py:68 +#: design/plone/contenttypes/interfaces/persona.py:76 msgid "competenze_label" msgstr "" -#. Default: "Informazioni di contatto generiche" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:137 +#. Default: "Condizioni di servizio" +#: design/plone/contenttypes/interfaces/servizio.py:388 +msgid "condizioni_di_servizio" +msgstr "" + +#. Default: "Contatti dell'unità organizzativa." +#: design/plone/contenttypes/behaviors/contatti.py:27 +msgid "contact_info_help" +msgstr "" + +#. Default: "Punti di contatto dell'unità organizzativa" +#: design/plone/contenttypes/behaviors/contatti.py:23 msgid "contact_info_label" msgstr "" @@ -1144,9 +1180,9 @@ msgid "contatti" msgstr "" #. Default: "Contatti" -#: design/plone/contenttypes/behaviors/address.py:52 -#: design/plone/contenttypes/behaviors/contatti.py:76 -#: design/plone/contenttypes/behaviors/evento.py:215 +#: design/plone/contenttypes/behaviors/contatti.py:57 +#: design/plone/contenttypes/behaviors/evento.py:170 +#: design/plone/contenttypes/behaviors/geolocation.py:18 msgid "contatti_label" msgstr "" @@ -1156,116 +1192,111 @@ msgid "contenuto" msgstr "" #. Default: "Indicare se il servizio si riferisce ad una particolare area geografica o all'intero territorio di riferimento." -#: design/plone/contenttypes/interfaces/servizio.py:72 +#: design/plone/contenttypes/interfaces/servizio.py:117 msgid "copertura_geografica_help" msgstr "" #. Default: "Copertura geografica" -#: design/plone/contenttypes/interfaces/servizio.py:70 +#: design/plone/contenttypes/interfaces/servizio.py:115 msgid "copertura_geografica_label" msgstr "" #. Default: "Contenuti collegati" -#: design/plone/contenttypes/behaviors/argomenti.py:74 +#: design/plone/contenttypes/behaviors/argomenti.py:108 #: design/plone/contenttypes/behaviors/dataset_correlati.py:40 -#: design/plone/contenttypes/behaviors/servizi_correlati.py:43 +#: design/plone/contenttypes/behaviors/news_additional_fields.py:120 msgid "correlati_label" msgstr "" #. Default: "Seleziona un correlato da mettere in evidenza per questo contenuto." -#: design/plone/contenttypes/behaviors/argomenti.py:36 +#: design/plone/contenttypes/behaviors/argomenti.py:40 msgid "correlato_in_evidenza_help" msgstr "" #. Default: "Correlato in evidenza" -#: design/plone/contenttypes/behaviors/argomenti.py:35 +#: design/plone/contenttypes/behaviors/argomenti.py:39 msgid "correlato_in_evidenza_label" msgstr "" -#. Default: "Cosa fa" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:206 +#. Default: "Competenze" +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:201 msgid "cosa_fa_label" msgstr "" #. Default: "Cosa serve" -#: design/plone/contenttypes/interfaces/servizio.py:177 +#: design/plone/contenttypes/interfaces/servizio.py:263 msgid "cosa_serve" msgstr "" #. Default: "Descrizione delle istruzioni per usufruire del servizio." -#: design/plone/contenttypes/interfaces/servizio.py:179 +#: design/plone/contenttypes/interfaces/servizio.py:265 msgid "cosa_serve_help" msgstr "" #. Default: "Cosa serve" -#: design/plone/contenttypes/interfaces/servizio.py:384 +#: design/plone/contenttypes/interfaces/servizio.py:497 msgid "cosa_serve_label" msgstr "" #. Default: "Cosa si ottiene" -#: design/plone/contenttypes/interfaces/servizio.py:90 +#: design/plone/contenttypes/interfaces/servizio.py:135 msgid "cosa_si_ottiene" msgstr "" #. Default: "Indicare cosa si può ottenere dal servizio, ad esempio 'carta di identità elettronica', 'certificato di residenza'." -#: design/plone/contenttypes/interfaces/servizio.py:91 +#: design/plone/contenttypes/interfaces/servizio.py:136 msgid "cosa_si_ottiene_help" msgstr "" #. Default: "Cos'è" -#: design/plone/contenttypes/behaviors/descrizione_estesa.py:40 -#: design/plone/contenttypes/behaviors/evento.py:200 +#: design/plone/contenttypes/behaviors/descrizione_estesa.py:52 +#: design/plone/contenttypes/behaviors/evento.py:155 msgid "cose_label" msgstr "" #. Default: "Costi" -#: design/plone/contenttypes/interfaces/servizio.py:186 +#: design/plone/contenttypes/interfaces/servizio.py:272 msgid "costi" msgstr "" #. Default: "Costi e vincoli" -#: design/plone/contenttypes/interfaces/servizio.py:389 +#: design/plone/contenttypes/interfaces/servizio.py:502 msgid "costi_e_vincoli_label" msgstr "" #. Default: "Descrizione delle condizioni e dei termini economici per completare la procedura di richiesta del servizio." -#: design/plone/contenttypes/interfaces/servizio.py:188 +#: design/plone/contenttypes/interfaces/servizio.py:274 msgid "costi_help" msgstr "" #. Default: "Costi" -#: design/plone/contenttypes/behaviors/evento.py:212 +#: design/plone/contenttypes/behaviors/evento.py:167 msgid "costi_label" msgstr "" #. Default: "Allega un file contenente il curriculum vitae della persona. Se ha più file da allegare, utilizza questo campo per quello principale e gli altri mettili dentro alla cartella \"Curriculum vitae\" che troverai dentro alla Persona." -#: design/plone/contenttypes/interfaces/persona.py:149 +#: design/plone/contenttypes/interfaces/persona.py:105 msgid "curriculum_vitae_help" msgstr "" #. Default: "Curriculum vitae" -#: design/plone/contenttypes/interfaces/persona.py:147 +#: design/plone/contenttypes/interfaces/persona.py:103 msgid "curriculum_vitae_label" msgstr "" #. Default: "Risultati indagini di customer satisfaction." -#: design/plone/contenttypes/behaviors/trasparenza.py:254 +#: design/plone/contenttypes/behaviors/trasparenza.py:255 msgid "customer_satisfaction_help" msgstr "" #. Default: "Risultati indagini di customer satisfaction" -#: design/plone/contenttypes/behaviors/trasparenza.py:249 +#: design/plone/contenttypes/behaviors/trasparenza.py:250 msgid "customer_satisfaction_label" msgstr "" -#. Default: "Data di conclusione dell'incarico." -#: design/plone/contenttypes/interfaces/persona.py:60 -msgid "data_conclusione_incarico_help" -msgstr "" - #. Default: "Data conclusione incarico" -#: design/plone/contenttypes/interfaces/persona.py:56 -msgid "data_conclusione_incarico_label" +#: design/plone/contenttypes/interfaces/incarico.py:100 +msgid "data_conclusione_incarico" msgstr "" #. Default: "Data e fasi intermedie" @@ -1278,14 +1309,14 @@ msgstr "" msgid "data_inizio" msgstr "" -#. Default: "Solo per persona politica: specificare la data di insediamento." -#: design/plone/contenttypes/interfaces/persona.py:97 -msgid "data_insediamento_help" +#. Default: "Data inizio incarico" +#: design/plone/contenttypes/interfaces/incarico.py:95 +msgid "data_inizio_incarico" msgstr "" #. Default: "Data insediamento" -#: design/plone/contenttypes/interfaces/persona.py:96 -msgid "data_insediamento_label" +#: design/plone/contenttypes/interfaces/incarico.py:105 +msgid "data_insediamento" msgstr "" #. Default: "Data del messaggio" @@ -1299,296 +1330,272 @@ msgid "data_pagamento" msgstr "" #. Default: "Data del protocollo" +#: design/plone/contenttypes/interfaces/documento.py:41 #: design/plone/contenttypes/interfaces/documento_personale.py:19 msgid "data_protocollo" msgstr "" +#. Default: "Data scadenza" +#: design/plone/contenttypes/interfaces/servizio.py:49 +msgid "data_scadenza_label" +msgstr "" + #. Default: "Data di scadenza della procedura" #: design/plone/contenttypes/interfaces/messaggio.py:40 msgid "data_scadenza_procedura" msgstr "" #. Default: "Dataset" -#: design/plone/contenttypes/interfaces/dataset.py:27 +#: design/plone/contenttypes/interfaces/dataset.py:20 msgid "dataset" msgstr "" +#. Default: "Schede dataset collegate al documento" +#: design/plone/contenttypes/interfaces/documento.py:150 +msgid "dataset_collegati_help" +msgstr "" + #. Default: "Seleziona una lista di schede dataset collegate a questo contenuto." -#: design/plone/contenttypes/behaviors/dataset_correlati.py:19 +#: design/plone/contenttypes/behaviors/dataset_correlati.py:20 msgid "dataset_correlati_help" msgstr "" #. Default: "Dataset correlati" -#: design/plone/contenttypes/behaviors/dataset_correlati.py:18 +#: design/plone/contenttypes/behaviors/dataset_correlati.py:19 msgid "dataset_correlati_label" msgstr "" +#. Default: "Dataset collegati" +#: design/plone/contenttypes/interfaces/documento.py:146 +msgid "dataset_label" +msgstr "" + +#. Default: "Date e informazioni" +#: design/plone/contenttypes/interfaces/incarico.py:175 +msgid "date_e_informazioni_label" +msgstr "" + #. Default: "Date e orari" -#: design/plone/contenttypes/behaviors/evento.py:209 -#: design/plone/contenttypes/schema_overrides.py:34 +#: design/plone/contenttypes/behaviors/evento.py:164 +#: design/plone/contenttypes/schema_overrides.py:33 msgid "date_e_orari_label" msgstr "" #. Default: "Inserisci la decorrenza termine del procedimento." -#: design/plone/contenttypes/behaviors/trasparenza.py:69 +#: design/plone/contenttypes/behaviors/trasparenza.py:70 msgid "decorrenza_termini_help" msgstr "" #. Default: "Decorrenza termine del procedimento" -#: design/plone/contenttypes/behaviors/trasparenza.py:64 +#: design/plone/contenttypes/behaviors/trasparenza.py:65 msgid "decorrenza_termini_label" msgstr "" #. Default: "Elenco delle deleghe a capo della persona." -#: design/plone/contenttypes/interfaces/persona.py:77 +#: design/plone/contenttypes/interfaces/persona.py:85 msgid "deleghe_help" msgstr "" #. Default: "Deleghe" -#: design/plone/contenttypes/interfaces/persona.py:76 +#: design/plone/contenttypes/interfaces/persona.py:84 msgid "deleghe_label" msgstr "" #. Default: "Descrizione completa" -#: design/plone/contenttypes/behaviors/luogo.py:23 +#: design/plone/contenttypes/behaviors/luogo.py:24 msgid "descrizione_completa" msgstr "" -#. Default: "Descrizione destinatari" -#: design/plone/contenttypes/behaviors/evento.py:38 -msgid "descrizione_destinatari" -msgstr "" - -#. Default: "Descrizione dei principali interlocutori dell'evento." -#: design/plone/contenttypes/behaviors/evento.py:40 -msgid "descrizione_destinatari_help" -msgstr "" - #. Default: "Descrizione estesa" -#: design/plone/contenttypes/behaviors/descrizione_estesa.py:16 -#: design/plone/contenttypes/behaviors/evento.py:30 -#: design/plone/contenttypes/behaviors/news_additional_fields.py:19 +#: design/plone/contenttypes/behaviors/descrizione_estesa.py:17 +#: design/plone/contenttypes/behaviors/evento.py:32 +#: design/plone/contenttypes/behaviors/news_additional_fields.py:21 msgid "descrizione_estesa" msgstr "" #. Default: "Descrizione dettagliata e completa." -#: design/plone/contenttypes/behaviors/descrizione_estesa.py:18 -#: design/plone/contenttypes/behaviors/evento.py:32 -#: design/plone/contenttypes/behaviors/news_additional_fields.py:21 +#: design/plone/contenttypes/behaviors/descrizione_estesa.py:19 +#: design/plone/contenttypes/behaviors/evento.py:34 +#: design/plone/contenttypes/behaviors/news_additional_fields.py:23 msgid "descrizione_estesa_help" msgstr "" #. Default: "Descrizione" -#: design/plone/contenttypes/behaviors/descrizione_estesa.py:51 -#: design/plone/contenttypes/behaviors/luogo.py:166 -#: design/plone/contenttypes/interfaces/documento.py:162 +#: design/plone/contenttypes/behaviors/descrizione_estesa.py:72 +#: design/plone/contenttypes/behaviors/luogo.py:135 +#: design/plone/contenttypes/interfaces/documento.py:242 msgid "descrizione_label" msgstr "" #. Default: "Inserisci eventuale testo descrittivo del procedimento." -#: design/plone/contenttypes/behaviors/trasparenza.py:37 +#: design/plone/contenttypes/behaviors/trasparenza.py:38 msgid "descrizione_procedimento_help" msgstr "" #. Default: "Descrizione del procedimento" -#: design/plone/contenttypes/behaviors/trasparenza.py:32 +#: design/plone/contenttypes/behaviors/trasparenza.py:33 msgid "descrizione_procedimento_label" msgstr "" #. Default: "Dirigente" -#: design/plone/contenttypes/behaviors/trasparenza.py:136 +#: design/plone/contenttypes/behaviors/trasparenza.py:137 msgid "dirigente" msgstr "" #. Default: "Indicare il dirigente." -#: design/plone/contenttypes/behaviors/trasparenza.py:140 +#: design/plone/contenttypes/behaviors/trasparenza.py:141 msgid "dirigente_help" msgstr "" #. Default: "Distribuzione" -#: design/plone/contenttypes/interfaces/dataset.py:22 +#: design/plone/contenttypes/interfaces/dataset.py:15 msgid "distribuzione" msgstr "" #. Default: "Documenti allegati" -#: design/plone/contenttypes/interfaces/messaggio.py:56 +#: design/plone/contenttypes/interfaces/messaggio.py:48 msgid "documenti_allegati" msgstr "" #. Default: "Seleziona una serie di altri contenuti di tipo Documento che vanno allegati a questo." -#: design/plone/contenttypes/interfaces/documento.py:113 +#: design/plone/contenttypes/interfaces/documento.py:194 msgid "documenti_allegati_help" msgstr "" #. Default: "Documenti allegati" -#: design/plone/contenttypes/interfaces/documento.py:109 +#: design/plone/contenttypes/interfaces/documento.py:190 msgid "documenti_allegati_label" msgstr "" #. Default: "Documenti" -#: design/plone/contenttypes/interfaces/persona.py:199 -#: design/plone/contenttypes/interfaces/servizio.py:412 +#: design/plone/contenttypes/interfaces/persona.py:146 +#: design/plone/contenttypes/interfaces/servizio.py:525 msgid "documenti_label" msgstr "" +#. Default: "Documenti pubblici importanti, collegati a questa Unità Organizzativa" +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:129 +msgid "documenti_pubblici_help" +msgstr "" + +#. Default: "Documenti pubblici" +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:127 +msgid "documenti_pubblici_label" +msgstr "" + #. Default: "Dove" -#: design/plone/contenttypes/behaviors/address.py:71 -#: design/plone/contenttypes/behaviors/geolocation.py:29 +#: design/plone/contenttypes/behaviors/address.py:53 +#: design/plone/contenttypes/behaviors/geolocation.py:26 msgid "dove_label" msgstr "" #. Default: "Dove rivolgersi: informazioni aggiuntive" -#: design/plone/contenttypes/interfaces/servizio.py:143 +#: design/plone/contenttypes/interfaces/servizio.py:212 msgid "dove_rivolgersi_extra" msgstr "" #. Default: "Indicare eventuali informazioni aggiuntive riguardo al dove rivolgersi per questo servizio." -#: design/plone/contenttypes/interfaces/servizio.py:147 +#: design/plone/contenttypes/interfaces/servizio.py:216 msgid "dove_rivolgersi_extra_help" msgstr "" #. Default: "Seleziona una lista delle sedi e dei luoghi in cui è presente questo servizio." -#: design/plone/contenttypes/interfaces/servizio.py:135 +#: design/plone/contenttypes/interfaces/servizio.py:204 msgid "dove_rivolgersi_help" msgstr "" #. Default: "Elementi di interesse" -#: design/plone/contenttypes/behaviors/luogo.py:44 +#: design/plone/contenttypes/behaviors/luogo.py:45 msgid "elementi_di_interesse" msgstr "" -#. Default: "Indicare un indirizzo mail per poter contattare gli organizzatori." -#: design/plone/contenttypes/behaviors/evento.py:128 -msgid "email_event_help" -msgstr "" - -#. Default: "E-mail" -#: design/plone/contenttypes/behaviors/evento.py:127 -msgid "email_event_label" -msgstr "" - -#. Default: "Indicare un indirizzo mail per poter contattare i referenti." -#: design/plone/contenttypes/behaviors/contatti.py:35 -msgid "email_help" -msgstr "" - -#. Default: "E-mail" -#: design/plone/contenttypes/behaviors/contatti.py:34 -msgid "email_label" -msgstr "" - -#. Default: "Contatto mail della persona. E' possibile inserire più di un indirizzo. Premendo \"Invio\" o \"tab\" si può passare al successivo da inserire." -#: design/plone/contenttypes/interfaces/persona.py:135 -msgid "email_persona_help" -msgstr "" - -#. Default: "Indirizzo email" -#: design/plone/contenttypes/interfaces/persona.py:134 -msgid "email_persona_label" -msgstr "" - #. Default: "Esito" #: design/plone/contenttypes/interfaces/ricevuta_pagamento.py:51 msgid "esito" msgstr "" -#. Default: "Fax" -#: design/plone/contenttypes/behaviors/evento.py:113 -msgid "fax_event_help" -msgstr "" - -#. Default: "Indicare un numero di fax." -#: design/plone/contenttypes/behaviors/evento.py:114 -msgid "fax_event_label" -msgstr "" - -#. Default: "Indicare un numero di fax." -#: design/plone/contenttypes/behaviors/contatti.py:29 -msgid "fax_help" -msgstr "" - -#. Default: "Fax" -#: design/plone/contenttypes/behaviors/contatti.py:28 -msgid "fax_label" -msgstr "" - -#. Default: "Indicare un numero di fax." -#: design/plone/contenttypes/interfaces/persona.py:130 -msgid "fax_persona_help" -msgstr "" - -#. Default: "Fax" -#: design/plone/contenttypes/interfaces/persona.py:129 -msgid "fax_persona_label" +#. Default: "Escludi dalla ricerca" +#: design/plone/contenttypes/behaviors/exclude_from_search.py:17 +msgid "exclude_from_search_label" msgstr "" #. Default: "Inserisci il file correlato di questo pocedimento." -#: design/plone/contenttypes/behaviors/trasparenza.py:44 +#: design/plone/contenttypes/behaviors/trasparenza.py:45 msgid "file_correlato_help" msgstr "" #. Default: "File correlato" -#: design/plone/contenttypes/behaviors/trasparenza.py:43 +#: design/plone/contenttypes/behaviors/trasparenza.py:44 msgid "file_correlato_label" msgstr "" #. Default: "Inserisci il file principale di questo contenuto." -#: design/plone/contenttypes/behaviors/multi_file.py:16 +#: design/plone/contenttypes/behaviors/multi_file.py:17 msgid "file_principale_help" msgstr "" #. Default: "File principale" -#: design/plone/contenttypes/behaviors/multi_file.py:15 +#: design/plone/contenttypes/behaviors/multi_file.py:16 msgid "file_principale_label" msgstr "" #. Default: "Inserisci la fine termine del procedimento." -#: design/plone/contenttypes/behaviors/trasparenza.py:80 +#: design/plone/contenttypes/behaviors/trasparenza.py:81 msgid "fine_termine_help" msgstr "" #. Default: "Fine termine del procedimento" -#: design/plone/contenttypes/behaviors/trasparenza.py:75 +#: design/plone/contenttypes/behaviors/trasparenza.py:76 msgid "fine_termine_label" msgstr "" +#. Default: "Lista dei formati in cui è disponibile il documento" +#: design/plone/contenttypes/interfaces/documento.py:117 +msgid "formati_disponibili_help" +msgstr "" + +#. Default: "Formati disponibili" +#: design/plone/contenttypes/interfaces/documento.py:116 +msgid "formati_disponibili_label" +msgstr "" + #. Default: "Inserisci un eventuale formato alternativo del file principale." -#: design/plone/contenttypes/behaviors/multi_file.py:25 +#: design/plone/contenttypes/behaviors/multi_file.py:26 msgid "formato_alternativo_1_help" msgstr "" #. Default: "Formato alternativo 1" -#: design/plone/contenttypes/behaviors/multi_file.py:24 +#: design/plone/contenttypes/behaviors/multi_file.py:25 msgid "formato_alternativo_1_label" msgstr "" #. Default: "Inserisci un eventuale formato alternativo del file principale." -#: design/plone/contenttypes/behaviors/multi_file.py:35 +#: design/plone/contenttypes/behaviors/multi_file.py:36 msgid "formato_alternativo_2_help" msgstr "" #. Default: "Formato alternativo 2" -#: design/plone/contenttypes/behaviors/multi_file.py:34 +#: design/plone/contenttypes/behaviors/multi_file.py:35 msgid "formato_alternativo_2_label" msgstr "" -#. Default: "Foto da mostrare della persona. La dimensione suggerita è 180x100 px." -#: design/plone/contenttypes/interfaces/persona.py:21 +#. Default: "Foto da mostrare della persona. La dimensione suggerita è 100x180px." +#: design/plone/contenttypes/interfaces/persona.py:30 msgid "foto_persona_help" msgstr "" #. Default: "Foto della persona" -#: design/plone/contenttypes/interfaces/persona.py:19 +#: design/plone/contenttypes/interfaces/persona.py:28 msgid "foto_persona_label" msgstr "" #. Default: "Frequenza di aggiornamento" -#: design/plone/contenttypes/interfaces/dataset.py:32 +#: design/plone/contenttypes/interfaces/dataset.py:25 msgid "frequenza_aggiornamento" msgstr "" #. Default: "Invalid geolocation data: ${value}. Provide latitude and longitude coordinates." -#: design/plone/contenttypes/restapi/deserializers/dxfields.py:28 +#: design/plone/contenttypes/restapi/deserializers/dxfields.py:39 msgid "geolocation_field_validator_label" msgstr "" @@ -1597,22 +1604,27 @@ msgid "help_circoscrizione" msgstr "" #. Default: "Indicare una descrizione completa, inserendo tutte le informazioni rilevanti relative al luogo" -#: design/plone/contenttypes/behaviors/luogo.py:24 +#: design/plone/contenttypes/behaviors/luogo.py:25 msgid "help_descrizione_completa" msgstr "" #. Default: "Indicare eventuali elementi di interesse per il cittadino." -#: design/plone/contenttypes/behaviors/luogo.py:45 +#: design/plone/contenttypes/behaviors/luogo.py:46 msgid "help_elementi_di_interesse" msgstr "" +#. Default: "Se selezionato, questo contenuto non verrà mostrato nelle ricerche del sito per gli utenti anonimi." +#: design/plone/contenttypes/behaviors/exclude_from_search.py:18 +msgid "help_exclude_from_search" +msgstr "" + #. Default: "Indicare tutte le informazioni relative alla modalità di accesso al luogo" -#: design/plone/contenttypes/behaviors/luogo.py:54 +#: design/plone/contenttypes/behaviors/luogo.py:55 msgid "help_modalita_accesso" msgstr "" #. Default: "Indicare, se esiste, un nome alternativo per il luogo; questo sarà mostrato affianco al titolo della scheda" -#: design/plone/contenttypes/behaviors/luogo.py:34 +#: design/plone/contenttypes/behaviors/luogo.py:35 msgid "help_nome_alternativo" msgstr "" @@ -1625,28 +1637,8 @@ msgstr "" msgid "help_quartiere" msgstr "" -#. Default: "Indicare un numero di fax della struttura responsabile." -#: design/plone/contenttypes/behaviors/luogo.py:108 -msgid "help_riferimento_fax_struttura" -msgstr "" - -#. Default: "Indicare un indirizzo mail per poter contattare i referenti della struttura responsabile." -#: design/plone/contenttypes/behaviors/luogo.py:119 -msgid "help_riferimento_mail_struttura" -msgstr "" - -#. Default: "Indicare un indirizzo pec per poter contattare i referenti della struttura responsabile." -#: design/plone/contenttypes/behaviors/luogo.py:132 -msgid "help_riferimento_pec_struttura" -msgstr "" - -#. Default: "Indicare il riferimento telefonico per poter contattare i referenti della struttura responsabile." -#: design/plone/contenttypes/behaviors/luogo.py:96 -msgid "help_riferimento_telefonico_struttura" -msgstr "" - -#. Default: "Inserisci una nota per indicare che il contenuto corrente è stato aggiornato.Questo testo può essere visualizzato nei blocchi elenco con determinati layout per informare gli utenti che un determinato contenuto è stato aggiornato. Ad esempio se in un bando sono stati aggiunti dei documenti." -#: design/plone/contenttypes/behaviors/update_note.py:17 +#. Default: "Inserisci una nota per indicare che il contenuto corrente è stato aggiornato. Questo testo può essere visualizzato nei blocchi elenco con determinati layout per informare gli utenti che un determinato contenuto è stato aggiornato. Ad esempio se in un bando sono stati aggiunti dei documenti." +#: design/plone/contenttypes/behaviors/update_note.py:18 msgid "help_update_note" msgstr "" @@ -1661,7 +1653,7 @@ msgid "icona_help" msgstr "" #. Default: "Identificativo" -#: design/plone/contenttypes/interfaces/servizio.py:290 +#: design/plone/contenttypes/interfaces/servizio.py:379 msgid "identificativo" msgstr "" @@ -1676,12 +1668,22 @@ msgid "identificativo_documento_label" msgstr "" #. Default: "Eventuale codice identificativo del servizio." -#: design/plone/contenttypes/interfaces/servizio.py:292 +#: design/plone/contenttypes/interfaces/servizio.py:381 msgid "identificativo_help" msgstr "" +#. Default: "Identificativo" +#: design/plone/contenttypes/behaviors/luogo.py:119 +msgid "identificativo_mibac" +msgstr "" + +#. Default: "Codice identificativo del luogo. Nel MIBAC c'è il codice del DBUnico per i luoghi della cultura e il codice ISIL per le biblioteche. Non deve comparire nel frontend del sito." +#: design/plone/contenttypes/behaviors/luogo.py:121 +msgid "identificativo_mibac_help" +msgstr "" + #. Default: "La dimensione dell'immagine dovrebbe essere di ${size} px" -#: design/plone/contenttypes/restapi/types/adapters.py:31 +#: design/plone/contenttypes/restapi/types/adapters.py:43 msgid "image_size_help" msgstr "" @@ -1690,11 +1692,31 @@ msgstr "" msgid "immagine" msgstr "" +#. Default: "Solo per incarico politico: importi di viaggi di servizio e missioni pagati con fondi pubblici." +#: design/plone/contenttypes/interfaces/incarico.py:34 +msgid "importi_viaggio_servizio_incarico_help" +msgstr "" + +#. Default: "Importi di viaggio e/o servizio" +#: design/plone/contenttypes/interfaces/incarico.py:30 +msgid "importi_viaggio_servizio_incarico_label" +msgstr "" + #. Default: "Importo pagato" #: design/plone/contenttypes/interfaces/ricevuta_pagamento.py:25 msgid "importo_pagato" msgstr "" +#. Default: "Seleziona l'incarico corrente della persona." +#: design/plone/contenttypes/interfaces/persona.py:63 +msgid "incarichi_help" +msgstr "" + +#. Default: "Incarichi" +#: design/plone/contenttypes/interfaces/persona.py:59 +msgid "incarichi_label" +msgstr "" + #. Default: "Inserisci eventuale testo informativo che verrà mostrato in testata." #: design/plone/contenttypes/behaviors/info_testata.py:23 msgid "info_testata_help" @@ -1710,35 +1732,60 @@ msgstr "" msgid "informazioni" msgstr "" +#. Default: "Compensi e trasparenza" +#: design/plone/contenttypes/interfaces/incarico.py:170 +msgid "informazioni_compensi_label" +msgstr "" + #. Default: "Ulteriori informazioni" #: design/plone/contenttypes/behaviors/additional_help_infos.py:28 -#: design/plone/contenttypes/behaviors/evento.py:229 #: design/plone/contenttypes/behaviors/strutture_correlate.py:42 +#: design/plone/contenttypes/interfaces/documento.py:253 msgid "informazioni_label" msgstr "" +#. Default: "Intervallo della fase (es. 1)" +#: design/plone/contenttypes/interfaces/servizio.py:32 +msgid "interval_qt_help" +msgstr "" + +#. Default: "Intervallo" +#: design/plone/contenttypes/interfaces/servizio.py:31 +msgid "interval_qt_label" +msgstr "" + +#. Default: "Ad esempio: ore, giorni, settimane, mesi." +#: design/plone/contenttypes/interfaces/servizio.py:41 +msgid "interval_type_help" +msgstr "" + +#. Default: "Tipo intervallo" +#: design/plone/contenttypes/interfaces/servizio.py:40 +msgid "interval_type_label" +msgstr "" + #. Default: "Se un content-type deve avere una dimensione della leadimage particolare, indicarle qui. Inserire le dimensioni nella forma di esempio PortalType|900x900" -#: design/plone/contenttypes/controlpanels/settings.py:110 +#: design/plone/contenttypes/controlpanels/settings.py:52 msgid "lead_image_dimension_help" msgstr "" #. Default: "Dimensioni lead image" -#: design/plone/contenttypes/controlpanels/settings.py:106 +#: design/plone/contenttypes/controlpanels/settings.py:48 msgid "lead_image_dimension_label" msgstr "" -#. Default: "Servizi o uffici di riferimento" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:27 +#. Default: "Strutture o uffici di riferimento" +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:31 msgid "legami_altre_strutture_label" msgstr "" #. Default: "Selezionare la lista di strutture e/o uffici collegati a questa unità organizzativa." -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:31 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:35 msgid "legami_con_altre_strutture_help" msgstr "" #. Default: "Licenza" -#: design/plone/contenttypes/interfaces/dataset.py:25 +#: design/plone/contenttypes/interfaces/dataset.py:18 msgid "licenza" msgstr "" @@ -1748,27 +1795,27 @@ msgid "licenza_distribuzione" msgstr "" #. Default: "La licenza con il quale viene distribuito questo documento." -#: design/plone/contenttypes/interfaces/documento.py:88 +#: design/plone/contenttypes/interfaces/documento.py:125 msgid "licenza_distribuzione_help" msgstr "" #. Default: "Licenza di distribuzione" -#: design/plone/contenttypes/interfaces/documento.py:87 +#: design/plone/contenttypes/interfaces/documento.py:124 msgid "licenza_distribuzione_label" msgstr "" #. Default: "Link a siti esterni" -#: design/plone/contenttypes/interfaces/servizio.py:258 +#: design/plone/contenttypes/interfaces/servizio.py:347 msgid "link_siti_esterni" msgstr "" #. Default: "Eventuali collegamenti a pagine web, siti, servizi esterni all'ambito Comunale utili all'erogazione del servizio." -#: design/plone/contenttypes/interfaces/servizio.py:260 +#: design/plone/contenttypes/interfaces/servizio.py:349 msgid "link_siti_esterni_help" msgstr "" #. Default: "Link utili" -#: design/plone/contenttypes/interfaces/servizio.py:417 +#: design/plone/contenttypes/interfaces/servizio.py:530 msgid "link_utili_label" msgstr "" @@ -1778,36 +1825,46 @@ msgid "luoghi_correlati_event_help" msgstr "" #. Default: "Seleziona una lista di luoghi citati." -#: design/plone/contenttypes/behaviors/luoghi_correlati.py:18 -#: design/plone/contenttypes/behaviors/news_additional_fields.py:72 +#: design/plone/contenttypes/behaviors/luoghi_correlati.py:19 +#: design/plone/contenttypes/behaviors/news_additional_fields.py:64 msgid "luoghi_correlati_help" msgstr "" #. Default: "Luoghi correlati" -#: design/plone/contenttypes/behaviors/luoghi_correlati.py:17 -#: design/plone/contenttypes/behaviors/news_additional_fields.py:71 +#: design/plone/contenttypes/behaviors/luoghi_correlati.py:18 +#: design/plone/contenttypes/behaviors/news_additional_fields.py:63 msgid "luoghi_correlati_label" msgstr "" #. Default: "Luogo" -#: design/plone/contenttypes/behaviors/address.py:89 -#: design/plone/contenttypes/behaviors/geolocation.py:38 -#: design/plone/contenttypes/behaviors/luoghi_correlati.py:74 +#: design/plone/contenttypes/behaviors/address.py:71 +#: design/plone/contenttypes/behaviors/geolocation.py:34 +#: design/plone/contenttypes/behaviors/luoghi_correlati.py:76 msgid "luogo_label" msgstr "" +#. Default: "Sottotitolo" +#: design/plone/contenttypes/interfaces/servizio.py:26 +msgid "milestone_description_label" +msgstr "" + +#. Default: "Titolo" +#: design/plone/contenttypes/interfaces/servizio.py:21 +msgid "milestone_label" +msgstr "" + #. Default: "Modalita' di accesso" -#: design/plone/contenttypes/behaviors/luogo.py:53 +#: design/plone/contenttypes/behaviors/luogo.py:54 msgid "modalita_accesso" msgstr "" #. Default: "Indicare la modalità di avvio del procedimento." -#: design/plone/contenttypes/behaviors/trasparenza.py:25 +#: design/plone/contenttypes/behaviors/trasparenza.py:26 msgid "modalita_avvio_help" msgstr "" #. Default: "Modalita di avvio" -#: design/plone/contenttypes/behaviors/trasparenza.py:24 +#: design/plone/contenttypes/behaviors/trasparenza.py:25 msgid "modalita_avvio_label" msgstr "" @@ -1817,12 +1874,12 @@ msgid "modalita_pagamento" msgstr "" #. Default: "Indicare le modalità per richiedere informazioni riguardo a questo procedimento." -#: design/plone/contenttypes/behaviors/trasparenza.py:168 +#: design/plone/contenttypes/behaviors/trasparenza.py:169 msgid "modalita_richiesta_informazioni_help" msgstr "" #. Default: "Modalità per richiedere informazioni" -#: design/plone/contenttypes/behaviors/trasparenza.py:163 +#: design/plone/contenttypes/behaviors/trasparenza.py:164 msgid "modalita_richiesta_informazioni_label" msgstr "" @@ -1846,18 +1903,18 @@ msgstr "" msgid "mostra_navigazione_label" msgstr "" -#. Default: "Descrizione del motivo per cui il servizio non è attivo." -#: design/plone/contenttypes/interfaces/servizio.py:44 +#. Default: "Descrizione del motivo per cui il servizio non è attivo. È obbligatorio se il campo precedente è spuntato." +#: design/plone/contenttypes/interfaces/servizio.py:89 msgid "motivo_stato_servizio_help" msgstr "" -#. Default: "Motivo dello stato del servizio nel caso non sia attivo" -#: design/plone/contenttypes/interfaces/servizio.py:39 +#. Default: "Motivo dello stato" +#: design/plone/contenttypes/interfaces/servizio.py:84 msgid "motivo_stato_servizio_label" msgstr "" #. Default: "Nome alternativo" -#: design/plone/contenttypes/behaviors/luogo.py:33 +#: design/plone/contenttypes/behaviors/luogo.py:34 msgid "nome_alternativo" msgstr "" @@ -1867,17 +1924,17 @@ msgid "nome_sede" msgstr "" #. Default: "Seleziona una lista di notizie correlate a questa." -#: design/plone/contenttypes/behaviors/news_additional_fields.py:83 +#: design/plone/contenttypes/behaviors/news_additional_fields.py:75 msgid "notizie_correlate_help" msgstr "" #. Default: "Notizie correlate" -#: design/plone/contenttypes/behaviors/news_additional_fields.py:82 +#: design/plone/contenttypes/behaviors/news_additional_fields.py:74 msgid "notizie_correlate_label" msgstr "" #. Default: "Numero progressivo del comunicato stampa" -#: design/plone/contenttypes/behaviors/news_additional_fields.py:38 +#: design/plone/contenttypes/behaviors/news_additional_fields.py:30 msgid "numero_progressivo_cs_label" msgstr "" @@ -1893,117 +1950,155 @@ msgid "oggetto" msgstr "" #. Default: "Informazioni sugli orari" -#: design/plone/contenttypes/behaviors/evento.py:62 +#: design/plone/contenttypes/behaviors/evento.py:50 msgid "orari" msgstr "" #. Default: "Informazioni sugli orari di svolgimento dell'evento." -#: design/plone/contenttypes/behaviors/evento.py:64 +#: design/plone/contenttypes/behaviors/evento.py:52 msgid "orari_help" msgstr "" #. Default: "Orari di apertura" -#: design/plone/contenttypes/behaviors/contatti.py:86 +#: design/plone/contenttypes/behaviors/luogo.py:151 msgid "orari_label" msgstr "" +#. Default: "Orario per il pubblico" +#: design/plone/contenttypes/behaviors/luogo.py:93 +msgid "orario_pubblico" +msgstr "" + #. Default: "Indicare eventuali orari di accesso al pubblico" -#: design/plone/contenttypes/behaviors/contatti.py:59 +#: design/plone/contenttypes/behaviors/contatti.py:40 +#: design/plone/contenttypes/behaviors/luogo.py:95 msgid "orario_pubblico_help" msgstr "" #. Default: "Orario per il pubblico" -#: design/plone/contenttypes/behaviors/contatti.py:58 +#: design/plone/contenttypes/behaviors/contatti.py:39 msgid "orario_pubblico_label" msgstr "" #. Default: "Se l'evento non è organizzato direttamente dal comune oppure ha anche un organizzatore esterno, indicare il nome del contatto." -#: design/plone/contenttypes/behaviors/evento.py:97 +#: design/plone/contenttypes/behaviors/evento.py:86 msgid "organizzato_da_esterno_help" msgstr "" #. Default: "Organizzatore" -#: design/plone/contenttypes/behaviors/evento.py:95 +#: design/plone/contenttypes/behaviors/evento.py:84 msgid "organizzato_da_esterno_label" msgstr "" #. Default: "Se l'evento è organizzato direttamente dal comune, indicare l'ufficio/ente organizzatore. I dati di contatto verranno presi direttamente dall'ufficio selezionato. Se l'evento non è organizzato direttamente dal comune, o si vogliono sovrascrivere alcuni dati di contatto, utilizzare i seguenti campi." -#: design/plone/contenttypes/behaviors/evento.py:84 +#: design/plone/contenttypes/behaviors/evento.py:74 msgid "organizzato_da_interno_help" msgstr "" #. Default: "Organizzato da" -#: design/plone/contenttypes/behaviors/evento.py:80 +#: design/plone/contenttypes/behaviors/evento.py:70 msgid "organizzato_da_interno_label" msgstr "" #. Default: "Seleziona una lista di organizzazioni a cui la persona appartiene." -#: design/plone/contenttypes/interfaces/persona.py:42 +#: design/plone/contenttypes/interfaces/persona.py:45 msgid "organizzazione_riferimento_help" msgstr "" #. Default: "Organizzazione di riferimento" -#: design/plone/contenttypes/interfaces/persona.py:38 +#: design/plone/contenttypes/interfaces/persona.py:41 msgid "organizzazione_riferimento_label" msgstr "" #. Default: "Organo competente del provvedimento finale." -#: design/plone/contenttypes/behaviors/trasparenza.py:157 +#: design/plone/contenttypes/behaviors/trasparenza.py:158 msgid "organo_competente_provvedimento_finale_help" msgstr "" #. Default: "Organo competente del provvedimento finale" -#: design/plone/contenttypes/behaviors/trasparenza.py:152 +#: design/plone/contenttypes/behaviors/trasparenza.py:153 msgid "organo_competente_provvedimento_finale_label" msgstr "" #. Default: "Indicare le informazioni riguardanti i pagamenti previsti e modalità di pagamento." -#: design/plone/contenttypes/behaviors/trasparenza.py:222 +#: design/plone/contenttypes/behaviors/trasparenza.py:223 msgid "pagamenti_help" msgstr "" #. Default: "Pagamenti previsti e modalità" -#: design/plone/contenttypes/behaviors/trasparenza.py:218 +#: design/plone/contenttypes/behaviors/trasparenza.py:219 msgid "pagamenti_label" msgstr "" +#. Default: "Link a persone dell'amministrazione che interverranno all'evento" +#: design/plone/contenttypes/behaviors/evento.py:118 +msgid "parteciperanno_help" +msgstr "" + +#. Default: "Parteciperanno (Persone)" +#: design/plone/contenttypes/behaviors/evento.py:114 +msgid "parteciperanno_label" +msgstr "" + #. Default: "Indicare l'ente che supporta l'evento, se presente." -#: design/plone/contenttypes/behaviors/evento.py:160 +#: design/plone/contenttypes/behaviors/evento.py:107 msgid "patrocinato_da_help" msgstr "" #. Default: "Patrocinato da" -#: design/plone/contenttypes/behaviors/evento.py:158 +#: design/plone/contenttypes/behaviors/evento.py:105 msgid "patrocinato_da_label" msgstr "" -#. Default: "Indicare un indirizzo pec per poter contattare i referenti." -#: design/plone/contenttypes/behaviors/contatti.py:44 -msgid "pec_help" +#. Default: "Descrizione" +#: design/plone/contenttypes/interfaces/punto_di_contatto.py:27 +msgid "pdc_desc_help" +msgstr "" + +#. Default: "Descrizione" +#: design/plone/contenttypes/interfaces/punto_di_contatto.py:26 +msgid "pdc_desc_label" +msgstr "" + +#. Default: "Tipo" +#: design/plone/contenttypes/interfaces/punto_di_contatto.py:16 +msgid "pdc_type_label" msgstr "" -#. Default: "Pec" -#: design/plone/contenttypes/behaviors/contatti.py:43 -msgid "pec_label" +#. Default: "Contatto" +#: design/plone/contenttypes/interfaces/punto_di_contatto.py:37 +msgid "pdc_value_help" msgstr "" -#. Default: "Elenco delle persone dell'amministrazione che parteciperanno all'evento." -#: design/plone/contenttypes/behaviors/evento.py:53 -msgid "persone_amministrazione_help" +#. Default: "Contatto" +#: design/plone/contenttypes/interfaces/punto_di_contatto.py:36 +msgid "pdc_value_label" +msgstr "" + +#. Default: "Seleziona la persona che ha questo incarico" +#: design/plone/contenttypes/interfaces/incarico.py:47 +#: design/plone/contenttypes/interfaces/punto_di_contatto.py:66 +msgid "persona_incarico_help" +msgstr "" + +#. Default: "La persona che ha la carica e l'incarico" +#: design/plone/contenttypes/interfaces/incarico.py:43 +#: design/plone/contenttypes/interfaces/punto_di_contatto.py:62 +msgid "persona_incarico_label" msgstr "" #. Default: "Persone" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:221 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:215 msgid "persone_label" msgstr "" #. Default: "Seleziona la lista delle persone che compongono la struttura." -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:95 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:87 msgid "persone_struttura_help" msgstr "" #. Default: "Persone che compongono la struttura" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:87 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:79 msgid "persone_struttura_label" msgstr "" @@ -2019,42 +2114,42 @@ msgid "pratica_associata_ricevuta" msgstr "" #. Default: "Prenota un appuntamento" -#: design/plone/contenttypes/interfaces/servizio.py:156 +#: design/plone/contenttypes/interfaces/servizio.py:225 msgid "prenota_appuntamento" msgstr "" #. Default: "Se è possibile prenotare un'appuntamento, indicare le informazioni necessarie e il collegamento al servizio di prenotazione appuntamenti del Comune." -#: design/plone/contenttypes/interfaces/servizio.py:157 +#: design/plone/contenttypes/interfaces/servizio.py:226 msgid "prenota_appuntamento_help" msgstr "" -#. Default: "Prezzo" -#: design/plone/contenttypes/behaviors/evento.py:71 +#. Default: "Costo" +#: design/plone/contenttypes/behaviors/evento.py:59 msgid "prezzo" msgstr "" -#. Default: "Indicare il prezzo dell'evento, se presente, specificando se esistono formati diversi." -#: design/plone/contenttypes/behaviors/evento.py:73 +#. Default: "Eventuale costo dell'evento (se ci sono uno o più biglietti), con link all'acquisto se disponibile" +#: design/plone/contenttypes/behaviors/evento.py:61 msgid "prezzo_help" msgstr "" #. Default: "Indicare, se la procedura è informatizzata online, il riferimento." -#: design/plone/contenttypes/behaviors/trasparenza.py:178 +#: design/plone/contenttypes/behaviors/trasparenza.py:179 msgid "procedura_online_help" msgstr "" #. Default: "Procedura informatizzata online" -#: design/plone/contenttypes/behaviors/trasparenza.py:174 +#: design/plone/contenttypes/behaviors/trasparenza.py:175 msgid "procedura_online_label" msgstr "" #. Default: "Procedure collegate all'esito" -#: design/plone/contenttypes/interfaces/servizio.py:100 +#: design/plone/contenttypes/interfaces/servizio.py:145 msgid "procedure_collegate" msgstr "" #. Default: "Indicare cosa deve fare l'utente del servizio per conoscere l'esito della procedura, e dove eventualmente poter ritirare l'esito." -#: design/plone/contenttypes/interfaces/servizio.py:102 +#: design/plone/contenttypes/interfaces/servizio.py:147 msgid "procedure_collegate_help" msgstr "" @@ -2063,13 +2158,23 @@ msgstr "" msgid "protocollo" msgstr "" +#. Default: "Il numero di protocollo del documento." +#: design/plone/contenttypes/interfaces/documento.py:33 +msgid "protocollo_documento_help" +msgstr "" + +#. Default: "Numero di protocollo" +#: design/plone/contenttypes/interfaces/documento.py:29 +msgid "protocollo_documento_label" +msgstr "" + #. Default: "Eventuale provvedimento finale del procedimento." -#: design/plone/contenttypes/behaviors/trasparenza.py:114 +#: design/plone/contenttypes/behaviors/trasparenza.py:115 msgid "provvedimento_finale_help" msgstr "" #. Default: "Provvedimento del procedimento" -#: design/plone/contenttypes/behaviors/trasparenza.py:109 +#: design/plone/contenttypes/behaviors/trasparenza.py:110 msgid "provvedimento_finale_label" msgstr "" @@ -2078,46 +2183,46 @@ msgstr "" msgid "quartiere" msgstr "" -#. Default: "Reperibilità organizzatore" -#: design/plone/contenttypes/behaviors/evento.py:118 -msgid "reperibilita" -msgstr "" - -#. Default: "Indicare gli orari in cui l'organizzatore è telefonicamente reperibile." -#: design/plone/contenttypes/behaviors/evento.py:120 -msgid "reperibilita_help" -msgstr "" - #. Default: "Indicare dove è possibile reperre la modulistica per il procedimento." -#: design/plone/contenttypes/behaviors/trasparenza.py:211 +#: design/plone/contenttypes/behaviors/trasparenza.py:212 msgid "reperimento_modulistica_help" msgstr "" #. Default: "Dove reperire la modulistica" -#: design/plone/contenttypes/behaviors/trasparenza.py:207 +#: design/plone/contenttypes/behaviors/trasparenza.py:208 msgid "reperimento_modulistica_label" msgstr "" #. Default: "Selezionare il/i responsabile/i della struttura." -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:48 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:52 msgid "responsabile_help" msgstr "" #. Default: "Responsabile" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:43 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:47 msgid "responsabile_label" msgstr "" #. Default: "Responsabile del procedimento" -#: design/plone/contenttypes/behaviors/trasparenza.py:120 +#: design/plone/contenttypes/behaviors/trasparenza.py:121 msgid "responsabile_procedimento" msgstr "" #. Default: "Indicare il responsabile del procedimento." -#: design/plone/contenttypes/behaviors/trasparenza.py:124 +#: design/plone/contenttypes/behaviors/trasparenza.py:125 msgid "responsabile_procedimento_help" msgstr "" +#. Default: "Se è un incarico di responsabilità, specificare l'organizzazione della quale è responsabile in base all'incarico" +#: design/plone/contenttypes/interfaces/incarico.py:81 +msgid "responsabile_struttura_incarico_help" +msgstr "" + +#. Default: "Responsabile della struttura" +#: design/plone/contenttypes/interfaces/incarico.py:77 +msgid "responsabile_struttura_incarico_label" +msgstr "" + #. Default: "Seleziona se mostrare o meno il campo di ricerca in testata." #: design/plone/contenttypes/behaviors/info_testata.py:32 msgid "ricerca_in_testata_help" @@ -2129,12 +2234,12 @@ msgid "ricerca_in_testata_label" msgstr "" #. Default: "Ulteriori informazioni non previste negli altri campi; si può trattare di contatti o note informative la cui conoscenza è indispensabile per la partecipazione al bando" -#: design/plone/contenttypes/interfaces/bando.py:96 +#: design/plone/contenttypes/interfaces/bando.py:97 msgid "riferimenti_bando_agid_help" msgstr "" #. Default: "Ulteriori informazioni" -#: design/plone/contenttypes/interfaces/bando.py:95 +#: design/plone/contenttypes/interfaces/bando.py:96 msgid "riferimenti_bando_agid_label" msgstr "" @@ -2144,122 +2249,87 @@ msgid "riferimenti_normativi" msgstr "" #. Default: "Inserisici del testo di dettaglio per eventuali riferimenti normativi utili a questo documento." -#: design/plone/contenttypes/interfaces/documento.py:100 +#: design/plone/contenttypes/interfaces/documento.py:137 msgid "riferimenti_normativi_documento_help" msgstr "" #. Default: "Riferimenti normativi" -#: design/plone/contenttypes/interfaces/documento.py:96 +#: design/plone/contenttypes/interfaces/documento.py:133 msgid "riferimenti_normativi_documento_label" msgstr "" #. Default: "Indicare eventuali riferimenti normativi." -#: design/plone/contenttypes/behaviors/trasparenza.py:265 +#: design/plone/contenttypes/behaviors/trasparenza.py:266 msgid "riferimenti_normativi_help" msgstr "" #. Default: "Riferimenti normativi" -#: design/plone/contenttypes/behaviors/trasparenza.py:260 +#: design/plone/contenttypes/behaviors/trasparenza.py:261 msgid "riferimenti_normativi_label" msgstr "" -#. Default: "Fax della struttura responsabile" -#: design/plone/contenttypes/behaviors/luogo.py:104 -msgid "riferimento_fax_struttura" -msgstr "" - -#. Default: "E-mail struttura responsabile" -#: design/plone/contenttypes/behaviors/luogo.py:115 -msgid "riferimento_mail_struttura" -msgstr "" - -#. Default: "Pec della struttura responsabile" -#: design/plone/contenttypes/behaviors/luogo.py:128 -msgid "riferimento_pec_struttura" -msgstr "" - -#. Default: "Telefono della struttura responsabile" -#: design/plone/contenttypes/behaviors/luogo.py:92 -msgid "riferimento_telefonico_struttura" -msgstr "" - -#. Default: "Inserisci i valori utilizzabili per il ruolo di una Persona. Se il sito è multilingua, puoi inserire valori diversi a seconda delle lingue del sito." -#: design/plone/contenttypes/controlpanels/settings.py:84 -msgid "ruoli_persona_help" -msgstr "" - -#. Default: "Ruoli Persona" -#: design/plone/contenttypes/controlpanels/settings.py:83 -msgid "ruoli_persona_label" -msgstr "" - -#. Default: "Seleziona il ruolo della persona tra quelli disponibili." -#: design/plone/contenttypes/interfaces/persona.py:29 -msgid "ruolo_help" -msgstr "" - #. Default: "Ruolo" -#: design/plone/contenttypes/interfaces/persona.py:28 +#: design/plone/contenttypes/interfaces/persona.py:135 msgid "ruolo_label" msgstr "" #. Default: "Data entro la quale sarà possibile far pervenire domande e richieste di chiarimento a chi eroga il bando" -#: design/plone/contenttypes/interfaces/bando.py:69 +#: design/plone/contenttypes/interfaces/bando.py:70 msgid "scadenza_domande_bando_help" msgstr "" #. Default: "Termine per le richieste di chiarimenti" -#: design/plone/contenttypes/interfaces/bando.py:65 +#: design/plone/contenttypes/interfaces/bando.py:66 msgid "scadenza_domande_bando_label" msgstr "" #. Default: "Inserire una lista di sezioni per la ricerca." -#: design/plone/contenttypes/controlpanels/settings.py:129 +#: design/plone/contenttypes/controlpanels/settings.py:71 msgid "search_sections_help" msgstr "" #. Default: "Sezioni ricerca" -#: design/plone/contenttypes/controlpanels/settings.py:128 +#: design/plone/contenttypes/controlpanels/settings.py:70 msgid "search_sections_label" msgstr "" -#. Default: "Seleziona il Luogo in cui questa struttura ha sede. Se non è presente un contenuto di tipo Luogo a cui far riferimento, puoi compilare i campi seguenti. Se selezioni un Luogo, puoi usare comunque i campi seguenti per sovrascrivere alcune informazioni." -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:105 +#. Default: "Seleziona il Luogo in cui questa struttura ha sede. Se non è presente creare il Luogo nella sezione dedicata nell'alberatura del sito." +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:97 msgid "sede_help" msgstr "" #. Default: "Sede principale" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:103 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:95 msgid "sede_label" msgstr "" #. Default: "Seleziona una lista di eventuali contenuti di tipo Luogo che sono sedi secondarie di questa struttura. Per queste sedi non sarà possibile sovrascrivere i dati. Nel caso servano informazioni diverse, è possibile usare il campo sottostante." -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:122 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:112 msgid "sedi_secondarie_help" msgstr "" -#. Default: "Sedi secondarie" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:120 +#. Default: "Altre sedi" +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:110 msgid "sedi_secondarie_label" msgstr "" #. Default: "Seleziona la lista dei servizi collegati a questo." -#: design/plone/contenttypes/interfaces/servizio.py:300 +#: design/plone/contenttypes/interfaces/servizio.py:394 msgid "servizi_collegati_help" msgstr "" #. Default: "Servizi collegati" -#: design/plone/contenttypes/interfaces/servizio.py:299 +#: design/plone/contenttypes/interfaces/servizio.py:393 msgid "servizi_collegati_label" msgstr "" #. Default: "Questi servizi non verranno mostrati nel contenuto, ma permetteranno di vedere questo contenuto associato quando si visita il servizio" -#: design/plone/contenttypes/behaviors/servizi_correlati.py:19 +#: design/plone/contenttypes/behaviors/servizi_correlati.py:20 msgid "servizi_correlati_description" msgstr "" #. Default: "Servizi correlati" -#: design/plone/contenttypes/behaviors/servizi_correlati.py:18 +#: design/plone/contenttypes/behaviors/servizi_correlati.py:19 msgid "servizi_correlati_label" msgstr "" @@ -2279,22 +2349,32 @@ msgid "servizio_origine_ricevuta" msgstr "" #. Default: "Settore merceologico" -#: design/plone/contenttypes/interfaces/servizio.py:280 +#: design/plone/contenttypes/interfaces/servizio.py:369 msgid "settore_merceologico" msgstr "" #. Default: "Classificazione del servizio basata su catalogo dei servizi (Classificazione NACE)." -#: design/plone/contenttypes/interfaces/servizio.py:282 +#: design/plone/contenttypes/interfaces/servizio.py:371 msgid "settore_merceologico_help" msgstr "" +#. Default: "Se selezionato, il footer verrà popolato automaticamente con i contenuti di primo livello non esclusi dalla navigazione." +#: design/plone/contenttypes/controlpanels/settings.py:93 +msgid "show_dynamic_folders_in_footer_help" +msgstr "" + +#. Default: "Footer dinamico" +#: design/plone/contenttypes/controlpanels/settings.py:92 +msgid "show_dynamic_folders_in_footer_label" +msgstr "" + #. Default: "Questo è il valore di default per decidere se mostrare o meno la data di modifica nei contenuti che hanno la behavior abilitata. E' poi possibile sovrascrivere il default nei singoli contenuti (nel tab \"Impostazioni\")." -#: design/plone/contenttypes/controlpanels/settings.py:139 +#: design/plone/contenttypes/controlpanels/settings.py:81 msgid "show_modified_default_help" msgstr "" #. Default: "Mostra la data di modifica" -#: design/plone/contenttypes/controlpanels/settings.py:138 +#: design/plone/contenttypes/controlpanels/settings.py:80 msgid "show_modified_default_label" msgstr "" @@ -2309,34 +2389,34 @@ msgid "show_modified_label" msgstr "" #. Default: "Indicare se il procedimento prevede il silenzio assenso o la dichiarazione dell'interessato sostitutiva del provvedimento finale." -#: design/plone/contenttypes/behaviors/trasparenza.py:103 +#: design/plone/contenttypes/behaviors/trasparenza.py:104 msgid "silenzio_assenso_help" msgstr "" #. Default: "Silenzio assenso/Dichiarazione dell'interessato sostitutiva del provvedimento finale" -#: design/plone/contenttypes/behaviors/trasparenza.py:97 +#: design/plone/contenttypes/behaviors/trasparenza.py:98 msgid "silenzio_assenso_label" msgstr "" #. Default: "Inserisci eventuali soggetti esterni, nonché, strutture interne coinvolte nel procedimento." -#: design/plone/contenttypes/behaviors/trasparenza.py:57 +#: design/plone/contenttypes/behaviors/trasparenza.py:58 msgid "soggetti_eserni_help" msgstr "" #. Default: "Soggetti esterni, nonché, strutture interne coinvolte nel procedimento" -#: design/plone/contenttypes/behaviors/trasparenza.py:52 +#: design/plone/contenttypes/behaviors/trasparenza.py:53 msgid "soggetti_eserni_label" msgstr "" #. Default: "Indica un eventuale sottotitolo/titolo alternativo." -#: design/plone/contenttypes/behaviors/evento.py:23 -#: design/plone/contenttypes/interfaces/servizio.py:19 +#: design/plone/contenttypes/behaviors/evento.py:24 +#: design/plone/contenttypes/interfaces/servizio.py:64 msgid "sottotitolo_help" msgstr "" #. Default: "Sottotitolo" -#: design/plone/contenttypes/behaviors/evento.py:22 -#: design/plone/contenttypes/interfaces/servizio.py:18 +#: design/plone/contenttypes/behaviors/evento.py:23 +#: design/plone/contenttypes/interfaces/servizio.py:63 msgid "sottotitolo_label" msgstr "" @@ -2350,273 +2430,188 @@ msgstr "" msgid "stato_pratica" msgstr "" -#. Default: "Indica se il servizio è effettivamente fruibile." -#: design/plone/contenttypes/interfaces/servizio.py:32 +#. Default: "Indica se il servizio è effettivamente fruibile; spuntare se non è fruibile." +#: design/plone/contenttypes/interfaces/servizio.py:77 msgid "stato_servizio_help" msgstr "" -#. Default: "Servizio non attivo" -#: design/plone/contenttypes/interfaces/servizio.py:30 +#. Default: "Servizio non fruibile" +#: design/plone/contenttypes/interfaces/servizio.py:75 msgid "stato_servizio_label" msgstr "" #. Default: "Indicare gli eventuali strumenti di tutela." -#: design/plone/contenttypes/behaviors/trasparenza.py:230 +#: design/plone/contenttypes/behaviors/trasparenza.py:231 msgid "strumenti_tutela_help" msgstr "" #. Default: "Strumenti di tutela" -#: design/plone/contenttypes/behaviors/trasparenza.py:229 +#: design/plone/contenttypes/behaviors/trasparenza.py:230 msgid "strumenti_tutela_label" msgstr "" #. Default: "Struttura" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:211 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:206 msgid "struttura_label" msgstr "" #. Default: "Struttura responsabile" -#: design/plone/contenttypes/behaviors/luogo.py:82 +#: design/plone/contenttypes/behaviors/luogo.py:83 msgid "struttura_responsabile" msgstr "" #. Default: "Struttura responsabile del luogo." -#: design/plone/contenttypes/behaviors/luogo.py:63 +#: design/plone/contenttypes/behaviors/luogo.py:64 msgid "struttura_responsabile_correlati" msgstr "" #. Default: "Indicare la struttura responsabile del luogo qualora sia fra unità organizzative del comune inserite nel sito; altrimenti compilare i campi testuali relativi alla struttura responsabile" -#: design/plone/contenttypes/behaviors/luogo.py:67 +#: design/plone/contenttypes/behaviors/luogo.py:68 msgid "struttura_responsabile_correlati_help" msgstr "" #. Default: "Nome/link al sito web della struttura che gestisce il luogo, se questa non è comunale." -#: design/plone/contenttypes/behaviors/luogo.py:84 +#: design/plone/contenttypes/behaviors/luogo.py:85 msgid "struttura_responsabile_help" msgstr "" #. Default: "Seleziona la lista delle strutture politiche coinvolte." -#: design/plone/contenttypes/behaviors/strutture_correlate.py:25 +#: design/plone/contenttypes/behaviors/strutture_correlate.py:26 msgid "strutture_politiche_help" msgstr "" #. Default: "Indicare gli uffici/enti che supportano l'evento." -#: design/plone/contenttypes/behaviors/evento.py:149 +#: design/plone/contenttypes/behaviors/evento.py:97 msgid "supportato_da_help" msgstr "" #. Default: "Evento supportato da" -#: design/plone/contenttypes/behaviors/evento.py:145 +#: design/plone/contenttypes/behaviors/evento.py:93 msgid "supportato_da_label" msgstr "" #. Default: "Seleziona una lista di argomenti d'interesse per questo contenuto." -#: design/plone/contenttypes/behaviors/argomenti.py:22 +#: design/plone/contenttypes/behaviors/argomenti.py:26 msgid "tassonomia_argomenti_help" msgstr "" -#. Default: "Tassonomia argomenti" -#: design/plone/contenttypes/behaviors/argomenti.py:21 +#. Default: "Argomenti" +#: design/plone/contenttypes/behaviors/argomenti.py:25 msgid "tassonomia_argomenti_label" msgstr "" -#. Default: "Telefono" -#: design/plone/contenttypes/behaviors/evento.py:104 -msgid "telefono_event_help" -msgstr "" - -#. Default: "Indicare un riferimento telefonico per poter contattare gli organizzatori." -#: design/plone/contenttypes/behaviors/evento.py:105 -msgid "telefono_event_label" -msgstr "" - -#. Default: "Indicare un riferimento telefonico per poter contattare i referenti." -#: design/plone/contenttypes/behaviors/contatti.py:19 -msgid "telefono_help" -msgstr "" - -#. Default: "Telefono" -#: design/plone/contenttypes/behaviors/contatti.py:18 -msgid "telefono_label" -msgstr "" - -#. Default: "Contatto telefonico della persona. E' possibile inserire più di un numero. Premendo \"Invio\" o \"tab\" si può passare al successivo da inserire." -#: design/plone/contenttypes/interfaces/persona.py:117 -msgid "telefono_persona_help" -msgstr "" - -#. Default: "Numero di telefono" -#: design/plone/contenttypes/interfaces/persona.py:116 -msgid "telefono_persona_label" -msgstr "" - -#. Default: "Temi" -#: design/plone/contenttypes/interfaces/dataset.py:14 -msgid "temi" -msgstr "" - #. Default: "Tempi e scadenze" -#: design/plone/contenttypes/interfaces/servizio.py:167 +#: design/plone/contenttypes/interfaces/servizio.py:236 msgid "tempi_e_scadenze" msgstr "" #. Default: "Descrivere le informazioni dettagliate riguardo eventuali tempi e scadenze di questo servizio." -#: design/plone/contenttypes/interfaces/servizio.py:169 +#: design/plone/contenttypes/interfaces/servizio.py:238 msgid "tempi_e_scadenze_help" msgstr "" #. Default: "Tempi e scadenze" -#: design/plone/contenttypes/interfaces/servizio.py:395 +#: design/plone/contenttypes/interfaces/servizio.py:508 msgid "tempi_e_scadenze_label" msgstr "" #. Default: "Inserisci il tempo medio del procedimento." -#: design/plone/contenttypes/behaviors/trasparenza.py:91 +#: design/plone/contenttypes/behaviors/trasparenza.py:92 msgid "tempo_medio_help" msgstr "" #. Default: "Tempo medio del procedimento" -#: design/plone/contenttypes/behaviors/trasparenza.py:86 +#: design/plone/contenttypes/behaviors/trasparenza.py:87 msgid "tempo_medio_label" msgstr "" #. Default: "Testata" -#: design/plone/contenttypes/behaviors/argomenti.py:104 +#: design/plone/contenttypes/behaviors/argomenti.py:232 #: design/plone/contenttypes/behaviors/info_testata.py:62 msgid "testata_fieldset_label" msgstr "" -#: design/plone/contenttypes/interfaces/bando.py:28 +#: design/plone/contenttypes/interfaces/bando.py:29 msgid "text_help" msgstr "" #. Default: "Testo" -#: design/plone/contenttypes/interfaces/bando.py:27 +#: design/plone/contenttypes/interfaces/bando.py:28 msgid "text_label" msgstr "" -#. Default: "Tipologia documento" -#: design/plone/contenttypes/interfaces/messaggio.py:49 -msgid "tipologia_documento" -msgstr "" - -#. Default: "Seleziona la tipologia del documento." -#: design/plone/contenttypes/interfaces/documento.py:30 -msgid "tipologia_documento_help" -msgstr "" - -#. Default: "Tipologia del documento" -#: design/plone/contenttypes/interfaces/documento.py:29 -msgid "tipologia_documento_label" -msgstr "" - -#. Default: "Seleziona la tipologia della notizia." -#: design/plone/contenttypes/behaviors/news_additional_fields.py:29 -msgid "tipologia_notizia_help" -msgstr "" - -#. Default: "Tipologia notizia" -#: design/plone/contenttypes/behaviors/news_additional_fields.py:28 -msgid "tipologia_notizia_label" -msgstr "" - -#. Default: "Specificare la tipologia di organizzazione: politica, amminsitrativa o di altro tipo." -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:60 -msgid "tipologia_organizzazione_help" -msgstr "" - -#. Default: "Tipologia organizzazione" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:57 -msgid "tipologia_organizzazione_label" -msgstr "" - -#. Default: "Seleziona la tipologia di persona: politica, amministrativa o di altro tipo." -#: design/plone/contenttypes/interfaces/persona.py:86 -msgid "tipologia_persona_help" -msgstr "" - -#. Default: "Tipologia persona" -#: design/plone/contenttypes/interfaces/persona.py:85 -msgid "tipologia_persona_label" -msgstr "" - -#. Default: "Inserisci i valori utilizzabili per le tipologie di un Documento. Se il sito è multilingua, puoi inserire valori diversi a seconda delle lingue del sito." -#: design/plone/contenttypes/controlpanels/settings.py:46 -msgid "tipologie_documento_help" +#. Default: "Timeline tempi e scadenze" +#: design/plone/contenttypes/interfaces/servizio.py:246 +msgid "timeline_tempi_scadenze" msgstr "" -#. Default: "Tipologie Documento" -#: design/plone/contenttypes/controlpanels/settings.py:45 -msgid "tipologie_documento_label" +#. Default: "Timeline tempi e scadenze del servizio: indicare per ogni scadenza un titolo descrittivo ed un eventuale sottotitolo. Per ogni scadenza, selezionare opzionalmente o l'intervallo (Campi \"Intervallo\" e \"Tipo Intervallo\", es. \"1\" e \"settimana\"), oppure direttamente una data di scadenza (campo: \"Data Scadenza\", esempio 31/12/2023). Se vengono compilati entrambi, ha priorità il campo \"Data Scadenza\"." +#: design/plone/contenttypes/interfaces/servizio.py:249 +msgid "timeline_tempi_scadenze_help" msgstr "" #. Default: "Inserisci i valori utilizzabili per le tipologie di una Notizia. Se il sito è multilingua, puoi inserire valori diversi a seconda delle lingue del sito." -#: design/plone/contenttypes/controlpanels/settings.py:19 +#: design/plone/contenttypes/controlpanels/settings.py:22 msgid "tipologie_notizia_help" msgstr "" #. Default: "Tipologie Notizia" -#: design/plone/contenttypes/controlpanels/settings.py:18 +#: design/plone/contenttypes/controlpanels/settings.py:21 msgid "tipologie_notizia_label" msgstr "" -#. Default: "Inserisci i valori utilizzabili per le tipologie di una Persona. Se il sito è multilingua, puoi inserire valori diversi a seconda delle lingue del sito." -#: design/plone/contenttypes/controlpanels/settings.py:72 -msgid "tipologie_persona_help" -msgstr "" - -#. Default: "Tipologie Persona" -#: design/plone/contenttypes/controlpanels/settings.py:71 -msgid "tipologie_persona_label" -msgstr "" - #. Default: "Inserisci i valori utilizzabili per le tipologie di un' Unità Organizzativa. Se il sito è multilingua, puoi inserire valori diversi a seconda delle lingue del sito." -#: design/plone/contenttypes/controlpanels/settings.py:34 +#: design/plone/contenttypes/controlpanels/settings.py:37 msgid "tipologie_unita_organizzativa_help" msgstr "" #. Default: "Tipologie Unità Organizzativa" -#: design/plone/contenttypes/controlpanels/settings.py:30 +#: design/plone/contenttypes/controlpanels/settings.py:33 msgid "tipologie_unita_organizzativa_label" msgstr "" #. Default: "Titolare" -#: design/plone/contenttypes/interfaces/dataset.py:29 +#: design/plone/contenttypes/interfaces/dataset.py:22 msgid "titolare" msgstr "" #. Default: "Eventuale titolare del potere sostitutivo." -#: design/plone/contenttypes/behaviors/trasparenza.py:243 +#: design/plone/contenttypes/behaviors/trasparenza.py:244 msgid "titolare_potere_sostitutivo_help" msgstr "" #. Default: "Titolare del potere sostitutivo" -#: design/plone/contenttypes/behaviors/trasparenza.py:238 +#: design/plone/contenttypes/behaviors/trasparenza.py:239 msgid "titolare_potere_sostitutivo_label" msgstr "" #. Default: "Trasparenza" -#: design/plone/contenttypes/behaviors/trasparenza.py:292 +#: design/plone/contenttypes/behaviors/trasparenza.py:291 msgid "trasparenza_fieldset_label" msgstr "" +#. Default: "Tipo" +#: design/plone/contenttypes/interfaces/punto_di_contatto.py:17 +msgid "type_help" +msgstr "" + #. Default: "Seleziona l'ufficio responsabile di questo bando." -#: design/plone/contenttypes/interfaces/bando.py:110 +#: design/plone/contenttypes/interfaces/bando.py:111 msgid "ufficio_responsabile_bando_help" msgstr "" #. Default: "Ufficio responsabile del bando" -#: design/plone/contenttypes/interfaces/bando.py:106 +#: design/plone/contenttypes/interfaces/bando.py:107 msgid "ufficio_responsabile_bando_label" msgstr "" #. Default: "Seleziona l'ufficio responsabile di questo documento." -#: design/plone/contenttypes/interfaces/documento.py:43 +#: design/plone/contenttypes/interfaces/documento.py:73 msgid "ufficio_responsabile_documento_help" msgstr "" #. Default: "Ufficio responsabile del documento" -#: design/plone/contenttypes/interfaces/documento.py:39 +#: design/plone/contenttypes/interfaces/documento.py:69 msgid "ufficio_responsabile_documento_label" msgstr "" @@ -2625,13 +2620,13 @@ msgstr "" msgid "ufficio_responsabile_documento_personale" msgstr "" -#. Default: "Uffici responsabili" -#: design/plone/contenttypes/interfaces/servizio.py:216 +#. Default: "Unità organizzativa responsabile" +#: design/plone/contenttypes/interfaces/servizio.py:302 msgid "ufficio_responsabile_erogazione" msgstr "" #. Default: "Seleziona gli uffici responsabili dell'erogazione di questo servizio." -#: design/plone/contenttypes/interfaces/servizio.py:217 +#: design/plone/contenttypes/interfaces/servizio.py:306 msgid "ufficio_responsabile_help" msgstr "" @@ -2662,52 +2657,52 @@ msgstr "" msgid "unita_amministrative_responsabili_help" msgstr "" +#. Default: "Seleziona l'organizzazione presso la quale svolge l'incarico." +#: design/plone/contenttypes/interfaces/incarico.py:64 +msgid "unita_organizzativa_incarico_help" +msgstr "" + +#. Default: "Unità organizzativa" +#: design/plone/contenttypes/interfaces/incarico.py:60 +msgid "unita_organizzativa_incarico_label" +msgstr "" + #. Default: "Descrizione dei compiti assegnati alla struttura." -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:19 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:23 msgid "uo_competenze_help" msgstr "" #. Default: "Competenze" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:18 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:22 msgid "uo_competenze_label" msgstr "" -#. Default: "Inserisci eventuali informazioni di contatto aggiuntive non contemplate nei campi precedenti. Utilizza questo campo se ci sono dei contatti aggiuntivi rispetto ai contatti della sede principale. Se inserisci un collegamento con un indirizzo email, aggiungi \"mailto:\" prima dell'indirizzo, per farlo aprire direttamente nel client di posta." -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:139 -msgid "uo_contact_info_description" -msgstr "" - #. Default: "Note di aggiornamento" -#: design/plone/contenttypes/behaviors/update_note.py:16 +#: design/plone/contenttypes/behaviors/update_note.py:17 msgid "update_note_label" msgstr "" +#. Default: "Il valore del punto di contatto: il numero compreso di prefisso internazionale (se telefono), l'account (se social network), l'URL (se sito o pagina web), l'indirizzo email (se email)." +#: design/plone/contenttypes/interfaces/punto_di_contatto.py:54 +msgid "value_punto_contatto_help" +msgstr "" + #. Default: "Vincoli" -#: design/plone/contenttypes/interfaces/servizio.py:196 +#: design/plone/contenttypes/interfaces/servizio.py:282 msgid "vincoli" msgstr "" #. Default: "Descrizione degli eventuali vincoli presenti." -#: design/plone/contenttypes/interfaces/servizio.py:198 +#: design/plone/contenttypes/interfaces/servizio.py:284 msgid "vincoli_help" msgstr "" -#. Default: "Indicare un indirizzo web di riferimento a questo evento." -#: design/plone/contenttypes/behaviors/evento.py:138 -msgid "web_event_help" -msgstr "" - -#. Default: "Sito web" -#: design/plone/contenttypes/behaviors/evento.py:137 -msgid "web_event_label" -msgstr "" - -#. Default: "Indicare un indirizzo web di riferimento." -#: design/plone/contenttypes/behaviors/contatti.py:53 -msgid "web_help" +#. Default: "Mostra i PDF in anteprima" +#: design/plone/contenttypes/interfaces/cartella_modulistica.py:12 +msgid "visualize_files_title" msgstr "" -#. Default: "Sito web" -#: design/plone/contenttypes/behaviors/contatti.py:52 -msgid "web_label" +#. Default: "Permette di aprire l'anteprima di tutti i PDF di questa cartella in una tab separata, altrimenti i PDF vengono scaricati" +#: design/plone/contenttypes/interfaces/cartella_modulistica.py:13 +msgid "visulize_files_description" msgstr "" diff --git a/src/design/plone/contenttypes/locales/design.plone.contenttypes.pot b/src/design/plone/contenttypes/locales/design.plone.contenttypes.pot index 0f661e42..47f7bc47 100644 --- a/src/design/plone/contenttypes/locales/design.plone.contenttypes.pot +++ b/src/design/plone/contenttypes/locales/design.plone.contenttypes.pot @@ -4,7 +4,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2023-01-13 13:15+0000\n" +"POT-Creation-Date: 2024-03-18 13:30+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI +ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,39 +17,23 @@ msgstr "" "Preferred-Encodings: utf-8 latin1\n" "Domain: design.plone.contenttypes\n" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:32 -msgid "Abitazione" -msgstr "" - -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:36 -msgid "Accesso al trasporto pubblico" -msgstr "" - -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:59 -msgid "Accesso luoghi della cultura" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:18 +msgid "Accesso all'informazione" msgstr "" #: design/plone/contenttypes/vocabularies/lista_azioni_pratica.py:33 msgid "Accettare" msgstr "" -#: design/plone/contenttypes/vocabularies/document_types_vocabulary.py:34 -msgid "Accordo tra enti" -msgstr "" - -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:52 +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:19 msgid "Acqua" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:194 +#: design/plone/contenttypes/behaviors/configure.zcml:223 msgid "Address Event" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:178 -msgid "Address UO" -msgstr "" - -#: design/plone/contenttypes/behaviors/configure.zcml:186 +#: design/plone/contenttypes/behaviors/configure.zcml:215 msgid "Address Venue" msgstr "" @@ -57,57 +41,53 @@ msgstr "" msgid "Adds fields." msgstr "" -#: design/plone/contenttypes/vocabularies/dataset.py:28 -msgid "Agricoltura, pesca, silvicoltura e prodotti alimentari" +#: design/plone/contenttypes/configure.zcml:66 +msgid "After Plone6 migration syndication is broken" msgstr "" -#: design/plone/contenttypes/browser/manage_content/templates/change_news_type.pt:22 -msgid "All the already existing News Types" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:20 +msgid "Agricoltura" msgstr "" -#: design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt:63 -msgid "All the selected items will be moved to indicated path" +#: design/plone/contenttypes/browser/utils/templates/change_news_type.pt:30 +msgid "All the already existing News Types" msgstr "" -#: design/plone/contenttypes/vocabularies/dataset.py:36 -msgid "Ambiente" +#: design/plone/contenttypes/browser/utils/templates/move_news_items.pt:113 +msgid "All the selected items will be moved to indicated path" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:33 +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:21 msgid "Animale domestico" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:25 -msgid "Anziano" -msgstr "" - -#: design/plone/contenttypes/interfaces/bando.py:134 -#: design/plone/contenttypes/interfaces/documento.py:67 -#: design/plone/contenttypes/interfaces/servizio.py:239 +#: design/plone/contenttypes/interfaces/bando.py:135 +#: design/plone/contenttypes/interfaces/documento.py:97 +#: design/plone/contenttypes/interfaces/servizio.py:328 msgid "Area" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:50 -msgid "Area di parcheggio" -msgstr "" - #: design/plone/contenttypes/behaviors/configure.zcml:49 msgid "Argomenti" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:76 +#: design/plone/contenttypes/behaviors/configure.zcml:94 msgid "Argomenti Bando" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:58 +#: design/plone/contenttypes/behaviors/configure.zcml:76 msgid "Argomenti Document" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:67 +#: design/plone/contenttypes/behaviors/configure.zcml:85 msgid "Argomenti Documento" msgstr "" -#: design/plone/contenttypes/behaviors/argomenti.py:28 +#: design/plone/contenttypes/behaviors/configure.zcml:112 +msgid "Argomenti Link" +msgstr "" + +#: design/plone/contenttypes/behaviors/argomenti.py:32 msgid "Argomenti correlati" msgstr "" @@ -115,20 +95,36 @@ msgstr "" msgid "Argomento" msgstr "" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:73 +#: design/plone/contenttypes/behaviors/configure.zcml:103 +msgid "Argomento Servizio" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:22 +msgid "Aria" +msgstr "" + +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:65 msgid "Assessore di riferimento" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:30 -msgid "Associazione" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:23 +msgid "Assistenza agli invalidi" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:24 +msgid "Assistenza sociale" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:25 +msgid "Associazioni" msgstr "" #: design/plone/contenttypes/vocabularies/lista_azioni_pratica.py:29 msgid "Attivare" msgstr "" -#: design/plone/contenttypes/vocabularies/document_types_vocabulary.py:33 -msgid "Atto normativo" +#: design/plone/contenttypes/interfaces/incarico.py:121 +msgid "Atto di nomina" msgstr "" #: design/plone/contenttypes/interfaces/documento_personale.py:86 @@ -139,70 +135,66 @@ msgstr "" msgid "Autorizzare" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:65 -msgid "Avvio impresa" -msgstr "" - -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:66 -msgid "Avvio nuova attività professionale" -msgstr "" - -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:69 -msgid "Avvio/registrazione filiale" +#: design/plone/contenttypes/behaviors/configure.zcml:223 +msgid "Behavior address per Event." msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:78 -msgid "Bancarotta" +#: design/plone/contenttypes/behaviors/configure.zcml:215 +msgid "Behavior address per Venue." msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:194 -msgid "Behavior address per Event." +#: design/plone/contenttypes/behaviors/configure.zcml:263 +msgid "Behavior contatti per Event." msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:178 -msgid "Behavior address per UO." +#: design/plone/contenttypes/behaviors/configure.zcml:255 +msgid "Behavior contatti per Persona." msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:186 -msgid "Behavior address per Venue." +#: design/plone/contenttypes/behaviors/configure.zcml:247 +msgid "Behavior contatti per Servizio." msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:202 +#: design/plone/contenttypes/behaviors/configure.zcml:231 msgid "Behavior contatti per UO." msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:210 +#: design/plone/contenttypes/behaviors/configure.zcml:239 msgid "Behavior contatti per Venue." msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:234 +#: design/plone/contenttypes/behaviors/configure.zcml:279 msgid "Behavior geolocatable per Event." msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:218 -msgid "Behavior geolocatable per UO." +#: design/plone/contenttypes/behaviors/configure.zcml:271 +msgid "Behavior geolocatable per Venue." msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:226 -msgid "Behavior geolocatable per Venue." +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:26 +msgid "Bilancio" msgstr "" #: design/plone/contenttypes/controlpanels/geolocation_defaults.py:18 msgid "CAP" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:43 -msgid "Cambio di residenza/domicilio" +#: design/plone/contenttypes/behaviors/configure.zcml:306 +msgid "Campi aggiuntivi per la sezione amministrazione trasparente." msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:261 -msgid "Campi aggiuntivi per la sezione amministrazione trasparente." +#: design/plone/contenttypes/behaviors/configure.zcml:324 +msgid "Campo per escludere un contenuto dalle ricerche del sito." msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:270 +#: design/plone/contenttypes/behaviors/configure.zcml:315 msgid "Campo per le note di aggiornamento." msgstr "" +#: design/plone/contenttypes/interfaces/servizio.py:183 +msgid "Canale fisico" +msgstr "" + #: design/plone/contenttypes/vocabularies/mockup.py:26 msgid "Canon 5D IV" msgstr "" @@ -211,39 +203,44 @@ msgstr "" msgid "Cartella Modulistica" msgstr "" -#: design/plone/contenttypes/browser/manage_content/templates/change_news_type.pt:11 +#: design/plone/contenttypes/browser/utils/templates/change_news_type.pt:13 msgid "Change News Type" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:75 -msgid "Chiusura filiale" +#: design/plone/contenttypes/controlpanels/geolocation_defaults.py:23 +msgid "Città" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:74 -msgid "Chiusura impresa e attività professionale" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:28 +msgid "Commercio al minuto" msgstr "" -#: design/plone/contenttypes/controlpanels/geolocation_defaults.py:23 -msgid "Città" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:27 +msgid "Commercio all'ingrosso" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:39 -msgid "Compravendita/affitto casa/edifici/terreni, costruzione o ristrutturazione casa/edificio " +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:29 +msgid "Commercio ambulante" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:36 -msgid "Comunicazione" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:30 +msgid "Comunicazione istituzionale" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:41 -msgid "Condizioni e organizzazione del lavoro" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:31 +msgid "Comunicazione politica" msgstr "" -#: design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt:57 +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:32 +msgid "Concorsi" +msgstr "" + +#: design/plone/contenttypes/browser/utils/templates/move_news_items.pt:104 msgid "Contained by" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:202 +#: design/plone/contenttypes/behaviors/configure.zcml:231 +#: design/plone/contenttypes/behaviors/contatti.py:112 msgid "Contatti" msgstr "" @@ -251,12 +248,12 @@ msgstr "" msgid "Coordinate" msgstr "" -#: design/plone/contenttypes/behaviors/argomenti.py:42 +#: design/plone/contenttypes/behaviors/argomenti.py:46 msgid "Correlato in evidenza" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:47 -msgid "Cultura" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:33 +msgid "Covid - 19" msgstr "" #: design/plone/contenttypes/interfaces/documento_personale.py:130 @@ -268,7 +265,7 @@ msgstr "" msgid "Dataset collegato" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:104 +#: design/plone/contenttypes/behaviors/configure.zcml:141 msgid "Dataset correlati" msgstr "" @@ -276,115 +273,102 @@ msgstr "" msgid "Delegare" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:52 -msgid "Denuncia crimini" -msgstr "" - -#: design/plone/contenttypes/behaviors/configure.zcml:143 +#: design/plone/contenttypes/behaviors/configure.zcml:180 msgid "Descrizione estesa" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:160 +#: design/plone/contenttypes/behaviors/configure.zcml:197 msgid "Descrizione estesa documento" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:152 +#: design/plone/contenttypes/behaviors/configure.zcml:189 msgid "Descrizione estesa servizio" msgstr "" -#: design/plone/contenttypes/configure.zcml:36 +#: design/plone/contenttypes/configure.zcml:32 msgid "Design Plone: Content-types" msgstr "" -#: design/plone/contenttypes/configure.zcml:45 +#: design/plone/contenttypes/configure.zcml:41 +msgid "Design Plone: Content-types (behaviors)" +msgstr "" + +#: design/plone/contenttypes/configure.zcml:50 msgid "Design Plone: Content-types (uninstall)" msgstr "" -#: design/plone/contenttypes/configure.zcml:52 +#: design/plone/contenttypes/configure.zcml:58 msgid "Design Plone: Content-types to 3000" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:55 -msgid "Dichiarazione dei redditi, versamento e riscossione tributi/imposte e contributi" +#: design/plone/contenttypes/configure.zcml:66 +msgid "Design Plone: Fix Syndication after Plone6 Migration" msgstr "" -#: design/plone/contenttypes/behaviors/trasparenza.py:145 +#: design/plone/contenttypes/behaviors/trasparenza.py:146 msgid "Dirigente" msgstr "" -#: design/plone/contenttypes/vocabularies/document_types_vocabulary.py:27 -msgid "Documenti albo pretorio" +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:134 +msgid "Documenti pubblici" msgstr "" -#: design/plone/contenttypes/interfaces/servizio.py:252 +#: design/plone/contenttypes/interfaces/servizio.py:341 #: design/plone/contenttypes/profiles/default/types/Documento.xml msgid "Documento" msgstr "" -#: design/plone/contenttypes/vocabularies/document_types_vocabulary.py:41 -msgid "Documento (tecnico) di supporto" -msgstr "" - #: design/plone/contenttypes/profiles/default/types/Documento_Personale.xml msgid "Documento Personale" msgstr "" -#: design/plone/contenttypes/vocabularies/document_types_vocabulary.py:37 -msgid "Documento attivita politica" -msgstr "" - -#: design/plone/contenttypes/vocabularies/document_types_vocabulary.py:31 -msgid "Documento funzionamento interno" -msgstr "" - -#: design/plone/contenttypes/vocabularies/dataset.py:30 -msgid "Economia e Finanze" -msgstr "" - #: design/plone/contenttypes/profiles/default/types/CartellaModulistica.xml #: design/plone/contenttypes/profiles/default/types/Dataset.xml #: design/plone/contenttypes/profiles/default/types/Documento.xml msgid "Edit" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:45 -msgid "Elezione" -msgstr "" - -#: design/plone/contenttypes/vocabularies/dataset.py:35 -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:61 -msgid "Energia" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:34 +msgid "Elezioni" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:28 -msgid "Famiglia" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:35 +msgid "Energie rinnovabili" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:26 -msgid "Fanciullo" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:36 +msgid "Estero" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:70 -msgid "Finanziamento impresa" +#: design/plone/contenttypes/behaviors/configure.zcml:324 +msgid "Exclude from search" msgstr "" -#: design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt:28 +#: design/plone/contenttypes/browser/utils/templates/move_news_items.pt:51 msgid "Find news with the indicated Path, put attention than generaly sites have the root name \"/Plone/\"" msgstr "" -#: design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt:21 +#: design/plone/contenttypes/browser/utils/templates/move_news_items.pt:29 msgid "Find news with this News Type" msgstr "" -#: design/plone/contenttypes/configure.zcml:52 +#: design/plone/contenttypes/configure.zcml:58 msgid "Fix control panel of design.plone.contenttypes add-on." msgstr "" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:37 +msgid "Foreste" +msgstr "" + #: design/plone/contenttypes/vocabularies/tags_vocabulary.py:38 msgid "Formazione professionale" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:218 +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:39 +msgid "Gemellaggi" +msgstr "" + +#: design/plone/contenttypes/behaviors/configure.zcml:271 msgid "Geolocatable" msgstr "" @@ -393,44 +377,57 @@ msgstr "" msgid "Geolocation default" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:53 -msgid "Gestione dei rifiuti" -msgstr "" - -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:71 -msgid "Gestione personale" -msgstr "" - -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:27 -msgid "Giovane" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:40 +msgid "Gestione rifiuti" msgstr "" #: design/plone/contenttypes/vocabularies/mockup.py:30 msgid "Giovanni" msgstr "" -#: design/plone/contenttypes/vocabularies/dataset.py:42 -msgid "Giustizia, sistema giuridico e sicurezza pubblica" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:41 +msgid "Giustizia" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:42 +msgid "Igiene pubblica" msgstr "" -#: design/plone/contenttypes/vocabularies/dataset.py:37 -msgid "Governo e settore pubblico" +#: design/plone/contenttypes/browser/utils/change_news_type.py:32 +#: design/plone/contenttypes/browser/utils/move_news_items.py:74 +msgid "Il vocabolario dei valori non è stato trovato" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:48 +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:43 msgid "Immigrazione" msgstr "" -#: design/plone/contenttypes/controlpanels/settings.py:154 +#: design/plone/contenttypes/controlpanels/settings.py:106 #: design/plone/contenttypes/profiles/default/controlpanel.xml msgid "Impostazioni Design Plone" msgstr "" -#: design/plone/contenttypes/browser/manage_content/move_news_items.py:33 +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:44 +msgid "Imposte" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:45 +msgid "Imprese" +msgstr "" + +#: design/plone/contenttypes/interfaces/persona.py:68 +msgid "Incarichi" +msgstr "" + +#: design/plone/contenttypes/profiles/default/types/Incarico.xml +msgid "Incarico" +msgstr "" + +#: design/plone/contenttypes/browser/utils/move_news_items.py:34 msgid "Indicated path is not valid" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:170 +#: design/plone/contenttypes/behaviors/configure.zcml:207 msgid "Info per la testata" msgstr "" @@ -438,64 +435,56 @@ msgstr "" msgid "Informare" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:64 -msgid "Informatica e trattamento dei dati" +#: design/plone/contenttypes/behaviors/contatti.py:34 +msgid "Informazioni di contatto" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:49 +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:46 msgid "Inquinamento" msgstr "" -#: design/plone/contenttypes/configure.zcml:36 +#: design/plone/contenttypes/configure.zcml:32 msgid "Installs the design.plone.contenttypes add-on." msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:34 +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:47 msgid "Integrazione sociale" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:28 -msgid "Invalidità" -msgstr "" - #: design/plone/contenttypes/vocabularies/lista_azioni_pratica.py:26 msgid "Iscriversi" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:26 -msgid "Iscrizione scuola/università e/o richiesta borsa di studio" -msgstr "" - -#: design/plone/contenttypes/vocabularies/document_types_vocabulary.py:43 -msgid "Istanza" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:48 +msgid "Isolamento termico" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:31 +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:49 msgid "Istruzione" msgstr "" -#: design/plone/contenttypes/vocabularies/dataset.py:33 -msgid "Istruzione, cultura e sport" +#: design/plone/contenttypes/browser/utils/move_news_items.py:48 +msgid "Items moved with success" msgstr "" -#: design/plone/contenttypes/browser/manage_content/move_news_items.py:47 -msgid "Items moved with success" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:50 +msgid "Lavoro" msgstr "" #: design/plone/contenttypes/vocabularies/lista_azioni_pratica.py:28 msgid "Leggere" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:85 +#: design/plone/contenttypes/behaviors/configure.zcml:122 msgid "Luoghi correlati" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:44 +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:51 msgid "Matrimonio" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:49 -msgid "Matrimonio e/o cambio stato civile" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:52 +msgid "Mercato" msgstr "" #: design/plone/contenttypes/profiles/default/types/Messaggio.xml @@ -514,72 +503,64 @@ msgstr "" msgid "Metadati news" msgstr "" -#: design/plone/contenttypes/vocabularies/document_types_vocabulary.py:28 -msgid "Modulistica" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:53 +msgid "Mobilità sostenibile" msgstr "" #: design/plone/contenttypes/profiles/default/types/Modulo.xml msgid "Modulo" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:50 -msgid "Morte ed eredità" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:54 +msgid "Morte" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:252 +#: design/plone/contenttypes/behaviors/configure.zcml:297 msgid "Mostra la data di modifica." msgstr "" -#: design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt:70 +#: design/plone/contenttypes/browser/utils/templates/move_news_items.pt:124 msgid "Move" msgstr "" -#: design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt:11 +#: design/plone/contenttypes/browser/utils/templates/move_news_items.pt:13 msgid "Move News Items" msgstr "" -#: design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt:62 +#: design/plone/contenttypes/browser/utils/templates/move_news_items.pt:110 msgid "Move to Path" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:243 +#: design/plone/contenttypes/behaviors/configure.zcml:288 msgid "Multi File" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:48 -msgid "Nascita di un bambino, richiesta adozioni" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:55 +msgid "Nascita" msgstr "" #: design/plone/contenttypes/controlpanels/geolocation_defaults.py:28 msgid "Nazione" msgstr "" -#: design/plone/contenttypes/browser/manage_content/templates/change_news_type.pt:21 -#: design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt:20 +#: design/plone/contenttypes/browser/utils/templates/change_news_type.pt:27 +#: design/plone/contenttypes/browser/utils/templates/move_news_items.pt:26 msgid "News Type" msgstr "" -#: design/plone/contenttypes/browser/manage_content/templates/change_news_type.pt:30 +#: design/plone/contenttypes/browser/utils/templates/change_news_type.pt:48 msgid "News Type to substitute" msgstr "" #. Default: "Nome e cognome" -#: design/plone/contenttypes/restapi/services/types/get.py:152 +#: design/plone/contenttypes/restapi/services/types/get.py:163 msgid "Nome e Cognome" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:73 -msgid "Notifiche autorità" -msgstr "" - -#: design/plone/contenttypes/interfaces/persona.py:48 +#: design/plone/contenttypes/interfaces/persona.py:51 msgid "Organizzazione di riferimento" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:72 -msgid "Pagamento tasse, iva e dogane" -msgstr "" - #: design/plone/contenttypes/vocabularies/lista_azioni_pratica.py:25 msgid "Pagare" msgstr "" @@ -588,84 +569,100 @@ msgstr "" msgid "Paperino" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:81 -msgid "Partecipazione ad appalti pubblici nazionali e trasfrontalieri" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:56 +msgid "Parcheggi" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:33 -msgid "Pensionamento" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:57 +msgid "Patrimonio culturale" msgstr "" -#: design/plone/contenttypes/profiles/default/types/Persona.xml +#: design/plone/contenttypes/interfaces/incarico.py:54 msgid "Persona" msgstr "" -#: design/plone/contenttypes/behaviors/evento.py:50 -msgid "Persona dell'amministrazione" +#: design/plone/contenttypes/profiles/default/types/Persona.xml +msgid "Persona pubblica" msgstr "" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:92 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:84 msgid "Persone della struttura" msgstr "" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:58 +msgid "Pesca" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:59 +msgid "Piano di sviluppo" +msgstr "" + #: design/plone/contenttypes/vocabularies/mockup.py:27 msgid "Pippo" msgstr "" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:60 +msgid "Pista ciclabile" +msgstr "" + #: design/plone/contenttypes/vocabularies/mockup.py:28 msgid "Pluto" msgstr "" -#: design/plone/contenttypes/vocabularies/dataset.py:45 -msgid "Popolazione e società" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:61 +msgid "Politica commerciale" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:60 -msgid "Possesso, cura, smarrimento animale da compagnia" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:62 +msgid "Polizia" msgstr "" #: design/plone/contenttypes/profiles/default/types/Pratica.xml msgid "Pratica" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:51 -msgid "Prenotazione e disdetta visite/esami" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:63 +msgid "Prodotti alimentari" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:35 -msgid "Protezione sociale" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:64 +msgid "Protezione civile" msgstr "" -#: design/plone/contenttypes/browser/manage_content/templates/change_news_type.pt:13 -msgid "Questo tool viene usato per cambiare il valore del campo 'Tipologia Notizia' in tutte le notizie che hanno il valore del campo selezionato. Fa anche il giro su tutti i blocchi elenco" +#: design/plone/contenttypes/behaviors/contatti.py:78 +msgid "Punti di contatto" msgstr "" -#: design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt:13 -msgid "Questo tool viene usato per trovare e spostare le Notizie con una Tipologia Notizia determinata." +#: design/plone/contenttypes/profiles/default/types/PuntoDiContatto.xml +msgid "Punto di Contatto" +msgstr "" + +#: design/plone/contenttypes/browser/utils/templates/change_news_type.pt:15 +msgid "Questo tool viene usato per cambiare il valore del campo 'Tipologia Notizia' in tutte le notizie che hanno il valore del campo selezionato. Fa anche il giro su tutti i blocchi elenco" msgstr "" -#: design/plone/contenttypes/vocabularies/dataset.py:44 -msgid "Regioni e città" +#: design/plone/contenttypes/browser/utils/templates/move_news_items.pt:15 +msgid "Questo tool viene usato per trovare e spostare le Notizie con una Tipologia Notizia determinata." msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:68 -msgid "Registrazione impresa transfrontalier" +#: design/plone/contenttypes/configure.zcml:41 +msgid "Registers taxonomies." msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:35 -msgid "Registrazione/possesso veicolo" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:65 +msgid "Residenza" msgstr "" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:45 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:49 msgid "Responsabile" msgstr "" -#: design/plone/contenttypes/behaviors/trasparenza.py:129 -msgid "Responsabile procedimento" +#: design/plone/contenttypes/interfaces/incarico.py:89 +msgid "Responsabile della struttura" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:31 -msgid "Ricerca di lavoro, avvio nuovo lavoro, disoccupazione" +#: design/plone/contenttypes/behaviors/trasparenza.py:130 +msgid "Responsabile procedimento" msgstr "" #: design/plone/contenttypes/profiles/default/types/RicevutaPagamento.xml @@ -676,40 +673,19 @@ msgstr "" msgid "Richiedere" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:67 -msgid "Richiesta licenze/permessi/certificati" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:66 +msgid "Risposta alle emergenze" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:34 -msgid "Richiesta o rinnovo patente" -msgstr "" - -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:46 -msgid "Richiesta passaporto, visto e assistenza viaggi internazionali" -msgstr "" - -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:76 -msgid "Ristrutturazione impresa" -msgstr "" - -#: design/plone/contenttypes/vocabularies/dataset.py:38 -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:54 -msgid "Salute" -msgstr "" - -#: design/plone/contenttypes/vocabularies/dataset.py:46 -msgid "Scienza e tecnologia" -msgstr "" - -#: design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt:27 +#: design/plone/contenttypes/browser/utils/templates/move_news_items.pt:47 msgid "Search Path" msgstr "" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:114 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:104 msgid "Sede" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:114 +#: design/plone/contenttypes/behaviors/configure.zcml:151 msgid "Servizi correlati" msgstr "" @@ -721,129 +697,128 @@ msgstr "" msgid "Servizio collegato" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:252 +#: design/plone/contenttypes/behaviors/configure.zcml:297 msgid "Show modified" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:56 -msgid "Sicurezza internazionale" -msgstr "" - -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:55 -msgid "Sicurezza pubblica" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:67 +msgid "Sistema giuridico" msgstr "" #: design/plone/contenttypes/vocabularies/mockup.py:25 msgid "Sony Aplha 7R III" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:57 -msgid "Spazio verde" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:68 +msgid "Spazio Verde" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:58 +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:69 msgid "Sport" msgstr "" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:37 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:41 msgid "Struttura" msgstr "" -#: design/plone/contenttypes/behaviors/strutture_correlate.py:20 +#: design/plone/contenttypes/behaviors/strutture_correlate.py:21 msgid "Struttura politica coinvolta" msgstr "" -#: design/plone/contenttypes/behaviors/luogo.py:74 +#: design/plone/contenttypes/behaviors/luogo.py:75 msgid "Struttura responsabile" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:124 +#: design/plone/contenttypes/behaviors/configure.zcml:161 msgid "Strutture correlate" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:29 -msgid "Studente" +#: design/plone/contenttypes/browser/utils/templates/change_news_type.pt:74 +msgid "Substitute" msgstr "" -#: design/plone/contenttypes/browser/manage_content/templates/change_news_type.pt:43 -msgid "Substitute" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:70 +msgid "Sviluppo sostenibile" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:71 +msgid "Tassa sui servizi" msgstr "" #: design/plone/contenttypes/behaviors/configure.zcml:49 msgid "Tassonomia argomenti" msgstr "" +#: design/plone/contenttypes/behaviors/configure.zcml:67 +msgid "Tassonomia argomenti evento" +msgstr "" + #: design/plone/contenttypes/behaviors/configure.zcml:58 -msgid "Tassonomia argomenti per i Document" +msgid "Tassonomia argomenti news" msgstr "" -#: design/plone/contenttypes/vocabularies/dataset.py:39 -msgid "Tematiche internazionali" +#: design/plone/contenttypes/behaviors/configure.zcml:76 +msgid "Tassonomia argomenti per i Document" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:46 +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:72 msgid "Tempo libero" msgstr "" -#: design/plone/contenttypes/browser/manage_content/templates/change_news_type.pt:31 +#: design/plone/contenttypes/browser/utils/templates/change_news_type.pt:52 msgid "The News Type selected above will be substituted by the selected value" msgstr "" -#: design/plone/contenttypes/browser/manage_content/change_news_type.py:97 +#: design/plone/contenttypes/browser/utils/change_news_type.py:108 msgid "The News Types was changed with success" msgstr "" -#: design/plone/contenttypes/browser/manage_content/change_news_type.py:55 +#: design/plone/contenttypes/browser/utils/change_news_type.py:64 msgid "The new News Type was not found between available values" msgstr "" -#: design/plone/contenttypes/browser/manage_content/change_news_type.py:49 +#: design/plone/contenttypes/browser/utils/change_news_type.py:58 msgid "The new type field was not populated" msgstr "" -#: design/plone/contenttypes/browser/manage_content/change_news_type.py:61 +#: design/plone/contenttypes/browser/utils/change_news_type.py:70 msgid "The old News Type was not found between available values" msgstr "" -#: design/plone/contenttypes/browser/manage_content/change_news_type.py:43 +#: design/plone/contenttypes/browser/utils/change_news_type.py:52 msgid "The old type field was not populated" msgstr "" -#: design/plone/contenttypes/browser/manage_content/move_news_items.py:51 +#: design/plone/contenttypes/browser/utils/move_news_items.py:52 msgid "The path was not indicated" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:51 -msgid "Traffico urbano" -msgstr "" - -#: design/plone/contenttypes/behaviors/configure.zcml:261 +#: design/plone/contenttypes/behaviors/configure.zcml:306 msgid "Trasparenza" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:43 -msgid "Trasporto" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:73 +msgid "Trasparenza amministrativa" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:59 -msgid "Trasporto stradale" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:74 +msgid "Trasporto pubblico" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:243 +#: design/plone/contenttypes/behaviors/configure.zcml:288 msgid "Tre campi file aggiuntivi." msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:60 +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:75 msgid "Turismo" msgstr "" -#: design/plone/contenttypes/interfaces/bando.py:117 -#: design/plone/contenttypes/interfaces/documento.py:50 -#: design/plone/contenttypes/interfaces/servizio.py:225 +#: design/plone/contenttypes/interfaces/bando.py:118 +#: design/plone/contenttypes/interfaces/documento.py:80 msgid "Ufficio responsabile" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:134 +#: design/plone/contenttypes/behaviors/configure.zcml:171 msgid "Ulteriori campi aiuto testuali" msgstr "" @@ -851,7 +826,11 @@ msgstr "" msgid "Un modulo compilabile." msgstr "" -#: design/plone/contenttypes/configure.zcml:45 +#: design/plone/contenttypes/browser/utils/templates/utils.pt:15 +msgid "Una raccolta di utility per i contenuti agid" +msgstr "" + +#: design/plone/contenttypes/configure.zcml:50 msgid "Uninstalls the design.plone.contenttypes add-on." msgstr "" @@ -863,65 +842,87 @@ msgstr "" msgid "Unità amministrative responsabili" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:270 -msgid "Update note" +#: design/plone/contenttypes/interfaces/incarico.py:71 +msgid "Unità organizzativa" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:37 -msgid "Urbanistica ed edilizia" +#: design/plone/contenttypes/interfaces/servizio.py:314 +msgid "Unità organizzativa responsabile" +msgstr "" + +#: design/plone/contenttypes/behaviors/configure.zcml:315 +msgid "Update note" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:77 -msgid "Vendita impresa" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:76 +msgid "Urbanizzazione" msgstr "" #: design/plone/contenttypes/controlpanels/geolocation_defaults.py:13 msgid "Via" msgstr "" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:77 +msgid "Viaggi" +msgstr "" + #: design/plone/contenttypes/profiles/default/types/CartellaModulistica.xml #: design/plone/contenttypes/profiles/default/types/Dataset.xml #: design/plone/contenttypes/profiles/default/types/Documento.xml msgid "View" msgstr "" -#. Default: "A chi si rivolge questo servizio e chi può usufruirne." -#: design/plone/contenttypes/interfaces/servizio.py:53 +#: design/plone/contenttypes/browser/utils/templates/utils.pt:13 +msgid "Viste di utility per Design Plone Contenttypes" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:79 +msgid "ZTL" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:78 +msgid "Zone pedonali" +msgstr "" + +#. Default: "Descrizione testuale dei principali destinatari dell'Evento" +#: design/plone/contenttypes/behaviors/evento.py:43 +#: design/plone/contenttypes/interfaces/servizio.py:98 msgid "a_chi_si_rivolge_help" msgstr "" -#. Default: "A chi si rivolge" -#: design/plone/contenttypes/interfaces/servizio.py:51 +#. Default: "A chi è rivolto" +#: design/plone/contenttypes/behaviors/evento.py:41 +#: design/plone/contenttypes/interfaces/servizio.py:96 msgid "a_chi_si_rivolge_label" msgstr "" #. Default: "Seleziona l'ufficio di comunicazione responsabile di questa notizia/comunicato stampa." -#: design/plone/contenttypes/behaviors/news_additional_fields.py:47 +#: design/plone/contenttypes/behaviors/news_additional_fields.py:39 msgid "a_cura_di_help" msgstr "" #. Default: "A cura di" -#: design/plone/contenttypes/behaviors/news_additional_fields.py:46 +#: design/plone/contenttypes/behaviors/news_additional_fields.py:38 msgid "a_cura_di_label" msgstr "" #. Default: "Seleziona una lista di persone dell'amministrazione citate in questa notizia/comunicato stampa. Questa informazione verrà mostrata nella sezione \"A cura di\"." -#: design/plone/contenttypes/behaviors/news_additional_fields.py:59 +#: design/plone/contenttypes/behaviors/news_additional_fields.py:51 msgid "a_cura_di_persone_help" msgstr "" #. Default: "Persone" -#: design/plone/contenttypes/behaviors/news_additional_fields.py:58 +#: design/plone/contenttypes/behaviors/news_additional_fields.py:50 msgid "a_cura_di_persone_label" msgstr "" #. Default: "Accedere al servizio" -#: design/plone/contenttypes/interfaces/servizio.py:370 +#: design/plone/contenttypes/interfaces/servizio.py:481 msgid "accedi_al_servizio_label" msgstr "" #. Default: "Modalità di accesso" -#: design/plone/contenttypes/behaviors/luogo.py:171 +#: design/plone/contenttypes/behaviors/luogo.py:140 msgid "accesso_label" msgstr "" @@ -931,37 +932,37 @@ msgid "allegato" msgstr "" #. Default: "Indicare, se esistono, altre modalità di invio." -#: design/plone/contenttypes/behaviors/trasparenza.py:189 +#: design/plone/contenttypes/behaviors/trasparenza.py:190 msgid "altre_modalita_invio_help" msgstr "" #. Default: "Altre modalità di invio" -#: design/plone/contenttypes/behaviors/trasparenza.py:185 +#: design/plone/contenttypes/behaviors/trasparenza.py:186 msgid "altre_modalita_invio_label" msgstr "" #. Default: "Seleziona la lista dei documenti di supporto collegati a questo servizio." -#: design/plone/contenttypes/interfaces/servizio.py:246 +#: design/plone/contenttypes/interfaces/servizio.py:335 msgid "altri_documenti_help" msgstr "" #. Default: "Date and time of the opening of the announcement. Use this field if you want to set a specific opening date. If not set, the announcement will be open immediately." -#: design/plone/contenttypes/interfaces/bando.py:56 +#: design/plone/contenttypes/interfaces/bando.py:57 msgid "apertura_bando_help" msgstr "" #. Default: "Opening date" -#: design/plone/contenttypes/interfaces/bando.py:55 +#: design/plone/contenttypes/interfaces/bando.py:56 msgid "apertura_bando_label" msgstr "" #. Default: "Area" -#: design/plone/contenttypes/interfaces/servizio.py:231 +#: design/plone/contenttypes/interfaces/servizio.py:320 msgid "area" msgstr "" #. Default: "Seleziona l'area da cui dipende questo servizio." -#: design/plone/contenttypes/interfaces/servizio.py:234 +#: design/plone/contenttypes/interfaces/servizio.py:323 msgid "area_help" msgstr "" @@ -971,14 +972,14 @@ msgid "area_responsabile_documento_personale" msgstr "" #. Default: "Seleziona l'area amministrativa responsabile del documento." -#: design/plone/contenttypes/interfaces/bando.py:127 -#: design/plone/contenttypes/interfaces/documento.py:60 +#: design/plone/contenttypes/interfaces/bando.py:128 +#: design/plone/contenttypes/interfaces/documento.py:90 msgid "area_responsabile_help" msgstr "" #. Default: "Area responsabile del documento" -#: design/plone/contenttypes/interfaces/bando.py:123 -#: design/plone/contenttypes/interfaces/documento.py:56 +#: design/plone/contenttypes/interfaces/bando.py:124 +#: design/plone/contenttypes/interfaces/documento.py:86 msgid "area_responsabile_label" msgstr "" @@ -988,47 +989,42 @@ msgid "argomenti_utenti" msgstr "" #. Default: "Inserire l'assessore di riferimento della struttura, se esiste." -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:76 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:68 msgid "assessore_riferimento_help" msgstr "" +#. Default: "Assessore di riferimento" +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:61 +msgid "assessore_riferimento_title" +msgstr "" + #. Default: "Indicare, se la esistono, atti e documenti a corredo dell'istanza." -#: design/plone/contenttypes/behaviors/trasparenza.py:200 +#: design/plone/contenttypes/behaviors/trasparenza.py:201 msgid "atti_documenti_corredo_help" msgstr "" #. Default: "Atti e documenti a corredo dell'istanza" -#: design/plone/contenttypes/behaviors/trasparenza.py:196 +#: design/plone/contenttypes/behaviors/trasparenza.py:197 msgid "atti_documenti_corredo_label" msgstr "" -#. Default: "Inserire un file contenente l'atto di nomina della persona." -#: design/plone/contenttypes/interfaces/persona.py:160 -msgid "atto_nomina_help" +#. Default: "Inserire riferimento all'atto di nomina della persona" +#: design/plone/contenttypes/interfaces/incarico.py:114 +msgid "atto_nomina_incarico_help" msgstr "" #. Default: "Atto di nomina" -#: design/plone/contenttypes/interfaces/persona.py:158 -msgid "atto_nomina_label" -msgstr "" - -#. Default: "Autenticazione" -#: design/plone/contenttypes/interfaces/servizio.py:121 -msgid "autenticazione" -msgstr "" - -#. Default: "Indicare, se previste, le modalità di autenticazione necessarie per poter accedere al servizio." -#: design/plone/contenttypes/interfaces/servizio.py:122 -msgid "autenticazione_help" +#: design/plone/contenttypes/interfaces/incarico.py:110 +msgid "atto_nomina_incarico_label" msgstr "" #. Default: "Seleziona una lista di autori che hanno pubblicato il documento. Possono essere Persone o Unità Organizzative." -#: design/plone/contenttypes/interfaces/documento.py:76 +#: design/plone/contenttypes/interfaces/documento.py:106 msgid "autori_help" msgstr "" #. Default: "Autore/i" -#: design/plone/contenttypes/interfaces/documento.py:72 +#: design/plone/contenttypes/interfaces/documento.py:102 msgid "autori_label" msgstr "" @@ -1048,52 +1044,72 @@ msgid "azioni_utente" msgstr "" #. Default: "Solo per persona politica: testo descrittivo che riporta la biografia della persona." -#: design/plone/contenttypes/interfaces/persona.py:107 +#: design/plone/contenttypes/interfaces/persona.py:94 msgid "biografia_help" msgstr "" #. Default: "Biografia" -#: design/plone/contenttypes/interfaces/persona.py:106 +#: design/plone/contenttypes/interfaces/persona.py:93 msgid "biografia_label" msgstr "" #. Default: "Canale digitale" -#: design/plone/contenttypes/interfaces/servizio.py:111 +#: design/plone/contenttypes/interfaces/servizio.py:156 msgid "canale_digitale" msgstr "" -#. Default: "Collegamento con l'eventuale canale digitale di attivazione del servizio." -#: design/plone/contenttypes/interfaces/servizio.py:112 +#. Default: "Testo di introduzione del canale digitale" +#: design/plone/contenttypes/interfaces/servizio.py:157 msgid "canale_digitale_help" msgstr "" +#. Default: "Link al canale digitale" +#: design/plone/contenttypes/interfaces/servizio.py:165 +msgid "canale_digitale_link" +msgstr "" + +#. Default: "Collegamento con l'eventuale canale digitale di attivazione del servizio." +#: design/plone/contenttypes/interfaces/servizio.py:166 +msgid "canale_digitale_link_help" +msgstr "" + #. Default: "Canale digitale servizio collegato" #: design/plone/contenttypes/interfaces/documento_personale.py:108 msgid "canale_digitale_servizio" msgstr "" +#. Default: "Canale fisico" +#: design/plone/contenttypes/interfaces/servizio.py:175 +msgid "canale_fisico" +msgstr "" + +#. Default: "Unità organizzative per la fruizione del servizio" +#: design/plone/contenttypes/interfaces/servizio.py:176 +msgid "canale_fisico_help" +msgstr "" + #. Default: "Casi particolari" -#: design/plone/contenttypes/interfaces/servizio.py:205 +#: design/plone/contenttypes/interfaces/servizio.py:291 msgid "casi_particolari" msgstr "" #. Default: "Descrizione degli evetuali casi particolari riferiti alla fruibilità di questo servizio." -#: design/plone/contenttypes/interfaces/servizio.py:207 +#: design/plone/contenttypes/interfaces/servizio.py:293 msgid "casi_particolari_help" msgstr "" #. Default: "Casi particolari" -#: design/plone/contenttypes/interfaces/servizio.py:401 +#: design/plone/contenttypes/interfaces/servizio.py:514 msgid "casi_particolari_label" msgstr "" #. Default: "Descrizione di chi può presentare domanda per usufruire del servizio e delle diverse casistiche." -#: design/plone/contenttypes/interfaces/servizio.py:62 +#: design/plone/contenttypes/interfaces/servizio.py:107 msgid "chi_puo_presentare_help" msgstr "" #. Default: "Chi può presentare" -#: design/plone/contenttypes/interfaces/servizio.py:60 +#: design/plone/contenttypes/interfaces/servizio.py:105 msgid "chi_puo_presentare_label" msgstr "" @@ -1103,37 +1119,57 @@ msgid "circoscrizione" msgstr "" #. Default: "Codice dell'ente erogatore (ipa)" -#: design/plone/contenttypes/interfaces/servizio.py:268 +#: design/plone/contenttypes/interfaces/servizio.py:357 msgid "codice_ipa" msgstr "" #. Default: "Specificare il nome dell’organizzazione, come indicato nell’Indice della Pubblica Amministrazione (IPA), che esercita uno specifico ruolo sul Servizio." -#: design/plone/contenttypes/interfaces/servizio.py:270 +#: design/plone/contenttypes/interfaces/servizio.py:359 msgid "codice_ipa_help" msgstr "" -#. Default: "Come si fa" -#: design/plone/contenttypes/interfaces/servizio.py:80 +#. Default: "Come fare" +#: design/plone/contenttypes/interfaces/servizio.py:125 msgid "come_si_fa" msgstr "" #. Default: "Descrizione della procedura da seguire per poter usufruire del servizio." -#: design/plone/contenttypes/interfaces/servizio.py:82 +#: design/plone/contenttypes/interfaces/servizio.py:127 msgid "come_si_fa_help" msgstr "" +#. Default: "Solo per incarico politico: compensi di qualsiasi natura connessi all'assunzione della carica." +#: design/plone/contenttypes/interfaces/incarico.py:21 +msgid "compensi_incarico_help" +msgstr "" + +#. Default: "Compensi" +#: design/plone/contenttypes/interfaces/incarico.py:17 +msgid "compensi_incarico_label" +msgstr "" + #. Default: "Descrizione del ruolo e dei compiti della persona." -#: design/plone/contenttypes/interfaces/persona.py:69 +#: design/plone/contenttypes/interfaces/persona.py:77 msgid "competenze_help" msgstr "" #. Default: "Competenze" -#: design/plone/contenttypes/interfaces/persona.py:68 +#: design/plone/contenttypes/interfaces/persona.py:76 msgid "competenze_label" msgstr "" -#. Default: "Informazioni di contatto generiche" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:137 +#. Default: "Condizioni di servizio" +#: design/plone/contenttypes/interfaces/servizio.py:388 +msgid "condizioni_di_servizio" +msgstr "" + +#. Default: "Contatti dell'unità organizzativa." +#: design/plone/contenttypes/behaviors/contatti.py:27 +msgid "contact_info_help" +msgstr "" + +#. Default: "Punti di contatto dell'unità organizzativa" +#: design/plone/contenttypes/behaviors/contatti.py:23 msgid "contact_info_label" msgstr "" @@ -1143,9 +1179,9 @@ msgid "contatti" msgstr "" #. Default: "Contatti" -#: design/plone/contenttypes/behaviors/address.py:52 -#: design/plone/contenttypes/behaviors/contatti.py:76 -#: design/plone/contenttypes/behaviors/evento.py:215 +#: design/plone/contenttypes/behaviors/contatti.py:57 +#: design/plone/contenttypes/behaviors/evento.py:170 +#: design/plone/contenttypes/behaviors/geolocation.py:18 msgid "contatti_label" msgstr "" @@ -1155,116 +1191,111 @@ msgid "contenuto" msgstr "" #. Default: "Indicare se il servizio si riferisce ad una particolare area geografica o all'intero territorio di riferimento." -#: design/plone/contenttypes/interfaces/servizio.py:72 +#: design/plone/contenttypes/interfaces/servizio.py:117 msgid "copertura_geografica_help" msgstr "" #. Default: "Copertura geografica" -#: design/plone/contenttypes/interfaces/servizio.py:70 +#: design/plone/contenttypes/interfaces/servizio.py:115 msgid "copertura_geografica_label" msgstr "" #. Default: "Contenuti collegati" -#: design/plone/contenttypes/behaviors/argomenti.py:74 +#: design/plone/contenttypes/behaviors/argomenti.py:108 #: design/plone/contenttypes/behaviors/dataset_correlati.py:40 -#: design/plone/contenttypes/behaviors/servizi_correlati.py:43 +#: design/plone/contenttypes/behaviors/news_additional_fields.py:120 msgid "correlati_label" msgstr "" #. Default: "Seleziona un correlato da mettere in evidenza per questo contenuto." -#: design/plone/contenttypes/behaviors/argomenti.py:36 +#: design/plone/contenttypes/behaviors/argomenti.py:40 msgid "correlato_in_evidenza_help" msgstr "" #. Default: "Correlato in evidenza" -#: design/plone/contenttypes/behaviors/argomenti.py:35 +#: design/plone/contenttypes/behaviors/argomenti.py:39 msgid "correlato_in_evidenza_label" msgstr "" -#. Default: "Cosa fa" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:206 +#. Default: "Competenze" +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:201 msgid "cosa_fa_label" msgstr "" #. Default: "Cosa serve" -#: design/plone/contenttypes/interfaces/servizio.py:177 +#: design/plone/contenttypes/interfaces/servizio.py:263 msgid "cosa_serve" msgstr "" #. Default: "Descrizione delle istruzioni per usufruire del servizio." -#: design/plone/contenttypes/interfaces/servizio.py:179 +#: design/plone/contenttypes/interfaces/servizio.py:265 msgid "cosa_serve_help" msgstr "" #. Default: "Cosa serve" -#: design/plone/contenttypes/interfaces/servizio.py:384 +#: design/plone/contenttypes/interfaces/servizio.py:497 msgid "cosa_serve_label" msgstr "" #. Default: "Cosa si ottiene" -#: design/plone/contenttypes/interfaces/servizio.py:90 +#: design/plone/contenttypes/interfaces/servizio.py:135 msgid "cosa_si_ottiene" msgstr "" #. Default: "Indicare cosa si può ottenere dal servizio, ad esempio 'carta di identità elettronica', 'certificato di residenza'." -#: design/plone/contenttypes/interfaces/servizio.py:91 +#: design/plone/contenttypes/interfaces/servizio.py:136 msgid "cosa_si_ottiene_help" msgstr "" #. Default: "Cos'è" -#: design/plone/contenttypes/behaviors/descrizione_estesa.py:40 -#: design/plone/contenttypes/behaviors/evento.py:200 +#: design/plone/contenttypes/behaviors/descrizione_estesa.py:52 +#: design/plone/contenttypes/behaviors/evento.py:155 msgid "cose_label" msgstr "" #. Default: "Costi" -#: design/plone/contenttypes/interfaces/servizio.py:186 +#: design/plone/contenttypes/interfaces/servizio.py:272 msgid "costi" msgstr "" #. Default: "Costi e vincoli" -#: design/plone/contenttypes/interfaces/servizio.py:389 +#: design/plone/contenttypes/interfaces/servizio.py:502 msgid "costi_e_vincoli_label" msgstr "" #. Default: "Descrizione delle condizioni e dei termini economici per completare la procedura di richiesta del servizio." -#: design/plone/contenttypes/interfaces/servizio.py:188 +#: design/plone/contenttypes/interfaces/servizio.py:274 msgid "costi_help" msgstr "" #. Default: "Costi" -#: design/plone/contenttypes/behaviors/evento.py:212 +#: design/plone/contenttypes/behaviors/evento.py:167 msgid "costi_label" msgstr "" #. Default: "Allega un file contenente il curriculum vitae della persona. Se ha più file da allegare, utilizza questo campo per quello principale e gli altri mettili dentro alla cartella \"Curriculum vitae\" che troverai dentro alla Persona." -#: design/plone/contenttypes/interfaces/persona.py:149 +#: design/plone/contenttypes/interfaces/persona.py:105 msgid "curriculum_vitae_help" msgstr "" #. Default: "Curriculum vitae" -#: design/plone/contenttypes/interfaces/persona.py:147 +#: design/plone/contenttypes/interfaces/persona.py:103 msgid "curriculum_vitae_label" msgstr "" #. Default: "Risultati indagini di customer satisfaction." -#: design/plone/contenttypes/behaviors/trasparenza.py:254 +#: design/plone/contenttypes/behaviors/trasparenza.py:255 msgid "customer_satisfaction_help" msgstr "" #. Default: "Risultati indagini di customer satisfaction" -#: design/plone/contenttypes/behaviors/trasparenza.py:249 +#: design/plone/contenttypes/behaviors/trasparenza.py:250 msgid "customer_satisfaction_label" msgstr "" -#. Default: "Data di conclusione dell'incarico." -#: design/plone/contenttypes/interfaces/persona.py:60 -msgid "data_conclusione_incarico_help" -msgstr "" - #. Default: "Data conclusione incarico" -#: design/plone/contenttypes/interfaces/persona.py:56 -msgid "data_conclusione_incarico_label" +#: design/plone/contenttypes/interfaces/incarico.py:100 +msgid "data_conclusione_incarico" msgstr "" #. Default: "Data e fasi intermedie" @@ -1277,14 +1308,14 @@ msgstr "" msgid "data_inizio" msgstr "" -#. Default: "Solo per persona politica: specificare la data di insediamento." -#: design/plone/contenttypes/interfaces/persona.py:97 -msgid "data_insediamento_help" +#. Default: "Data inizio incarico" +#: design/plone/contenttypes/interfaces/incarico.py:95 +msgid "data_inizio_incarico" msgstr "" #. Default: "Data insediamento" -#: design/plone/contenttypes/interfaces/persona.py:96 -msgid "data_insediamento_label" +#: design/plone/contenttypes/interfaces/incarico.py:105 +msgid "data_insediamento" msgstr "" #. Default: "Data del messaggio" @@ -1298,296 +1329,272 @@ msgid "data_pagamento" msgstr "" #. Default: "Data del protocollo" +#: design/plone/contenttypes/interfaces/documento.py:41 #: design/plone/contenttypes/interfaces/documento_personale.py:19 msgid "data_protocollo" msgstr "" +#. Default: "Data scadenza" +#: design/plone/contenttypes/interfaces/servizio.py:49 +msgid "data_scadenza_label" +msgstr "" + #. Default: "Data di scadenza della procedura" #: design/plone/contenttypes/interfaces/messaggio.py:40 msgid "data_scadenza_procedura" msgstr "" #. Default: "Dataset" -#: design/plone/contenttypes/interfaces/dataset.py:27 +#: design/plone/contenttypes/interfaces/dataset.py:20 msgid "dataset" msgstr "" +#. Default: "Schede dataset collegate al documento" +#: design/plone/contenttypes/interfaces/documento.py:150 +msgid "dataset_collegati_help" +msgstr "" + #. Default: "Seleziona una lista di schede dataset collegate a questo contenuto." -#: design/plone/contenttypes/behaviors/dataset_correlati.py:19 +#: design/plone/contenttypes/behaviors/dataset_correlati.py:20 msgid "dataset_correlati_help" msgstr "" #. Default: "Dataset correlati" -#: design/plone/contenttypes/behaviors/dataset_correlati.py:18 +#: design/plone/contenttypes/behaviors/dataset_correlati.py:19 msgid "dataset_correlati_label" msgstr "" +#. Default: "Dataset collegati" +#: design/plone/contenttypes/interfaces/documento.py:146 +msgid "dataset_label" +msgstr "" + +#. Default: "Date e informazioni" +#: design/plone/contenttypes/interfaces/incarico.py:175 +msgid "date_e_informazioni_label" +msgstr "" + #. Default: "Date e orari" -#: design/plone/contenttypes/behaviors/evento.py:209 -#: design/plone/contenttypes/schema_overrides.py:34 +#: design/plone/contenttypes/behaviors/evento.py:164 +#: design/plone/contenttypes/schema_overrides.py:33 msgid "date_e_orari_label" msgstr "" #. Default: "Inserisci la decorrenza termine del procedimento." -#: design/plone/contenttypes/behaviors/trasparenza.py:69 +#: design/plone/contenttypes/behaviors/trasparenza.py:70 msgid "decorrenza_termini_help" msgstr "" #. Default: "Decorrenza termine del procedimento" -#: design/plone/contenttypes/behaviors/trasparenza.py:64 +#: design/plone/contenttypes/behaviors/trasparenza.py:65 msgid "decorrenza_termini_label" msgstr "" #. Default: "Elenco delle deleghe a capo della persona." -#: design/plone/contenttypes/interfaces/persona.py:77 +#: design/plone/contenttypes/interfaces/persona.py:85 msgid "deleghe_help" msgstr "" #. Default: "Deleghe" -#: design/plone/contenttypes/interfaces/persona.py:76 +#: design/plone/contenttypes/interfaces/persona.py:84 msgid "deleghe_label" msgstr "" #. Default: "Descrizione completa" -#: design/plone/contenttypes/behaviors/luogo.py:23 +#: design/plone/contenttypes/behaviors/luogo.py:24 msgid "descrizione_completa" msgstr "" -#. Default: "Descrizione destinatari" -#: design/plone/contenttypes/behaviors/evento.py:38 -msgid "descrizione_destinatari" -msgstr "" - -#. Default: "Descrizione dei principali interlocutori dell'evento." -#: design/plone/contenttypes/behaviors/evento.py:40 -msgid "descrizione_destinatari_help" -msgstr "" - #. Default: "Descrizione estesa" -#: design/plone/contenttypes/behaviors/descrizione_estesa.py:16 -#: design/plone/contenttypes/behaviors/evento.py:30 -#: design/plone/contenttypes/behaviors/news_additional_fields.py:19 +#: design/plone/contenttypes/behaviors/descrizione_estesa.py:17 +#: design/plone/contenttypes/behaviors/evento.py:32 +#: design/plone/contenttypes/behaviors/news_additional_fields.py:21 msgid "descrizione_estesa" msgstr "" #. Default: "Descrizione dettagliata e completa." -#: design/plone/contenttypes/behaviors/descrizione_estesa.py:18 -#: design/plone/contenttypes/behaviors/evento.py:32 -#: design/plone/contenttypes/behaviors/news_additional_fields.py:21 +#: design/plone/contenttypes/behaviors/descrizione_estesa.py:19 +#: design/plone/contenttypes/behaviors/evento.py:34 +#: design/plone/contenttypes/behaviors/news_additional_fields.py:23 msgid "descrizione_estesa_help" msgstr "" #. Default: "Descrizione" -#: design/plone/contenttypes/behaviors/descrizione_estesa.py:51 -#: design/plone/contenttypes/behaviors/luogo.py:166 -#: design/plone/contenttypes/interfaces/documento.py:162 +#: design/plone/contenttypes/behaviors/descrizione_estesa.py:72 +#: design/plone/contenttypes/behaviors/luogo.py:135 +#: design/plone/contenttypes/interfaces/documento.py:242 msgid "descrizione_label" msgstr "" #. Default: "Inserisci eventuale testo descrittivo del procedimento." -#: design/plone/contenttypes/behaviors/trasparenza.py:37 +#: design/plone/contenttypes/behaviors/trasparenza.py:38 msgid "descrizione_procedimento_help" msgstr "" #. Default: "Descrizione del procedimento" -#: design/plone/contenttypes/behaviors/trasparenza.py:32 +#: design/plone/contenttypes/behaviors/trasparenza.py:33 msgid "descrizione_procedimento_label" msgstr "" #. Default: "Dirigente" -#: design/plone/contenttypes/behaviors/trasparenza.py:136 +#: design/plone/contenttypes/behaviors/trasparenza.py:137 msgid "dirigente" msgstr "" #. Default: "Indicare il dirigente." -#: design/plone/contenttypes/behaviors/trasparenza.py:140 +#: design/plone/contenttypes/behaviors/trasparenza.py:141 msgid "dirigente_help" msgstr "" #. Default: "Distribuzione" -#: design/plone/contenttypes/interfaces/dataset.py:22 +#: design/plone/contenttypes/interfaces/dataset.py:15 msgid "distribuzione" msgstr "" #. Default: "Documenti allegati" -#: design/plone/contenttypes/interfaces/messaggio.py:56 +#: design/plone/contenttypes/interfaces/messaggio.py:48 msgid "documenti_allegati" msgstr "" #. Default: "Seleziona una serie di altri contenuti di tipo Documento che vanno allegati a questo." -#: design/plone/contenttypes/interfaces/documento.py:113 +#: design/plone/contenttypes/interfaces/documento.py:194 msgid "documenti_allegati_help" msgstr "" #. Default: "Documenti allegati" -#: design/plone/contenttypes/interfaces/documento.py:109 +#: design/plone/contenttypes/interfaces/documento.py:190 msgid "documenti_allegati_label" msgstr "" #. Default: "Documenti" -#: design/plone/contenttypes/interfaces/persona.py:199 -#: design/plone/contenttypes/interfaces/servizio.py:412 +#: design/plone/contenttypes/interfaces/persona.py:146 +#: design/plone/contenttypes/interfaces/servizio.py:525 msgid "documenti_label" msgstr "" +#. Default: "Documenti pubblici importanti, collegati a questa Unità Organizzativa" +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:129 +msgid "documenti_pubblici_help" +msgstr "" + +#. Default: "Documenti pubblici" +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:127 +msgid "documenti_pubblici_label" +msgstr "" + #. Default: "Dove" -#: design/plone/contenttypes/behaviors/address.py:71 -#: design/plone/contenttypes/behaviors/geolocation.py:29 +#: design/plone/contenttypes/behaviors/address.py:53 +#: design/plone/contenttypes/behaviors/geolocation.py:26 msgid "dove_label" msgstr "" #. Default: "Dove rivolgersi: informazioni aggiuntive" -#: design/plone/contenttypes/interfaces/servizio.py:143 +#: design/plone/contenttypes/interfaces/servizio.py:212 msgid "dove_rivolgersi_extra" msgstr "" #. Default: "Indicare eventuali informazioni aggiuntive riguardo al dove rivolgersi per questo servizio." -#: design/plone/contenttypes/interfaces/servizio.py:147 +#: design/plone/contenttypes/interfaces/servizio.py:216 msgid "dove_rivolgersi_extra_help" msgstr "" #. Default: "Seleziona una lista delle sedi e dei luoghi in cui è presente questo servizio." -#: design/plone/contenttypes/interfaces/servizio.py:135 +#: design/plone/contenttypes/interfaces/servizio.py:204 msgid "dove_rivolgersi_help" msgstr "" #. Default: "Elementi di interesse" -#: design/plone/contenttypes/behaviors/luogo.py:44 +#: design/plone/contenttypes/behaviors/luogo.py:45 msgid "elementi_di_interesse" msgstr "" -#. Default: "Indicare un indirizzo mail per poter contattare gli organizzatori." -#: design/plone/contenttypes/behaviors/evento.py:128 -msgid "email_event_help" -msgstr "" - -#. Default: "E-mail" -#: design/plone/contenttypes/behaviors/evento.py:127 -msgid "email_event_label" -msgstr "" - -#. Default: "Indicare un indirizzo mail per poter contattare i referenti." -#: design/plone/contenttypes/behaviors/contatti.py:35 -msgid "email_help" -msgstr "" - -#. Default: "E-mail" -#: design/plone/contenttypes/behaviors/contatti.py:34 -msgid "email_label" -msgstr "" - -#. Default: "Contatto mail della persona. E' possibile inserire più di un indirizzo. Premendo \"Invio\" o \"tab\" si può passare al successivo da inserire." -#: design/plone/contenttypes/interfaces/persona.py:135 -msgid "email_persona_help" -msgstr "" - -#. Default: "Indirizzo email" -#: design/plone/contenttypes/interfaces/persona.py:134 -msgid "email_persona_label" -msgstr "" - #. Default: "Esito" #: design/plone/contenttypes/interfaces/ricevuta_pagamento.py:51 msgid "esito" msgstr "" -#. Default: "Fax" -#: design/plone/contenttypes/behaviors/evento.py:113 -msgid "fax_event_help" -msgstr "" - -#. Default: "Indicare un numero di fax." -#: design/plone/contenttypes/behaviors/evento.py:114 -msgid "fax_event_label" -msgstr "" - -#. Default: "Indicare un numero di fax." -#: design/plone/contenttypes/behaviors/contatti.py:29 -msgid "fax_help" -msgstr "" - -#. Default: "Fax" -#: design/plone/contenttypes/behaviors/contatti.py:28 -msgid "fax_label" -msgstr "" - -#. Default: "Indicare un numero di fax." -#: design/plone/contenttypes/interfaces/persona.py:130 -msgid "fax_persona_help" -msgstr "" - -#. Default: "Fax" -#: design/plone/contenttypes/interfaces/persona.py:129 -msgid "fax_persona_label" +#. Default: "Escludi dalla ricerca" +#: design/plone/contenttypes/behaviors/exclude_from_search.py:17 +msgid "exclude_from_search_label" msgstr "" #. Default: "Inserisci il file correlato di questo pocedimento." -#: design/plone/contenttypes/behaviors/trasparenza.py:44 +#: design/plone/contenttypes/behaviors/trasparenza.py:45 msgid "file_correlato_help" msgstr "" #. Default: "File correlato" -#: design/plone/contenttypes/behaviors/trasparenza.py:43 +#: design/plone/contenttypes/behaviors/trasparenza.py:44 msgid "file_correlato_label" msgstr "" #. Default: "Inserisci il file principale di questo contenuto." -#: design/plone/contenttypes/behaviors/multi_file.py:16 +#: design/plone/contenttypes/behaviors/multi_file.py:17 msgid "file_principale_help" msgstr "" #. Default: "File principale" -#: design/plone/contenttypes/behaviors/multi_file.py:15 +#: design/plone/contenttypes/behaviors/multi_file.py:16 msgid "file_principale_label" msgstr "" #. Default: "Inserisci la fine termine del procedimento." -#: design/plone/contenttypes/behaviors/trasparenza.py:80 +#: design/plone/contenttypes/behaviors/trasparenza.py:81 msgid "fine_termine_help" msgstr "" #. Default: "Fine termine del procedimento" -#: design/plone/contenttypes/behaviors/trasparenza.py:75 +#: design/plone/contenttypes/behaviors/trasparenza.py:76 msgid "fine_termine_label" msgstr "" +#. Default: "Lista dei formati in cui è disponibile il documento" +#: design/plone/contenttypes/interfaces/documento.py:117 +msgid "formati_disponibili_help" +msgstr "" + +#. Default: "Formati disponibili" +#: design/plone/contenttypes/interfaces/documento.py:116 +msgid "formati_disponibili_label" +msgstr "" + #. Default: "Inserisci un eventuale formato alternativo del file principale." -#: design/plone/contenttypes/behaviors/multi_file.py:25 +#: design/plone/contenttypes/behaviors/multi_file.py:26 msgid "formato_alternativo_1_help" msgstr "" #. Default: "Formato alternativo 1" -#: design/plone/contenttypes/behaviors/multi_file.py:24 +#: design/plone/contenttypes/behaviors/multi_file.py:25 msgid "formato_alternativo_1_label" msgstr "" #. Default: "Inserisci un eventuale formato alternativo del file principale." -#: design/plone/contenttypes/behaviors/multi_file.py:35 +#: design/plone/contenttypes/behaviors/multi_file.py:36 msgid "formato_alternativo_2_help" msgstr "" #. Default: "Formato alternativo 2" -#: design/plone/contenttypes/behaviors/multi_file.py:34 +#: design/plone/contenttypes/behaviors/multi_file.py:35 msgid "formato_alternativo_2_label" msgstr "" -#. Default: "Foto da mostrare della persona. La dimensione suggerita è 180x100 px." -#: design/plone/contenttypes/interfaces/persona.py:21 +#. Default: "Foto da mostrare della persona. La dimensione suggerita è 100x180px." +#: design/plone/contenttypes/interfaces/persona.py:30 msgid "foto_persona_help" msgstr "" #. Default: "Foto della persona" -#: design/plone/contenttypes/interfaces/persona.py:19 +#: design/plone/contenttypes/interfaces/persona.py:28 msgid "foto_persona_label" msgstr "" #. Default: "Frequenza di aggiornamento" -#: design/plone/contenttypes/interfaces/dataset.py:32 +#: design/plone/contenttypes/interfaces/dataset.py:25 msgid "frequenza_aggiornamento" msgstr "" #. Default: "Invalid geolocation data: ${value}. Provide latitude and longitude coordinates." -#: design/plone/contenttypes/restapi/deserializers/dxfields.py:28 +#: design/plone/contenttypes/restapi/deserializers/dxfields.py:39 msgid "geolocation_field_validator_label" msgstr "" @@ -1596,22 +1603,27 @@ msgid "help_circoscrizione" msgstr "" #. Default: "Indicare una descrizione completa, inserendo tutte le informazioni rilevanti relative al luogo" -#: design/plone/contenttypes/behaviors/luogo.py:24 +#: design/plone/contenttypes/behaviors/luogo.py:25 msgid "help_descrizione_completa" msgstr "" #. Default: "Indicare eventuali elementi di interesse per il cittadino." -#: design/plone/contenttypes/behaviors/luogo.py:45 +#: design/plone/contenttypes/behaviors/luogo.py:46 msgid "help_elementi_di_interesse" msgstr "" +#. Default: "Se selezionato, questo contenuto non verrà mostrato nelle ricerche del sito per gli utenti anonimi." +#: design/plone/contenttypes/behaviors/exclude_from_search.py:18 +msgid "help_exclude_from_search" +msgstr "" + #. Default: "Indicare tutte le informazioni relative alla modalità di accesso al luogo" -#: design/plone/contenttypes/behaviors/luogo.py:54 +#: design/plone/contenttypes/behaviors/luogo.py:55 msgid "help_modalita_accesso" msgstr "" #. Default: "Indicare, se esiste, un nome alternativo per il luogo; questo sarà mostrato affianco al titolo della scheda" -#: design/plone/contenttypes/behaviors/luogo.py:34 +#: design/plone/contenttypes/behaviors/luogo.py:35 msgid "help_nome_alternativo" msgstr "" @@ -1624,28 +1636,8 @@ msgstr "" msgid "help_quartiere" msgstr "" -#. Default: "Indicare un numero di fax della struttura responsabile." -#: design/plone/contenttypes/behaviors/luogo.py:108 -msgid "help_riferimento_fax_struttura" -msgstr "" - -#. Default: "Indicare un indirizzo mail per poter contattare i referenti della struttura responsabile." -#: design/plone/contenttypes/behaviors/luogo.py:119 -msgid "help_riferimento_mail_struttura" -msgstr "" - -#. Default: "Indicare un indirizzo pec per poter contattare i referenti della struttura responsabile." -#: design/plone/contenttypes/behaviors/luogo.py:132 -msgid "help_riferimento_pec_struttura" -msgstr "" - -#. Default: "Indicare il riferimento telefonico per poter contattare i referenti della struttura responsabile." -#: design/plone/contenttypes/behaviors/luogo.py:96 -msgid "help_riferimento_telefonico_struttura" -msgstr "" - -#. Default: "Inserisci una nota per indicare che il contenuto corrente è stato aggiornato.Questo testo può essere visualizzato nei blocchi elenco con determinati layout per informare gli utenti che un determinato contenuto è stato aggiornato. Ad esempio se in un bando sono stati aggiunti dei documenti." -#: design/plone/contenttypes/behaviors/update_note.py:17 +#. Default: "Inserisci una nota per indicare che il contenuto corrente è stato aggiornato. Questo testo può essere visualizzato nei blocchi elenco con determinati layout per informare gli utenti che un determinato contenuto è stato aggiornato. Ad esempio se in un bando sono stati aggiunti dei documenti." +#: design/plone/contenttypes/behaviors/update_note.py:18 msgid "help_update_note" msgstr "" @@ -1660,7 +1652,7 @@ msgid "icona_help" msgstr "" #. Default: "Identificativo" -#: design/plone/contenttypes/interfaces/servizio.py:290 +#: design/plone/contenttypes/interfaces/servizio.py:379 msgid "identificativo" msgstr "" @@ -1675,12 +1667,22 @@ msgid "identificativo_documento_label" msgstr "" #. Default: "Eventuale codice identificativo del servizio." -#: design/plone/contenttypes/interfaces/servizio.py:292 +#: design/plone/contenttypes/interfaces/servizio.py:381 msgid "identificativo_help" msgstr "" +#. Default: "Identificativo" +#: design/plone/contenttypes/behaviors/luogo.py:119 +msgid "identificativo_mibac" +msgstr "" + +#. Default: "Codice identificativo del luogo. Nel MIBAC c'è il codice del DBUnico per i luoghi della cultura e il codice ISIL per le biblioteche. Non deve comparire nel frontend del sito." +#: design/plone/contenttypes/behaviors/luogo.py:121 +msgid "identificativo_mibac_help" +msgstr "" + #. Default: "La dimensione dell'immagine dovrebbe essere di ${size} px" -#: design/plone/contenttypes/restapi/types/adapters.py:31 +#: design/plone/contenttypes/restapi/types/adapters.py:43 msgid "image_size_help" msgstr "" @@ -1689,11 +1691,31 @@ msgstr "" msgid "immagine" msgstr "" +#. Default: "Solo per incarico politico: importi di viaggi di servizio e missioni pagati con fondi pubblici." +#: design/plone/contenttypes/interfaces/incarico.py:34 +msgid "importi_viaggio_servizio_incarico_help" +msgstr "" + +#. Default: "Importi di viaggio e/o servizio" +#: design/plone/contenttypes/interfaces/incarico.py:30 +msgid "importi_viaggio_servizio_incarico_label" +msgstr "" + #. Default: "Importo pagato" #: design/plone/contenttypes/interfaces/ricevuta_pagamento.py:25 msgid "importo_pagato" msgstr "" +#. Default: "Seleziona l'incarico corrente della persona." +#: design/plone/contenttypes/interfaces/persona.py:63 +msgid "incarichi_help" +msgstr "" + +#. Default: "Incarichi" +#: design/plone/contenttypes/interfaces/persona.py:59 +msgid "incarichi_label" +msgstr "" + #. Default: "Inserisci eventuale testo informativo che verrà mostrato in testata." #: design/plone/contenttypes/behaviors/info_testata.py:23 msgid "info_testata_help" @@ -1709,35 +1731,60 @@ msgstr "" msgid "informazioni" msgstr "" +#. Default: "Compensi e trasparenza" +#: design/plone/contenttypes/interfaces/incarico.py:170 +msgid "informazioni_compensi_label" +msgstr "" + #. Default: "Ulteriori informazioni" #: design/plone/contenttypes/behaviors/additional_help_infos.py:28 -#: design/plone/contenttypes/behaviors/evento.py:229 #: design/plone/contenttypes/behaviors/strutture_correlate.py:42 +#: design/plone/contenttypes/interfaces/documento.py:253 msgid "informazioni_label" msgstr "" +#. Default: "Intervallo della fase (es. 1)" +#: design/plone/contenttypes/interfaces/servizio.py:32 +msgid "interval_qt_help" +msgstr "" + +#. Default: "Intervallo" +#: design/plone/contenttypes/interfaces/servizio.py:31 +msgid "interval_qt_label" +msgstr "" + +#. Default: "Ad esempio: ore, giorni, settimane, mesi." +#: design/plone/contenttypes/interfaces/servizio.py:41 +msgid "interval_type_help" +msgstr "" + +#. Default: "Tipo intervallo" +#: design/plone/contenttypes/interfaces/servizio.py:40 +msgid "interval_type_label" +msgstr "" + #. Default: "Se un content-type deve avere una dimensione della leadimage particolare, indicarle qui. Inserire le dimensioni nella forma di esempio PortalType|900x900" -#: design/plone/contenttypes/controlpanels/settings.py:110 +#: design/plone/contenttypes/controlpanels/settings.py:52 msgid "lead_image_dimension_help" msgstr "" #. Default: "Dimensioni lead image" -#: design/plone/contenttypes/controlpanels/settings.py:106 +#: design/plone/contenttypes/controlpanels/settings.py:48 msgid "lead_image_dimension_label" msgstr "" -#. Default: "Servizi o uffici di riferimento" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:27 +#. Default: "Strutture o uffici di riferimento" +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:31 msgid "legami_altre_strutture_label" msgstr "" #. Default: "Selezionare la lista di strutture e/o uffici collegati a questa unità organizzativa." -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:31 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:35 msgid "legami_con_altre_strutture_help" msgstr "" #. Default: "Licenza" -#: design/plone/contenttypes/interfaces/dataset.py:25 +#: design/plone/contenttypes/interfaces/dataset.py:18 msgid "licenza" msgstr "" @@ -1747,27 +1794,27 @@ msgid "licenza_distribuzione" msgstr "" #. Default: "La licenza con il quale viene distribuito questo documento." -#: design/plone/contenttypes/interfaces/documento.py:88 +#: design/plone/contenttypes/interfaces/documento.py:125 msgid "licenza_distribuzione_help" msgstr "" #. Default: "Licenza di distribuzione" -#: design/plone/contenttypes/interfaces/documento.py:87 +#: design/plone/contenttypes/interfaces/documento.py:124 msgid "licenza_distribuzione_label" msgstr "" #. Default: "Link a siti esterni" -#: design/plone/contenttypes/interfaces/servizio.py:258 +#: design/plone/contenttypes/interfaces/servizio.py:347 msgid "link_siti_esterni" msgstr "" #. Default: "Eventuali collegamenti a pagine web, siti, servizi esterni all'ambito Comunale utili all'erogazione del servizio." -#: design/plone/contenttypes/interfaces/servizio.py:260 +#: design/plone/contenttypes/interfaces/servizio.py:349 msgid "link_siti_esterni_help" msgstr "" #. Default: "Link utili" -#: design/plone/contenttypes/interfaces/servizio.py:417 +#: design/plone/contenttypes/interfaces/servizio.py:530 msgid "link_utili_label" msgstr "" @@ -1777,36 +1824,46 @@ msgid "luoghi_correlati_event_help" msgstr "" #. Default: "Seleziona una lista di luoghi citati." -#: design/plone/contenttypes/behaviors/luoghi_correlati.py:18 -#: design/plone/contenttypes/behaviors/news_additional_fields.py:72 +#: design/plone/contenttypes/behaviors/luoghi_correlati.py:19 +#: design/plone/contenttypes/behaviors/news_additional_fields.py:64 msgid "luoghi_correlati_help" msgstr "" #. Default: "Luoghi correlati" -#: design/plone/contenttypes/behaviors/luoghi_correlati.py:17 -#: design/plone/contenttypes/behaviors/news_additional_fields.py:71 +#: design/plone/contenttypes/behaviors/luoghi_correlati.py:18 +#: design/plone/contenttypes/behaviors/news_additional_fields.py:63 msgid "luoghi_correlati_label" msgstr "" #. Default: "Luogo" -#: design/plone/contenttypes/behaviors/address.py:89 -#: design/plone/contenttypes/behaviors/geolocation.py:38 -#: design/plone/contenttypes/behaviors/luoghi_correlati.py:74 +#: design/plone/contenttypes/behaviors/address.py:71 +#: design/plone/contenttypes/behaviors/geolocation.py:34 +#: design/plone/contenttypes/behaviors/luoghi_correlati.py:76 msgid "luogo_label" msgstr "" +#. Default: "Sottotitolo" +#: design/plone/contenttypes/interfaces/servizio.py:26 +msgid "milestone_description_label" +msgstr "" + +#. Default: "Titolo" +#: design/plone/contenttypes/interfaces/servizio.py:21 +msgid "milestone_label" +msgstr "" + #. Default: "Modalita' di accesso" -#: design/plone/contenttypes/behaviors/luogo.py:53 +#: design/plone/contenttypes/behaviors/luogo.py:54 msgid "modalita_accesso" msgstr "" #. Default: "Indicare la modalità di avvio del procedimento." -#: design/plone/contenttypes/behaviors/trasparenza.py:25 +#: design/plone/contenttypes/behaviors/trasparenza.py:26 msgid "modalita_avvio_help" msgstr "" #. Default: "Modalita di avvio" -#: design/plone/contenttypes/behaviors/trasparenza.py:24 +#: design/plone/contenttypes/behaviors/trasparenza.py:25 msgid "modalita_avvio_label" msgstr "" @@ -1816,12 +1873,12 @@ msgid "modalita_pagamento" msgstr "" #. Default: "Indicare le modalità per richiedere informazioni riguardo a questo procedimento." -#: design/plone/contenttypes/behaviors/trasparenza.py:168 +#: design/plone/contenttypes/behaviors/trasparenza.py:169 msgid "modalita_richiesta_informazioni_help" msgstr "" #. Default: "Modalità per richiedere informazioni" -#: design/plone/contenttypes/behaviors/trasparenza.py:163 +#: design/plone/contenttypes/behaviors/trasparenza.py:164 msgid "modalita_richiesta_informazioni_label" msgstr "" @@ -1845,18 +1902,18 @@ msgstr "" msgid "mostra_navigazione_label" msgstr "" -#. Default: "Descrizione del motivo per cui il servizio non è attivo." -#: design/plone/contenttypes/interfaces/servizio.py:44 +#. Default: "Descrizione del motivo per cui il servizio non è attivo. È obbligatorio se il campo precedente è spuntato." +#: design/plone/contenttypes/interfaces/servizio.py:89 msgid "motivo_stato_servizio_help" msgstr "" -#. Default: "Motivo dello stato del servizio nel caso non sia attivo" -#: design/plone/contenttypes/interfaces/servizio.py:39 +#. Default: "Motivo dello stato" +#: design/plone/contenttypes/interfaces/servizio.py:84 msgid "motivo_stato_servizio_label" msgstr "" #. Default: "Nome alternativo" -#: design/plone/contenttypes/behaviors/luogo.py:33 +#: design/plone/contenttypes/behaviors/luogo.py:34 msgid "nome_alternativo" msgstr "" @@ -1866,17 +1923,17 @@ msgid "nome_sede" msgstr "" #. Default: "Seleziona una lista di notizie correlate a questa." -#: design/plone/contenttypes/behaviors/news_additional_fields.py:83 +#: design/plone/contenttypes/behaviors/news_additional_fields.py:75 msgid "notizie_correlate_help" msgstr "" #. Default: "Notizie correlate" -#: design/plone/contenttypes/behaviors/news_additional_fields.py:82 +#: design/plone/contenttypes/behaviors/news_additional_fields.py:74 msgid "notizie_correlate_label" msgstr "" #. Default: "Numero progressivo del comunicato stampa" -#: design/plone/contenttypes/behaviors/news_additional_fields.py:38 +#: design/plone/contenttypes/behaviors/news_additional_fields.py:30 msgid "numero_progressivo_cs_label" msgstr "" @@ -1892,117 +1949,155 @@ msgid "oggetto" msgstr "" #. Default: "Informazioni sugli orari" -#: design/plone/contenttypes/behaviors/evento.py:62 +#: design/plone/contenttypes/behaviors/evento.py:50 msgid "orari" msgstr "" #. Default: "Informazioni sugli orari di svolgimento dell'evento." -#: design/plone/contenttypes/behaviors/evento.py:64 +#: design/plone/contenttypes/behaviors/evento.py:52 msgid "orari_help" msgstr "" #. Default: "Orari di apertura" -#: design/plone/contenttypes/behaviors/contatti.py:86 +#: design/plone/contenttypes/behaviors/luogo.py:151 msgid "orari_label" msgstr "" +#. Default: "Orario per il pubblico" +#: design/plone/contenttypes/behaviors/luogo.py:93 +msgid "orario_pubblico" +msgstr "" + #. Default: "Indicare eventuali orari di accesso al pubblico" -#: design/plone/contenttypes/behaviors/contatti.py:59 +#: design/plone/contenttypes/behaviors/contatti.py:40 +#: design/plone/contenttypes/behaviors/luogo.py:95 msgid "orario_pubblico_help" msgstr "" #. Default: "Orario per il pubblico" -#: design/plone/contenttypes/behaviors/contatti.py:58 +#: design/plone/contenttypes/behaviors/contatti.py:39 msgid "orario_pubblico_label" msgstr "" #. Default: "Se l'evento non è organizzato direttamente dal comune oppure ha anche un organizzatore esterno, indicare il nome del contatto." -#: design/plone/contenttypes/behaviors/evento.py:97 +#: design/plone/contenttypes/behaviors/evento.py:86 msgid "organizzato_da_esterno_help" msgstr "" #. Default: "Organizzatore" -#: design/plone/contenttypes/behaviors/evento.py:95 +#: design/plone/contenttypes/behaviors/evento.py:84 msgid "organizzato_da_esterno_label" msgstr "" #. Default: "Se l'evento è organizzato direttamente dal comune, indicare l'ufficio/ente organizzatore. I dati di contatto verranno presi direttamente dall'ufficio selezionato. Se l'evento non è organizzato direttamente dal comune, o si vogliono sovrascrivere alcuni dati di contatto, utilizzare i seguenti campi." -#: design/plone/contenttypes/behaviors/evento.py:84 +#: design/plone/contenttypes/behaviors/evento.py:74 msgid "organizzato_da_interno_help" msgstr "" #. Default: "Organizzato da" -#: design/plone/contenttypes/behaviors/evento.py:80 +#: design/plone/contenttypes/behaviors/evento.py:70 msgid "organizzato_da_interno_label" msgstr "" #. Default: "Seleziona una lista di organizzazioni a cui la persona appartiene." -#: design/plone/contenttypes/interfaces/persona.py:42 +#: design/plone/contenttypes/interfaces/persona.py:45 msgid "organizzazione_riferimento_help" msgstr "" #. Default: "Organizzazione di riferimento" -#: design/plone/contenttypes/interfaces/persona.py:38 +#: design/plone/contenttypes/interfaces/persona.py:41 msgid "organizzazione_riferimento_label" msgstr "" #. Default: "Organo competente del provvedimento finale." -#: design/plone/contenttypes/behaviors/trasparenza.py:157 +#: design/plone/contenttypes/behaviors/trasparenza.py:158 msgid "organo_competente_provvedimento_finale_help" msgstr "" #. Default: "Organo competente del provvedimento finale" -#: design/plone/contenttypes/behaviors/trasparenza.py:152 +#: design/plone/contenttypes/behaviors/trasparenza.py:153 msgid "organo_competente_provvedimento_finale_label" msgstr "" #. Default: "Indicare le informazioni riguardanti i pagamenti previsti e modalità di pagamento." -#: design/plone/contenttypes/behaviors/trasparenza.py:222 +#: design/plone/contenttypes/behaviors/trasparenza.py:223 msgid "pagamenti_help" msgstr "" #. Default: "Pagamenti previsti e modalità" -#: design/plone/contenttypes/behaviors/trasparenza.py:218 +#: design/plone/contenttypes/behaviors/trasparenza.py:219 msgid "pagamenti_label" msgstr "" +#. Default: "Link a persone dell'amministrazione che interverranno all'evento" +#: design/plone/contenttypes/behaviors/evento.py:118 +msgid "parteciperanno_help" +msgstr "" + +#. Default: "Parteciperanno (Persone)" +#: design/plone/contenttypes/behaviors/evento.py:114 +msgid "parteciperanno_label" +msgstr "" + #. Default: "Indicare l'ente che supporta l'evento, se presente." -#: design/plone/contenttypes/behaviors/evento.py:160 +#: design/plone/contenttypes/behaviors/evento.py:107 msgid "patrocinato_da_help" msgstr "" #. Default: "Patrocinato da" -#: design/plone/contenttypes/behaviors/evento.py:158 +#: design/plone/contenttypes/behaviors/evento.py:105 msgid "patrocinato_da_label" msgstr "" -#. Default: "Indicare un indirizzo pec per poter contattare i referenti." -#: design/plone/contenttypes/behaviors/contatti.py:44 -msgid "pec_help" +#. Default: "Descrizione" +#: design/plone/contenttypes/interfaces/punto_di_contatto.py:27 +msgid "pdc_desc_help" +msgstr "" + +#. Default: "Descrizione" +#: design/plone/contenttypes/interfaces/punto_di_contatto.py:26 +msgid "pdc_desc_label" +msgstr "" + +#. Default: "Tipo" +#: design/plone/contenttypes/interfaces/punto_di_contatto.py:16 +msgid "pdc_type_label" msgstr "" -#. Default: "Pec" -#: design/plone/contenttypes/behaviors/contatti.py:43 -msgid "pec_label" +#. Default: "Contatto" +#: design/plone/contenttypes/interfaces/punto_di_contatto.py:37 +msgid "pdc_value_help" msgstr "" -#. Default: "Elenco delle persone dell'amministrazione che parteciperanno all'evento." -#: design/plone/contenttypes/behaviors/evento.py:53 -msgid "persone_amministrazione_help" +#. Default: "Contatto" +#: design/plone/contenttypes/interfaces/punto_di_contatto.py:36 +msgid "pdc_value_label" +msgstr "" + +#. Default: "Seleziona la persona che ha questo incarico" +#: design/plone/contenttypes/interfaces/incarico.py:47 +#: design/plone/contenttypes/interfaces/punto_di_contatto.py:66 +msgid "persona_incarico_help" +msgstr "" + +#. Default: "La persona che ha la carica e l'incarico" +#: design/plone/contenttypes/interfaces/incarico.py:43 +#: design/plone/contenttypes/interfaces/punto_di_contatto.py:62 +msgid "persona_incarico_label" msgstr "" #. Default: "Persone" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:221 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:215 msgid "persone_label" msgstr "" #. Default: "Seleziona la lista delle persone che compongono la struttura." -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:95 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:87 msgid "persone_struttura_help" msgstr "" #. Default: "Persone che compongono la struttura" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:87 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:79 msgid "persone_struttura_label" msgstr "" @@ -2018,42 +2113,42 @@ msgid "pratica_associata_ricevuta" msgstr "" #. Default: "Prenota un appuntamento" -#: design/plone/contenttypes/interfaces/servizio.py:156 +#: design/plone/contenttypes/interfaces/servizio.py:225 msgid "prenota_appuntamento" msgstr "" #. Default: "Se è possibile prenotare un'appuntamento, indicare le informazioni necessarie e il collegamento al servizio di prenotazione appuntamenti del Comune." -#: design/plone/contenttypes/interfaces/servizio.py:157 +#: design/plone/contenttypes/interfaces/servizio.py:226 msgid "prenota_appuntamento_help" msgstr "" -#. Default: "Prezzo" -#: design/plone/contenttypes/behaviors/evento.py:71 +#. Default: "Costo" +#: design/plone/contenttypes/behaviors/evento.py:59 msgid "prezzo" msgstr "" -#. Default: "Indicare il prezzo dell'evento, se presente, specificando se esistono formati diversi." -#: design/plone/contenttypes/behaviors/evento.py:73 +#. Default: "Eventuale costo dell'evento (se ci sono uno o più biglietti), con link all'acquisto se disponibile" +#: design/plone/contenttypes/behaviors/evento.py:61 msgid "prezzo_help" msgstr "" #. Default: "Indicare, se la procedura è informatizzata online, il riferimento." -#: design/plone/contenttypes/behaviors/trasparenza.py:178 +#: design/plone/contenttypes/behaviors/trasparenza.py:179 msgid "procedura_online_help" msgstr "" #. Default: "Procedura informatizzata online" -#: design/plone/contenttypes/behaviors/trasparenza.py:174 +#: design/plone/contenttypes/behaviors/trasparenza.py:175 msgid "procedura_online_label" msgstr "" #. Default: "Procedure collegate all'esito" -#: design/plone/contenttypes/interfaces/servizio.py:100 +#: design/plone/contenttypes/interfaces/servizio.py:145 msgid "procedure_collegate" msgstr "" #. Default: "Indicare cosa deve fare l'utente del servizio per conoscere l'esito della procedura, e dove eventualmente poter ritirare l'esito." -#: design/plone/contenttypes/interfaces/servizio.py:102 +#: design/plone/contenttypes/interfaces/servizio.py:147 msgid "procedure_collegate_help" msgstr "" @@ -2062,13 +2157,23 @@ msgstr "" msgid "protocollo" msgstr "" +#. Default: "Il numero di protocollo del documento." +#: design/plone/contenttypes/interfaces/documento.py:33 +msgid "protocollo_documento_help" +msgstr "" + +#. Default: "Numero di protocollo" +#: design/plone/contenttypes/interfaces/documento.py:29 +msgid "protocollo_documento_label" +msgstr "" + #. Default: "Eventuale provvedimento finale del procedimento." -#: design/plone/contenttypes/behaviors/trasparenza.py:114 +#: design/plone/contenttypes/behaviors/trasparenza.py:115 msgid "provvedimento_finale_help" msgstr "" #. Default: "Provvedimento del procedimento" -#: design/plone/contenttypes/behaviors/trasparenza.py:109 +#: design/plone/contenttypes/behaviors/trasparenza.py:110 msgid "provvedimento_finale_label" msgstr "" @@ -2077,46 +2182,46 @@ msgstr "" msgid "quartiere" msgstr "" -#. Default: "Reperibilità organizzatore" -#: design/plone/contenttypes/behaviors/evento.py:118 -msgid "reperibilita" -msgstr "" - -#. Default: "Indicare gli orari in cui l'organizzatore è telefonicamente reperibile." -#: design/plone/contenttypes/behaviors/evento.py:120 -msgid "reperibilita_help" -msgstr "" - #. Default: "Indicare dove è possibile reperre la modulistica per il procedimento." -#: design/plone/contenttypes/behaviors/trasparenza.py:211 +#: design/plone/contenttypes/behaviors/trasparenza.py:212 msgid "reperimento_modulistica_help" msgstr "" #. Default: "Dove reperire la modulistica" -#: design/plone/contenttypes/behaviors/trasparenza.py:207 +#: design/plone/contenttypes/behaviors/trasparenza.py:208 msgid "reperimento_modulistica_label" msgstr "" #. Default: "Selezionare il/i responsabile/i della struttura." -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:48 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:52 msgid "responsabile_help" msgstr "" #. Default: "Responsabile" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:43 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:47 msgid "responsabile_label" msgstr "" #. Default: "Responsabile del procedimento" -#: design/plone/contenttypes/behaviors/trasparenza.py:120 +#: design/plone/contenttypes/behaviors/trasparenza.py:121 msgid "responsabile_procedimento" msgstr "" #. Default: "Indicare il responsabile del procedimento." -#: design/plone/contenttypes/behaviors/trasparenza.py:124 +#: design/plone/contenttypes/behaviors/trasparenza.py:125 msgid "responsabile_procedimento_help" msgstr "" +#. Default: "Se è un incarico di responsabilità, specificare l'organizzazione della quale è responsabile in base all'incarico" +#: design/plone/contenttypes/interfaces/incarico.py:81 +msgid "responsabile_struttura_incarico_help" +msgstr "" + +#. Default: "Responsabile della struttura" +#: design/plone/contenttypes/interfaces/incarico.py:77 +msgid "responsabile_struttura_incarico_label" +msgstr "" + #. Default: "Seleziona se mostrare o meno il campo di ricerca in testata." #: design/plone/contenttypes/behaviors/info_testata.py:32 msgid "ricerca_in_testata_help" @@ -2128,12 +2233,12 @@ msgid "ricerca_in_testata_label" msgstr "" #. Default: "Ulteriori informazioni non previste negli altri campi; si può trattare di contatti o note informative la cui conoscenza è indispensabile per la partecipazione al bando" -#: design/plone/contenttypes/interfaces/bando.py:96 +#: design/plone/contenttypes/interfaces/bando.py:97 msgid "riferimenti_bando_agid_help" msgstr "" #. Default: "Ulteriori informazioni" -#: design/plone/contenttypes/interfaces/bando.py:95 +#: design/plone/contenttypes/interfaces/bando.py:96 msgid "riferimenti_bando_agid_label" msgstr "" @@ -2143,122 +2248,87 @@ msgid "riferimenti_normativi" msgstr "" #. Default: "Inserisici del testo di dettaglio per eventuali riferimenti normativi utili a questo documento." -#: design/plone/contenttypes/interfaces/documento.py:100 +#: design/plone/contenttypes/interfaces/documento.py:137 msgid "riferimenti_normativi_documento_help" msgstr "" #. Default: "Riferimenti normativi" -#: design/plone/contenttypes/interfaces/documento.py:96 +#: design/plone/contenttypes/interfaces/documento.py:133 msgid "riferimenti_normativi_documento_label" msgstr "" #. Default: "Indicare eventuali riferimenti normativi." -#: design/plone/contenttypes/behaviors/trasparenza.py:265 +#: design/plone/contenttypes/behaviors/trasparenza.py:266 msgid "riferimenti_normativi_help" msgstr "" #. Default: "Riferimenti normativi" -#: design/plone/contenttypes/behaviors/trasparenza.py:260 +#: design/plone/contenttypes/behaviors/trasparenza.py:261 msgid "riferimenti_normativi_label" msgstr "" -#. Default: "Fax della struttura responsabile" -#: design/plone/contenttypes/behaviors/luogo.py:104 -msgid "riferimento_fax_struttura" -msgstr "" - -#. Default: "E-mail struttura responsabile" -#: design/plone/contenttypes/behaviors/luogo.py:115 -msgid "riferimento_mail_struttura" -msgstr "" - -#. Default: "Pec della struttura responsabile" -#: design/plone/contenttypes/behaviors/luogo.py:128 -msgid "riferimento_pec_struttura" -msgstr "" - -#. Default: "Telefono della struttura responsabile" -#: design/plone/contenttypes/behaviors/luogo.py:92 -msgid "riferimento_telefonico_struttura" -msgstr "" - -#. Default: "Inserisci i valori utilizzabili per il ruolo di una Persona. Se il sito è multilingua, puoi inserire valori diversi a seconda delle lingue del sito." -#: design/plone/contenttypes/controlpanels/settings.py:84 -msgid "ruoli_persona_help" -msgstr "" - -#. Default: "Ruoli Persona" -#: design/plone/contenttypes/controlpanels/settings.py:83 -msgid "ruoli_persona_label" -msgstr "" - -#. Default: "Seleziona il ruolo della persona tra quelli disponibili." -#: design/plone/contenttypes/interfaces/persona.py:29 -msgid "ruolo_help" -msgstr "" - #. Default: "Ruolo" -#: design/plone/contenttypes/interfaces/persona.py:28 +#: design/plone/contenttypes/interfaces/persona.py:135 msgid "ruolo_label" msgstr "" #. Default: "Data entro la quale sarà possibile far pervenire domande e richieste di chiarimento a chi eroga il bando" -#: design/plone/contenttypes/interfaces/bando.py:69 +#: design/plone/contenttypes/interfaces/bando.py:70 msgid "scadenza_domande_bando_help" msgstr "" #. Default: "Termine per le richieste di chiarimenti" -#: design/plone/contenttypes/interfaces/bando.py:65 +#: design/plone/contenttypes/interfaces/bando.py:66 msgid "scadenza_domande_bando_label" msgstr "" #. Default: "Inserire una lista di sezioni per la ricerca." -#: design/plone/contenttypes/controlpanels/settings.py:129 +#: design/plone/contenttypes/controlpanels/settings.py:71 msgid "search_sections_help" msgstr "" #. Default: "Sezioni ricerca" -#: design/plone/contenttypes/controlpanels/settings.py:128 +#: design/plone/contenttypes/controlpanels/settings.py:70 msgid "search_sections_label" msgstr "" -#. Default: "Seleziona il Luogo in cui questa struttura ha sede. Se non è presente un contenuto di tipo Luogo a cui far riferimento, puoi compilare i campi seguenti. Se selezioni un Luogo, puoi usare comunque i campi seguenti per sovrascrivere alcune informazioni." -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:105 +#. Default: "Seleziona il Luogo in cui questa struttura ha sede. Se non è presente creare il Luogo nella sezione dedicata nell'alberatura del sito." +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:97 msgid "sede_help" msgstr "" #. Default: "Sede principale" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:103 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:95 msgid "sede_label" msgstr "" #. Default: "Seleziona una lista di eventuali contenuti di tipo Luogo che sono sedi secondarie di questa struttura. Per queste sedi non sarà possibile sovrascrivere i dati. Nel caso servano informazioni diverse, è possibile usare il campo sottostante." -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:122 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:112 msgid "sedi_secondarie_help" msgstr "" -#. Default: "Sedi secondarie" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:120 +#. Default: "Altre sedi" +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:110 msgid "sedi_secondarie_label" msgstr "" #. Default: "Seleziona la lista dei servizi collegati a questo." -#: design/plone/contenttypes/interfaces/servizio.py:300 +#: design/plone/contenttypes/interfaces/servizio.py:394 msgid "servizi_collegati_help" msgstr "" #. Default: "Servizi collegati" -#: design/plone/contenttypes/interfaces/servizio.py:299 +#: design/plone/contenttypes/interfaces/servizio.py:393 msgid "servizi_collegati_label" msgstr "" #. Default: "Questi servizi non verranno mostrati nel contenuto, ma permetteranno di vedere questo contenuto associato quando si visita il servizio" -#: design/plone/contenttypes/behaviors/servizi_correlati.py:19 +#: design/plone/contenttypes/behaviors/servizi_correlati.py:20 msgid "servizi_correlati_description" msgstr "" #. Default: "Servizi correlati" -#: design/plone/contenttypes/behaviors/servizi_correlati.py:18 +#: design/plone/contenttypes/behaviors/servizi_correlati.py:19 msgid "servizi_correlati_label" msgstr "" @@ -2278,22 +2348,32 @@ msgid "servizio_origine_ricevuta" msgstr "" #. Default: "Settore merceologico" -#: design/plone/contenttypes/interfaces/servizio.py:280 +#: design/plone/contenttypes/interfaces/servizio.py:369 msgid "settore_merceologico" msgstr "" #. Default: "Classificazione del servizio basata su catalogo dei servizi (Classificazione NACE)." -#: design/plone/contenttypes/interfaces/servizio.py:282 +#: design/plone/contenttypes/interfaces/servizio.py:371 msgid "settore_merceologico_help" msgstr "" +#. Default: "Se selezionato, il footer verrà popolato automaticamente con i contenuti di primo livello non esclusi dalla navigazione." +#: design/plone/contenttypes/controlpanels/settings.py:93 +msgid "show_dynamic_folders_in_footer_help" +msgstr "" + +#. Default: "Footer dinamico" +#: design/plone/contenttypes/controlpanels/settings.py:92 +msgid "show_dynamic_folders_in_footer_label" +msgstr "" + #. Default: "Questo è il valore di default per decidere se mostrare o meno la data di modifica nei contenuti che hanno la behavior abilitata. E' poi possibile sovrascrivere il default nei singoli contenuti (nel tab \"Impostazioni\")." -#: design/plone/contenttypes/controlpanels/settings.py:139 +#: design/plone/contenttypes/controlpanels/settings.py:81 msgid "show_modified_default_help" msgstr "" #. Default: "Mostra la data di modifica" -#: design/plone/contenttypes/controlpanels/settings.py:138 +#: design/plone/contenttypes/controlpanels/settings.py:80 msgid "show_modified_default_label" msgstr "" @@ -2308,34 +2388,34 @@ msgid "show_modified_label" msgstr "" #. Default: "Indicare se il procedimento prevede il silenzio assenso o la dichiarazione dell'interessato sostitutiva del provvedimento finale." -#: design/plone/contenttypes/behaviors/trasparenza.py:103 +#: design/plone/contenttypes/behaviors/trasparenza.py:104 msgid "silenzio_assenso_help" msgstr "" #. Default: "Silenzio assenso/Dichiarazione dell'interessato sostitutiva del provvedimento finale" -#: design/plone/contenttypes/behaviors/trasparenza.py:97 +#: design/plone/contenttypes/behaviors/trasparenza.py:98 msgid "silenzio_assenso_label" msgstr "" #. Default: "Inserisci eventuali soggetti esterni, nonché, strutture interne coinvolte nel procedimento." -#: design/plone/contenttypes/behaviors/trasparenza.py:57 +#: design/plone/contenttypes/behaviors/trasparenza.py:58 msgid "soggetti_eserni_help" msgstr "" #. Default: "Soggetti esterni, nonché, strutture interne coinvolte nel procedimento" -#: design/plone/contenttypes/behaviors/trasparenza.py:52 +#: design/plone/contenttypes/behaviors/trasparenza.py:53 msgid "soggetti_eserni_label" msgstr "" #. Default: "Indica un eventuale sottotitolo/titolo alternativo." -#: design/plone/contenttypes/behaviors/evento.py:23 -#: design/plone/contenttypes/interfaces/servizio.py:19 +#: design/plone/contenttypes/behaviors/evento.py:24 +#: design/plone/contenttypes/interfaces/servizio.py:64 msgid "sottotitolo_help" msgstr "" #. Default: "Sottotitolo" -#: design/plone/contenttypes/behaviors/evento.py:22 -#: design/plone/contenttypes/interfaces/servizio.py:18 +#: design/plone/contenttypes/behaviors/evento.py:23 +#: design/plone/contenttypes/interfaces/servizio.py:63 msgid "sottotitolo_label" msgstr "" @@ -2349,273 +2429,188 @@ msgstr "" msgid "stato_pratica" msgstr "" -#. Default: "Indica se il servizio è effettivamente fruibile." -#: design/plone/contenttypes/interfaces/servizio.py:32 +#. Default: "Indica se il servizio è effettivamente fruibile; spuntare se non è fruibile." +#: design/plone/contenttypes/interfaces/servizio.py:77 msgid "stato_servizio_help" msgstr "" -#. Default: "Servizio non attivo" -#: design/plone/contenttypes/interfaces/servizio.py:30 +#. Default: "Servizio non fruibile" +#: design/plone/contenttypes/interfaces/servizio.py:75 msgid "stato_servizio_label" msgstr "" #. Default: "Indicare gli eventuali strumenti di tutela." -#: design/plone/contenttypes/behaviors/trasparenza.py:230 +#: design/plone/contenttypes/behaviors/trasparenza.py:231 msgid "strumenti_tutela_help" msgstr "" #. Default: "Strumenti di tutela" -#: design/plone/contenttypes/behaviors/trasparenza.py:229 +#: design/plone/contenttypes/behaviors/trasparenza.py:230 msgid "strumenti_tutela_label" msgstr "" #. Default: "Struttura" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:211 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:206 msgid "struttura_label" msgstr "" #. Default: "Struttura responsabile" -#: design/plone/contenttypes/behaviors/luogo.py:82 +#: design/plone/contenttypes/behaviors/luogo.py:83 msgid "struttura_responsabile" msgstr "" #. Default: "Struttura responsabile del luogo." -#: design/plone/contenttypes/behaviors/luogo.py:63 +#: design/plone/contenttypes/behaviors/luogo.py:64 msgid "struttura_responsabile_correlati" msgstr "" #. Default: "Indicare la struttura responsabile del luogo qualora sia fra unità organizzative del comune inserite nel sito; altrimenti compilare i campi testuali relativi alla struttura responsabile" -#: design/plone/contenttypes/behaviors/luogo.py:67 +#: design/plone/contenttypes/behaviors/luogo.py:68 msgid "struttura_responsabile_correlati_help" msgstr "" #. Default: "Nome/link al sito web della struttura che gestisce il luogo, se questa non è comunale." -#: design/plone/contenttypes/behaviors/luogo.py:84 +#: design/plone/contenttypes/behaviors/luogo.py:85 msgid "struttura_responsabile_help" msgstr "" #. Default: "Seleziona la lista delle strutture politiche coinvolte." -#: design/plone/contenttypes/behaviors/strutture_correlate.py:25 +#: design/plone/contenttypes/behaviors/strutture_correlate.py:26 msgid "strutture_politiche_help" msgstr "" #. Default: "Indicare gli uffici/enti che supportano l'evento." -#: design/plone/contenttypes/behaviors/evento.py:149 +#: design/plone/contenttypes/behaviors/evento.py:97 msgid "supportato_da_help" msgstr "" #. Default: "Evento supportato da" -#: design/plone/contenttypes/behaviors/evento.py:145 +#: design/plone/contenttypes/behaviors/evento.py:93 msgid "supportato_da_label" msgstr "" #. Default: "Seleziona una lista di argomenti d'interesse per questo contenuto." -#: design/plone/contenttypes/behaviors/argomenti.py:22 +#: design/plone/contenttypes/behaviors/argomenti.py:26 msgid "tassonomia_argomenti_help" msgstr "" -#. Default: "Tassonomia argomenti" -#: design/plone/contenttypes/behaviors/argomenti.py:21 +#. Default: "Argomenti" +#: design/plone/contenttypes/behaviors/argomenti.py:25 msgid "tassonomia_argomenti_label" msgstr "" -#. Default: "Telefono" -#: design/plone/contenttypes/behaviors/evento.py:104 -msgid "telefono_event_help" -msgstr "" - -#. Default: "Indicare un riferimento telefonico per poter contattare gli organizzatori." -#: design/plone/contenttypes/behaviors/evento.py:105 -msgid "telefono_event_label" -msgstr "" - -#. Default: "Indicare un riferimento telefonico per poter contattare i referenti." -#: design/plone/contenttypes/behaviors/contatti.py:19 -msgid "telefono_help" -msgstr "" - -#. Default: "Telefono" -#: design/plone/contenttypes/behaviors/contatti.py:18 -msgid "telefono_label" -msgstr "" - -#. Default: "Contatto telefonico della persona. E' possibile inserire più di un numero. Premendo \"Invio\" o \"tab\" si può passare al successivo da inserire." -#: design/plone/contenttypes/interfaces/persona.py:117 -msgid "telefono_persona_help" -msgstr "" - -#. Default: "Numero di telefono" -#: design/plone/contenttypes/interfaces/persona.py:116 -msgid "telefono_persona_label" -msgstr "" - -#. Default: "Temi" -#: design/plone/contenttypes/interfaces/dataset.py:14 -msgid "temi" -msgstr "" - #. Default: "Tempi e scadenze" -#: design/plone/contenttypes/interfaces/servizio.py:167 +#: design/plone/contenttypes/interfaces/servizio.py:236 msgid "tempi_e_scadenze" msgstr "" #. Default: "Descrivere le informazioni dettagliate riguardo eventuali tempi e scadenze di questo servizio." -#: design/plone/contenttypes/interfaces/servizio.py:169 +#: design/plone/contenttypes/interfaces/servizio.py:238 msgid "tempi_e_scadenze_help" msgstr "" #. Default: "Tempi e scadenze" -#: design/plone/contenttypes/interfaces/servizio.py:395 +#: design/plone/contenttypes/interfaces/servizio.py:508 msgid "tempi_e_scadenze_label" msgstr "" #. Default: "Inserisci il tempo medio del procedimento." -#: design/plone/contenttypes/behaviors/trasparenza.py:91 +#: design/plone/contenttypes/behaviors/trasparenza.py:92 msgid "tempo_medio_help" msgstr "" #. Default: "Tempo medio del procedimento" -#: design/plone/contenttypes/behaviors/trasparenza.py:86 +#: design/plone/contenttypes/behaviors/trasparenza.py:87 msgid "tempo_medio_label" msgstr "" #. Default: "Testata" -#: design/plone/contenttypes/behaviors/argomenti.py:104 +#: design/plone/contenttypes/behaviors/argomenti.py:232 #: design/plone/contenttypes/behaviors/info_testata.py:62 msgid "testata_fieldset_label" msgstr "" -#: design/plone/contenttypes/interfaces/bando.py:28 +#: design/plone/contenttypes/interfaces/bando.py:29 msgid "text_help" msgstr "" #. Default: "Testo" -#: design/plone/contenttypes/interfaces/bando.py:27 +#: design/plone/contenttypes/interfaces/bando.py:28 msgid "text_label" msgstr "" -#. Default: "Tipologia documento" -#: design/plone/contenttypes/interfaces/messaggio.py:49 -msgid "tipologia_documento" -msgstr "" - -#. Default: "Seleziona la tipologia del documento." -#: design/plone/contenttypes/interfaces/documento.py:30 -msgid "tipologia_documento_help" -msgstr "" - -#. Default: "Tipologia del documento" -#: design/plone/contenttypes/interfaces/documento.py:29 -msgid "tipologia_documento_label" -msgstr "" - -#. Default: "Seleziona la tipologia della notizia." -#: design/plone/contenttypes/behaviors/news_additional_fields.py:29 -msgid "tipologia_notizia_help" -msgstr "" - -#. Default: "Tipologia notizia" -#: design/plone/contenttypes/behaviors/news_additional_fields.py:28 -msgid "tipologia_notizia_label" -msgstr "" - -#. Default: "Specificare la tipologia di organizzazione: politica, amminsitrativa o di altro tipo." -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:60 -msgid "tipologia_organizzazione_help" -msgstr "" - -#. Default: "Tipologia organizzazione" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:57 -msgid "tipologia_organizzazione_label" -msgstr "" - -#. Default: "Seleziona la tipologia di persona: politica, amministrativa o di altro tipo." -#: design/plone/contenttypes/interfaces/persona.py:86 -msgid "tipologia_persona_help" -msgstr "" - -#. Default: "Tipologia persona" -#: design/plone/contenttypes/interfaces/persona.py:85 -msgid "tipologia_persona_label" -msgstr "" - -#. Default: "Inserisci i valori utilizzabili per le tipologie di un Documento. Se il sito è multilingua, puoi inserire valori diversi a seconda delle lingue del sito." -#: design/plone/contenttypes/controlpanels/settings.py:46 -msgid "tipologie_documento_help" +#. Default: "Timeline tempi e scadenze" +#: design/plone/contenttypes/interfaces/servizio.py:246 +msgid "timeline_tempi_scadenze" msgstr "" -#. Default: "Tipologie Documento" -#: design/plone/contenttypes/controlpanels/settings.py:45 -msgid "tipologie_documento_label" +#. Default: "Timeline tempi e scadenze del servizio: indicare per ogni scadenza un titolo descrittivo ed un eventuale sottotitolo. Per ogni scadenza, selezionare opzionalmente o l'intervallo (Campi \"Intervallo\" e \"Tipo Intervallo\", es. \"1\" e \"settimana\"), oppure direttamente una data di scadenza (campo: \"Data Scadenza\", esempio 31/12/2023). Se vengono compilati entrambi, ha priorità il campo \"Data Scadenza\"." +#: design/plone/contenttypes/interfaces/servizio.py:249 +msgid "timeline_tempi_scadenze_help" msgstr "" #. Default: "Inserisci i valori utilizzabili per le tipologie di una Notizia. Se il sito è multilingua, puoi inserire valori diversi a seconda delle lingue del sito." -#: design/plone/contenttypes/controlpanels/settings.py:19 +#: design/plone/contenttypes/controlpanels/settings.py:22 msgid "tipologie_notizia_help" msgstr "" #. Default: "Tipologie Notizia" -#: design/plone/contenttypes/controlpanels/settings.py:18 +#: design/plone/contenttypes/controlpanels/settings.py:21 msgid "tipologie_notizia_label" msgstr "" -#. Default: "Inserisci i valori utilizzabili per le tipologie di una Persona. Se il sito è multilingua, puoi inserire valori diversi a seconda delle lingue del sito." -#: design/plone/contenttypes/controlpanels/settings.py:72 -msgid "tipologie_persona_help" -msgstr "" - -#. Default: "Tipologie Persona" -#: design/plone/contenttypes/controlpanels/settings.py:71 -msgid "tipologie_persona_label" -msgstr "" - #. Default: "Inserisci i valori utilizzabili per le tipologie di un' Unità Organizzativa. Se il sito è multilingua, puoi inserire valori diversi a seconda delle lingue del sito." -#: design/plone/contenttypes/controlpanels/settings.py:34 +#: design/plone/contenttypes/controlpanels/settings.py:37 msgid "tipologie_unita_organizzativa_help" msgstr "" #. Default: "Tipologie Unità Organizzativa" -#: design/plone/contenttypes/controlpanels/settings.py:30 +#: design/plone/contenttypes/controlpanels/settings.py:33 msgid "tipologie_unita_organizzativa_label" msgstr "" #. Default: "Titolare" -#: design/plone/contenttypes/interfaces/dataset.py:29 +#: design/plone/contenttypes/interfaces/dataset.py:22 msgid "titolare" msgstr "" #. Default: "Eventuale titolare del potere sostitutivo." -#: design/plone/contenttypes/behaviors/trasparenza.py:243 +#: design/plone/contenttypes/behaviors/trasparenza.py:244 msgid "titolare_potere_sostitutivo_help" msgstr "" #. Default: "Titolare del potere sostitutivo" -#: design/plone/contenttypes/behaviors/trasparenza.py:238 +#: design/plone/contenttypes/behaviors/trasparenza.py:239 msgid "titolare_potere_sostitutivo_label" msgstr "" #. Default: "Trasparenza" -#: design/plone/contenttypes/behaviors/trasparenza.py:292 +#: design/plone/contenttypes/behaviors/trasparenza.py:291 msgid "trasparenza_fieldset_label" msgstr "" +#. Default: "Tipo" +#: design/plone/contenttypes/interfaces/punto_di_contatto.py:17 +msgid "type_help" +msgstr "" + #. Default: "Seleziona l'ufficio responsabile di questo bando." -#: design/plone/contenttypes/interfaces/bando.py:110 +#: design/plone/contenttypes/interfaces/bando.py:111 msgid "ufficio_responsabile_bando_help" msgstr "" #. Default: "Ufficio responsabile del bando" -#: design/plone/contenttypes/interfaces/bando.py:106 +#: design/plone/contenttypes/interfaces/bando.py:107 msgid "ufficio_responsabile_bando_label" msgstr "" #. Default: "Seleziona l'ufficio responsabile di questo documento." -#: design/plone/contenttypes/interfaces/documento.py:43 +#: design/plone/contenttypes/interfaces/documento.py:73 msgid "ufficio_responsabile_documento_help" msgstr "" #. Default: "Ufficio responsabile del documento" -#: design/plone/contenttypes/interfaces/documento.py:39 +#: design/plone/contenttypes/interfaces/documento.py:69 msgid "ufficio_responsabile_documento_label" msgstr "" @@ -2624,13 +2619,13 @@ msgstr "" msgid "ufficio_responsabile_documento_personale" msgstr "" -#. Default: "Uffici responsabili" -#: design/plone/contenttypes/interfaces/servizio.py:216 +#. Default: "Unità organizzativa responsabile" +#: design/plone/contenttypes/interfaces/servizio.py:302 msgid "ufficio_responsabile_erogazione" msgstr "" #. Default: "Seleziona gli uffici responsabili dell'erogazione di questo servizio." -#: design/plone/contenttypes/interfaces/servizio.py:217 +#: design/plone/contenttypes/interfaces/servizio.py:306 msgid "ufficio_responsabile_help" msgstr "" @@ -2661,52 +2656,52 @@ msgstr "" msgid "unita_amministrative_responsabili_help" msgstr "" +#. Default: "Seleziona l'organizzazione presso la quale svolge l'incarico." +#: design/plone/contenttypes/interfaces/incarico.py:64 +msgid "unita_organizzativa_incarico_help" +msgstr "" + +#. Default: "Unità organizzativa" +#: design/plone/contenttypes/interfaces/incarico.py:60 +msgid "unita_organizzativa_incarico_label" +msgstr "" + #. Default: "Descrizione dei compiti assegnati alla struttura." -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:19 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:23 msgid "uo_competenze_help" msgstr "" #. Default: "Competenze" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:18 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:22 msgid "uo_competenze_label" msgstr "" -#. Default: "Inserisci eventuali informazioni di contatto aggiuntive non contemplate nei campi precedenti. Utilizza questo campo se ci sono dei contatti aggiuntivi rispetto ai contatti della sede principale. Se inserisci un collegamento con un indirizzo email, aggiungi \"mailto:\" prima dell'indirizzo, per farlo aprire direttamente nel client di posta." -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:139 -msgid "uo_contact_info_description" -msgstr "" - #. Default: "Note di aggiornamento" -#: design/plone/contenttypes/behaviors/update_note.py:16 +#: design/plone/contenttypes/behaviors/update_note.py:17 msgid "update_note_label" msgstr "" +#. Default: "Il valore del punto di contatto: il numero compreso di prefisso internazionale (se telefono), l'account (se social network), l'URL (se sito o pagina web), l'indirizzo email (se email)." +#: design/plone/contenttypes/interfaces/punto_di_contatto.py:54 +msgid "value_punto_contatto_help" +msgstr "" + #. Default: "Vincoli" -#: design/plone/contenttypes/interfaces/servizio.py:196 +#: design/plone/contenttypes/interfaces/servizio.py:282 msgid "vincoli" msgstr "" #. Default: "Descrizione degli eventuali vincoli presenti." -#: design/plone/contenttypes/interfaces/servizio.py:198 +#: design/plone/contenttypes/interfaces/servizio.py:284 msgid "vincoli_help" msgstr "" -#. Default: "Indicare un indirizzo web di riferimento a questo evento." -#: design/plone/contenttypes/behaviors/evento.py:138 -msgid "web_event_help" -msgstr "" - -#. Default: "Sito web" -#: design/plone/contenttypes/behaviors/evento.py:137 -msgid "web_event_label" -msgstr "" - -#. Default: "Indicare un indirizzo web di riferimento." -#: design/plone/contenttypes/behaviors/contatti.py:53 -msgid "web_help" +#. Default: "Mostra i PDF in anteprima" +#: design/plone/contenttypes/interfaces/cartella_modulistica.py:12 +msgid "visualize_files_title" msgstr "" -#. Default: "Sito web" -#: design/plone/contenttypes/behaviors/contatti.py:52 -msgid "web_label" +#. Default: "Permette di aprire l'anteprima di tutti i PDF di questa cartella in una tab separata, altrimenti i PDF vengono scaricati" +#: design/plone/contenttypes/interfaces/cartella_modulistica.py:13 +msgid "visulize_files_description" msgstr "" diff --git a/src/design/plone/contenttypes/locales/en/LC_MESSAGES/design.plone.contenttypes.po b/src/design/plone/contenttypes/locales/en/LC_MESSAGES/design.plone.contenttypes.po index 69f5e5e7..fbc969d6 100644 --- a/src/design/plone/contenttypes/locales/en/LC_MESSAGES/design.plone.contenttypes.po +++ b/src/design/plone/contenttypes/locales/en/LC_MESSAGES/design.plone.contenttypes.po @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2023-01-13 13:15+0000\n" +"POT-Creation-Date: 2024-03-18 13:30+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI +ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -14,39 +14,23 @@ msgstr "" "Preferred-Encodings: utf-8 latin1\n" "Domain: DOMAIN\n" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:32 -msgid "Abitazione" -msgstr "" - -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:36 -msgid "Accesso al trasporto pubblico" -msgstr "" - -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:59 -msgid "Accesso luoghi della cultura" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:18 +msgid "Accesso all'informazione" msgstr "" #: design/plone/contenttypes/vocabularies/lista_azioni_pratica.py:33 msgid "Accettare" msgstr "" -#: design/plone/contenttypes/vocabularies/document_types_vocabulary.py:34 -msgid "Accordo tra enti" -msgstr "" - -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:52 +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:19 msgid "Acqua" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:194 +#: design/plone/contenttypes/behaviors/configure.zcml:223 msgid "Address Event" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:178 -msgid "Address UO" -msgstr "" - -#: design/plone/contenttypes/behaviors/configure.zcml:186 +#: design/plone/contenttypes/behaviors/configure.zcml:215 msgid "Address Venue" msgstr "" @@ -54,61 +38,53 @@ msgstr "" msgid "Adds fields." msgstr "" -#: design/plone/contenttypes/vocabularies/dataset.py:28 -msgid "Agricoltura, pesca, silvicoltura e prodotti alimentari" +#: design/plone/contenttypes/configure.zcml:66 +msgid "After Plone6 migration syndication is broken" msgstr "" -#: design/plone/contenttypes/browser/manage_content/templates/change_news_type.pt:22 -msgid "All the already existing News Types" -msgstr "" - -#: design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt:63 -msgid "All the selected items will be moved to indicated path" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:20 +msgid "Agricoltura" msgstr "" -#: design/plone/contenttypes/browser/manage_content/templates/change_news_type.pt:20 +#: design/plone/contenttypes/browser/utils/templates/change_news_type.pt:30 msgid "All the already existing News Types" msgstr "" -#: design/plone/contenttypes/vocabularies/dataset.py:36 -msgid "Ambiente" +#: design/plone/contenttypes/browser/utils/templates/move_news_items.pt:113 +msgid "All the selected items will be moved to indicated path" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:33 +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:21 msgid "Animale domestico" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:25 -msgid "Anziano" -msgstr "" - -#: design/plone/contenttypes/interfaces/bando.py:134 -#: design/plone/contenttypes/interfaces/documento.py:67 -#: design/plone/contenttypes/interfaces/servizio.py:239 +#: design/plone/contenttypes/interfaces/bando.py:135 +#: design/plone/contenttypes/interfaces/documento.py:97 +#: design/plone/contenttypes/interfaces/servizio.py:328 msgid "Area" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:50 -msgid "Area di parcheggio" -msgstr "" - #: design/plone/contenttypes/behaviors/configure.zcml:49 msgid "Argomenti" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:76 +#: design/plone/contenttypes/behaviors/configure.zcml:94 msgid "Argomenti Bando" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:58 +#: design/plone/contenttypes/behaviors/configure.zcml:76 msgid "Argomenti Document" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:67 +#: design/plone/contenttypes/behaviors/configure.zcml:85 msgid "Argomenti Documento" msgstr "" -#: design/plone/contenttypes/behaviors/argomenti.py:28 +#: design/plone/contenttypes/behaviors/configure.zcml:112 +msgid "Argomenti Link" +msgstr "" + +#: design/plone/contenttypes/behaviors/argomenti.py:32 msgid "Argomenti correlati" msgstr "" @@ -116,20 +92,36 @@ msgstr "" msgid "Argomento" msgstr "" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:73 +#: design/plone/contenttypes/behaviors/configure.zcml:103 +msgid "Argomento Servizio" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:22 +msgid "Aria" +msgstr "" + +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:65 msgid "Assessore di riferimento" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:30 -msgid "Associazione" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:23 +msgid "Assistenza agli invalidi" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:24 +msgid "Assistenza sociale" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:25 +msgid "Associazioni" msgstr "" #: design/plone/contenttypes/vocabularies/lista_azioni_pratica.py:29 msgid "Attivare" msgstr "" -#: design/plone/contenttypes/vocabularies/document_types_vocabulary.py:33 -msgid "Atto normativo" +#: design/plone/contenttypes/interfaces/incarico.py:121 +msgid "Atto di nomina" msgstr "" #: design/plone/contenttypes/interfaces/documento_personale.py:86 @@ -140,70 +132,66 @@ msgstr "" msgid "Autorizzare" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:65 -msgid "Avvio impresa" -msgstr "" - -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:66 -msgid "Avvio nuova attività professionale" -msgstr "" - -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:69 -msgid "Avvio/registrazione filiale" +#: design/plone/contenttypes/behaviors/configure.zcml:223 +msgid "Behavior address per Event." msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:78 -msgid "Bancarotta" +#: design/plone/contenttypes/behaviors/configure.zcml:215 +msgid "Behavior address per Venue." msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:194 -msgid "Behavior address per Event." +#: design/plone/contenttypes/behaviors/configure.zcml:263 +msgid "Behavior contatti per Event." msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:178 -msgid "Behavior address per UO." +#: design/plone/contenttypes/behaviors/configure.zcml:255 +msgid "Behavior contatti per Persona." msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:186 -msgid "Behavior address per Venue." +#: design/plone/contenttypes/behaviors/configure.zcml:247 +msgid "Behavior contatti per Servizio." msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:202 +#: design/plone/contenttypes/behaviors/configure.zcml:231 msgid "Behavior contatti per UO." msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:210 +#: design/plone/contenttypes/behaviors/configure.zcml:239 msgid "Behavior contatti per Venue." msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:234 +#: design/plone/contenttypes/behaviors/configure.zcml:279 msgid "Behavior geolocatable per Event." msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:218 -msgid "Behavior geolocatable per UO." +#: design/plone/contenttypes/behaviors/configure.zcml:271 +msgid "Behavior geolocatable per Venue." msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:226 -msgid "Behavior geolocatable per Venue." +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:26 +msgid "Bilancio" msgstr "" #: design/plone/contenttypes/controlpanels/geolocation_defaults.py:18 msgid "CAP" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:43 -msgid "Cambio di residenza/domicilio" +#: design/plone/contenttypes/behaviors/configure.zcml:306 +msgid "Campi aggiuntivi per la sezione amministrazione trasparente." msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:261 -msgid "Campi aggiuntivi per la sezione amministrazione trasparente." +#: design/plone/contenttypes/behaviors/configure.zcml:324 +msgid "Campo per escludere un contenuto dalle ricerche del sito." msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:270 +#: design/plone/contenttypes/behaviors/configure.zcml:315 msgid "Campo per le note di aggiornamento." msgstr "" +#: design/plone/contenttypes/interfaces/servizio.py:183 +msgid "Canale fisico" +msgstr "" + #: design/plone/contenttypes/vocabularies/mockup.py:26 msgid "Canon 5D IV" msgstr "" @@ -212,39 +200,44 @@ msgstr "" msgid "Cartella Modulistica" msgstr "" -#: design/plone/contenttypes/browser/manage_content/templates/change_news_type.pt:11 +#: design/plone/contenttypes/browser/utils/templates/change_news_type.pt:13 msgid "Change News Type" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:75 -msgid "Chiusura filiale" +#: design/plone/contenttypes/controlpanels/geolocation_defaults.py:23 +msgid "Città" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:74 -msgid "Chiusura impresa e attività professionale" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:28 +msgid "Commercio al minuto" msgstr "" -#: design/plone/contenttypes/controlpanels/geolocation_defaults.py:23 -msgid "Città" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:27 +msgid "Commercio all'ingrosso" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:39 -msgid "Compravendita/affitto casa/edifici/terreni, costruzione o ristrutturazione casa/edificio " +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:29 +msgid "Commercio ambulante" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:36 -msgid "Comunicazione" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:30 +msgid "Comunicazione istituzionale" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:41 -msgid "Condizioni e organizzazione del lavoro" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:31 +msgid "Comunicazione politica" msgstr "" -#: design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt:57 +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:32 +msgid "Concorsi" +msgstr "" + +#: design/plone/contenttypes/browser/utils/templates/move_news_items.pt:104 msgid "Contained by" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:202 +#: design/plone/contenttypes/behaviors/configure.zcml:231 +#: design/plone/contenttypes/behaviors/contatti.py:112 msgid "Contatti" msgstr "" @@ -252,12 +245,12 @@ msgstr "" msgid "Coordinate" msgstr "" -#: design/plone/contenttypes/behaviors/argomenti.py:42 +#: design/plone/contenttypes/behaviors/argomenti.py:46 msgid "Correlato in evidenza" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:47 -msgid "Cultura" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:33 +msgid "Covid - 19" msgstr "" #: design/plone/contenttypes/interfaces/documento_personale.py:130 @@ -269,7 +262,7 @@ msgstr "" msgid "Dataset collegato" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:104 +#: design/plone/contenttypes/behaviors/configure.zcml:141 msgid "Dataset correlati" msgstr "" @@ -277,115 +270,102 @@ msgstr "" msgid "Delegare" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:52 -msgid "Denuncia crimini" -msgstr "" - -#: design/plone/contenttypes/behaviors/configure.zcml:143 +#: design/plone/contenttypes/behaviors/configure.zcml:180 msgid "Descrizione estesa" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:160 +#: design/plone/contenttypes/behaviors/configure.zcml:197 msgid "Descrizione estesa documento" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:152 +#: design/plone/contenttypes/behaviors/configure.zcml:189 msgid "Descrizione estesa servizio" msgstr "" -#: design/plone/contenttypes/configure.zcml:36 +#: design/plone/contenttypes/configure.zcml:32 msgid "Design Plone: Content-types" msgstr "" -#: design/plone/contenttypes/configure.zcml:45 +#: design/plone/contenttypes/configure.zcml:41 +msgid "Design Plone: Content-types (behaviors)" +msgstr "" + +#: design/plone/contenttypes/configure.zcml:50 msgid "Design Plone: Content-types (uninstall)" msgstr "" -#: design/plone/contenttypes/configure.zcml:52 +#: design/plone/contenttypes/configure.zcml:58 msgid "Design Plone: Content-types to 3000" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:55 -msgid "Dichiarazione dei redditi, versamento e riscossione tributi/imposte e contributi" +#: design/plone/contenttypes/configure.zcml:66 +msgid "Design Plone: Fix Syndication after Plone6 Migration" msgstr "" -#: design/plone/contenttypes/behaviors/trasparenza.py:145 +#: design/plone/contenttypes/behaviors/trasparenza.py:146 msgid "Dirigente" msgstr "" -#: design/plone/contenttypes/vocabularies/document_types_vocabulary.py:27 -msgid "Documenti albo pretorio" +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:134 +msgid "Documenti pubblici" msgstr "" -#: design/plone/contenttypes/interfaces/servizio.py:252 +#: design/plone/contenttypes/interfaces/servizio.py:341 #: design/plone/contenttypes/profiles/default/types/Documento.xml msgid "Documento" msgstr "" -#: design/plone/contenttypes/vocabularies/document_types_vocabulary.py:41 -msgid "Documento (tecnico) di supporto" -msgstr "" - #: design/plone/contenttypes/profiles/default/types/Documento_Personale.xml msgid "Documento Personale" msgstr "" -#: design/plone/contenttypes/vocabularies/document_types_vocabulary.py:37 -msgid "Documento attivita politica" -msgstr "" - -#: design/plone/contenttypes/vocabularies/document_types_vocabulary.py:31 -msgid "Documento funzionamento interno" -msgstr "" - -#: design/plone/contenttypes/vocabularies/dataset.py:30 -msgid "Economia e Finanze" -msgstr "" - #: design/plone/contenttypes/profiles/default/types/CartellaModulistica.xml #: design/plone/contenttypes/profiles/default/types/Dataset.xml #: design/plone/contenttypes/profiles/default/types/Documento.xml msgid "Edit" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:45 -msgid "Elezione" -msgstr "" - -#: design/plone/contenttypes/vocabularies/dataset.py:35 -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:61 -msgid "Energia" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:34 +msgid "Elezioni" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:28 -msgid "Famiglia" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:35 +msgid "Energie rinnovabili" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:26 -msgid "Fanciullo" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:36 +msgid "Estero" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:70 -msgid "Finanziamento impresa" +#: design/plone/contenttypes/behaviors/configure.zcml:324 +msgid "Exclude from search" msgstr "" -#: design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt:28 +#: design/plone/contenttypes/browser/utils/templates/move_news_items.pt:51 msgid "Find news with the indicated Path, put attention than generaly sites have the root name \"/Plone/\"" msgstr "" -#: design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt:21 +#: design/plone/contenttypes/browser/utils/templates/move_news_items.pt:29 msgid "Find news with this News Type" msgstr "" -#: design/plone/contenttypes/configure.zcml:52 +#: design/plone/contenttypes/configure.zcml:58 msgid "Fix control panel of design.plone.contenttypes add-on." msgstr "" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:37 +msgid "Foreste" +msgstr "" + #: design/plone/contenttypes/vocabularies/tags_vocabulary.py:38 msgid "Formazione professionale" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:218 +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:39 +msgid "Gemellaggi" +msgstr "" + +#: design/plone/contenttypes/behaviors/configure.zcml:271 msgid "Geolocatable" msgstr "" @@ -394,44 +374,57 @@ msgstr "" msgid "Geolocation default" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:53 -msgid "Gestione dei rifiuti" -msgstr "" - -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:71 -msgid "Gestione personale" -msgstr "" - -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:27 -msgid "Giovane" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:40 +msgid "Gestione rifiuti" msgstr "" #: design/plone/contenttypes/vocabularies/mockup.py:30 msgid "Giovanni" msgstr "" -#: design/plone/contenttypes/vocabularies/dataset.py:42 -msgid "Giustizia, sistema giuridico e sicurezza pubblica" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:41 +msgid "Giustizia" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:42 +msgid "Igiene pubblica" msgstr "" -#: design/plone/contenttypes/vocabularies/dataset.py:37 -msgid "Governo e settore pubblico" +#: design/plone/contenttypes/browser/utils/change_news_type.py:32 +#: design/plone/contenttypes/browser/utils/move_news_items.py:74 +msgid "Il vocabolario dei valori non è stato trovato" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:48 +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:43 msgid "Immigrazione" msgstr "" -#: design/plone/contenttypes/controlpanels/settings.py:154 +#: design/plone/contenttypes/controlpanels/settings.py:106 #: design/plone/contenttypes/profiles/default/controlpanel.xml msgid "Impostazioni Design Plone" msgstr "" -#: design/plone/contenttypes/browser/manage_content/move_news_items.py:33 +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:44 +msgid "Imposte" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:45 +msgid "Imprese" +msgstr "" + +#: design/plone/contenttypes/interfaces/persona.py:68 +msgid "Incarichi" +msgstr "" + +#: design/plone/contenttypes/profiles/default/types/Incarico.xml +msgid "Incarico" +msgstr "" + +#: design/plone/contenttypes/browser/utils/move_news_items.py:34 msgid "Indicated path is not valid" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:170 +#: design/plone/contenttypes/behaviors/configure.zcml:207 msgid "Info per la testata" msgstr "" @@ -439,64 +432,56 @@ msgstr "" msgid "Informare" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:64 -msgid "Informatica e trattamento dei dati" +#: design/plone/contenttypes/behaviors/contatti.py:34 +msgid "Informazioni di contatto" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:49 +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:46 msgid "Inquinamento" msgstr "" -#: design/plone/contenttypes/configure.zcml:36 +#: design/plone/contenttypes/configure.zcml:32 msgid "Installs the design.plone.contenttypes add-on." msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:34 +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:47 msgid "Integrazione sociale" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:28 -msgid "Invalidità" -msgstr "" - #: design/plone/contenttypes/vocabularies/lista_azioni_pratica.py:26 msgid "Iscriversi" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:26 -msgid "Iscrizione scuola/università e/o richiesta borsa di studio" -msgstr "" - -#: design/plone/contenttypes/vocabularies/document_types_vocabulary.py:43 -msgid "Istanza" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:48 +msgid "Isolamento termico" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:31 +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:49 msgid "Istruzione" msgstr "" -#: design/plone/contenttypes/vocabularies/dataset.py:33 -msgid "Istruzione, cultura e sport" +#: design/plone/contenttypes/browser/utils/move_news_items.py:48 +msgid "Items moved with success" msgstr "" -#: design/plone/contenttypes/browser/manage_content/move_news_items.py:47 -msgid "Items moved with success" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:50 +msgid "Lavoro" msgstr "" #: design/plone/contenttypes/vocabularies/lista_azioni_pratica.py:28 msgid "Leggere" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:85 +#: design/plone/contenttypes/behaviors/configure.zcml:122 msgid "Luoghi correlati" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:44 +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:51 msgid "Matrimonio" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:49 -msgid "Matrimonio e/o cambio stato civile" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:52 +msgid "Mercato" msgstr "" #: design/plone/contenttypes/profiles/default/types/Messaggio.xml @@ -515,72 +500,64 @@ msgstr "" msgid "Metadati news" msgstr "" -#: design/plone/contenttypes/vocabularies/document_types_vocabulary.py:28 -msgid "Modulistica" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:53 +msgid "Mobilità sostenibile" msgstr "" #: design/plone/contenttypes/profiles/default/types/Modulo.xml msgid "Modulo" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:50 -msgid "Morte ed eredità" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:54 +msgid "Morte" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:252 +#: design/plone/contenttypes/behaviors/configure.zcml:297 msgid "Mostra la data di modifica." msgstr "" -#: design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt:70 +#: design/plone/contenttypes/browser/utils/templates/move_news_items.pt:124 msgid "Move" msgstr "" -#: design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt:11 +#: design/plone/contenttypes/browser/utils/templates/move_news_items.pt:13 msgid "Move News Items" msgstr "" -#: design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt:62 +#: design/plone/contenttypes/browser/utils/templates/move_news_items.pt:110 msgid "Move to Path" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:243 +#: design/plone/contenttypes/behaviors/configure.zcml:288 msgid "Multi File" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:48 -msgid "Nascita di un bambino, richiesta adozioni" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:55 +msgid "Nascita" msgstr "" #: design/plone/contenttypes/controlpanels/geolocation_defaults.py:28 msgid "Nazione" msgstr "" -#: design/plone/contenttypes/browser/manage_content/templates/change_news_type.pt:21 -#: design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt:20 +#: design/plone/contenttypes/browser/utils/templates/change_news_type.pt:27 +#: design/plone/contenttypes/browser/utils/templates/move_news_items.pt:26 msgid "News Type" msgstr "" -#: design/plone/contenttypes/browser/manage_content/templates/change_news_type.pt:30 +#: design/plone/contenttypes/browser/utils/templates/change_news_type.pt:48 msgid "News Type to substitute" msgstr "" #. Default: "Nome e cognome" -#: design/plone/contenttypes/restapi/services/types/get.py:152 +#: design/plone/contenttypes/restapi/services/types/get.py:163 msgid "Nome e Cognome" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:73 -msgid "Notifiche autorità" -msgstr "" - -#: design/plone/contenttypes/interfaces/persona.py:48 +#: design/plone/contenttypes/interfaces/persona.py:51 msgid "Organizzazione di riferimento" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:72 -msgid "Pagamento tasse, iva e dogane" -msgstr "" - #: design/plone/contenttypes/vocabularies/lista_azioni_pratica.py:25 msgid "Pagare" msgstr "" @@ -589,84 +566,100 @@ msgstr "" msgid "Paperino" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:81 -msgid "Partecipazione ad appalti pubblici nazionali e trasfrontalieri" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:56 +msgid "Parcheggi" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:33 -msgid "Pensionamento" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:57 +msgid "Patrimonio culturale" msgstr "" -#: design/plone/contenttypes/profiles/default/types/Persona.xml +#: design/plone/contenttypes/interfaces/incarico.py:54 msgid "Persona" msgstr "" -#: design/plone/contenttypes/behaviors/evento.py:50 -msgid "Persona dell'amministrazione" +#: design/plone/contenttypes/profiles/default/types/Persona.xml +msgid "Persona pubblica" msgstr "" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:92 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:84 msgid "Persone della struttura" msgstr "" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:58 +msgid "Pesca" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:59 +msgid "Piano di sviluppo" +msgstr "" + #: design/plone/contenttypes/vocabularies/mockup.py:27 msgid "Pippo" msgstr "" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:60 +msgid "Pista ciclabile" +msgstr "" + #: design/plone/contenttypes/vocabularies/mockup.py:28 msgid "Pluto" msgstr "" -#: design/plone/contenttypes/vocabularies/dataset.py:45 -msgid "Popolazione e società" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:61 +msgid "Politica commerciale" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:60 -msgid "Possesso, cura, smarrimento animale da compagnia" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:62 +msgid "Polizia" msgstr "" #: design/plone/contenttypes/profiles/default/types/Pratica.xml msgid "Pratica" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:51 -msgid "Prenotazione e disdetta visite/esami" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:63 +msgid "Prodotti alimentari" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:35 -msgid "Protezione sociale" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:64 +msgid "Protezione civile" msgstr "" -#: design/plone/contenttypes/browser/manage_content/templates/change_news_type.pt:13 -msgid "Questo tool viene usato per cambiare il valore del campo 'Tipologia Notizia' in tutte le notizie che hanno il valore del campo selezionato. Fa anche il giro su tutti i blocchi elenco" +#: design/plone/contenttypes/behaviors/contatti.py:78 +msgid "Punti di contatto" msgstr "" -#: design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt:13 -msgid "Questo tool viene usato per trovare e spostare le Notizie con una Tipologia Notizia determinata." +#: design/plone/contenttypes/profiles/default/types/PuntoDiContatto.xml +msgid "Punto di Contatto" +msgstr "" + +#: design/plone/contenttypes/browser/utils/templates/change_news_type.pt:15 +msgid "Questo tool viene usato per cambiare il valore del campo 'Tipologia Notizia' in tutte le notizie che hanno il valore del campo selezionato. Fa anche il giro su tutti i blocchi elenco" msgstr "" -#: design/plone/contenttypes/vocabularies/dataset.py:44 -msgid "Regioni e città" +#: design/plone/contenttypes/browser/utils/templates/move_news_items.pt:15 +msgid "Questo tool viene usato per trovare e spostare le Notizie con una Tipologia Notizia determinata." msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:68 -msgid "Registrazione impresa transfrontalier" +#: design/plone/contenttypes/configure.zcml:41 +msgid "Registers taxonomies." msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:35 -msgid "Registrazione/possesso veicolo" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:65 +msgid "Residenza" msgstr "" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:45 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:49 msgid "Responsabile" msgstr "" -#: design/plone/contenttypes/behaviors/trasparenza.py:129 -msgid "Responsabile procedimento" +#: design/plone/contenttypes/interfaces/incarico.py:89 +msgid "Responsabile della struttura" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:31 -msgid "Ricerca di lavoro, avvio nuovo lavoro, disoccupazione" +#: design/plone/contenttypes/behaviors/trasparenza.py:130 +msgid "Responsabile procedimento" msgstr "" #: design/plone/contenttypes/profiles/default/types/RicevutaPagamento.xml @@ -677,40 +670,19 @@ msgstr "" msgid "Richiedere" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:67 -msgid "Richiesta licenze/permessi/certificati" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:66 +msgid "Risposta alle emergenze" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:34 -msgid "Richiesta o rinnovo patente" -msgstr "" - -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:46 -msgid "Richiesta passaporto, visto e assistenza viaggi internazionali" -msgstr "" - -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:76 -msgid "Ristrutturazione impresa" -msgstr "" - -#: design/plone/contenttypes/vocabularies/dataset.py:38 -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:54 -msgid "Salute" -msgstr "" - -#: design/plone/contenttypes/vocabularies/dataset.py:46 -msgid "Scienza e tecnologia" -msgstr "" - -#: design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt:27 +#: design/plone/contenttypes/browser/utils/templates/move_news_items.pt:47 msgid "Search Path" msgstr "" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:114 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:104 msgid "Sede" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:114 +#: design/plone/contenttypes/behaviors/configure.zcml:151 msgid "Servizi correlati" msgstr "" @@ -722,129 +694,128 @@ msgstr "" msgid "Servizio collegato" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:252 +#: design/plone/contenttypes/behaviors/configure.zcml:297 msgid "Show modified" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:56 -msgid "Sicurezza internazionale" -msgstr "" - -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:55 -msgid "Sicurezza pubblica" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:67 +msgid "Sistema giuridico" msgstr "" #: design/plone/contenttypes/vocabularies/mockup.py:25 msgid "Sony Aplha 7R III" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:57 -msgid "Spazio verde" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:68 +msgid "Spazio Verde" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:58 +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:69 msgid "Sport" msgstr "" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:37 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:41 msgid "Struttura" msgstr "" -#: design/plone/contenttypes/behaviors/strutture_correlate.py:20 +#: design/plone/contenttypes/behaviors/strutture_correlate.py:21 msgid "Struttura politica coinvolta" msgstr "" -#: design/plone/contenttypes/behaviors/luogo.py:74 +#: design/plone/contenttypes/behaviors/luogo.py:75 msgid "Struttura responsabile" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:124 +#: design/plone/contenttypes/behaviors/configure.zcml:161 msgid "Strutture correlate" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:29 -msgid "Studente" +#: design/plone/contenttypes/browser/utils/templates/change_news_type.pt:74 +msgid "Substitute" msgstr "" -#: design/plone/contenttypes/browser/manage_content/templates/change_news_type.pt:43 -msgid "Substitute" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:70 +msgid "Sviluppo sostenibile" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:71 +msgid "Tassa sui servizi" msgstr "" #: design/plone/contenttypes/behaviors/configure.zcml:49 msgid "Tassonomia argomenti" msgstr "" +#: design/plone/contenttypes/behaviors/configure.zcml:67 +msgid "Tassonomia argomenti evento" +msgstr "" + #: design/plone/contenttypes/behaviors/configure.zcml:58 -msgid "Tassonomia argomenti per i Document" +msgid "Tassonomia argomenti news" msgstr "" -#: design/plone/contenttypes/vocabularies/dataset.py:39 -msgid "Tematiche internazionali" +#: design/plone/contenttypes/behaviors/configure.zcml:76 +msgid "Tassonomia argomenti per i Document" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:46 +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:72 msgid "Tempo libero" msgstr "" -#: design/plone/contenttypes/browser/manage_content/templates/change_news_type.pt:31 +#: design/plone/contenttypes/browser/utils/templates/change_news_type.pt:52 msgid "The News Type selected above will be substituted by the selected value" msgstr "" -#: design/plone/contenttypes/browser/manage_content/change_news_type.py:97 +#: design/plone/contenttypes/browser/utils/change_news_type.py:108 msgid "The News Types was changed with success" msgstr "" -#: design/plone/contenttypes/browser/manage_content/change_news_type.py:55 +#: design/plone/contenttypes/browser/utils/change_news_type.py:64 msgid "The new News Type was not found between available values" msgstr "" -#: design/plone/contenttypes/browser/manage_content/change_news_type.py:49 +#: design/plone/contenttypes/browser/utils/change_news_type.py:58 msgid "The new type field was not populated" msgstr "" -#: design/plone/contenttypes/browser/manage_content/change_news_type.py:61 +#: design/plone/contenttypes/browser/utils/change_news_type.py:70 msgid "The old News Type was not found between available values" msgstr "" -#: design/plone/contenttypes/browser/manage_content/change_news_type.py:43 +#: design/plone/contenttypes/browser/utils/change_news_type.py:52 msgid "The old type field was not populated" msgstr "" -#: design/plone/contenttypes/browser/manage_content/move_news_items.py:51 +#: design/plone/contenttypes/browser/utils/move_news_items.py:52 msgid "The path was not indicated" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:51 -msgid "Traffico urbano" -msgstr "" - -#: design/plone/contenttypes/behaviors/configure.zcml:261 +#: design/plone/contenttypes/behaviors/configure.zcml:306 msgid "Trasparenza" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:43 -msgid "Trasporto" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:73 +msgid "Trasparenza amministrativa" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:59 -msgid "Trasporto stradale" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:74 +msgid "Trasporto pubblico" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:243 +#: design/plone/contenttypes/behaviors/configure.zcml:288 msgid "Tre campi file aggiuntivi." msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:60 +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:75 msgid "Turismo" msgstr "" -#: design/plone/contenttypes/interfaces/bando.py:117 -#: design/plone/contenttypes/interfaces/documento.py:50 -#: design/plone/contenttypes/interfaces/servizio.py:225 +#: design/plone/contenttypes/interfaces/bando.py:118 +#: design/plone/contenttypes/interfaces/documento.py:80 msgid "Ufficio responsabile" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:134 +#: design/plone/contenttypes/behaviors/configure.zcml:171 msgid "Ulteriori campi aiuto testuali" msgstr "" @@ -852,7 +823,11 @@ msgstr "" msgid "Un modulo compilabile." msgstr "" -#: design/plone/contenttypes/configure.zcml:45 +#: design/plone/contenttypes/browser/utils/templates/utils.pt:15 +msgid "Una raccolta di utility per i contenuti agid" +msgstr "" + +#: design/plone/contenttypes/configure.zcml:50 msgid "Uninstalls the design.plone.contenttypes add-on." msgstr "" @@ -864,65 +839,87 @@ msgstr "" msgid "Unità amministrative responsabili" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:270 -msgid "Update note" +#: design/plone/contenttypes/interfaces/incarico.py:71 +msgid "Unità organizzativa" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:37 -msgid "Urbanistica ed edilizia" +#: design/plone/contenttypes/interfaces/servizio.py:314 +msgid "Unità organizzativa responsabile" +msgstr "" + +#: design/plone/contenttypes/behaviors/configure.zcml:315 +msgid "Update note" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:77 -msgid "Vendita impresa" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:76 +msgid "Urbanizzazione" msgstr "" #: design/plone/contenttypes/controlpanels/geolocation_defaults.py:13 msgid "Via" msgstr "" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:77 +msgid "Viaggi" +msgstr "" + #: design/plone/contenttypes/profiles/default/types/CartellaModulistica.xml #: design/plone/contenttypes/profiles/default/types/Dataset.xml #: design/plone/contenttypes/profiles/default/types/Documento.xml msgid "View" msgstr "" -#. Default: "A chi si rivolge questo servizio e chi può usufruirne." -#: design/plone/contenttypes/interfaces/servizio.py:53 +#: design/plone/contenttypes/browser/utils/templates/utils.pt:13 +msgid "Viste di utility per Design Plone Contenttypes" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:79 +msgid "ZTL" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:78 +msgid "Zone pedonali" +msgstr "" + +#. Default: "Descrizione testuale dei principali destinatari dell'Evento" +#: design/plone/contenttypes/behaviors/evento.py:43 +#: design/plone/contenttypes/interfaces/servizio.py:98 msgid "a_chi_si_rivolge_help" msgstr "" -#. Default: "A chi si rivolge" -#: design/plone/contenttypes/interfaces/servizio.py:51 +#. Default: "A chi è rivolto" +#: design/plone/contenttypes/behaviors/evento.py:41 +#: design/plone/contenttypes/interfaces/servizio.py:96 msgid "a_chi_si_rivolge_label" msgstr "" #. Default: "Seleziona l'ufficio di comunicazione responsabile di questa notizia/comunicato stampa." -#: design/plone/contenttypes/behaviors/news_additional_fields.py:47 +#: design/plone/contenttypes/behaviors/news_additional_fields.py:39 msgid "a_cura_di_help" msgstr "" #. Default: "A cura di" -#: design/plone/contenttypes/behaviors/news_additional_fields.py:46 +#: design/plone/contenttypes/behaviors/news_additional_fields.py:38 msgid "a_cura_di_label" msgstr "" #. Default: "Seleziona una lista di persone dell'amministrazione citate in questa notizia/comunicato stampa. Questa informazione verrà mostrata nella sezione \"A cura di\"." -#: design/plone/contenttypes/behaviors/news_additional_fields.py:59 +#: design/plone/contenttypes/behaviors/news_additional_fields.py:51 msgid "a_cura_di_persone_help" msgstr "" #. Default: "Persone" -#: design/plone/contenttypes/behaviors/news_additional_fields.py:58 +#: design/plone/contenttypes/behaviors/news_additional_fields.py:50 msgid "a_cura_di_persone_label" msgstr "" #. Default: "Accedere al servizio" -#: design/plone/contenttypes/interfaces/servizio.py:370 +#: design/plone/contenttypes/interfaces/servizio.py:481 msgid "accedi_al_servizio_label" msgstr "" #. Default: "Modalità di accesso" -#: design/plone/contenttypes/behaviors/luogo.py:171 +#: design/plone/contenttypes/behaviors/luogo.py:140 msgid "accesso_label" msgstr "" @@ -932,37 +929,37 @@ msgid "allegato" msgstr "" #. Default: "Indicare, se esistono, altre modalità di invio." -#: design/plone/contenttypes/behaviors/trasparenza.py:189 +#: design/plone/contenttypes/behaviors/trasparenza.py:190 msgid "altre_modalita_invio_help" msgstr "" #. Default: "Altre modalità di invio" -#: design/plone/contenttypes/behaviors/trasparenza.py:185 +#: design/plone/contenttypes/behaviors/trasparenza.py:186 msgid "altre_modalita_invio_label" msgstr "" #. Default: "Seleziona la lista dei documenti di supporto collegati a questo servizio." -#: design/plone/contenttypes/interfaces/servizio.py:246 +#: design/plone/contenttypes/interfaces/servizio.py:335 msgid "altri_documenti_help" msgstr "" #. Default: "Date and time of the opening of the announcement. Use this field if you want to set a specific opening date. If not set, the announcement will be open immediately." -#: design/plone/contenttypes/interfaces/bando.py:56 +#: design/plone/contenttypes/interfaces/bando.py:57 msgid "apertura_bando_help" msgstr "" #. Default: "Opening date" -#: design/plone/contenttypes/interfaces/bando.py:55 +#: design/plone/contenttypes/interfaces/bando.py:56 msgid "apertura_bando_label" msgstr "" #. Default: "Area" -#: design/plone/contenttypes/interfaces/servizio.py:231 +#: design/plone/contenttypes/interfaces/servizio.py:320 msgid "area" msgstr "" #. Default: "Seleziona l'area da cui dipende questo servizio." -#: design/plone/contenttypes/interfaces/servizio.py:234 +#: design/plone/contenttypes/interfaces/servizio.py:323 msgid "area_help" msgstr "" @@ -972,14 +969,14 @@ msgid "area_responsabile_documento_personale" msgstr "" #. Default: "Seleziona l'area amministrativa responsabile del documento." -#: design/plone/contenttypes/interfaces/bando.py:127 -#: design/plone/contenttypes/interfaces/documento.py:60 +#: design/plone/contenttypes/interfaces/bando.py:128 +#: design/plone/contenttypes/interfaces/documento.py:90 msgid "area_responsabile_help" msgstr "" #. Default: "Area responsabile del documento" -#: design/plone/contenttypes/interfaces/bando.py:123 -#: design/plone/contenttypes/interfaces/documento.py:56 +#: design/plone/contenttypes/interfaces/bando.py:124 +#: design/plone/contenttypes/interfaces/documento.py:86 msgid "area_responsabile_label" msgstr "" @@ -989,47 +986,42 @@ msgid "argomenti_utenti" msgstr "" #. Default: "Inserire l'assessore di riferimento della struttura, se esiste." -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:76 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:68 msgid "assessore_riferimento_help" msgstr "" +#. Default: "Assessore di riferimento" +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:61 +msgid "assessore_riferimento_title" +msgstr "" + #. Default: "Indicare, se la esistono, atti e documenti a corredo dell'istanza." -#: design/plone/contenttypes/behaviors/trasparenza.py:200 +#: design/plone/contenttypes/behaviors/trasparenza.py:201 msgid "atti_documenti_corredo_help" msgstr "" #. Default: "Atti e documenti a corredo dell'istanza" -#: design/plone/contenttypes/behaviors/trasparenza.py:196 +#: design/plone/contenttypes/behaviors/trasparenza.py:197 msgid "atti_documenti_corredo_label" msgstr "" -#. Default: "Inserire un file contenente l'atto di nomina della persona." -#: design/plone/contenttypes/interfaces/persona.py:160 -msgid "atto_nomina_help" +#. Default: "Inserire riferimento all'atto di nomina della persona" +#: design/plone/contenttypes/interfaces/incarico.py:114 +msgid "atto_nomina_incarico_help" msgstr "" #. Default: "Atto di nomina" -#: design/plone/contenttypes/interfaces/persona.py:158 -msgid "atto_nomina_label" -msgstr "" - -#. Default: "Autenticazione" -#: design/plone/contenttypes/interfaces/servizio.py:121 -msgid "autenticazione" -msgstr "" - -#. Default: "Indicare, se previste, le modalità di autenticazione necessarie per poter accedere al servizio." -#: design/plone/contenttypes/interfaces/servizio.py:122 -msgid "autenticazione_help" +#: design/plone/contenttypes/interfaces/incarico.py:110 +msgid "atto_nomina_incarico_label" msgstr "" #. Default: "Seleziona una lista di autori che hanno pubblicato il documento. Possono essere Persone o Unità Organizzative." -#: design/plone/contenttypes/interfaces/documento.py:76 +#: design/plone/contenttypes/interfaces/documento.py:106 msgid "autori_help" msgstr "" #. Default: "Autore/i" -#: design/plone/contenttypes/interfaces/documento.py:72 +#: design/plone/contenttypes/interfaces/documento.py:102 msgid "autori_label" msgstr "" @@ -1049,52 +1041,72 @@ msgid "azioni_utente" msgstr "" #. Default: "Solo per persona politica: testo descrittivo che riporta la biografia della persona." -#: design/plone/contenttypes/interfaces/persona.py:107 +#: design/plone/contenttypes/interfaces/persona.py:94 msgid "biografia_help" msgstr "" #. Default: "Biografia" -#: design/plone/contenttypes/interfaces/persona.py:106 +#: design/plone/contenttypes/interfaces/persona.py:93 msgid "biografia_label" msgstr "" #. Default: "Canale digitale" -#: design/plone/contenttypes/interfaces/servizio.py:111 +#: design/plone/contenttypes/interfaces/servizio.py:156 msgid "canale_digitale" msgstr "" -#. Default: "Collegamento con l'eventuale canale digitale di attivazione del servizio." -#: design/plone/contenttypes/interfaces/servizio.py:112 +#. Default: "Testo di introduzione del canale digitale" +#: design/plone/contenttypes/interfaces/servizio.py:157 msgid "canale_digitale_help" msgstr "" +#. Default: "Link al canale digitale" +#: design/plone/contenttypes/interfaces/servizio.py:165 +msgid "canale_digitale_link" +msgstr "" + +#. Default: "Collegamento con l'eventuale canale digitale di attivazione del servizio." +#: design/plone/contenttypes/interfaces/servizio.py:166 +msgid "canale_digitale_link_help" +msgstr "" + #. Default: "Canale digitale servizio collegato" #: design/plone/contenttypes/interfaces/documento_personale.py:108 msgid "canale_digitale_servizio" msgstr "" +#. Default: "Canale fisico" +#: design/plone/contenttypes/interfaces/servizio.py:175 +msgid "canale_fisico" +msgstr "" + +#. Default: "Unità organizzative per la fruizione del servizio" +#: design/plone/contenttypes/interfaces/servizio.py:176 +msgid "canale_fisico_help" +msgstr "" + #. Default: "Casi particolari" -#: design/plone/contenttypes/interfaces/servizio.py:205 +#: design/plone/contenttypes/interfaces/servizio.py:291 msgid "casi_particolari" msgstr "" #. Default: "Descrizione degli evetuali casi particolari riferiti alla fruibilità di questo servizio." -#: design/plone/contenttypes/interfaces/servizio.py:207 +#: design/plone/contenttypes/interfaces/servizio.py:293 msgid "casi_particolari_help" msgstr "" #. Default: "Casi particolari" -#: design/plone/contenttypes/interfaces/servizio.py:401 +#: design/plone/contenttypes/interfaces/servizio.py:514 msgid "casi_particolari_label" msgstr "" #. Default: "Descrizione di chi può presentare domanda per usufruire del servizio e delle diverse casistiche." -#: design/plone/contenttypes/interfaces/servizio.py:62 +#: design/plone/contenttypes/interfaces/servizio.py:107 msgid "chi_puo_presentare_help" msgstr "" #. Default: "Chi può presentare" -#: design/plone/contenttypes/interfaces/servizio.py:60 +#: design/plone/contenttypes/interfaces/servizio.py:105 msgid "chi_puo_presentare_label" msgstr "" @@ -1104,37 +1116,57 @@ msgid "circoscrizione" msgstr "" #. Default: "Codice dell'ente erogatore (ipa)" -#: design/plone/contenttypes/interfaces/servizio.py:268 +#: design/plone/contenttypes/interfaces/servizio.py:357 msgid "codice_ipa" msgstr "" #. Default: "Specificare il nome dell’organizzazione, come indicato nell’Indice della Pubblica Amministrazione (IPA), che esercita uno specifico ruolo sul Servizio." -#: design/plone/contenttypes/interfaces/servizio.py:270 +#: design/plone/contenttypes/interfaces/servizio.py:359 msgid "codice_ipa_help" msgstr "" -#. Default: "Come si fa" -#: design/plone/contenttypes/interfaces/servizio.py:80 +#. Default: "Come fare" +#: design/plone/contenttypes/interfaces/servizio.py:125 msgid "come_si_fa" msgstr "" #. Default: "Descrizione della procedura da seguire per poter usufruire del servizio." -#: design/plone/contenttypes/interfaces/servizio.py:82 +#: design/plone/contenttypes/interfaces/servizio.py:127 msgid "come_si_fa_help" msgstr "" +#. Default: "Solo per incarico politico: compensi di qualsiasi natura connessi all'assunzione della carica." +#: design/plone/contenttypes/interfaces/incarico.py:21 +msgid "compensi_incarico_help" +msgstr "" + +#. Default: "Compensi" +#: design/plone/contenttypes/interfaces/incarico.py:17 +msgid "compensi_incarico_label" +msgstr "" + #. Default: "Descrizione del ruolo e dei compiti della persona." -#: design/plone/contenttypes/interfaces/persona.py:69 +#: design/plone/contenttypes/interfaces/persona.py:77 msgid "competenze_help" msgstr "" #. Default: "Competenze" -#: design/plone/contenttypes/interfaces/persona.py:68 +#: design/plone/contenttypes/interfaces/persona.py:76 msgid "competenze_label" msgstr "" -#. Default: "Informazioni di contatto generiche" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:137 +#. Default: "Condizioni di servizio" +#: design/plone/contenttypes/interfaces/servizio.py:388 +msgid "condizioni_di_servizio" +msgstr "" + +#. Default: "Contatti dell'unità organizzativa." +#: design/plone/contenttypes/behaviors/contatti.py:27 +msgid "contact_info_help" +msgstr "" + +#. Default: "Punti di contatto dell'unità organizzativa" +#: design/plone/contenttypes/behaviors/contatti.py:23 msgid "contact_info_label" msgstr "" @@ -1144,9 +1176,9 @@ msgid "contatti" msgstr "" #. Default: "Contatti" -#: design/plone/contenttypes/behaviors/address.py:52 -#: design/plone/contenttypes/behaviors/contatti.py:76 -#: design/plone/contenttypes/behaviors/evento.py:215 +#: design/plone/contenttypes/behaviors/contatti.py:57 +#: design/plone/contenttypes/behaviors/evento.py:170 +#: design/plone/contenttypes/behaviors/geolocation.py:18 msgid "contatti_label" msgstr "" @@ -1156,116 +1188,111 @@ msgid "contenuto" msgstr "" #. Default: "Indicare se il servizio si riferisce ad una particolare area geografica o all'intero territorio di riferimento." -#: design/plone/contenttypes/interfaces/servizio.py:72 +#: design/plone/contenttypes/interfaces/servizio.py:117 msgid "copertura_geografica_help" msgstr "" #. Default: "Copertura geografica" -#: design/plone/contenttypes/interfaces/servizio.py:70 +#: design/plone/contenttypes/interfaces/servizio.py:115 msgid "copertura_geografica_label" msgstr "" #. Default: "Contenuti collegati" -#: design/plone/contenttypes/behaviors/argomenti.py:74 +#: design/plone/contenttypes/behaviors/argomenti.py:108 #: design/plone/contenttypes/behaviors/dataset_correlati.py:40 -#: design/plone/contenttypes/behaviors/servizi_correlati.py:43 +#: design/plone/contenttypes/behaviors/news_additional_fields.py:120 msgid "correlati_label" msgstr "" #. Default: "Seleziona un correlato da mettere in evidenza per questo contenuto." -#: design/plone/contenttypes/behaviors/argomenti.py:36 +#: design/plone/contenttypes/behaviors/argomenti.py:40 msgid "correlato_in_evidenza_help" msgstr "" #. Default: "Correlato in evidenza" -#: design/plone/contenttypes/behaviors/argomenti.py:35 +#: design/plone/contenttypes/behaviors/argomenti.py:39 msgid "correlato_in_evidenza_label" msgstr "" -#. Default: "Cosa fa" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:206 +#. Default: "Competenze" +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:201 msgid "cosa_fa_label" msgstr "" #. Default: "Cosa serve" -#: design/plone/contenttypes/interfaces/servizio.py:177 +#: design/plone/contenttypes/interfaces/servizio.py:263 msgid "cosa_serve" msgstr "" #. Default: "Descrizione delle istruzioni per usufruire del servizio." -#: design/plone/contenttypes/interfaces/servizio.py:179 +#: design/plone/contenttypes/interfaces/servizio.py:265 msgid "cosa_serve_help" msgstr "" #. Default: "Cosa serve" -#: design/plone/contenttypes/interfaces/servizio.py:384 +#: design/plone/contenttypes/interfaces/servizio.py:497 msgid "cosa_serve_label" msgstr "" #. Default: "Cosa si ottiene" -#: design/plone/contenttypes/interfaces/servizio.py:90 +#: design/plone/contenttypes/interfaces/servizio.py:135 msgid "cosa_si_ottiene" msgstr "" #. Default: "Indicare cosa si può ottenere dal servizio, ad esempio 'carta di identità elettronica', 'certificato di residenza'." -#: design/plone/contenttypes/interfaces/servizio.py:91 +#: design/plone/contenttypes/interfaces/servizio.py:136 msgid "cosa_si_ottiene_help" msgstr "" #. Default: "Cos'è" -#: design/plone/contenttypes/behaviors/descrizione_estesa.py:40 -#: design/plone/contenttypes/behaviors/evento.py:200 +#: design/plone/contenttypes/behaviors/descrizione_estesa.py:52 +#: design/plone/contenttypes/behaviors/evento.py:155 msgid "cose_label" msgstr "" #. Default: "Costi" -#: design/plone/contenttypes/interfaces/servizio.py:186 +#: design/plone/contenttypes/interfaces/servizio.py:272 msgid "costi" msgstr "" #. Default: "Costi e vincoli" -#: design/plone/contenttypes/interfaces/servizio.py:389 +#: design/plone/contenttypes/interfaces/servizio.py:502 msgid "costi_e_vincoli_label" msgstr "" #. Default: "Descrizione delle condizioni e dei termini economici per completare la procedura di richiesta del servizio." -#: design/plone/contenttypes/interfaces/servizio.py:188 +#: design/plone/contenttypes/interfaces/servizio.py:274 msgid "costi_help" msgstr "" #. Default: "Costi" -#: design/plone/contenttypes/behaviors/evento.py:212 +#: design/plone/contenttypes/behaviors/evento.py:167 msgid "costi_label" msgstr "" #. Default: "Allega un file contenente il curriculum vitae della persona. Se ha più file da allegare, utilizza questo campo per quello principale e gli altri mettili dentro alla cartella \"Curriculum vitae\" che troverai dentro alla Persona." -#: design/plone/contenttypes/interfaces/persona.py:149 +#: design/plone/contenttypes/interfaces/persona.py:105 msgid "curriculum_vitae_help" msgstr "" #. Default: "Curriculum vitae" -#: design/plone/contenttypes/interfaces/persona.py:147 +#: design/plone/contenttypes/interfaces/persona.py:103 msgid "curriculum_vitae_label" msgstr "" #. Default: "Risultati indagini di customer satisfaction." -#: design/plone/contenttypes/behaviors/trasparenza.py:254 +#: design/plone/contenttypes/behaviors/trasparenza.py:255 msgid "customer_satisfaction_help" msgstr "" #. Default: "Risultati indagini di customer satisfaction" -#: design/plone/contenttypes/behaviors/trasparenza.py:249 +#: design/plone/contenttypes/behaviors/trasparenza.py:250 msgid "customer_satisfaction_label" msgstr "" -#. Default: "Data di conclusione dell'incarico." -#: design/plone/contenttypes/interfaces/persona.py:60 -msgid "data_conclusione_incarico_help" -msgstr "" - #. Default: "Data conclusione incarico" -#: design/plone/contenttypes/interfaces/persona.py:56 -msgid "data_conclusione_incarico_label" +#: design/plone/contenttypes/interfaces/incarico.py:100 +msgid "data_conclusione_incarico" msgstr "" #. Default: "Data e fasi intermedie" @@ -1278,14 +1305,14 @@ msgstr "" msgid "data_inizio" msgstr "" -#. Default: "Solo per persona politica: specificare la data di insediamento." -#: design/plone/contenttypes/interfaces/persona.py:97 -msgid "data_insediamento_help" +#. Default: "Data inizio incarico" +#: design/plone/contenttypes/interfaces/incarico.py:95 +msgid "data_inizio_incarico" msgstr "" #. Default: "Data insediamento" -#: design/plone/contenttypes/interfaces/persona.py:96 -msgid "data_insediamento_label" +#: design/plone/contenttypes/interfaces/incarico.py:105 +msgid "data_insediamento" msgstr "" #. Default: "Data del messaggio" @@ -1299,296 +1326,272 @@ msgid "data_pagamento" msgstr "" #. Default: "Data del protocollo" +#: design/plone/contenttypes/interfaces/documento.py:41 #: design/plone/contenttypes/interfaces/documento_personale.py:19 msgid "data_protocollo" msgstr "" +#. Default: "Data scadenza" +#: design/plone/contenttypes/interfaces/servizio.py:49 +msgid "data_scadenza_label" +msgstr "" + #. Default: "Data di scadenza della procedura" #: design/plone/contenttypes/interfaces/messaggio.py:40 msgid "data_scadenza_procedura" msgstr "" #. Default: "Dataset" -#: design/plone/contenttypes/interfaces/dataset.py:27 +#: design/plone/contenttypes/interfaces/dataset.py:20 msgid "dataset" msgstr "" +#. Default: "Schede dataset collegate al documento" +#: design/plone/contenttypes/interfaces/documento.py:150 +msgid "dataset_collegati_help" +msgstr "" + #. Default: "Seleziona una lista di schede dataset collegate a questo contenuto." -#: design/plone/contenttypes/behaviors/dataset_correlati.py:19 +#: design/plone/contenttypes/behaviors/dataset_correlati.py:20 msgid "dataset_correlati_help" msgstr "" #. Default: "Dataset correlati" -#: design/plone/contenttypes/behaviors/dataset_correlati.py:18 +#: design/plone/contenttypes/behaviors/dataset_correlati.py:19 msgid "dataset_correlati_label" msgstr "" +#. Default: "Dataset collegati" +#: design/plone/contenttypes/interfaces/documento.py:146 +msgid "dataset_label" +msgstr "" + +#. Default: "Date e informazioni" +#: design/plone/contenttypes/interfaces/incarico.py:175 +msgid "date_e_informazioni_label" +msgstr "" + #. Default: "Date e orari" -#: design/plone/contenttypes/behaviors/evento.py:209 -#: design/plone/contenttypes/schema_overrides.py:34 +#: design/plone/contenttypes/behaviors/evento.py:164 +#: design/plone/contenttypes/schema_overrides.py:33 msgid "date_e_orari_label" msgstr "" #. Default: "Inserisci la decorrenza termine del procedimento." -#: design/plone/contenttypes/behaviors/trasparenza.py:69 +#: design/plone/contenttypes/behaviors/trasparenza.py:70 msgid "decorrenza_termini_help" msgstr "" #. Default: "Decorrenza termine del procedimento" -#: design/plone/contenttypes/behaviors/trasparenza.py:64 +#: design/plone/contenttypes/behaviors/trasparenza.py:65 msgid "decorrenza_termini_label" msgstr "" #. Default: "Elenco delle deleghe a capo della persona." -#: design/plone/contenttypes/interfaces/persona.py:77 +#: design/plone/contenttypes/interfaces/persona.py:85 msgid "deleghe_help" msgstr "" #. Default: "Deleghe" -#: design/plone/contenttypes/interfaces/persona.py:76 +#: design/plone/contenttypes/interfaces/persona.py:84 msgid "deleghe_label" msgstr "" #. Default: "Descrizione completa" -#: design/plone/contenttypes/behaviors/luogo.py:23 +#: design/plone/contenttypes/behaviors/luogo.py:24 msgid "descrizione_completa" msgstr "" -#. Default: "Descrizione destinatari" -#: design/plone/contenttypes/behaviors/evento.py:38 -msgid "descrizione_destinatari" -msgstr "" - -#. Default: "Descrizione dei principali interlocutori dell'evento." -#: design/plone/contenttypes/behaviors/evento.py:40 -msgid "descrizione_destinatari_help" -msgstr "" - #. Default: "Descrizione estesa" -#: design/plone/contenttypes/behaviors/descrizione_estesa.py:16 -#: design/plone/contenttypes/behaviors/evento.py:30 -#: design/plone/contenttypes/behaviors/news_additional_fields.py:19 +#: design/plone/contenttypes/behaviors/descrizione_estesa.py:17 +#: design/plone/contenttypes/behaviors/evento.py:32 +#: design/plone/contenttypes/behaviors/news_additional_fields.py:21 msgid "descrizione_estesa" msgstr "" #. Default: "Descrizione dettagliata e completa." -#: design/plone/contenttypes/behaviors/descrizione_estesa.py:18 -#: design/plone/contenttypes/behaviors/evento.py:32 -#: design/plone/contenttypes/behaviors/news_additional_fields.py:21 +#: design/plone/contenttypes/behaviors/descrizione_estesa.py:19 +#: design/plone/contenttypes/behaviors/evento.py:34 +#: design/plone/contenttypes/behaviors/news_additional_fields.py:23 msgid "descrizione_estesa_help" msgstr "" #. Default: "Descrizione" -#: design/plone/contenttypes/behaviors/descrizione_estesa.py:51 -#: design/plone/contenttypes/behaviors/luogo.py:166 -#: design/plone/contenttypes/interfaces/documento.py:162 +#: design/plone/contenttypes/behaviors/descrizione_estesa.py:72 +#: design/plone/contenttypes/behaviors/luogo.py:135 +#: design/plone/contenttypes/interfaces/documento.py:242 msgid "descrizione_label" msgstr "" #. Default: "Inserisci eventuale testo descrittivo del procedimento." -#: design/plone/contenttypes/behaviors/trasparenza.py:37 +#: design/plone/contenttypes/behaviors/trasparenza.py:38 msgid "descrizione_procedimento_help" msgstr "" #. Default: "Descrizione del procedimento" -#: design/plone/contenttypes/behaviors/trasparenza.py:32 +#: design/plone/contenttypes/behaviors/trasparenza.py:33 msgid "descrizione_procedimento_label" msgstr "" #. Default: "Dirigente" -#: design/plone/contenttypes/behaviors/trasparenza.py:136 +#: design/plone/contenttypes/behaviors/trasparenza.py:137 msgid "dirigente" msgstr "" #. Default: "Indicare il dirigente." -#: design/plone/contenttypes/behaviors/trasparenza.py:140 +#: design/plone/contenttypes/behaviors/trasparenza.py:141 msgid "dirigente_help" msgstr "" #. Default: "Distribuzione" -#: design/plone/contenttypes/interfaces/dataset.py:22 +#: design/plone/contenttypes/interfaces/dataset.py:15 msgid "distribuzione" msgstr "" #. Default: "Documenti allegati" -#: design/plone/contenttypes/interfaces/messaggio.py:56 +#: design/plone/contenttypes/interfaces/messaggio.py:48 msgid "documenti_allegati" msgstr "" #. Default: "Seleziona una serie di altri contenuti di tipo Documento che vanno allegati a questo." -#: design/plone/contenttypes/interfaces/documento.py:113 +#: design/plone/contenttypes/interfaces/documento.py:194 msgid "documenti_allegati_help" msgstr "" #. Default: "Documenti allegati" -#: design/plone/contenttypes/interfaces/documento.py:109 +#: design/plone/contenttypes/interfaces/documento.py:190 msgid "documenti_allegati_label" msgstr "" #. Default: "Documenti" -#: design/plone/contenttypes/interfaces/persona.py:199 -#: design/plone/contenttypes/interfaces/servizio.py:412 +#: design/plone/contenttypes/interfaces/persona.py:146 +#: design/plone/contenttypes/interfaces/servizio.py:525 msgid "documenti_label" msgstr "" +#. Default: "Documenti pubblici importanti, collegati a questa Unità Organizzativa" +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:129 +msgid "documenti_pubblici_help" +msgstr "" + +#. Default: "Documenti pubblici" +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:127 +msgid "documenti_pubblici_label" +msgstr "" + #. Default: "Dove" -#: design/plone/contenttypes/behaviors/address.py:71 -#: design/plone/contenttypes/behaviors/geolocation.py:29 +#: design/plone/contenttypes/behaviors/address.py:53 +#: design/plone/contenttypes/behaviors/geolocation.py:26 msgid "dove_label" msgstr "" #. Default: "Dove rivolgersi: informazioni aggiuntive" -#: design/plone/contenttypes/interfaces/servizio.py:143 +#: design/plone/contenttypes/interfaces/servizio.py:212 msgid "dove_rivolgersi_extra" msgstr "" #. Default: "Indicare eventuali informazioni aggiuntive riguardo al dove rivolgersi per questo servizio." -#: design/plone/contenttypes/interfaces/servizio.py:147 +#: design/plone/contenttypes/interfaces/servizio.py:216 msgid "dove_rivolgersi_extra_help" msgstr "" #. Default: "Seleziona una lista delle sedi e dei luoghi in cui è presente questo servizio." -#: design/plone/contenttypes/interfaces/servizio.py:135 +#: design/plone/contenttypes/interfaces/servizio.py:204 msgid "dove_rivolgersi_help" msgstr "" #. Default: "Elementi di interesse" -#: design/plone/contenttypes/behaviors/luogo.py:44 +#: design/plone/contenttypes/behaviors/luogo.py:45 msgid "elementi_di_interesse" msgstr "" -#. Default: "Indicare un indirizzo mail per poter contattare gli organizzatori." -#: design/plone/contenttypes/behaviors/evento.py:128 -msgid "email_event_help" -msgstr "" - -#. Default: "E-mail" -#: design/plone/contenttypes/behaviors/evento.py:127 -msgid "email_event_label" -msgstr "" - -#. Default: "Indicare un indirizzo mail per poter contattare i referenti." -#: design/plone/contenttypes/behaviors/contatti.py:35 -msgid "email_help" -msgstr "" - -#. Default: "E-mail" -#: design/plone/contenttypes/behaviors/contatti.py:34 -msgid "email_label" -msgstr "" - -#. Default: "Contatto mail della persona. E' possibile inserire più di un indirizzo. Premendo \"Invio\" o \"tab\" si può passare al successivo da inserire." -#: design/plone/contenttypes/interfaces/persona.py:135 -msgid "email_persona_help" -msgstr "" - -#. Default: "Indirizzo email" -#: design/plone/contenttypes/interfaces/persona.py:134 -msgid "email_persona_label" -msgstr "" - #. Default: "Esito" #: design/plone/contenttypes/interfaces/ricevuta_pagamento.py:51 msgid "esito" msgstr "" -#. Default: "Fax" -#: design/plone/contenttypes/behaviors/evento.py:113 -msgid "fax_event_help" -msgstr "" - -#. Default: "Indicare un numero di fax." -#: design/plone/contenttypes/behaviors/evento.py:114 -msgid "fax_event_label" -msgstr "" - -#. Default: "Indicare un numero di fax." -#: design/plone/contenttypes/behaviors/contatti.py:29 -msgid "fax_help" -msgstr "" - -#. Default: "Fax" -#: design/plone/contenttypes/behaviors/contatti.py:28 -msgid "fax_label" -msgstr "" - -#. Default: "Indicare un numero di fax." -#: design/plone/contenttypes/interfaces/persona.py:130 -msgid "fax_persona_help" -msgstr "" - -#. Default: "Fax" -#: design/plone/contenttypes/interfaces/persona.py:129 -msgid "fax_persona_label" +#. Default: "Escludi dalla ricerca" +#: design/plone/contenttypes/behaviors/exclude_from_search.py:17 +msgid "exclude_from_search_label" msgstr "" #. Default: "Inserisci il file correlato di questo pocedimento." -#: design/plone/contenttypes/behaviors/trasparenza.py:44 +#: design/plone/contenttypes/behaviors/trasparenza.py:45 msgid "file_correlato_help" msgstr "" #. Default: "File correlato" -#: design/plone/contenttypes/behaviors/trasparenza.py:43 +#: design/plone/contenttypes/behaviors/trasparenza.py:44 msgid "file_correlato_label" msgstr "" #. Default: "Inserisci il file principale di questo contenuto." -#: design/plone/contenttypes/behaviors/multi_file.py:16 +#: design/plone/contenttypes/behaviors/multi_file.py:17 msgid "file_principale_help" msgstr "" #. Default: "File principale" -#: design/plone/contenttypes/behaviors/multi_file.py:15 +#: design/plone/contenttypes/behaviors/multi_file.py:16 msgid "file_principale_label" msgstr "" #. Default: "Inserisci la fine termine del procedimento." -#: design/plone/contenttypes/behaviors/trasparenza.py:80 +#: design/plone/contenttypes/behaviors/trasparenza.py:81 msgid "fine_termine_help" msgstr "" #. Default: "Fine termine del procedimento" -#: design/plone/contenttypes/behaviors/trasparenza.py:75 +#: design/plone/contenttypes/behaviors/trasparenza.py:76 msgid "fine_termine_label" msgstr "" +#. Default: "Lista dei formati in cui è disponibile il documento" +#: design/plone/contenttypes/interfaces/documento.py:117 +msgid "formati_disponibili_help" +msgstr "" + +#. Default: "Formati disponibili" +#: design/plone/contenttypes/interfaces/documento.py:116 +msgid "formati_disponibili_label" +msgstr "" + #. Default: "Inserisci un eventuale formato alternativo del file principale." -#: design/plone/contenttypes/behaviors/multi_file.py:25 +#: design/plone/contenttypes/behaviors/multi_file.py:26 msgid "formato_alternativo_1_help" msgstr "" #. Default: "Formato alternativo 1" -#: design/plone/contenttypes/behaviors/multi_file.py:24 +#: design/plone/contenttypes/behaviors/multi_file.py:25 msgid "formato_alternativo_1_label" msgstr "" #. Default: "Inserisci un eventuale formato alternativo del file principale." -#: design/plone/contenttypes/behaviors/multi_file.py:35 +#: design/plone/contenttypes/behaviors/multi_file.py:36 msgid "formato_alternativo_2_help" msgstr "" #. Default: "Formato alternativo 2" -#: design/plone/contenttypes/behaviors/multi_file.py:34 +#: design/plone/contenttypes/behaviors/multi_file.py:35 msgid "formato_alternativo_2_label" msgstr "" -#. Default: "Foto da mostrare della persona. La dimensione suggerita è 180x100 px." -#: design/plone/contenttypes/interfaces/persona.py:21 +#. Default: "Foto da mostrare della persona. La dimensione suggerita è 100x180px." +#: design/plone/contenttypes/interfaces/persona.py:30 msgid "foto_persona_help" msgstr "" #. Default: "Foto della persona" -#: design/plone/contenttypes/interfaces/persona.py:19 +#: design/plone/contenttypes/interfaces/persona.py:28 msgid "foto_persona_label" msgstr "" #. Default: "Frequenza di aggiornamento" -#: design/plone/contenttypes/interfaces/dataset.py:32 +#: design/plone/contenttypes/interfaces/dataset.py:25 msgid "frequenza_aggiornamento" msgstr "" #. Default: "Invalid geolocation data: ${value}. Provide latitude and longitude coordinates." -#: design/plone/contenttypes/restapi/deserializers/dxfields.py:28 +#: design/plone/contenttypes/restapi/deserializers/dxfields.py:39 msgid "geolocation_field_validator_label" msgstr "" @@ -1598,22 +1601,27 @@ msgid "help_circoscrizione" msgstr "" #. Default: "Indicare una descrizione completa, inserendo tutte le informazioni rilevanti relative al luogo" -#: design/plone/contenttypes/behaviors/luogo.py:24 +#: design/plone/contenttypes/behaviors/luogo.py:25 msgid "help_descrizione_completa" msgstr "" #. Default: "Indicare eventuali elementi di interesse per il cittadino." -#: design/plone/contenttypes/behaviors/luogo.py:45 +#: design/plone/contenttypes/behaviors/luogo.py:46 msgid "help_elementi_di_interesse" msgstr "" +#. Default: "Se selezionato, questo contenuto non verrà mostrato nelle ricerche del sito per gli utenti anonimi." +#: design/plone/contenttypes/behaviors/exclude_from_search.py:18 +msgid "help_exclude_from_search" +msgstr "" + #. Default: "Indicare tutte le informazioni relative alla modalità di accesso al luogo" -#: design/plone/contenttypes/behaviors/luogo.py:54 +#: design/plone/contenttypes/behaviors/luogo.py:55 msgid "help_modalita_accesso" msgstr "" #. Default: "Indicare, se esiste, un nome alternativo per il luogo; questo sarà mostrato affianco al titolo della scheda" -#: design/plone/contenttypes/behaviors/luogo.py:34 +#: design/plone/contenttypes/behaviors/luogo.py:35 msgid "help_nome_alternativo" msgstr "" @@ -1627,28 +1635,8 @@ msgstr "" msgid "help_quartiere" msgstr "" -#. Default: "Indicare un numero di fax della struttura responsabile." -#: design/plone/contenttypes/behaviors/luogo.py:108 -msgid "help_riferimento_fax_struttura" -msgstr "" - -#. Default: "Indicare un indirizzo mail per poter contattare i referenti della struttura responsabile." -#: design/plone/contenttypes/behaviors/luogo.py:119 -msgid "help_riferimento_mail_struttura" -msgstr "" - -#. Default: "Indicare un indirizzo pec per poter contattare i referenti della struttura responsabile." -#: design/plone/contenttypes/behaviors/luogo.py:132 -msgid "help_riferimento_pec_struttura" -msgstr "" - -#. Default: "Indicare il riferimento telefonico per poter contattare i referenti della struttura responsabile." -#: design/plone/contenttypes/behaviors/luogo.py:96 -msgid "help_riferimento_telefonico_struttura" -msgstr "" - -#. Default: "Inserisci una nota per indicare che il contenuto corrente è stato aggiornato.Questo testo può essere visualizzato nei blocchi elenco con determinati layout per informare gli utenti che un determinato contenuto è stato aggiornato. Ad esempio se in un bando sono stati aggiunti dei documenti." -#: design/plone/contenttypes/behaviors/update_note.py:17 +#. Default: "Inserisci una nota per indicare che il contenuto corrente è stato aggiornato. Questo testo può essere visualizzato nei blocchi elenco con determinati layout per informare gli utenti che un determinato contenuto è stato aggiornato. Ad esempio se in un bando sono stati aggiunti dei documenti." +#: design/plone/contenttypes/behaviors/update_note.py:18 msgid "help_update_note" msgstr "" @@ -1663,7 +1651,7 @@ msgid "icona_help" msgstr "" #. Default: "Identificativo" -#: design/plone/contenttypes/interfaces/servizio.py:290 +#: design/plone/contenttypes/interfaces/servizio.py:379 msgid "identificativo" msgstr "" @@ -1678,12 +1666,22 @@ msgid "identificativo_documento_label" msgstr "" #. Default: "Eventuale codice identificativo del servizio." -#: design/plone/contenttypes/interfaces/servizio.py:292 +#: design/plone/contenttypes/interfaces/servizio.py:381 msgid "identificativo_help" msgstr "" +#. Default: "Identificativo" +#: design/plone/contenttypes/behaviors/luogo.py:119 +msgid "identificativo_mibac" +msgstr "" + +#. Default: "Codice identificativo del luogo. Nel MIBAC c'è il codice del DBUnico per i luoghi della cultura e il codice ISIL per le biblioteche. Non deve comparire nel frontend del sito." +#: design/plone/contenttypes/behaviors/luogo.py:121 +msgid "identificativo_mibac_help" +msgstr "" + #. Default: "La dimensione dell'immagine dovrebbe essere di ${size} px" -#: design/plone/contenttypes/restapi/types/adapters.py:31 +#: design/plone/contenttypes/restapi/types/adapters.py:43 msgid "image_size_help" msgstr "" @@ -1692,11 +1690,31 @@ msgstr "" msgid "immagine" msgstr "" +#. Default: "Solo per incarico politico: importi di viaggi di servizio e missioni pagati con fondi pubblici." +#: design/plone/contenttypes/interfaces/incarico.py:34 +msgid "importi_viaggio_servizio_incarico_help" +msgstr "" + +#. Default: "Importi di viaggio e/o servizio" +#: design/plone/contenttypes/interfaces/incarico.py:30 +msgid "importi_viaggio_servizio_incarico_label" +msgstr "" + #. Default: "Importo pagato" #: design/plone/contenttypes/interfaces/ricevuta_pagamento.py:25 msgid "importo_pagato" msgstr "" +#. Default: "Seleziona l'incarico corrente della persona." +#: design/plone/contenttypes/interfaces/persona.py:63 +msgid "incarichi_help" +msgstr "" + +#. Default: "Incarichi" +#: design/plone/contenttypes/interfaces/persona.py:59 +msgid "incarichi_label" +msgstr "" + #. Default: "Inserisci eventuale testo informativo che verrà mostrato in testata." #: design/plone/contenttypes/behaviors/info_testata.py:23 msgid "info_testata_help" @@ -1712,35 +1730,60 @@ msgstr "" msgid "informazioni" msgstr "" +#. Default: "Compensi e trasparenza" +#: design/plone/contenttypes/interfaces/incarico.py:170 +msgid "informazioni_compensi_label" +msgstr "" + #. Default: "Ulteriori informazioni" #: design/plone/contenttypes/behaviors/additional_help_infos.py:28 -#: design/plone/contenttypes/behaviors/evento.py:229 #: design/plone/contenttypes/behaviors/strutture_correlate.py:42 +#: design/plone/contenttypes/interfaces/documento.py:253 msgid "informazioni_label" msgstr "" +#. Default: "Intervallo della fase (es. 1)" +#: design/plone/contenttypes/interfaces/servizio.py:32 +msgid "interval_qt_help" +msgstr "" + +#. Default: "Intervallo" +#: design/plone/contenttypes/interfaces/servizio.py:31 +msgid "interval_qt_label" +msgstr "" + +#. Default: "Ad esempio: ore, giorni, settimane, mesi." +#: design/plone/contenttypes/interfaces/servizio.py:41 +msgid "interval_type_help" +msgstr "" + +#. Default: "Tipo intervallo" +#: design/plone/contenttypes/interfaces/servizio.py:40 +msgid "interval_type_label" +msgstr "" + #. Default: "Se un content-type deve avere una dimensione della leadimage particolare, indicarle qui. Inserire le dimensioni nella forma di esempio PortalType|900x900" -#: design/plone/contenttypes/controlpanels/settings.py:110 +#: design/plone/contenttypes/controlpanels/settings.py:52 msgid "lead_image_dimension_help" msgstr "" #. Default: "Dimensioni lead image" -#: design/plone/contenttypes/controlpanels/settings.py:106 +#: design/plone/contenttypes/controlpanels/settings.py:48 msgid "lead_image_dimension_label" msgstr "" -#. Default: "Servizi o uffici di riferimento" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:27 +#. Default: "Strutture o uffici di riferimento" +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:31 msgid "legami_altre_strutture_label" msgstr "" #. Default: "Selezionare la lista di strutture e/o uffici collegati a questa unità organizzativa." -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:31 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:35 msgid "legami_con_altre_strutture_help" msgstr "" #. Default: "Licenza" -#: design/plone/contenttypes/interfaces/dataset.py:25 +#: design/plone/contenttypes/interfaces/dataset.py:18 msgid "licenza" msgstr "" @@ -1750,27 +1793,27 @@ msgid "licenza_distribuzione" msgstr "" #. Default: "La licenza con il quale viene distribuito questo documento." -#: design/plone/contenttypes/interfaces/documento.py:88 +#: design/plone/contenttypes/interfaces/documento.py:125 msgid "licenza_distribuzione_help" msgstr "" #. Default: "Licenza di distribuzione" -#: design/plone/contenttypes/interfaces/documento.py:87 +#: design/plone/contenttypes/interfaces/documento.py:124 msgid "licenza_distribuzione_label" msgstr "" #. Default: "Link a siti esterni" -#: design/plone/contenttypes/interfaces/servizio.py:258 +#: design/plone/contenttypes/interfaces/servizio.py:347 msgid "link_siti_esterni" msgstr "" #. Default: "Eventuali collegamenti a pagine web, siti, servizi esterni all'ambito Comunale utili all'erogazione del servizio." -#: design/plone/contenttypes/interfaces/servizio.py:260 +#: design/plone/contenttypes/interfaces/servizio.py:349 msgid "link_siti_esterni_help" msgstr "" #. Default: "Link utili" -#: design/plone/contenttypes/interfaces/servizio.py:417 +#: design/plone/contenttypes/interfaces/servizio.py:530 msgid "link_utili_label" msgstr "" @@ -1780,36 +1823,46 @@ msgid "luoghi_correlati_event_help" msgstr "" #. Default: "Seleziona una lista di luoghi citati." -#: design/plone/contenttypes/behaviors/luoghi_correlati.py:18 -#: design/plone/contenttypes/behaviors/news_additional_fields.py:72 +#: design/plone/contenttypes/behaviors/luoghi_correlati.py:19 +#: design/plone/contenttypes/behaviors/news_additional_fields.py:64 msgid "luoghi_correlati_help" msgstr "" #. Default: "Luoghi correlati" -#: design/plone/contenttypes/behaviors/luoghi_correlati.py:17 -#: design/plone/contenttypes/behaviors/news_additional_fields.py:71 +#: design/plone/contenttypes/behaviors/luoghi_correlati.py:18 +#: design/plone/contenttypes/behaviors/news_additional_fields.py:63 msgid "luoghi_correlati_label" msgstr "" #. Default: "Luogo" -#: design/plone/contenttypes/behaviors/address.py:89 -#: design/plone/contenttypes/behaviors/geolocation.py:38 -#: design/plone/contenttypes/behaviors/luoghi_correlati.py:74 +#: design/plone/contenttypes/behaviors/address.py:71 +#: design/plone/contenttypes/behaviors/geolocation.py:34 +#: design/plone/contenttypes/behaviors/luoghi_correlati.py:76 msgid "luogo_label" msgstr "" +#. Default: "Sottotitolo" +#: design/plone/contenttypes/interfaces/servizio.py:26 +msgid "milestone_description_label" +msgstr "" + +#. Default: "Titolo" +#: design/plone/contenttypes/interfaces/servizio.py:21 +msgid "milestone_label" +msgstr "" + #. Default: "Modalita' di accesso" -#: design/plone/contenttypes/behaviors/luogo.py:53 +#: design/plone/contenttypes/behaviors/luogo.py:54 msgid "modalita_accesso" msgstr "" #. Default: "Indicare la modalità di avvio del procedimento." -#: design/plone/contenttypes/behaviors/trasparenza.py:25 +#: design/plone/contenttypes/behaviors/trasparenza.py:26 msgid "modalita_avvio_help" msgstr "" #. Default: "Modalita di avvio" -#: design/plone/contenttypes/behaviors/trasparenza.py:24 +#: design/plone/contenttypes/behaviors/trasparenza.py:25 msgid "modalita_avvio_label" msgstr "" @@ -1819,12 +1872,12 @@ msgid "modalita_pagamento" msgstr "" #. Default: "Indicare le modalità per richiedere informazioni riguardo a questo procedimento." -#: design/plone/contenttypes/behaviors/trasparenza.py:168 +#: design/plone/contenttypes/behaviors/trasparenza.py:169 msgid "modalita_richiesta_informazioni_help" msgstr "" #. Default: "Modalità per richiedere informazioni" -#: design/plone/contenttypes/behaviors/trasparenza.py:163 +#: design/plone/contenttypes/behaviors/trasparenza.py:164 msgid "modalita_richiesta_informazioni_label" msgstr "" @@ -1848,18 +1901,18 @@ msgstr "" msgid "mostra_navigazione_label" msgstr "" -#. Default: "Descrizione del motivo per cui il servizio non è attivo." -#: design/plone/contenttypes/interfaces/servizio.py:44 +#. Default: "Descrizione del motivo per cui il servizio non è attivo. È obbligatorio se il campo precedente è spuntato." +#: design/plone/contenttypes/interfaces/servizio.py:89 msgid "motivo_stato_servizio_help" msgstr "" -#. Default: "Motivo dello stato del servizio nel caso non sia attivo" -#: design/plone/contenttypes/interfaces/servizio.py:39 +#. Default: "Motivo dello stato" +#: design/plone/contenttypes/interfaces/servizio.py:84 msgid "motivo_stato_servizio_label" msgstr "" #. Default: "Nome alternativo" -#: design/plone/contenttypes/behaviors/luogo.py:33 +#: design/plone/contenttypes/behaviors/luogo.py:34 msgid "nome_alternativo" msgstr "" @@ -1869,17 +1922,17 @@ msgid "nome_sede" msgstr "" #. Default: "Seleziona una lista di notizie correlate a questa." -#: design/plone/contenttypes/behaviors/news_additional_fields.py:83 +#: design/plone/contenttypes/behaviors/news_additional_fields.py:75 msgid "notizie_correlate_help" msgstr "" #. Default: "Notizie correlate" -#: design/plone/contenttypes/behaviors/news_additional_fields.py:82 +#: design/plone/contenttypes/behaviors/news_additional_fields.py:74 msgid "notizie_correlate_label" msgstr "" #. Default: "Numero progressivo del comunicato stampa" -#: design/plone/contenttypes/behaviors/news_additional_fields.py:38 +#: design/plone/contenttypes/behaviors/news_additional_fields.py:30 msgid "numero_progressivo_cs_label" msgstr "" @@ -1895,117 +1948,155 @@ msgid "oggetto" msgstr "" #. Default: "Informazioni sugli orari" -#: design/plone/contenttypes/behaviors/evento.py:62 +#: design/plone/contenttypes/behaviors/evento.py:50 msgid "orari" msgstr "" #. Default: "Informazioni sugli orari di svolgimento dell'evento." -#: design/plone/contenttypes/behaviors/evento.py:64 +#: design/plone/contenttypes/behaviors/evento.py:52 msgid "orari_help" msgstr "" #. Default: "Orari di apertura" -#: design/plone/contenttypes/behaviors/contatti.py:86 +#: design/plone/contenttypes/behaviors/luogo.py:151 msgid "orari_label" msgstr "" +#. Default: "Orario per il pubblico" +#: design/plone/contenttypes/behaviors/luogo.py:93 +msgid "orario_pubblico" +msgstr "" + #. Default: "Indicare eventuali orari di accesso al pubblico" -#: design/plone/contenttypes/behaviors/contatti.py:59 +#: design/plone/contenttypes/behaviors/contatti.py:40 +#: design/plone/contenttypes/behaviors/luogo.py:95 msgid "orario_pubblico_help" msgstr "" #. Default: "Orario per il pubblico" -#: design/plone/contenttypes/behaviors/contatti.py:58 +#: design/plone/contenttypes/behaviors/contatti.py:39 msgid "orario_pubblico_label" msgstr "" #. Default: "Se l'evento non è organizzato direttamente dal comune oppure ha anche un organizzatore esterno, indicare il nome del contatto." -#: design/plone/contenttypes/behaviors/evento.py:97 +#: design/plone/contenttypes/behaviors/evento.py:86 msgid "organizzato_da_esterno_help" msgstr "" #. Default: "Organizzatore" -#: design/plone/contenttypes/behaviors/evento.py:95 +#: design/plone/contenttypes/behaviors/evento.py:84 msgid "organizzato_da_esterno_label" msgstr "" #. Default: "Se l'evento è organizzato direttamente dal comune, indicare l'ufficio/ente organizzatore. I dati di contatto verranno presi direttamente dall'ufficio selezionato. Se l'evento non è organizzato direttamente dal comune, o si vogliono sovrascrivere alcuni dati di contatto, utilizzare i seguenti campi." -#: design/plone/contenttypes/behaviors/evento.py:84 +#: design/plone/contenttypes/behaviors/evento.py:74 msgid "organizzato_da_interno_help" msgstr "" #. Default: "Organizzato da" -#: design/plone/contenttypes/behaviors/evento.py:80 +#: design/plone/contenttypes/behaviors/evento.py:70 msgid "organizzato_da_interno_label" msgstr "" #. Default: "Seleziona una lista di organizzazioni a cui la persona appartiene." -#: design/plone/contenttypes/interfaces/persona.py:42 +#: design/plone/contenttypes/interfaces/persona.py:45 msgid "organizzazione_riferimento_help" msgstr "" #. Default: "Organizzazione di riferimento" -#: design/plone/contenttypes/interfaces/persona.py:38 +#: design/plone/contenttypes/interfaces/persona.py:41 msgid "organizzazione_riferimento_label" msgstr "" #. Default: "Organo competente del provvedimento finale." -#: design/plone/contenttypes/behaviors/trasparenza.py:157 +#: design/plone/contenttypes/behaviors/trasparenza.py:158 msgid "organo_competente_provvedimento_finale_help" msgstr "" #. Default: "Organo competente del provvedimento finale" -#: design/plone/contenttypes/behaviors/trasparenza.py:152 +#: design/plone/contenttypes/behaviors/trasparenza.py:153 msgid "organo_competente_provvedimento_finale_label" msgstr "" #. Default: "Indicare le informazioni riguardanti i pagamenti previsti e modalità di pagamento." -#: design/plone/contenttypes/behaviors/trasparenza.py:222 +#: design/plone/contenttypes/behaviors/trasparenza.py:223 msgid "pagamenti_help" msgstr "" #. Default: "Pagamenti previsti e modalità" -#: design/plone/contenttypes/behaviors/trasparenza.py:218 +#: design/plone/contenttypes/behaviors/trasparenza.py:219 msgid "pagamenti_label" msgstr "" +#. Default: "Link a persone dell'amministrazione che interverranno all'evento" +#: design/plone/contenttypes/behaviors/evento.py:118 +msgid "parteciperanno_help" +msgstr "" + +#. Default: "Parteciperanno (Persone)" +#: design/plone/contenttypes/behaviors/evento.py:114 +msgid "parteciperanno_label" +msgstr "" + #. Default: "Indicare l'ente che supporta l'evento, se presente." -#: design/plone/contenttypes/behaviors/evento.py:160 +#: design/plone/contenttypes/behaviors/evento.py:107 msgid "patrocinato_da_help" msgstr "" #. Default: "Patrocinato da" -#: design/plone/contenttypes/behaviors/evento.py:158 +#: design/plone/contenttypes/behaviors/evento.py:105 msgid "patrocinato_da_label" msgstr "" -#. Default: "Indicare un indirizzo pec per poter contattare i referenti." -#: design/plone/contenttypes/behaviors/contatti.py:44 -msgid "pec_help" +#. Default: "Descrizione" +#: design/plone/contenttypes/interfaces/punto_di_contatto.py:27 +msgid "pdc_desc_help" +msgstr "" + +#. Default: "Descrizione" +#: design/plone/contenttypes/interfaces/punto_di_contatto.py:26 +msgid "pdc_desc_label" +msgstr "" + +#. Default: "Tipo" +#: design/plone/contenttypes/interfaces/punto_di_contatto.py:16 +msgid "pdc_type_label" msgstr "" -#. Default: "Pec" -#: design/plone/contenttypes/behaviors/contatti.py:43 -msgid "pec_label" +#. Default: "Contatto" +#: design/plone/contenttypes/interfaces/punto_di_contatto.py:37 +msgid "pdc_value_help" msgstr "" -#. Default: "Elenco delle persone dell'amministrazione che parteciperanno all'evento." -#: design/plone/contenttypes/behaviors/evento.py:53 -msgid "persone_amministrazione_help" +#. Default: "Contatto" +#: design/plone/contenttypes/interfaces/punto_di_contatto.py:36 +msgid "pdc_value_label" +msgstr "" + +#. Default: "Seleziona la persona che ha questo incarico" +#: design/plone/contenttypes/interfaces/incarico.py:47 +#: design/plone/contenttypes/interfaces/punto_di_contatto.py:66 +msgid "persona_incarico_help" +msgstr "" + +#. Default: "La persona che ha la carica e l'incarico" +#: design/plone/contenttypes/interfaces/incarico.py:43 +#: design/plone/contenttypes/interfaces/punto_di_contatto.py:62 +msgid "persona_incarico_label" msgstr "" #. Default: "Persone" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:221 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:215 msgid "persone_label" msgstr "" #. Default: "Seleziona la lista delle persone che compongono la struttura." -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:95 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:87 msgid "persone_struttura_help" msgstr "" #. Default: "Persone che compongono la struttura" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:87 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:79 msgid "persone_struttura_label" msgstr "" @@ -2021,42 +2112,42 @@ msgid "pratica_associata_ricevuta" msgstr "" #. Default: "Prenota un appuntamento" -#: design/plone/contenttypes/interfaces/servizio.py:156 +#: design/plone/contenttypes/interfaces/servizio.py:225 msgid "prenota_appuntamento" msgstr "" #. Default: "Se è possibile prenotare un'appuntamento, indicare le informazioni necessarie e il collegamento al servizio di prenotazione appuntamenti del Comune." -#: design/plone/contenttypes/interfaces/servizio.py:157 +#: design/plone/contenttypes/interfaces/servizio.py:226 msgid "prenota_appuntamento_help" msgstr "" -#. Default: "Prezzo" -#: design/plone/contenttypes/behaviors/evento.py:71 +#. Default: "Costo" +#: design/plone/contenttypes/behaviors/evento.py:59 msgid "prezzo" msgstr "" -#. Default: "Indicare il prezzo dell'evento, se presente, specificando se esistono formati diversi." -#: design/plone/contenttypes/behaviors/evento.py:73 +#. Default: "Eventuale costo dell'evento (se ci sono uno o più biglietti), con link all'acquisto se disponibile" +#: design/plone/contenttypes/behaviors/evento.py:61 msgid "prezzo_help" msgstr "" #. Default: "Indicare, se la procedura è informatizzata online, il riferimento." -#: design/plone/contenttypes/behaviors/trasparenza.py:178 +#: design/plone/contenttypes/behaviors/trasparenza.py:179 msgid "procedura_online_help" msgstr "" #. Default: "Procedura informatizzata online" -#: design/plone/contenttypes/behaviors/trasparenza.py:174 +#: design/plone/contenttypes/behaviors/trasparenza.py:175 msgid "procedura_online_label" msgstr "" #. Default: "Procedure collegate all'esito" -#: design/plone/contenttypes/interfaces/servizio.py:100 +#: design/plone/contenttypes/interfaces/servizio.py:145 msgid "procedure_collegate" msgstr "" #. Default: "Indicare cosa deve fare l'utente del servizio per conoscere l'esito della procedura, e dove eventualmente poter ritirare l'esito." -#: design/plone/contenttypes/interfaces/servizio.py:102 +#: design/plone/contenttypes/interfaces/servizio.py:147 msgid "procedure_collegate_help" msgstr "" @@ -2065,13 +2156,23 @@ msgstr "" msgid "protocollo" msgstr "" +#. Default: "Il numero di protocollo del documento." +#: design/plone/contenttypes/interfaces/documento.py:33 +msgid "protocollo_documento_help" +msgstr "" + +#. Default: "Numero di protocollo" +#: design/plone/contenttypes/interfaces/documento.py:29 +msgid "protocollo_documento_label" +msgstr "" + #. Default: "Eventuale provvedimento finale del procedimento." -#: design/plone/contenttypes/behaviors/trasparenza.py:114 +#: design/plone/contenttypes/behaviors/trasparenza.py:115 msgid "provvedimento_finale_help" msgstr "" #. Default: "Provvedimento del procedimento" -#: design/plone/contenttypes/behaviors/trasparenza.py:109 +#: design/plone/contenttypes/behaviors/trasparenza.py:110 msgid "provvedimento_finale_label" msgstr "" @@ -2080,46 +2181,46 @@ msgstr "" msgid "quartiere" msgstr "" -#. Default: "Reperibilità organizzatore" -#: design/plone/contenttypes/behaviors/evento.py:118 -msgid "reperibilita" -msgstr "" - -#. Default: "Indicare gli orari in cui l'organizzatore è telefonicamente reperibile." -#: design/plone/contenttypes/behaviors/evento.py:120 -msgid "reperibilita_help" -msgstr "" - #. Default: "Indicare dove è possibile reperre la modulistica per il procedimento." -#: design/plone/contenttypes/behaviors/trasparenza.py:211 +#: design/plone/contenttypes/behaviors/trasparenza.py:212 msgid "reperimento_modulistica_help" msgstr "" #. Default: "Dove reperire la modulistica" -#: design/plone/contenttypes/behaviors/trasparenza.py:207 +#: design/plone/contenttypes/behaviors/trasparenza.py:208 msgid "reperimento_modulistica_label" msgstr "" #. Default: "Selezionare il/i responsabile/i della struttura." -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:48 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:52 msgid "responsabile_help" msgstr "" #. Default: "Responsabile" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:43 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:47 msgid "responsabile_label" msgstr "" #. Default: "Responsabile del procedimento" -#: design/plone/contenttypes/behaviors/trasparenza.py:120 +#: design/plone/contenttypes/behaviors/trasparenza.py:121 msgid "responsabile_procedimento" msgstr "" #. Default: "Indicare il responsabile del procedimento." -#: design/plone/contenttypes/behaviors/trasparenza.py:124 +#: design/plone/contenttypes/behaviors/trasparenza.py:125 msgid "responsabile_procedimento_help" msgstr "" +#. Default: "Se è un incarico di responsabilità, specificare l'organizzazione della quale è responsabile in base all'incarico" +#: design/plone/contenttypes/interfaces/incarico.py:81 +msgid "responsabile_struttura_incarico_help" +msgstr "" + +#. Default: "Responsabile della struttura" +#: design/plone/contenttypes/interfaces/incarico.py:77 +msgid "responsabile_struttura_incarico_label" +msgstr "" + #. Default: "Seleziona se mostrare o meno il campo di ricerca in testata." #: design/plone/contenttypes/behaviors/info_testata.py:32 msgid "ricerca_in_testata_help" @@ -2131,12 +2232,12 @@ msgid "ricerca_in_testata_label" msgstr "" #. Default: "Ulteriori informazioni non previste negli altri campi; si può trattare di contatti o note informative la cui conoscenza è indispensabile per la partecipazione al bando" -#: design/plone/contenttypes/interfaces/bando.py:96 +#: design/plone/contenttypes/interfaces/bando.py:97 msgid "riferimenti_bando_agid_help" msgstr "" #. Default: "Ulteriori informazioni" -#: design/plone/contenttypes/interfaces/bando.py:95 +#: design/plone/contenttypes/interfaces/bando.py:96 msgid "riferimenti_bando_agid_label" msgstr "" @@ -2146,122 +2247,87 @@ msgid "riferimenti_normativi" msgstr "" #. Default: "Inserisici del testo di dettaglio per eventuali riferimenti normativi utili a questo documento." -#: design/plone/contenttypes/interfaces/documento.py:100 +#: design/plone/contenttypes/interfaces/documento.py:137 msgid "riferimenti_normativi_documento_help" msgstr "" #. Default: "Riferimenti normativi" -#: design/plone/contenttypes/interfaces/documento.py:96 +#: design/plone/contenttypes/interfaces/documento.py:133 msgid "riferimenti_normativi_documento_label" msgstr "" #. Default: "Indicare eventuali riferimenti normativi." -#: design/plone/contenttypes/behaviors/trasparenza.py:265 +#: design/plone/contenttypes/behaviors/trasparenza.py:266 msgid "riferimenti_normativi_help" msgstr "" #. Default: "Riferimenti normativi" -#: design/plone/contenttypes/behaviors/trasparenza.py:260 +#: design/plone/contenttypes/behaviors/trasparenza.py:261 msgid "riferimenti_normativi_label" msgstr "" -#. Default: "Fax della struttura responsabile" -#: design/plone/contenttypes/behaviors/luogo.py:104 -msgid "riferimento_fax_struttura" -msgstr "" - -#. Default: "E-mail struttura responsabile" -#: design/plone/contenttypes/behaviors/luogo.py:115 -msgid "riferimento_mail_struttura" -msgstr "" - -#. Default: "Pec della struttura responsabile" -#: design/plone/contenttypes/behaviors/luogo.py:128 -msgid "riferimento_pec_struttura" -msgstr "" - -#. Default: "Telefono della struttura responsabile" -#: design/plone/contenttypes/behaviors/luogo.py:92 -msgid "riferimento_telefonico_struttura" -msgstr "" - -#. Default: "Inserisci i valori utilizzabili per il ruolo di una Persona. Se il sito è multilingua, puoi inserire valori diversi a seconda delle lingue del sito." -#: design/plone/contenttypes/controlpanels/settings.py:84 -msgid "ruoli_persona_help" -msgstr "" - -#. Default: "Ruoli Persona" -#: design/plone/contenttypes/controlpanels/settings.py:83 -msgid "ruoli_persona_label" -msgstr "" - -#. Default: "Seleziona il ruolo della persona tra quelli disponibili." -#: design/plone/contenttypes/interfaces/persona.py:29 -msgid "ruolo_help" -msgstr "" - #. Default: "Ruolo" -#: design/plone/contenttypes/interfaces/persona.py:28 +#: design/plone/contenttypes/interfaces/persona.py:135 msgid "ruolo_label" msgstr "" #. Default: "Data entro la quale sarà possibile far pervenire domande e richieste di chiarimento a chi eroga il bando" -#: design/plone/contenttypes/interfaces/bando.py:69 +#: design/plone/contenttypes/interfaces/bando.py:70 msgid "scadenza_domande_bando_help" msgstr "" #. Default: "Termine per le richieste di chiarimenti" -#: design/plone/contenttypes/interfaces/bando.py:65 +#: design/plone/contenttypes/interfaces/bando.py:66 msgid "scadenza_domande_bando_label" msgstr "" #. Default: "Inserire una lista di sezioni per la ricerca." -#: design/plone/contenttypes/controlpanels/settings.py:129 +#: design/plone/contenttypes/controlpanels/settings.py:71 msgid "search_sections_help" msgstr "" #. Default: "Sezioni ricerca" -#: design/plone/contenttypes/controlpanels/settings.py:128 +#: design/plone/contenttypes/controlpanels/settings.py:70 msgid "search_sections_label" msgstr "" -#. Default: "Seleziona il Luogo in cui questa struttura ha sede. Se non è presente un contenuto di tipo Luogo a cui far riferimento, puoi compilare i campi seguenti. Se selezioni un Luogo, puoi usare comunque i campi seguenti per sovrascrivere alcune informazioni." -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:105 +#. Default: "Seleziona il Luogo in cui questa struttura ha sede. Se non è presente creare il Luogo nella sezione dedicata nell'alberatura del sito." +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:97 msgid "sede_help" msgstr "" #. Default: "Sede principale" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:103 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:95 msgid "sede_label" msgstr "" #. Default: "Seleziona una lista di eventuali contenuti di tipo Luogo che sono sedi secondarie di questa struttura. Per queste sedi non sarà possibile sovrascrivere i dati. Nel caso servano informazioni diverse, è possibile usare il campo sottostante." -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:122 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:112 msgid "sedi_secondarie_help" msgstr "" -#. Default: "Sedi secondarie" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:120 +#. Default: "Altre sedi" +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:110 msgid "sedi_secondarie_label" msgstr "" #. Default: "Seleziona la lista dei servizi collegati a questo." -#: design/plone/contenttypes/interfaces/servizio.py:300 +#: design/plone/contenttypes/interfaces/servizio.py:394 msgid "servizi_collegati_help" msgstr "" #. Default: "Servizi collegati" -#: design/plone/contenttypes/interfaces/servizio.py:299 +#: design/plone/contenttypes/interfaces/servizio.py:393 msgid "servizi_collegati_label" msgstr "" #. Default: "Questi servizi non verranno mostrati nel contenuto, ma permetteranno di vedere questo contenuto associato quando si visita il servizio" -#: design/plone/contenttypes/behaviors/servizi_correlati.py:19 +#: design/plone/contenttypes/behaviors/servizi_correlati.py:20 msgid "servizi_correlati_description" msgstr "" #. Default: "Servizi correlati" -#: design/plone/contenttypes/behaviors/servizi_correlati.py:18 +#: design/plone/contenttypes/behaviors/servizi_correlati.py:19 msgid "servizi_correlati_label" msgstr "" @@ -2281,22 +2347,32 @@ msgid "servizio_origine_ricevuta" msgstr "" #. Default: "Settore merceologico" -#: design/plone/contenttypes/interfaces/servizio.py:280 +#: design/plone/contenttypes/interfaces/servizio.py:369 msgid "settore_merceologico" msgstr "" #. Default: "Classificazione del servizio basata su catalogo dei servizi (Classificazione NACE)." -#: design/plone/contenttypes/interfaces/servizio.py:282 +#: design/plone/contenttypes/interfaces/servizio.py:371 msgid "settore_merceologico_help" msgstr "" +#. Default: "Se selezionato, il footer verrà popolato automaticamente con i contenuti di primo livello non esclusi dalla navigazione." +#: design/plone/contenttypes/controlpanels/settings.py:93 +msgid "show_dynamic_folders_in_footer_help" +msgstr "" + +#. Default: "Footer dinamico" +#: design/plone/contenttypes/controlpanels/settings.py:92 +msgid "show_dynamic_folders_in_footer_label" +msgstr "" + #. Default: "Questo è il valore di default per decidere se mostrare o meno la data di modifica nei contenuti che hanno la behavior abilitata. E' poi possibile sovrascrivere il default nei singoli contenuti (nel tab \"Impostazioni\")." -#: design/plone/contenttypes/controlpanels/settings.py:139 +#: design/plone/contenttypes/controlpanels/settings.py:81 msgid "show_modified_default_help" msgstr "" #. Default: "Mostra la data di modifica" -#: design/plone/contenttypes/controlpanels/settings.py:138 +#: design/plone/contenttypes/controlpanels/settings.py:80 msgid "show_modified_default_label" msgstr "" @@ -2311,34 +2387,34 @@ msgid "show_modified_label" msgstr "" #. Default: "Indicare se il procedimento prevede il silenzio assenso o la dichiarazione dell'interessato sostitutiva del provvedimento finale." -#: design/plone/contenttypes/behaviors/trasparenza.py:103 +#: design/plone/contenttypes/behaviors/trasparenza.py:104 msgid "silenzio_assenso_help" msgstr "" #. Default: "Silenzio assenso/Dichiarazione dell'interessato sostitutiva del provvedimento finale" -#: design/plone/contenttypes/behaviors/trasparenza.py:97 +#: design/plone/contenttypes/behaviors/trasparenza.py:98 msgid "silenzio_assenso_label" msgstr "" #. Default: "Inserisci eventuali soggetti esterni, nonché, strutture interne coinvolte nel procedimento." -#: design/plone/contenttypes/behaviors/trasparenza.py:57 +#: design/plone/contenttypes/behaviors/trasparenza.py:58 msgid "soggetti_eserni_help" msgstr "" #. Default: "Soggetti esterni, nonché, strutture interne coinvolte nel procedimento" -#: design/plone/contenttypes/behaviors/trasparenza.py:52 +#: design/plone/contenttypes/behaviors/trasparenza.py:53 msgid "soggetti_eserni_label" msgstr "" #. Default: "Indica un eventuale sottotitolo/titolo alternativo." -#: design/plone/contenttypes/behaviors/evento.py:23 -#: design/plone/contenttypes/interfaces/servizio.py:19 +#: design/plone/contenttypes/behaviors/evento.py:24 +#: design/plone/contenttypes/interfaces/servizio.py:64 msgid "sottotitolo_help" msgstr "" #. Default: "Sottotitolo" -#: design/plone/contenttypes/behaviors/evento.py:22 -#: design/plone/contenttypes/interfaces/servizio.py:18 +#: design/plone/contenttypes/behaviors/evento.py:23 +#: design/plone/contenttypes/interfaces/servizio.py:63 msgid "sottotitolo_label" msgstr "" @@ -2352,273 +2428,188 @@ msgstr "" msgid "stato_pratica" msgstr "" -#. Default: "Indica se il servizio è effettivamente fruibile." -#: design/plone/contenttypes/interfaces/servizio.py:32 +#. Default: "Indica se il servizio è effettivamente fruibile; spuntare se non è fruibile." +#: design/plone/contenttypes/interfaces/servizio.py:77 msgid "stato_servizio_help" msgstr "" -#. Default: "Servizio non attivo" -#: design/plone/contenttypes/interfaces/servizio.py:30 +#. Default: "Servizio non fruibile" +#: design/plone/contenttypes/interfaces/servizio.py:75 msgid "stato_servizio_label" msgstr "" #. Default: "Indicare gli eventuali strumenti di tutela." -#: design/plone/contenttypes/behaviors/trasparenza.py:230 +#: design/plone/contenttypes/behaviors/trasparenza.py:231 msgid "strumenti_tutela_help" msgstr "" #. Default: "Strumenti di tutela" -#: design/plone/contenttypes/behaviors/trasparenza.py:229 +#: design/plone/contenttypes/behaviors/trasparenza.py:230 msgid "strumenti_tutela_label" msgstr "" #. Default: "Struttura" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:211 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:206 msgid "struttura_label" msgstr "" #. Default: "Struttura responsabile" -#: design/plone/contenttypes/behaviors/luogo.py:82 +#: design/plone/contenttypes/behaviors/luogo.py:83 msgid "struttura_responsabile" msgstr "" #. Default: "Struttura responsabile del luogo." -#: design/plone/contenttypes/behaviors/luogo.py:63 +#: design/plone/contenttypes/behaviors/luogo.py:64 msgid "struttura_responsabile_correlati" msgstr "" #. Default: "Indicare la struttura responsabile del luogo qualora sia fra unità organizzative del comune inserite nel sito; altrimenti compilare i campi testuali relativi alla struttura responsabile" -#: design/plone/contenttypes/behaviors/luogo.py:67 +#: design/plone/contenttypes/behaviors/luogo.py:68 msgid "struttura_responsabile_correlati_help" msgstr "" #. Default: "Nome/link al sito web della struttura che gestisce il luogo, se questa non è comunale." -#: design/plone/contenttypes/behaviors/luogo.py:84 +#: design/plone/contenttypes/behaviors/luogo.py:85 msgid "struttura_responsabile_help" msgstr "" #. Default: "Seleziona la lista delle strutture politiche coinvolte." -#: design/plone/contenttypes/behaviors/strutture_correlate.py:25 +#: design/plone/contenttypes/behaviors/strutture_correlate.py:26 msgid "strutture_politiche_help" msgstr "" #. Default: "Indicare gli uffici/enti che supportano l'evento." -#: design/plone/contenttypes/behaviors/evento.py:149 +#: design/plone/contenttypes/behaviors/evento.py:97 msgid "supportato_da_help" msgstr "" #. Default: "Evento supportato da" -#: design/plone/contenttypes/behaviors/evento.py:145 +#: design/plone/contenttypes/behaviors/evento.py:93 msgid "supportato_da_label" msgstr "" #. Default: "Seleziona una lista di argomenti d'interesse per questo contenuto." -#: design/plone/contenttypes/behaviors/argomenti.py:22 +#: design/plone/contenttypes/behaviors/argomenti.py:26 msgid "tassonomia_argomenti_help" msgstr "" -#. Default: "Tassonomia argomenti" -#: design/plone/contenttypes/behaviors/argomenti.py:21 +#. Default: "Argomenti" +#: design/plone/contenttypes/behaviors/argomenti.py:25 msgid "tassonomia_argomenti_label" msgstr "" -#. Default: "Telefono" -#: design/plone/contenttypes/behaviors/evento.py:104 -msgid "telefono_event_help" -msgstr "" - -#. Default: "Indicare un riferimento telefonico per poter contattare gli organizzatori." -#: design/plone/contenttypes/behaviors/evento.py:105 -msgid "telefono_event_label" -msgstr "" - -#. Default: "Indicare un riferimento telefonico per poter contattare i referenti." -#: design/plone/contenttypes/behaviors/contatti.py:19 -msgid "telefono_help" -msgstr "" - -#. Default: "Telefono" -#: design/plone/contenttypes/behaviors/contatti.py:18 -msgid "telefono_label" -msgstr "" - -#. Default: "Contatto telefonico della persona. E' possibile inserire più di un numero. Premendo \"Invio\" o \"tab\" si può passare al successivo da inserire." -#: design/plone/contenttypes/interfaces/persona.py:117 -msgid "telefono_persona_help" -msgstr "" - -#. Default: "Numero di telefono" -#: design/plone/contenttypes/interfaces/persona.py:116 -msgid "telefono_persona_label" -msgstr "" - -#. Default: "Temi" -#: design/plone/contenttypes/interfaces/dataset.py:14 -msgid "temi" -msgstr "" - #. Default: "Tempi e scadenze" -#: design/plone/contenttypes/interfaces/servizio.py:167 +#: design/plone/contenttypes/interfaces/servizio.py:236 msgid "tempi_e_scadenze" msgstr "" #. Default: "Descrivere le informazioni dettagliate riguardo eventuali tempi e scadenze di questo servizio." -#: design/plone/contenttypes/interfaces/servizio.py:169 +#: design/plone/contenttypes/interfaces/servizio.py:238 msgid "tempi_e_scadenze_help" msgstr "" #. Default: "Tempi e scadenze" -#: design/plone/contenttypes/interfaces/servizio.py:395 +#: design/plone/contenttypes/interfaces/servizio.py:508 msgid "tempi_e_scadenze_label" msgstr "" #. Default: "Inserisci il tempo medio del procedimento." -#: design/plone/contenttypes/behaviors/trasparenza.py:91 +#: design/plone/contenttypes/behaviors/trasparenza.py:92 msgid "tempo_medio_help" msgstr "" #. Default: "Tempo medio del procedimento" -#: design/plone/contenttypes/behaviors/trasparenza.py:86 +#: design/plone/contenttypes/behaviors/trasparenza.py:87 msgid "tempo_medio_label" msgstr "" #. Default: "Testata" -#: design/plone/contenttypes/behaviors/argomenti.py:104 +#: design/plone/contenttypes/behaviors/argomenti.py:232 #: design/plone/contenttypes/behaviors/info_testata.py:62 msgid "testata_fieldset_label" msgstr "" -#: design/plone/contenttypes/interfaces/bando.py:28 +#: design/plone/contenttypes/interfaces/bando.py:29 msgid "text_help" msgstr "" #. Default: "Testo" -#: design/plone/contenttypes/interfaces/bando.py:27 +#: design/plone/contenttypes/interfaces/bando.py:28 msgid "text_label" msgstr "" -#. Default: "Tipologia documento" -#: design/plone/contenttypes/interfaces/messaggio.py:49 -msgid "tipologia_documento" -msgstr "" - -#. Default: "Seleziona la tipologia del documento." -#: design/plone/contenttypes/interfaces/documento.py:30 -msgid "tipologia_documento_help" -msgstr "" - -#. Default: "Tipologia del documento" -#: design/plone/contenttypes/interfaces/documento.py:29 -msgid "tipologia_documento_label" -msgstr "" - -#. Default: "Seleziona la tipologia della notizia." -#: design/plone/contenttypes/behaviors/news_additional_fields.py:29 -msgid "tipologia_notizia_help" -msgstr "" - -#. Default: "Tipologia notizia" -#: design/plone/contenttypes/behaviors/news_additional_fields.py:28 -msgid "tipologia_notizia_label" -msgstr "" - -#. Default: "Specificare la tipologia di organizzazione: politica, amminsitrativa o di altro tipo." -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:60 -msgid "tipologia_organizzazione_help" -msgstr "" - -#. Default: "Tipologia organizzazione" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:57 -msgid "tipologia_organizzazione_label" -msgstr "" - -#. Default: "Seleziona la tipologia di persona: politica, amministrativa o di altro tipo." -#: design/plone/contenttypes/interfaces/persona.py:86 -msgid "tipologia_persona_help" -msgstr "" - -#. Default: "Tipologia persona" -#: design/plone/contenttypes/interfaces/persona.py:85 -msgid "tipologia_persona_label" -msgstr "" - -#. Default: "Inserisci i valori utilizzabili per le tipologie di un Documento. Se il sito è multilingua, puoi inserire valori diversi a seconda delle lingue del sito." -#: design/plone/contenttypes/controlpanels/settings.py:46 -msgid "tipologie_documento_help" +#. Default: "Timeline tempi e scadenze" +#: design/plone/contenttypes/interfaces/servizio.py:246 +msgid "timeline_tempi_scadenze" msgstr "" -#. Default: "Tipologie Documento" -#: design/plone/contenttypes/controlpanels/settings.py:45 -msgid "tipologie_documento_label" +#. Default: "Timeline tempi e scadenze del servizio: indicare per ogni scadenza un titolo descrittivo ed un eventuale sottotitolo. Per ogni scadenza, selezionare opzionalmente o l'intervallo (Campi \"Intervallo\" e \"Tipo Intervallo\", es. \"1\" e \"settimana\"), oppure direttamente una data di scadenza (campo: \"Data Scadenza\", esempio 31/12/2023). Se vengono compilati entrambi, ha priorità il campo \"Data Scadenza\"." +#: design/plone/contenttypes/interfaces/servizio.py:249 +msgid "timeline_tempi_scadenze_help" msgstr "" #. Default: "Inserisci i valori utilizzabili per le tipologie di una Notizia. Se il sito è multilingua, puoi inserire valori diversi a seconda delle lingue del sito." -#: design/plone/contenttypes/controlpanels/settings.py:19 +#: design/plone/contenttypes/controlpanels/settings.py:22 msgid "tipologie_notizia_help" msgstr "" #. Default: "Tipologie Notizia" -#: design/plone/contenttypes/controlpanels/settings.py:18 +#: design/plone/contenttypes/controlpanels/settings.py:21 msgid "tipologie_notizia_label" msgstr "" -#. Default: "Inserisci i valori utilizzabili per le tipologie di una Persona. Se il sito è multilingua, puoi inserire valori diversi a seconda delle lingue del sito." -#: design/plone/contenttypes/controlpanels/settings.py:72 -msgid "tipologie_persona_help" -msgstr "" - -#. Default: "Tipologie Persona" -#: design/plone/contenttypes/controlpanels/settings.py:71 -msgid "tipologie_persona_label" -msgstr "" - #. Default: "Inserisci i valori utilizzabili per le tipologie di un' Unità Organizzativa. Se il sito è multilingua, puoi inserire valori diversi a seconda delle lingue del sito." -#: design/plone/contenttypes/controlpanels/settings.py:34 +#: design/plone/contenttypes/controlpanels/settings.py:37 msgid "tipologie_unita_organizzativa_help" msgstr "" #. Default: "Tipologie Unità Organizzativa" -#: design/plone/contenttypes/controlpanels/settings.py:30 +#: design/plone/contenttypes/controlpanels/settings.py:33 msgid "tipologie_unita_organizzativa_label" msgstr "" #. Default: "Titolare" -#: design/plone/contenttypes/interfaces/dataset.py:29 +#: design/plone/contenttypes/interfaces/dataset.py:22 msgid "titolare" msgstr "" #. Default: "Eventuale titolare del potere sostitutivo." -#: design/plone/contenttypes/behaviors/trasparenza.py:243 +#: design/plone/contenttypes/behaviors/trasparenza.py:244 msgid "titolare_potere_sostitutivo_help" msgstr "" #. Default: "Titolare del potere sostitutivo" -#: design/plone/contenttypes/behaviors/trasparenza.py:238 +#: design/plone/contenttypes/behaviors/trasparenza.py:239 msgid "titolare_potere_sostitutivo_label" msgstr "" #. Default: "Trasparenza" -#: design/plone/contenttypes/behaviors/trasparenza.py:292 +#: design/plone/contenttypes/behaviors/trasparenza.py:291 msgid "trasparenza_fieldset_label" msgstr "" +#. Default: "Tipo" +#: design/plone/contenttypes/interfaces/punto_di_contatto.py:17 +msgid "type_help" +msgstr "" + #. Default: "Seleziona l'ufficio responsabile di questo bando." -#: design/plone/contenttypes/interfaces/bando.py:110 +#: design/plone/contenttypes/interfaces/bando.py:111 msgid "ufficio_responsabile_bando_help" msgstr "" #. Default: "Ufficio responsabile del bando" -#: design/plone/contenttypes/interfaces/bando.py:106 +#: design/plone/contenttypes/interfaces/bando.py:107 msgid "ufficio_responsabile_bando_label" msgstr "" #. Default: "Seleziona l'ufficio responsabile di questo documento." -#: design/plone/contenttypes/interfaces/documento.py:43 +#: design/plone/contenttypes/interfaces/documento.py:73 msgid "ufficio_responsabile_documento_help" msgstr "" #. Default: "Ufficio responsabile del documento" -#: design/plone/contenttypes/interfaces/documento.py:39 +#: design/plone/contenttypes/interfaces/documento.py:69 msgid "ufficio_responsabile_documento_label" msgstr "" @@ -2627,13 +2618,13 @@ msgstr "" msgid "ufficio_responsabile_documento_personale" msgstr "" -#. Default: "Uffici responsabili" -#: design/plone/contenttypes/interfaces/servizio.py:216 +#. Default: "Unità organizzativa responsabile" +#: design/plone/contenttypes/interfaces/servizio.py:302 msgid "ufficio_responsabile_erogazione" msgstr "" #. Default: "Seleziona gli uffici responsabili dell'erogazione di questo servizio." -#: design/plone/contenttypes/interfaces/servizio.py:217 +#: design/plone/contenttypes/interfaces/servizio.py:306 msgid "ufficio_responsabile_help" msgstr "" @@ -2664,52 +2655,52 @@ msgstr "" msgid "unita_amministrative_responsabili_help" msgstr "" +#. Default: "Seleziona l'organizzazione presso la quale svolge l'incarico." +#: design/plone/contenttypes/interfaces/incarico.py:64 +msgid "unita_organizzativa_incarico_help" +msgstr "" + +#. Default: "Unità organizzativa" +#: design/plone/contenttypes/interfaces/incarico.py:60 +msgid "unita_organizzativa_incarico_label" +msgstr "" + #. Default: "Descrizione dei compiti assegnati alla struttura." -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:19 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:23 msgid "uo_competenze_help" msgstr "" #. Default: "Competenze" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:18 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:22 msgid "uo_competenze_label" msgstr "" -#. Default: "Inserisci eventuali informazioni di contatto aggiuntive non contemplate nei campi precedenti. Utilizza questo campo se ci sono dei contatti aggiuntivi rispetto ai contatti della sede principale. Se inserisci un collegamento con un indirizzo email, aggiungi \"mailto:\" prima dell'indirizzo, per farlo aprire direttamente nel client di posta." -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:139 -msgid "uo_contact_info_description" -msgstr "" - #. Default: "Note di aggiornamento" -#: design/plone/contenttypes/behaviors/update_note.py:16 +#: design/plone/contenttypes/behaviors/update_note.py:17 msgid "update_note_label" msgstr "" +#. Default: "Il valore del punto di contatto: il numero compreso di prefisso internazionale (se telefono), l'account (se social network), l'URL (se sito o pagina web), l'indirizzo email (se email)." +#: design/plone/contenttypes/interfaces/punto_di_contatto.py:54 +msgid "value_punto_contatto_help" +msgstr "" + #. Default: "Vincoli" -#: design/plone/contenttypes/interfaces/servizio.py:196 +#: design/plone/contenttypes/interfaces/servizio.py:282 msgid "vincoli" msgstr "" #. Default: "Descrizione degli eventuali vincoli presenti." -#: design/plone/contenttypes/interfaces/servizio.py:198 +#: design/plone/contenttypes/interfaces/servizio.py:284 msgid "vincoli_help" msgstr "" -#. Default: "Indicare un indirizzo web di riferimento a questo evento." -#: design/plone/contenttypes/behaviors/evento.py:138 -msgid "web_event_help" -msgstr "" - -#. Default: "Sito web" -#: design/plone/contenttypes/behaviors/evento.py:137 -msgid "web_event_label" -msgstr "" - -#. Default: "Indicare un indirizzo web di riferimento." -#: design/plone/contenttypes/behaviors/contatti.py:53 -msgid "web_help" +#. Default: "Mostra i PDF in anteprima" +#: design/plone/contenttypes/interfaces/cartella_modulistica.py:12 +msgid "visualize_files_title" msgstr "" -#. Default: "Sito web" -#: design/plone/contenttypes/behaviors/contatti.py:52 -msgid "web_label" +#. Default: "Permette di aprire l'anteprima di tutti i PDF di questa cartella in una tab separata, altrimenti i PDF vengono scaricati" +#: design/plone/contenttypes/interfaces/cartella_modulistica.py:13 +msgid "visulize_files_description" msgstr "" diff --git a/src/design/plone/contenttypes/locales/it/LC_MESSAGES/design.plone.contenttypes.po b/src/design/plone/contenttypes/locales/it/LC_MESSAGES/design.plone.contenttypes.po index 627f70da..5f990592 100644 --- a/src/design/plone/contenttypes/locales/it/LC_MESSAGES/design.plone.contenttypes.po +++ b/src/design/plone/contenttypes/locales/it/LC_MESSAGES/design.plone.contenttypes.po @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2023-01-13 13:15+0000\n" +"POT-Creation-Date: 2024-03-18 13:30+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI +ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -14,39 +14,23 @@ msgstr "" "Preferred-Encodings: utf-8 latin1\n" "Domain: DOMAIN\n" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:32 -msgid "Abitazione" -msgstr "" - -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:36 -msgid "Accesso al trasporto pubblico" -msgstr "" - -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:59 -msgid "Accesso luoghi della cultura" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:18 +msgid "Accesso all'informazione" msgstr "" #: design/plone/contenttypes/vocabularies/lista_azioni_pratica.py:33 msgid "Accettare" msgstr "" -#: design/plone/contenttypes/vocabularies/document_types_vocabulary.py:34 -msgid "Accordo tra enti" -msgstr "" - -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:52 +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:19 msgid "Acqua" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:194 +#: design/plone/contenttypes/behaviors/configure.zcml:223 msgid "Address Event" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:178 -msgid "Address UO" -msgstr "" - -#: design/plone/contenttypes/behaviors/configure.zcml:186 +#: design/plone/contenttypes/behaviors/configure.zcml:215 msgid "Address Venue" msgstr "" @@ -54,61 +38,53 @@ msgstr "" msgid "Adds fields." msgstr "" -#: design/plone/contenttypes/vocabularies/dataset.py:28 -msgid "Agricoltura, pesca, silvicoltura e prodotti alimentari" +#: design/plone/contenttypes/configure.zcml:66 +msgid "After Plone6 migration syndication is broken" msgstr "" -#: design/plone/contenttypes/browser/manage_content/templates/change_news_type.pt:22 -msgid "All the already existing News Types" -msgstr "Tipologie Notizie presenti sul sito" - -#: design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt:63 -msgid "All the selected items will be moved to indicated path" -msgstr "Tutti gli elementi selezionati saranno spostati nella cartella indicata" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:20 +msgid "Agricoltura" +msgstr "" -#: design/plone/contenttypes/browser/manage_content/templates/change_news_type.pt:20 +#: design/plone/contenttypes/browser/utils/templates/change_news_type.pt:30 msgid "All the already existing News Types" msgstr "I tipi delle notizie che esistono sul sito" -#: design/plone/contenttypes/vocabularies/dataset.py:36 -msgid "Ambiente" -msgstr "" +#: design/plone/contenttypes/browser/utils/templates/move_news_items.pt:113 +msgid "All the selected items will be moved to indicated path" +msgstr "Tutti gli elementi selezionati saranno spostati nella cartella indicata" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:33 +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:21 msgid "Animale domestico" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:25 -msgid "Anziano" -msgstr "" - -#: design/plone/contenttypes/interfaces/bando.py:134 -#: design/plone/contenttypes/interfaces/documento.py:67 -#: design/plone/contenttypes/interfaces/servizio.py:239 +#: design/plone/contenttypes/interfaces/bando.py:135 +#: design/plone/contenttypes/interfaces/documento.py:97 +#: design/plone/contenttypes/interfaces/servizio.py:328 msgid "Area" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:50 -msgid "Area di parcheggio" -msgstr "" - #: design/plone/contenttypes/behaviors/configure.zcml:49 msgid "Argomenti" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:76 +#: design/plone/contenttypes/behaviors/configure.zcml:94 msgid "Argomenti Bando" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:58 +#: design/plone/contenttypes/behaviors/configure.zcml:76 msgid "Argomenti Document" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:67 +#: design/plone/contenttypes/behaviors/configure.zcml:85 msgid "Argomenti Documento" msgstr "" -#: design/plone/contenttypes/behaviors/argomenti.py:28 +#: design/plone/contenttypes/behaviors/configure.zcml:112 +msgid "Argomenti Link" +msgstr "" + +#: design/plone/contenttypes/behaviors/argomenti.py:32 msgid "Argomenti correlati" msgstr "" @@ -116,20 +92,36 @@ msgstr "" msgid "Argomento" msgstr "" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:73 +#: design/plone/contenttypes/behaviors/configure.zcml:103 +msgid "Argomento Servizio" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:22 +msgid "Aria" +msgstr "" + +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:65 msgid "Assessore di riferimento" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:30 -msgid "Associazione" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:23 +msgid "Assistenza agli invalidi" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:24 +msgid "Assistenza sociale" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:25 +msgid "Associazioni" msgstr "" #: design/plone/contenttypes/vocabularies/lista_azioni_pratica.py:29 msgid "Attivare" msgstr "" -#: design/plone/contenttypes/vocabularies/document_types_vocabulary.py:33 -msgid "Atto normativo" +#: design/plone/contenttypes/interfaces/incarico.py:121 +msgid "Atto di nomina" msgstr "" #: design/plone/contenttypes/interfaces/documento_personale.py:86 @@ -140,70 +132,66 @@ msgstr "" msgid "Autorizzare" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:65 -msgid "Avvio impresa" -msgstr "" - -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:66 -msgid "Avvio nuova attività professionale" +#: design/plone/contenttypes/behaviors/configure.zcml:223 +msgid "Behavior address per Event." msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:69 -msgid "Avvio/registrazione filiale" +#: design/plone/contenttypes/behaviors/configure.zcml:215 +msgid "Behavior address per Venue." msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:78 -msgid "Bancarotta" +#: design/plone/contenttypes/behaviors/configure.zcml:263 +msgid "Behavior contatti per Event." msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:194 -msgid "Behavior address per Event." +#: design/plone/contenttypes/behaviors/configure.zcml:255 +msgid "Behavior contatti per Persona." msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:178 -msgid "Behavior address per UO." +#: design/plone/contenttypes/behaviors/configure.zcml:247 +msgid "Behavior contatti per Servizio." msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:186 -msgid "Behavior address per Venue." -msgstr "" - -#: design/plone/contenttypes/behaviors/configure.zcml:202 +#: design/plone/contenttypes/behaviors/configure.zcml:231 msgid "Behavior contatti per UO." msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:210 +#: design/plone/contenttypes/behaviors/configure.zcml:239 msgid "Behavior contatti per Venue." msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:234 +#: design/plone/contenttypes/behaviors/configure.zcml:279 msgid "Behavior geolocatable per Event." msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:218 -msgid "Behavior geolocatable per UO." +#: design/plone/contenttypes/behaviors/configure.zcml:271 +msgid "Behavior geolocatable per Venue." msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:226 -msgid "Behavior geolocatable per Venue." +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:26 +msgid "Bilancio" msgstr "" #: design/plone/contenttypes/controlpanels/geolocation_defaults.py:18 msgid "CAP" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:43 -msgid "Cambio di residenza/domicilio" +#: design/plone/contenttypes/behaviors/configure.zcml:306 +msgid "Campi aggiuntivi per la sezione amministrazione trasparente." msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:261 -msgid "Campi aggiuntivi per la sezione amministrazione trasparente." +#: design/plone/contenttypes/behaviors/configure.zcml:324 +msgid "Campo per escludere un contenuto dalle ricerche del sito." msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:270 +#: design/plone/contenttypes/behaviors/configure.zcml:315 msgid "Campo per le note di aggiornamento." msgstr "" +#: design/plone/contenttypes/interfaces/servizio.py:183 +msgid "Canale fisico" +msgstr "" + #: design/plone/contenttypes/vocabularies/mockup.py:26 msgid "Canon 5D IV" msgstr "" @@ -212,39 +200,44 @@ msgstr "" msgid "Cartella Modulistica" msgstr "" -#: design/plone/contenttypes/browser/manage_content/templates/change_news_type.pt:11 +#: design/plone/contenttypes/browser/utils/templates/change_news_type.pt:13 msgid "Change News Type" msgstr "Cambia la Tipologia Notizia" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:75 -msgid "Chiusura filiale" +#: design/plone/contenttypes/controlpanels/geolocation_defaults.py:23 +msgid "Città" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:74 -msgid "Chiusura impresa e attività professionale" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:28 +msgid "Commercio al minuto" msgstr "" -#: design/plone/contenttypes/controlpanels/geolocation_defaults.py:23 -msgid "Città" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:27 +msgid "Commercio all'ingrosso" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:39 -msgid "Compravendita/affitto casa/edifici/terreni, costruzione o ristrutturazione casa/edificio " +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:29 +msgid "Commercio ambulante" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:36 -msgid "Comunicazione" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:30 +msgid "Comunicazione istituzionale" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:41 -msgid "Condizioni e organizzazione del lavoro" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:31 +msgid "Comunicazione politica" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:32 +msgid "Concorsi" msgstr "" -#: design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt:57 +#: design/plone/contenttypes/browser/utils/templates/move_news_items.pt:104 msgid "Contained by" msgstr "Contenuto da" -#: design/plone/contenttypes/behaviors/configure.zcml:202 +#: design/plone/contenttypes/behaviors/configure.zcml:231 +#: design/plone/contenttypes/behaviors/contatti.py:112 msgid "Contatti" msgstr "" @@ -252,12 +245,12 @@ msgstr "" msgid "Coordinate" msgstr "" -#: design/plone/contenttypes/behaviors/argomenti.py:42 +#: design/plone/contenttypes/behaviors/argomenti.py:46 msgid "Correlato in evidenza" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:47 -msgid "Cultura" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:33 +msgid "Covid - 19" msgstr "" #: design/plone/contenttypes/interfaces/documento_personale.py:130 @@ -269,7 +262,7 @@ msgstr "" msgid "Dataset collegato" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:104 +#: design/plone/contenttypes/behaviors/configure.zcml:141 msgid "Dataset correlati" msgstr "" @@ -277,115 +270,102 @@ msgstr "" msgid "Delegare" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:52 -msgid "Denuncia crimini" -msgstr "" - -#: design/plone/contenttypes/behaviors/configure.zcml:143 +#: design/plone/contenttypes/behaviors/configure.zcml:180 msgid "Descrizione estesa" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:160 +#: design/plone/contenttypes/behaviors/configure.zcml:197 msgid "Descrizione estesa documento" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:152 +#: design/plone/contenttypes/behaviors/configure.zcml:189 msgid "Descrizione estesa servizio" msgstr "" -#: design/plone/contenttypes/configure.zcml:36 +#: design/plone/contenttypes/configure.zcml:32 msgid "Design Plone: Content-types" msgstr "" -#: design/plone/contenttypes/configure.zcml:45 +#: design/plone/contenttypes/configure.zcml:41 +msgid "Design Plone: Content-types (behaviors)" +msgstr "" + +#: design/plone/contenttypes/configure.zcml:50 msgid "Design Plone: Content-types (uninstall)" msgstr "" -#: design/plone/contenttypes/configure.zcml:52 +#: design/plone/contenttypes/configure.zcml:58 msgid "Design Plone: Content-types to 3000" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:55 -msgid "Dichiarazione dei redditi, versamento e riscossione tributi/imposte e contributi" +#: design/plone/contenttypes/configure.zcml:66 +msgid "Design Plone: Fix Syndication after Plone6 Migration" msgstr "" -#: design/plone/contenttypes/behaviors/trasparenza.py:145 +#: design/plone/contenttypes/behaviors/trasparenza.py:146 msgid "Dirigente" msgstr "" -#: design/plone/contenttypes/vocabularies/document_types_vocabulary.py:27 -msgid "Documenti albo pretorio" +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:134 +msgid "Documenti pubblici" msgstr "" -#: design/plone/contenttypes/interfaces/servizio.py:252 +#: design/plone/contenttypes/interfaces/servizio.py:341 #: design/plone/contenttypes/profiles/default/types/Documento.xml msgid "Documento" msgstr "" -#: design/plone/contenttypes/vocabularies/document_types_vocabulary.py:41 -msgid "Documento (tecnico) di supporto" -msgstr "" - #: design/plone/contenttypes/profiles/default/types/Documento_Personale.xml msgid "Documento Personale" msgstr "" -#: design/plone/contenttypes/vocabularies/document_types_vocabulary.py:37 -msgid "Documento attivita politica" -msgstr "" - -#: design/plone/contenttypes/vocabularies/document_types_vocabulary.py:31 -msgid "Documento funzionamento interno" -msgstr "" - -#: design/plone/contenttypes/vocabularies/dataset.py:30 -msgid "Economia e Finanze" -msgstr "" - #: design/plone/contenttypes/profiles/default/types/CartellaModulistica.xml #: design/plone/contenttypes/profiles/default/types/Dataset.xml #: design/plone/contenttypes/profiles/default/types/Documento.xml msgid "Edit" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:45 -msgid "Elezione" -msgstr "" - -#: design/plone/contenttypes/vocabularies/dataset.py:35 -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:61 -msgid "Energia" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:34 +msgid "Elezioni" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:28 -msgid "Famiglia" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:35 +msgid "Energie rinnovabili" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:26 -msgid "Fanciullo" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:36 +msgid "Estero" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:70 -msgid "Finanziamento impresa" +#: design/plone/contenttypes/behaviors/configure.zcml:324 +msgid "Exclude from search" msgstr "" -#: design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt:28 +#: design/plone/contenttypes/browser/utils/templates/move_news_items.pt:51 msgid "Find news with the indicated Path, put attention than generaly sites have the root name \"/Plone/\"" msgstr "Trova le notizie in path indicato. Attenzione, in maggior parte dei casi il sito ha il nome \"/Plone/\"" -#: design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt:21 +#: design/plone/contenttypes/browser/utils/templates/move_news_items.pt:29 msgid "Find news with this News Type" msgstr "Trova le notizie con la Tipologia Notizia indicata" -#: design/plone/contenttypes/configure.zcml:52 +#: design/plone/contenttypes/configure.zcml:58 msgid "Fix control panel of design.plone.contenttypes add-on." msgstr "" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:37 +msgid "Foreste" +msgstr "" + #: design/plone/contenttypes/vocabularies/tags_vocabulary.py:38 msgid "Formazione professionale" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:218 +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:39 +msgid "Gemellaggi" +msgstr "" + +#: design/plone/contenttypes/behaviors/configure.zcml:271 msgid "Geolocatable" msgstr "" @@ -394,44 +374,57 @@ msgstr "" msgid "Geolocation default" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:53 -msgid "Gestione dei rifiuti" -msgstr "" - -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:71 -msgid "Gestione personale" -msgstr "" - -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:27 -msgid "Giovane" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:40 +msgid "Gestione rifiuti" msgstr "" #: design/plone/contenttypes/vocabularies/mockup.py:30 msgid "Giovanni" msgstr "" -#: design/plone/contenttypes/vocabularies/dataset.py:42 -msgid "Giustizia, sistema giuridico e sicurezza pubblica" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:41 +msgid "Giustizia" msgstr "" -#: design/plone/contenttypes/vocabularies/dataset.py:37 -msgid "Governo e settore pubblico" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:42 +msgid "Igiene pubblica" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:48 +#: design/plone/contenttypes/browser/utils/change_news_type.py:32 +#: design/plone/contenttypes/browser/utils/move_news_items.py:74 +msgid "Il vocabolario dei valori non è stato trovato" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:43 msgid "Immigrazione" msgstr "" -#: design/plone/contenttypes/controlpanels/settings.py:154 +#: design/plone/contenttypes/controlpanels/settings.py:106 #: design/plone/contenttypes/profiles/default/controlpanel.xml msgid "Impostazioni Design Plone" msgstr "" -#: design/plone/contenttypes/browser/manage_content/move_news_items.py:33 +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:44 +msgid "Imposte" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:45 +msgid "Imprese" +msgstr "" + +#: design/plone/contenttypes/interfaces/persona.py:68 +msgid "Incarichi" +msgstr "" + +#: design/plone/contenttypes/profiles/default/types/Incarico.xml +msgid "Incarico" +msgstr "" + +#: design/plone/contenttypes/browser/utils/move_news_items.py:34 msgid "Indicated path is not valid" msgstr "Path indicato non è valido" -#: design/plone/contenttypes/behaviors/configure.zcml:170 +#: design/plone/contenttypes/behaviors/configure.zcml:207 msgid "Info per la testata" msgstr "" @@ -439,64 +432,56 @@ msgstr "" msgid "Informare" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:64 -msgid "Informatica e trattamento dei dati" +#: design/plone/contenttypes/behaviors/contatti.py:34 +msgid "Informazioni di contatto" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:49 +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:46 msgid "Inquinamento" msgstr "" -#: design/plone/contenttypes/configure.zcml:36 +#: design/plone/contenttypes/configure.zcml:32 msgid "Installs the design.plone.contenttypes add-on." msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:34 +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:47 msgid "Integrazione sociale" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:28 -msgid "Invalidità" -msgstr "" - #: design/plone/contenttypes/vocabularies/lista_azioni_pratica.py:26 msgid "Iscriversi" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:26 -msgid "Iscrizione scuola/università e/o richiesta borsa di studio" -msgstr "" - -#: design/plone/contenttypes/vocabularies/document_types_vocabulary.py:43 -msgid "Istanza" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:48 +msgid "Isolamento termico" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:31 +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:49 msgid "Istruzione" msgstr "" -#: design/plone/contenttypes/vocabularies/dataset.py:33 -msgid "Istruzione, cultura e sport" -msgstr "" - -#: design/plone/contenttypes/browser/manage_content/move_news_items.py:47 +#: design/plone/contenttypes/browser/utils/move_news_items.py:48 msgid "Items moved with success" msgstr "Gli elementi sono stati spostati con successo" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:50 +msgid "Lavoro" +msgstr "" + #: design/plone/contenttypes/vocabularies/lista_azioni_pratica.py:28 msgid "Leggere" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:85 +#: design/plone/contenttypes/behaviors/configure.zcml:122 msgid "Luoghi correlati" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:44 +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:51 msgid "Matrimonio" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:49 -msgid "Matrimonio e/o cambio stato civile" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:52 +msgid "Mercato" msgstr "" #: design/plone/contenttypes/profiles/default/types/Messaggio.xml @@ -515,72 +500,64 @@ msgstr "" msgid "Metadati news" msgstr "" -#: design/plone/contenttypes/vocabularies/document_types_vocabulary.py:28 -msgid "Modulistica" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:53 +msgid "Mobilità sostenibile" msgstr "" #: design/plone/contenttypes/profiles/default/types/Modulo.xml msgid "Modulo" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:50 -msgid "Morte ed eredità" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:54 +msgid "Morte" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:252 +#: design/plone/contenttypes/behaviors/configure.zcml:297 msgid "Mostra la data di modifica." msgstr "" -#: design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt:70 +#: design/plone/contenttypes/browser/utils/templates/move_news_items.pt:124 msgid "Move" msgstr "Sposta" -#: design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt:11 +#: design/plone/contenttypes/browser/utils/templates/move_news_items.pt:13 msgid "Move News Items" msgstr "Sposta le notizie" -#: design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt:62 +#: design/plone/contenttypes/browser/utils/templates/move_news_items.pt:110 msgid "Move to Path" msgstr "Sposta nella cartella" -#: design/plone/contenttypes/behaviors/configure.zcml:243 +#: design/plone/contenttypes/behaviors/configure.zcml:288 msgid "Multi File" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:48 -msgid "Nascita di un bambino, richiesta adozioni" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:55 +msgid "Nascita" msgstr "" #: design/plone/contenttypes/controlpanels/geolocation_defaults.py:28 msgid "Nazione" msgstr "" -#: design/plone/contenttypes/browser/manage_content/templates/change_news_type.pt:21 -#: design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt:20 +#: design/plone/contenttypes/browser/utils/templates/change_news_type.pt:27 +#: design/plone/contenttypes/browser/utils/templates/move_news_items.pt:26 msgid "News Type" msgstr "Tipologia Notizia" -#: design/plone/contenttypes/browser/manage_content/templates/change_news_type.pt:30 +#: design/plone/contenttypes/browser/utils/templates/change_news_type.pt:48 msgid "News Type to substitute" msgstr "Tipologia Notizia da sostituire" #. Default: "Nome e cognome" -#: design/plone/contenttypes/restapi/services/types/get.py:152 +#: design/plone/contenttypes/restapi/services/types/get.py:163 msgid "Nome e Cognome" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:73 -msgid "Notifiche autorità" -msgstr "" - -#: design/plone/contenttypes/interfaces/persona.py:48 +#: design/plone/contenttypes/interfaces/persona.py:51 msgid "Organizzazione di riferimento" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:72 -msgid "Pagamento tasse, iva e dogane" -msgstr "" - #: design/plone/contenttypes/vocabularies/lista_azioni_pratica.py:25 msgid "Pagare" msgstr "" @@ -589,84 +566,100 @@ msgstr "" msgid "Paperino" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:81 -msgid "Partecipazione ad appalti pubblici nazionali e trasfrontalieri" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:56 +msgid "Parcheggi" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:33 -msgid "Pensionamento" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:57 +msgid "Patrimonio culturale" msgstr "" -#: design/plone/contenttypes/profiles/default/types/Persona.xml +#: design/plone/contenttypes/interfaces/incarico.py:54 msgid "Persona" msgstr "" -#: design/plone/contenttypes/behaviors/evento.py:50 -msgid "Persona dell'amministrazione" +#: design/plone/contenttypes/profiles/default/types/Persona.xml +msgid "Persona pubblica" msgstr "" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:92 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:84 msgid "Persone della struttura" msgstr "" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:58 +msgid "Pesca" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:59 +msgid "Piano di sviluppo" +msgstr "" + #: design/plone/contenttypes/vocabularies/mockup.py:27 msgid "Pippo" msgstr "" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:60 +msgid "Pista ciclabile" +msgstr "" + #: design/plone/contenttypes/vocabularies/mockup.py:28 msgid "Pluto" msgstr "" -#: design/plone/contenttypes/vocabularies/dataset.py:45 -msgid "Popolazione e società" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:61 +msgid "Politica commerciale" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:60 -msgid "Possesso, cura, smarrimento animale da compagnia" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:62 +msgid "Polizia" msgstr "" #: design/plone/contenttypes/profiles/default/types/Pratica.xml msgid "Pratica" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:51 -msgid "Prenotazione e disdetta visite/esami" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:63 +msgid "Prodotti alimentari" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:35 -msgid "Protezione sociale" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:64 +msgid "Protezione civile" msgstr "" -#: design/plone/contenttypes/browser/manage_content/templates/change_news_type.pt:13 -msgid "Questo tool viene usato per cambiare il valore del campo 'Tipologia Notizia' in tutte le notizie che hanno il valore del campo selezionato. Fa anche il giro su tutti i blocchi elenco" +#: design/plone/contenttypes/behaviors/contatti.py:78 +msgid "Punti di contatto" msgstr "" -#: design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt:13 -msgid "Questo tool viene usato per trovare e spostare le Notizie con una Tipologia Notizia determinata." +#: design/plone/contenttypes/profiles/default/types/PuntoDiContatto.xml +msgid "Punto di Contatto" +msgstr "" + +#: design/plone/contenttypes/browser/utils/templates/change_news_type.pt:15 +msgid "Questo tool viene usato per cambiare il valore del campo 'Tipologia Notizia' in tutte le notizie che hanno il valore del campo selezionato. Fa anche il giro su tutti i blocchi elenco" msgstr "" -#: design/plone/contenttypes/vocabularies/dataset.py:44 -msgid "Regioni e città" +#: design/plone/contenttypes/browser/utils/templates/move_news_items.pt:15 +msgid "Questo tool viene usato per trovare e spostare le Notizie con una Tipologia Notizia determinata." msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:68 -msgid "Registrazione impresa transfrontalier" +#: design/plone/contenttypes/configure.zcml:41 +msgid "Registers taxonomies." msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:35 -msgid "Registrazione/possesso veicolo" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:65 +msgid "Residenza" msgstr "" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:45 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:49 msgid "Responsabile" msgstr "" -#: design/plone/contenttypes/behaviors/trasparenza.py:129 -msgid "Responsabile procedimento" +#: design/plone/contenttypes/interfaces/incarico.py:89 +msgid "Responsabile della struttura" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:31 -msgid "Ricerca di lavoro, avvio nuovo lavoro, disoccupazione" +#: design/plone/contenttypes/behaviors/trasparenza.py:130 +msgid "Responsabile procedimento" msgstr "" #: design/plone/contenttypes/profiles/default/types/RicevutaPagamento.xml @@ -677,40 +670,19 @@ msgstr "" msgid "Richiedere" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:67 -msgid "Richiesta licenze/permessi/certificati" -msgstr "" - -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:34 -msgid "Richiesta o rinnovo patente" -msgstr "" - -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:46 -msgid "Richiesta passaporto, visto e assistenza viaggi internazionali" -msgstr "" - -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:76 -msgid "Ristrutturazione impresa" -msgstr "" - -#: design/plone/contenttypes/vocabularies/dataset.py:38 -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:54 -msgid "Salute" -msgstr "" - -#: design/plone/contenttypes/vocabularies/dataset.py:46 -msgid "Scienza e tecnologia" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:66 +msgid "Risposta alle emergenze" msgstr "" -#: design/plone/contenttypes/browser/manage_content/templates/move_news_items.pt:27 +#: design/plone/contenttypes/browser/utils/templates/move_news_items.pt:47 msgid "Search Path" msgstr "Cartella della ricerca" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:114 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:104 msgid "Sede" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:114 +#: design/plone/contenttypes/behaviors/configure.zcml:151 msgid "Servizi correlati" msgstr "" @@ -722,129 +694,128 @@ msgstr "" msgid "Servizio collegato" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:252 +#: design/plone/contenttypes/behaviors/configure.zcml:297 msgid "Show modified" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:56 -msgid "Sicurezza internazionale" -msgstr "" - -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:55 -msgid "Sicurezza pubblica" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:67 +msgid "Sistema giuridico" msgstr "" #: design/plone/contenttypes/vocabularies/mockup.py:25 msgid "Sony Aplha 7R III" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:57 -msgid "Spazio verde" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:68 +msgid "Spazio Verde" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:58 +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:69 msgid "Sport" msgstr "" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:37 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:41 msgid "Struttura" msgstr "" -#: design/plone/contenttypes/behaviors/strutture_correlate.py:20 +#: design/plone/contenttypes/behaviors/strutture_correlate.py:21 msgid "Struttura politica coinvolta" msgstr "" -#: design/plone/contenttypes/behaviors/luogo.py:74 +#: design/plone/contenttypes/behaviors/luogo.py:75 msgid "Struttura responsabile" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:124 +#: design/plone/contenttypes/behaviors/configure.zcml:161 msgid "Strutture correlate" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:29 -msgid "Studente" -msgstr "" - -#: design/plone/contenttypes/browser/manage_content/templates/change_news_type.pt:43 +#: design/plone/contenttypes/browser/utils/templates/change_news_type.pt:74 msgid "Substitute" msgstr "Sostituisci" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:70 +msgid "Sviluppo sostenibile" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:71 +msgid "Tassa sui servizi" +msgstr "" + #: design/plone/contenttypes/behaviors/configure.zcml:49 msgid "Tassonomia argomenti" msgstr "" +#: design/plone/contenttypes/behaviors/configure.zcml:67 +msgid "Tassonomia argomenti evento" +msgstr "" + #: design/plone/contenttypes/behaviors/configure.zcml:58 -msgid "Tassonomia argomenti per i Document" +msgid "Tassonomia argomenti news" msgstr "" -#: design/plone/contenttypes/vocabularies/dataset.py:39 -msgid "Tematiche internazionali" +#: design/plone/contenttypes/behaviors/configure.zcml:76 +msgid "Tassonomia argomenti per i Document" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:46 +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:72 msgid "Tempo libero" msgstr "" -#: design/plone/contenttypes/browser/manage_content/templates/change_news_type.pt:31 +#: design/plone/contenttypes/browser/utils/templates/change_news_type.pt:52 msgid "The News Type selected above will be substituted by the selected value" msgstr "La Tipologia Notizia indicata sopra sarà sostituita dalla tipologia notizia selezionata" -#: design/plone/contenttypes/browser/manage_content/change_news_type.py:97 +#: design/plone/contenttypes/browser/utils/change_news_type.py:108 msgid "The News Types was changed with success" msgstr "Le Tiplogie Notizie sono state sostituite con successo" -#: design/plone/contenttypes/browser/manage_content/change_news_type.py:55 +#: design/plone/contenttypes/browser/utils/change_news_type.py:64 msgid "The new News Type was not found between available values" msgstr "La Tipologia Notizia nuova non è stata trovata tra i valori possibli" -#: design/plone/contenttypes/browser/manage_content/change_news_type.py:49 +#: design/plone/contenttypes/browser/utils/change_news_type.py:58 msgid "The new type field was not populated" msgstr "Il campo della avitabile Tipologia Notizia non è stato popolato" -#: design/plone/contenttypes/browser/manage_content/change_news_type.py:61 +#: design/plone/contenttypes/browser/utils/change_news_type.py:70 msgid "The old News Type was not found between available values" msgstr "La Tipologia Notizia vecchia non è stata trovata tra i valori possibli" -#: design/plone/contenttypes/browser/manage_content/change_news_type.py:43 +#: design/plone/contenttypes/browser/utils/change_news_type.py:52 msgid "The old type field was not populated" msgstr "l campo della Tipologia Notizia esistente non è stato popolato" -#: design/plone/contenttypes/browser/manage_content/move_news_items.py:51 +#: design/plone/contenttypes/browser/utils/move_news_items.py:52 msgid "The path was not indicated" msgstr "Il path non è stato indicato" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:51 -msgid "Traffico urbano" -msgstr "" - -#: design/plone/contenttypes/behaviors/configure.zcml:261 +#: design/plone/contenttypes/behaviors/configure.zcml:306 msgid "Trasparenza" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:43 -msgid "Trasporto" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:73 +msgid "Trasparenza amministrativa" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:59 -msgid "Trasporto stradale" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:74 +msgid "Trasporto pubblico" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:243 +#: design/plone/contenttypes/behaviors/configure.zcml:288 msgid "Tre campi file aggiuntivi." msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:60 +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:75 msgid "Turismo" msgstr "" -#: design/plone/contenttypes/interfaces/bando.py:117 -#: design/plone/contenttypes/interfaces/documento.py:50 -#: design/plone/contenttypes/interfaces/servizio.py:225 +#: design/plone/contenttypes/interfaces/bando.py:118 +#: design/plone/contenttypes/interfaces/documento.py:80 msgid "Ufficio responsabile" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:134 +#: design/plone/contenttypes/behaviors/configure.zcml:171 msgid "Ulteriori campi aiuto testuali" msgstr "" @@ -852,7 +823,11 @@ msgstr "" msgid "Un modulo compilabile." msgstr "" -#: design/plone/contenttypes/configure.zcml:45 +#: design/plone/contenttypes/browser/utils/templates/utils.pt:15 +msgid "Una raccolta di utility per i contenuti agid" +msgstr "" + +#: design/plone/contenttypes/configure.zcml:50 msgid "Uninstalls the design.plone.contenttypes add-on." msgstr "" @@ -864,65 +839,87 @@ msgstr "" msgid "Unità amministrative responsabili" msgstr "" -#: design/plone/contenttypes/behaviors/configure.zcml:270 -msgid "Update note" +#: design/plone/contenttypes/interfaces/incarico.py:71 +msgid "Unità organizzativa" msgstr "" -#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:37 -msgid "Urbanistica ed edilizia" +#: design/plone/contenttypes/interfaces/servizio.py:314 +msgid "Unità organizzativa responsabile" +msgstr "" + +#: design/plone/contenttypes/behaviors/configure.zcml:315 +msgid "Update note" msgstr "" -#: design/plone/contenttypes/vocabularies/all_life_events_vocabulary.py:77 -msgid "Vendita impresa" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:76 +msgid "Urbanizzazione" msgstr "" #: design/plone/contenttypes/controlpanels/geolocation_defaults.py:13 msgid "Via" msgstr "" +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:77 +msgid "Viaggi" +msgstr "" + #: design/plone/contenttypes/profiles/default/types/CartellaModulistica.xml #: design/plone/contenttypes/profiles/default/types/Dataset.xml #: design/plone/contenttypes/profiles/default/types/Documento.xml msgid "View" msgstr "" -#. Default: "A chi si rivolge questo servizio e chi può usufruirne." -#: design/plone/contenttypes/interfaces/servizio.py:53 +#: design/plone/contenttypes/browser/utils/templates/utils.pt:13 +msgid "Viste di utility per Design Plone Contenttypes" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:79 +msgid "ZTL" +msgstr "" + +#: design/plone/contenttypes/vocabularies/tags_vocabulary.py:78 +msgid "Zone pedonali" +msgstr "" + +#. Default: "Descrizione testuale dei principali destinatari dell'Evento" +#: design/plone/contenttypes/behaviors/evento.py:43 +#: design/plone/contenttypes/interfaces/servizio.py:98 msgid "a_chi_si_rivolge_help" msgstr "" -#. Default: "A chi si rivolge" -#: design/plone/contenttypes/interfaces/servizio.py:51 +#. Default: "A chi è rivolto" +#: design/plone/contenttypes/behaviors/evento.py:41 +#: design/plone/contenttypes/interfaces/servizio.py:96 msgid "a_chi_si_rivolge_label" msgstr "" #. Default: "Seleziona l'ufficio di comunicazione responsabile di questa notizia/comunicato stampa." -#: design/plone/contenttypes/behaviors/news_additional_fields.py:47 +#: design/plone/contenttypes/behaviors/news_additional_fields.py:39 msgid "a_cura_di_help" msgstr "" #. Default: "A cura di" -#: design/plone/contenttypes/behaviors/news_additional_fields.py:46 +#: design/plone/contenttypes/behaviors/news_additional_fields.py:38 msgid "a_cura_di_label" msgstr "" #. Default: "Seleziona una lista di persone dell'amministrazione citate in questa notizia/comunicato stampa. Questa informazione verrà mostrata nella sezione \"A cura di\"." -#: design/plone/contenttypes/behaviors/news_additional_fields.py:59 +#: design/plone/contenttypes/behaviors/news_additional_fields.py:51 msgid "a_cura_di_persone_help" msgstr "" #. Default: "Persone" -#: design/plone/contenttypes/behaviors/news_additional_fields.py:58 +#: design/plone/contenttypes/behaviors/news_additional_fields.py:50 msgid "a_cura_di_persone_label" msgstr "" #. Default: "Accedere al servizio" -#: design/plone/contenttypes/interfaces/servizio.py:370 +#: design/plone/contenttypes/interfaces/servizio.py:481 msgid "accedi_al_servizio_label" msgstr "" #. Default: "Modalità di accesso" -#: design/plone/contenttypes/behaviors/luogo.py:171 +#: design/plone/contenttypes/behaviors/luogo.py:140 msgid "accesso_label" msgstr "" @@ -932,37 +929,37 @@ msgid "allegato" msgstr "" #. Default: "Indicare, se esistono, altre modalità di invio." -#: design/plone/contenttypes/behaviors/trasparenza.py:189 +#: design/plone/contenttypes/behaviors/trasparenza.py:190 msgid "altre_modalita_invio_help" msgstr "" #. Default: "Altre modalità di invio" -#: design/plone/contenttypes/behaviors/trasparenza.py:185 +#: design/plone/contenttypes/behaviors/trasparenza.py:186 msgid "altre_modalita_invio_label" msgstr "" #. Default: "Seleziona la lista dei documenti di supporto collegati a questo servizio." -#: design/plone/contenttypes/interfaces/servizio.py:246 +#: design/plone/contenttypes/interfaces/servizio.py:335 msgid "altri_documenti_help" msgstr "" #. Default: "Date and time of the opening of the announcement. Use this field if you want to set a specific opening date. If not set, the announcement will be open immediately." -#: design/plone/contenttypes/interfaces/bando.py:56 +#: design/plone/contenttypes/interfaces/bando.py:57 msgid "apertura_bando_help" msgstr "" #. Default: "Opening date" -#: design/plone/contenttypes/interfaces/bando.py:55 +#: design/plone/contenttypes/interfaces/bando.py:56 msgid "apertura_bando_label" msgstr "" #. Default: "Area" -#: design/plone/contenttypes/interfaces/servizio.py:231 +#: design/plone/contenttypes/interfaces/servizio.py:320 msgid "area" msgstr "" #. Default: "Seleziona l'area da cui dipende questo servizio." -#: design/plone/contenttypes/interfaces/servizio.py:234 +#: design/plone/contenttypes/interfaces/servizio.py:323 msgid "area_help" msgstr "" @@ -972,14 +969,14 @@ msgid "area_responsabile_documento_personale" msgstr "" #. Default: "Seleziona l'area amministrativa responsabile del documento." -#: design/plone/contenttypes/interfaces/bando.py:127 -#: design/plone/contenttypes/interfaces/documento.py:60 +#: design/plone/contenttypes/interfaces/bando.py:128 +#: design/plone/contenttypes/interfaces/documento.py:90 msgid "area_responsabile_help" msgstr "" #. Default: "Area responsabile del documento" -#: design/plone/contenttypes/interfaces/bando.py:123 -#: design/plone/contenttypes/interfaces/documento.py:56 +#: design/plone/contenttypes/interfaces/bando.py:124 +#: design/plone/contenttypes/interfaces/documento.py:86 msgid "area_responsabile_label" msgstr "" @@ -989,47 +986,42 @@ msgid "argomenti_utenti" msgstr "" #. Default: "Inserire l'assessore di riferimento della struttura, se esiste." -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:76 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:68 msgid "assessore_riferimento_help" msgstr "" +#. Default: "Assessore di riferimento" +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:61 +msgid "assessore_riferimento_title" +msgstr "" + #. Default: "Indicare, se la esistono, atti e documenti a corredo dell'istanza." -#: design/plone/contenttypes/behaviors/trasparenza.py:200 +#: design/plone/contenttypes/behaviors/trasparenza.py:201 msgid "atti_documenti_corredo_help" msgstr "" #. Default: "Atti e documenti a corredo dell'istanza" -#: design/plone/contenttypes/behaviors/trasparenza.py:196 +#: design/plone/contenttypes/behaviors/trasparenza.py:197 msgid "atti_documenti_corredo_label" msgstr "" -#. Default: "Inserire un file contenente l'atto di nomina della persona." -#: design/plone/contenttypes/interfaces/persona.py:160 -msgid "atto_nomina_help" +#. Default: "Inserire riferimento all'atto di nomina della persona" +#: design/plone/contenttypes/interfaces/incarico.py:114 +msgid "atto_nomina_incarico_help" msgstr "" #. Default: "Atto di nomina" -#: design/plone/contenttypes/interfaces/persona.py:158 -msgid "atto_nomina_label" -msgstr "" - -#. Default: "Autenticazione" -#: design/plone/contenttypes/interfaces/servizio.py:121 -msgid "autenticazione" -msgstr "" - -#. Default: "Indicare, se previste, le modalità di autenticazione necessarie per poter accedere al servizio." -#: design/plone/contenttypes/interfaces/servizio.py:122 -msgid "autenticazione_help" +#: design/plone/contenttypes/interfaces/incarico.py:110 +msgid "atto_nomina_incarico_label" msgstr "" #. Default: "Seleziona una lista di autori che hanno pubblicato il documento. Possono essere Persone o Unità Organizzative." -#: design/plone/contenttypes/interfaces/documento.py:76 +#: design/plone/contenttypes/interfaces/documento.py:106 msgid "autori_help" msgstr "" #. Default: "Autore/i" -#: design/plone/contenttypes/interfaces/documento.py:72 +#: design/plone/contenttypes/interfaces/documento.py:102 msgid "autori_label" msgstr "" @@ -1049,52 +1041,72 @@ msgid "azioni_utente" msgstr "" #. Default: "Solo per persona politica: testo descrittivo che riporta la biografia della persona." -#: design/plone/contenttypes/interfaces/persona.py:107 +#: design/plone/contenttypes/interfaces/persona.py:94 msgid "biografia_help" msgstr "" #. Default: "Biografia" -#: design/plone/contenttypes/interfaces/persona.py:106 +#: design/plone/contenttypes/interfaces/persona.py:93 msgid "biografia_label" msgstr "" #. Default: "Canale digitale" -#: design/plone/contenttypes/interfaces/servizio.py:111 +#: design/plone/contenttypes/interfaces/servizio.py:156 msgid "canale_digitale" msgstr "" -#. Default: "Collegamento con l'eventuale canale digitale di attivazione del servizio." -#: design/plone/contenttypes/interfaces/servizio.py:112 +#. Default: "Testo di introduzione del canale digitale" +#: design/plone/contenttypes/interfaces/servizio.py:157 msgid "canale_digitale_help" msgstr "" +#. Default: "Link al canale digitale" +#: design/plone/contenttypes/interfaces/servizio.py:165 +msgid "canale_digitale_link" +msgstr "" + +#. Default: "Collegamento con l'eventuale canale digitale di attivazione del servizio." +#: design/plone/contenttypes/interfaces/servizio.py:166 +msgid "canale_digitale_link_help" +msgstr "" + #. Default: "Canale digitale servizio collegato" #: design/plone/contenttypes/interfaces/documento_personale.py:108 msgid "canale_digitale_servizio" msgstr "" +#. Default: "Canale fisico" +#: design/plone/contenttypes/interfaces/servizio.py:175 +msgid "canale_fisico" +msgstr "" + +#. Default: "Unità organizzative per la fruizione del servizio" +#: design/plone/contenttypes/interfaces/servizio.py:176 +msgid "canale_fisico_help" +msgstr "" + #. Default: "Casi particolari" -#: design/plone/contenttypes/interfaces/servizio.py:205 +#: design/plone/contenttypes/interfaces/servizio.py:291 msgid "casi_particolari" msgstr "" #. Default: "Descrizione degli evetuali casi particolari riferiti alla fruibilità di questo servizio." -#: design/plone/contenttypes/interfaces/servizio.py:207 +#: design/plone/contenttypes/interfaces/servizio.py:293 msgid "casi_particolari_help" msgstr "" #. Default: "Casi particolari" -#: design/plone/contenttypes/interfaces/servizio.py:401 +#: design/plone/contenttypes/interfaces/servizio.py:514 msgid "casi_particolari_label" msgstr "" #. Default: "Descrizione di chi può presentare domanda per usufruire del servizio e delle diverse casistiche." -#: design/plone/contenttypes/interfaces/servizio.py:62 +#: design/plone/contenttypes/interfaces/servizio.py:107 msgid "chi_puo_presentare_help" msgstr "" #. Default: "Chi può presentare" -#: design/plone/contenttypes/interfaces/servizio.py:60 +#: design/plone/contenttypes/interfaces/servizio.py:105 msgid "chi_puo_presentare_label" msgstr "" @@ -1104,37 +1116,57 @@ msgid "circoscrizione" msgstr "" #. Default: "Codice dell'ente erogatore (ipa)" -#: design/plone/contenttypes/interfaces/servizio.py:268 +#: design/plone/contenttypes/interfaces/servizio.py:357 msgid "codice_ipa" msgstr "" #. Default: "Specificare il nome dell’organizzazione, come indicato nell’Indice della Pubblica Amministrazione (IPA), che esercita uno specifico ruolo sul Servizio." -#: design/plone/contenttypes/interfaces/servizio.py:270 +#: design/plone/contenttypes/interfaces/servizio.py:359 msgid "codice_ipa_help" msgstr "" -#. Default: "Come si fa" -#: design/plone/contenttypes/interfaces/servizio.py:80 +#. Default: "Come fare" +#: design/plone/contenttypes/interfaces/servizio.py:125 msgid "come_si_fa" msgstr "" #. Default: "Descrizione della procedura da seguire per poter usufruire del servizio." -#: design/plone/contenttypes/interfaces/servizio.py:82 +#: design/plone/contenttypes/interfaces/servizio.py:127 msgid "come_si_fa_help" msgstr "" +#. Default: "Solo per incarico politico: compensi di qualsiasi natura connessi all'assunzione della carica." +#: design/plone/contenttypes/interfaces/incarico.py:21 +msgid "compensi_incarico_help" +msgstr "" + +#. Default: "Compensi" +#: design/plone/contenttypes/interfaces/incarico.py:17 +msgid "compensi_incarico_label" +msgstr "" + #. Default: "Descrizione del ruolo e dei compiti della persona." -#: design/plone/contenttypes/interfaces/persona.py:69 +#: design/plone/contenttypes/interfaces/persona.py:77 msgid "competenze_help" msgstr "" #. Default: "Competenze" -#: design/plone/contenttypes/interfaces/persona.py:68 +#: design/plone/contenttypes/interfaces/persona.py:76 msgid "competenze_label" msgstr "" -#. Default: "Informazioni di contatto generiche" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:137 +#. Default: "Condizioni di servizio" +#: design/plone/contenttypes/interfaces/servizio.py:388 +msgid "condizioni_di_servizio" +msgstr "" + +#. Default: "Contatti dell'unità organizzativa." +#: design/plone/contenttypes/behaviors/contatti.py:27 +msgid "contact_info_help" +msgstr "" + +#. Default: "Punti di contatto dell'unità organizzativa" +#: design/plone/contenttypes/behaviors/contatti.py:23 msgid "contact_info_label" msgstr "" @@ -1144,9 +1176,9 @@ msgid "contatti" msgstr "" #. Default: "Contatti" -#: design/plone/contenttypes/behaviors/address.py:52 -#: design/plone/contenttypes/behaviors/contatti.py:76 -#: design/plone/contenttypes/behaviors/evento.py:215 +#: design/plone/contenttypes/behaviors/contatti.py:57 +#: design/plone/contenttypes/behaviors/evento.py:170 +#: design/plone/contenttypes/behaviors/geolocation.py:18 msgid "contatti_label" msgstr "" @@ -1156,116 +1188,111 @@ msgid "contenuto" msgstr "" #. Default: "Indicare se il servizio si riferisce ad una particolare area geografica o all'intero territorio di riferimento." -#: design/plone/contenttypes/interfaces/servizio.py:72 +#: design/plone/contenttypes/interfaces/servizio.py:117 msgid "copertura_geografica_help" msgstr "" #. Default: "Copertura geografica" -#: design/plone/contenttypes/interfaces/servizio.py:70 +#: design/plone/contenttypes/interfaces/servizio.py:115 msgid "copertura_geografica_label" msgstr "" #. Default: "Contenuti collegati" -#: design/plone/contenttypes/behaviors/argomenti.py:74 +#: design/plone/contenttypes/behaviors/argomenti.py:108 #: design/plone/contenttypes/behaviors/dataset_correlati.py:40 -#: design/plone/contenttypes/behaviors/servizi_correlati.py:43 +#: design/plone/contenttypes/behaviors/news_additional_fields.py:120 msgid "correlati_label" msgstr "" #. Default: "Seleziona un correlato da mettere in evidenza per questo contenuto." -#: design/plone/contenttypes/behaviors/argomenti.py:36 +#: design/plone/contenttypes/behaviors/argomenti.py:40 msgid "correlato_in_evidenza_help" msgstr "" #. Default: "Correlato in evidenza" -#: design/plone/contenttypes/behaviors/argomenti.py:35 +#: design/plone/contenttypes/behaviors/argomenti.py:39 msgid "correlato_in_evidenza_label" msgstr "" -#. Default: "Cosa fa" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:206 +#. Default: "Competenze" +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:201 msgid "cosa_fa_label" msgstr "" #. Default: "Cosa serve" -#: design/plone/contenttypes/interfaces/servizio.py:177 +#: design/plone/contenttypes/interfaces/servizio.py:263 msgid "cosa_serve" msgstr "" #. Default: "Descrizione delle istruzioni per usufruire del servizio." -#: design/plone/contenttypes/interfaces/servizio.py:179 +#: design/plone/contenttypes/interfaces/servizio.py:265 msgid "cosa_serve_help" msgstr "" #. Default: "Cosa serve" -#: design/plone/contenttypes/interfaces/servizio.py:384 +#: design/plone/contenttypes/interfaces/servizio.py:497 msgid "cosa_serve_label" msgstr "" #. Default: "Cosa si ottiene" -#: design/plone/contenttypes/interfaces/servizio.py:90 +#: design/plone/contenttypes/interfaces/servizio.py:135 msgid "cosa_si_ottiene" msgstr "" #. Default: "Indicare cosa si può ottenere dal servizio, ad esempio 'carta di identità elettronica', 'certificato di residenza'." -#: design/plone/contenttypes/interfaces/servizio.py:91 +#: design/plone/contenttypes/interfaces/servizio.py:136 msgid "cosa_si_ottiene_help" msgstr "" #. Default: "Cos'è" -#: design/plone/contenttypes/behaviors/descrizione_estesa.py:40 -#: design/plone/contenttypes/behaviors/evento.py:200 +#: design/plone/contenttypes/behaviors/descrizione_estesa.py:52 +#: design/plone/contenttypes/behaviors/evento.py:155 msgid "cose_label" msgstr "" #. Default: "Costi" -#: design/plone/contenttypes/interfaces/servizio.py:186 +#: design/plone/contenttypes/interfaces/servizio.py:272 msgid "costi" msgstr "" #. Default: "Costi e vincoli" -#: design/plone/contenttypes/interfaces/servizio.py:389 +#: design/plone/contenttypes/interfaces/servizio.py:502 msgid "costi_e_vincoli_label" msgstr "" #. Default: "Descrizione delle condizioni e dei termini economici per completare la procedura di richiesta del servizio." -#: design/plone/contenttypes/interfaces/servizio.py:188 +#: design/plone/contenttypes/interfaces/servizio.py:274 msgid "costi_help" msgstr "" #. Default: "Costi" -#: design/plone/contenttypes/behaviors/evento.py:212 +#: design/plone/contenttypes/behaviors/evento.py:167 msgid "costi_label" msgstr "" #. Default: "Allega un file contenente il curriculum vitae della persona. Se ha più file da allegare, utilizza questo campo per quello principale e gli altri mettili dentro alla cartella \"Curriculum vitae\" che troverai dentro alla Persona." -#: design/plone/contenttypes/interfaces/persona.py:149 +#: design/plone/contenttypes/interfaces/persona.py:105 msgid "curriculum_vitae_help" msgstr "" #. Default: "Curriculum vitae" -#: design/plone/contenttypes/interfaces/persona.py:147 +#: design/plone/contenttypes/interfaces/persona.py:103 msgid "curriculum_vitae_label" msgstr "" #. Default: "Risultati indagini di customer satisfaction." -#: design/plone/contenttypes/behaviors/trasparenza.py:254 +#: design/plone/contenttypes/behaviors/trasparenza.py:255 msgid "customer_satisfaction_help" msgstr "" #. Default: "Risultati indagini di customer satisfaction" -#: design/plone/contenttypes/behaviors/trasparenza.py:249 +#: design/plone/contenttypes/behaviors/trasparenza.py:250 msgid "customer_satisfaction_label" msgstr "" -#. Default: "Data di conclusione dell'incarico." -#: design/plone/contenttypes/interfaces/persona.py:60 -msgid "data_conclusione_incarico_help" -msgstr "" - #. Default: "Data conclusione incarico" -#: design/plone/contenttypes/interfaces/persona.py:56 -msgid "data_conclusione_incarico_label" +#: design/plone/contenttypes/interfaces/incarico.py:100 +msgid "data_conclusione_incarico" msgstr "" #. Default: "Data e fasi intermedie" @@ -1278,14 +1305,14 @@ msgstr "" msgid "data_inizio" msgstr "" -#. Default: "Solo per persona politica: specificare la data di insediamento." -#: design/plone/contenttypes/interfaces/persona.py:97 -msgid "data_insediamento_help" +#. Default: "Data inizio incarico" +#: design/plone/contenttypes/interfaces/incarico.py:95 +msgid "data_inizio_incarico" msgstr "" #. Default: "Data insediamento" -#: design/plone/contenttypes/interfaces/persona.py:96 -msgid "data_insediamento_label" +#: design/plone/contenttypes/interfaces/incarico.py:105 +msgid "data_insediamento" msgstr "" #. Default: "Data del messaggio" @@ -1299,296 +1326,272 @@ msgid "data_pagamento" msgstr "" #. Default: "Data del protocollo" +#: design/plone/contenttypes/interfaces/documento.py:41 #: design/plone/contenttypes/interfaces/documento_personale.py:19 msgid "data_protocollo" msgstr "" +#. Default: "Data scadenza" +#: design/plone/contenttypes/interfaces/servizio.py:49 +msgid "data_scadenza_label" +msgstr "" + #. Default: "Data di scadenza della procedura" #: design/plone/contenttypes/interfaces/messaggio.py:40 msgid "data_scadenza_procedura" msgstr "" #. Default: "Dataset" -#: design/plone/contenttypes/interfaces/dataset.py:27 +#: design/plone/contenttypes/interfaces/dataset.py:20 msgid "dataset" msgstr "" +#. Default: "Schede dataset collegate al documento" +#: design/plone/contenttypes/interfaces/documento.py:150 +msgid "dataset_collegati_help" +msgstr "" + #. Default: "Seleziona una lista di schede dataset collegate a questo contenuto." -#: design/plone/contenttypes/behaviors/dataset_correlati.py:19 +#: design/plone/contenttypes/behaviors/dataset_correlati.py:20 msgid "dataset_correlati_help" msgstr "" #. Default: "Dataset correlati" -#: design/plone/contenttypes/behaviors/dataset_correlati.py:18 +#: design/plone/contenttypes/behaviors/dataset_correlati.py:19 msgid "dataset_correlati_label" msgstr "" +#. Default: "Dataset collegati" +#: design/plone/contenttypes/interfaces/documento.py:146 +msgid "dataset_label" +msgstr "" + +#. Default: "Date e informazioni" +#: design/plone/contenttypes/interfaces/incarico.py:175 +msgid "date_e_informazioni_label" +msgstr "" + #. Default: "Date e orari" -#: design/plone/contenttypes/behaviors/evento.py:209 -#: design/plone/contenttypes/schema_overrides.py:34 +#: design/plone/contenttypes/behaviors/evento.py:164 +#: design/plone/contenttypes/schema_overrides.py:33 msgid "date_e_orari_label" msgstr "" #. Default: "Inserisci la decorrenza termine del procedimento." -#: design/plone/contenttypes/behaviors/trasparenza.py:69 +#: design/plone/contenttypes/behaviors/trasparenza.py:70 msgid "decorrenza_termini_help" msgstr "" #. Default: "Decorrenza termine del procedimento" -#: design/plone/contenttypes/behaviors/trasparenza.py:64 +#: design/plone/contenttypes/behaviors/trasparenza.py:65 msgid "decorrenza_termini_label" msgstr "" #. Default: "Elenco delle deleghe a capo della persona." -#: design/plone/contenttypes/interfaces/persona.py:77 +#: design/plone/contenttypes/interfaces/persona.py:85 msgid "deleghe_help" msgstr "" #. Default: "Deleghe" -#: design/plone/contenttypes/interfaces/persona.py:76 +#: design/plone/contenttypes/interfaces/persona.py:84 msgid "deleghe_label" msgstr "" #. Default: "Descrizione completa" -#: design/plone/contenttypes/behaviors/luogo.py:23 +#: design/plone/contenttypes/behaviors/luogo.py:24 msgid "descrizione_completa" msgstr "" -#. Default: "Descrizione destinatari" -#: design/plone/contenttypes/behaviors/evento.py:38 -msgid "descrizione_destinatari" -msgstr "" - -#. Default: "Descrizione dei principali interlocutori dell'evento." -#: design/plone/contenttypes/behaviors/evento.py:40 -msgid "descrizione_destinatari_help" -msgstr "" - #. Default: "Descrizione estesa" -#: design/plone/contenttypes/behaviors/descrizione_estesa.py:16 -#: design/plone/contenttypes/behaviors/evento.py:30 -#: design/plone/contenttypes/behaviors/news_additional_fields.py:19 +#: design/plone/contenttypes/behaviors/descrizione_estesa.py:17 +#: design/plone/contenttypes/behaviors/evento.py:32 +#: design/plone/contenttypes/behaviors/news_additional_fields.py:21 msgid "descrizione_estesa" msgstr "" #. Default: "Descrizione dettagliata e completa." -#: design/plone/contenttypes/behaviors/descrizione_estesa.py:18 -#: design/plone/contenttypes/behaviors/evento.py:32 -#: design/plone/contenttypes/behaviors/news_additional_fields.py:21 +#: design/plone/contenttypes/behaviors/descrizione_estesa.py:19 +#: design/plone/contenttypes/behaviors/evento.py:34 +#: design/plone/contenttypes/behaviors/news_additional_fields.py:23 msgid "descrizione_estesa_help" msgstr "" #. Default: "Descrizione" -#: design/plone/contenttypes/behaviors/descrizione_estesa.py:51 -#: design/plone/contenttypes/behaviors/luogo.py:166 -#: design/plone/contenttypes/interfaces/documento.py:162 +#: design/plone/contenttypes/behaviors/descrizione_estesa.py:72 +#: design/plone/contenttypes/behaviors/luogo.py:135 +#: design/plone/contenttypes/interfaces/documento.py:242 msgid "descrizione_label" msgstr "" #. Default: "Inserisci eventuale testo descrittivo del procedimento." -#: design/plone/contenttypes/behaviors/trasparenza.py:37 +#: design/plone/contenttypes/behaviors/trasparenza.py:38 msgid "descrizione_procedimento_help" msgstr "" #. Default: "Descrizione del procedimento" -#: design/plone/contenttypes/behaviors/trasparenza.py:32 +#: design/plone/contenttypes/behaviors/trasparenza.py:33 msgid "descrizione_procedimento_label" msgstr "" #. Default: "Dirigente" -#: design/plone/contenttypes/behaviors/trasparenza.py:136 +#: design/plone/contenttypes/behaviors/trasparenza.py:137 msgid "dirigente" msgstr "" #. Default: "Indicare il dirigente." -#: design/plone/contenttypes/behaviors/trasparenza.py:140 +#: design/plone/contenttypes/behaviors/trasparenza.py:141 msgid "dirigente_help" msgstr "" #. Default: "Distribuzione" -#: design/plone/contenttypes/interfaces/dataset.py:22 +#: design/plone/contenttypes/interfaces/dataset.py:15 msgid "distribuzione" msgstr "" #. Default: "Documenti allegati" -#: design/plone/contenttypes/interfaces/messaggio.py:56 +#: design/plone/contenttypes/interfaces/messaggio.py:48 msgid "documenti_allegati" msgstr "" #. Default: "Seleziona una serie di altri contenuti di tipo Documento che vanno allegati a questo." -#: design/plone/contenttypes/interfaces/documento.py:113 +#: design/plone/contenttypes/interfaces/documento.py:194 msgid "documenti_allegati_help" msgstr "" #. Default: "Documenti allegati" -#: design/plone/contenttypes/interfaces/documento.py:109 +#: design/plone/contenttypes/interfaces/documento.py:190 msgid "documenti_allegati_label" msgstr "" #. Default: "Documenti" -#: design/plone/contenttypes/interfaces/persona.py:199 -#: design/plone/contenttypes/interfaces/servizio.py:412 +#: design/plone/contenttypes/interfaces/persona.py:146 +#: design/plone/contenttypes/interfaces/servizio.py:525 msgid "documenti_label" msgstr "" +#. Default: "Documenti pubblici importanti, collegati a questa Unità Organizzativa" +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:129 +msgid "documenti_pubblici_help" +msgstr "" + +#. Default: "Documenti pubblici" +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:127 +msgid "documenti_pubblici_label" +msgstr "" + #. Default: "Dove" -#: design/plone/contenttypes/behaviors/address.py:71 -#: design/plone/contenttypes/behaviors/geolocation.py:29 +#: design/plone/contenttypes/behaviors/address.py:53 +#: design/plone/contenttypes/behaviors/geolocation.py:26 msgid "dove_label" msgstr "" #. Default: "Dove rivolgersi: informazioni aggiuntive" -#: design/plone/contenttypes/interfaces/servizio.py:143 +#: design/plone/contenttypes/interfaces/servizio.py:212 msgid "dove_rivolgersi_extra" msgstr "" #. Default: "Indicare eventuali informazioni aggiuntive riguardo al dove rivolgersi per questo servizio." -#: design/plone/contenttypes/interfaces/servizio.py:147 +#: design/plone/contenttypes/interfaces/servizio.py:216 msgid "dove_rivolgersi_extra_help" msgstr "" #. Default: "Seleziona una lista delle sedi e dei luoghi in cui è presente questo servizio." -#: design/plone/contenttypes/interfaces/servizio.py:135 +#: design/plone/contenttypes/interfaces/servizio.py:204 msgid "dove_rivolgersi_help" msgstr "" #. Default: "Elementi di interesse" -#: design/plone/contenttypes/behaviors/luogo.py:44 +#: design/plone/contenttypes/behaviors/luogo.py:45 msgid "elementi_di_interesse" msgstr "" -#. Default: "Indicare un indirizzo mail per poter contattare gli organizzatori." -#: design/plone/contenttypes/behaviors/evento.py:128 -msgid "email_event_help" -msgstr "" - -#. Default: "E-mail" -#: design/plone/contenttypes/behaviors/evento.py:127 -msgid "email_event_label" -msgstr "" - -#. Default: "Indicare un indirizzo mail per poter contattare i referenti." -#: design/plone/contenttypes/behaviors/contatti.py:35 -msgid "email_help" -msgstr "" - -#. Default: "E-mail" -#: design/plone/contenttypes/behaviors/contatti.py:34 -msgid "email_label" -msgstr "" - -#. Default: "Contatto mail della persona. E' possibile inserire più di un indirizzo. Premendo \"Invio\" o \"tab\" si può passare al successivo da inserire." -#: design/plone/contenttypes/interfaces/persona.py:135 -msgid "email_persona_help" -msgstr "" - -#. Default: "Indirizzo email" -#: design/plone/contenttypes/interfaces/persona.py:134 -msgid "email_persona_label" -msgstr "" - #. Default: "Esito" #: design/plone/contenttypes/interfaces/ricevuta_pagamento.py:51 msgid "esito" msgstr "" -#. Default: "Fax" -#: design/plone/contenttypes/behaviors/evento.py:113 -msgid "fax_event_help" -msgstr "" - -#. Default: "Indicare un numero di fax." -#: design/plone/contenttypes/behaviors/evento.py:114 -msgid "fax_event_label" -msgstr "" - -#. Default: "Indicare un numero di fax." -#: design/plone/contenttypes/behaviors/contatti.py:29 -msgid "fax_help" -msgstr "" - -#. Default: "Fax" -#: design/plone/contenttypes/behaviors/contatti.py:28 -msgid "fax_label" -msgstr "" - -#. Default: "Indicare un numero di fax." -#: design/plone/contenttypes/interfaces/persona.py:130 -msgid "fax_persona_help" -msgstr "" - -#. Default: "Fax" -#: design/plone/contenttypes/interfaces/persona.py:129 -msgid "fax_persona_label" +#. Default: "Escludi dalla ricerca" +#: design/plone/contenttypes/behaviors/exclude_from_search.py:17 +msgid "exclude_from_search_label" msgstr "" #. Default: "Inserisci il file correlato di questo pocedimento." -#: design/plone/contenttypes/behaviors/trasparenza.py:44 +#: design/plone/contenttypes/behaviors/trasparenza.py:45 msgid "file_correlato_help" msgstr "" #. Default: "File correlato" -#: design/plone/contenttypes/behaviors/trasparenza.py:43 +#: design/plone/contenttypes/behaviors/trasparenza.py:44 msgid "file_correlato_label" msgstr "" #. Default: "Inserisci il file principale di questo contenuto." -#: design/plone/contenttypes/behaviors/multi_file.py:16 +#: design/plone/contenttypes/behaviors/multi_file.py:17 msgid "file_principale_help" msgstr "" #. Default: "File principale" -#: design/plone/contenttypes/behaviors/multi_file.py:15 +#: design/plone/contenttypes/behaviors/multi_file.py:16 msgid "file_principale_label" msgstr "" #. Default: "Inserisci la fine termine del procedimento." -#: design/plone/contenttypes/behaviors/trasparenza.py:80 +#: design/plone/contenttypes/behaviors/trasparenza.py:81 msgid "fine_termine_help" msgstr "" #. Default: "Fine termine del procedimento" -#: design/plone/contenttypes/behaviors/trasparenza.py:75 +#: design/plone/contenttypes/behaviors/trasparenza.py:76 msgid "fine_termine_label" msgstr "" +#. Default: "Lista dei formati in cui è disponibile il documento" +#: design/plone/contenttypes/interfaces/documento.py:117 +msgid "formati_disponibili_help" +msgstr "" + +#. Default: "Formati disponibili" +#: design/plone/contenttypes/interfaces/documento.py:116 +msgid "formati_disponibili_label" +msgstr "" + #. Default: "Inserisci un eventuale formato alternativo del file principale." -#: design/plone/contenttypes/behaviors/multi_file.py:25 +#: design/plone/contenttypes/behaviors/multi_file.py:26 msgid "formato_alternativo_1_help" msgstr "" #. Default: "Formato alternativo 1" -#: design/plone/contenttypes/behaviors/multi_file.py:24 +#: design/plone/contenttypes/behaviors/multi_file.py:25 msgid "formato_alternativo_1_label" msgstr "" #. Default: "Inserisci un eventuale formato alternativo del file principale." -#: design/plone/contenttypes/behaviors/multi_file.py:35 +#: design/plone/contenttypes/behaviors/multi_file.py:36 msgid "formato_alternativo_2_help" msgstr "" #. Default: "Formato alternativo 2" -#: design/plone/contenttypes/behaviors/multi_file.py:34 +#: design/plone/contenttypes/behaviors/multi_file.py:35 msgid "formato_alternativo_2_label" msgstr "" -#. Default: "Foto da mostrare della persona. La dimensione suggerita è 180x100 px." -#: design/plone/contenttypes/interfaces/persona.py:21 +#. Default: "Foto da mostrare della persona. La dimensione suggerita è 100x180px." +#: design/plone/contenttypes/interfaces/persona.py:30 msgid "foto_persona_help" msgstr "" #. Default: "Foto della persona" -#: design/plone/contenttypes/interfaces/persona.py:19 +#: design/plone/contenttypes/interfaces/persona.py:28 msgid "foto_persona_label" msgstr "" #. Default: "Frequenza di aggiornamento" -#: design/plone/contenttypes/interfaces/dataset.py:32 +#: design/plone/contenttypes/interfaces/dataset.py:25 msgid "frequenza_aggiornamento" msgstr "" #. Default: "Invalid geolocation data: ${value}. Provide latitude and longitude coordinates." -#: design/plone/contenttypes/restapi/deserializers/dxfields.py:28 +#: design/plone/contenttypes/restapi/deserializers/dxfields.py:39 msgid "geolocation_field_validator_label" msgstr "" @@ -1598,22 +1601,27 @@ msgid "help_circoscrizione" msgstr "" #. Default: "Indicare una descrizione completa, inserendo tutte le informazioni rilevanti relative al luogo" -#: design/plone/contenttypes/behaviors/luogo.py:24 +#: design/plone/contenttypes/behaviors/luogo.py:25 msgid "help_descrizione_completa" msgstr "" #. Default: "Indicare eventuali elementi di interesse per il cittadino." -#: design/plone/contenttypes/behaviors/luogo.py:45 +#: design/plone/contenttypes/behaviors/luogo.py:46 msgid "help_elementi_di_interesse" msgstr "" +#. Default: "Se selezionato, questo contenuto non verrà mostrato nelle ricerche del sito per gli utenti anonimi." +#: design/plone/contenttypes/behaviors/exclude_from_search.py:18 +msgid "help_exclude_from_search" +msgstr "" + #. Default: "Indicare tutte le informazioni relative alla modalità di accesso al luogo" -#: design/plone/contenttypes/behaviors/luogo.py:54 +#: design/plone/contenttypes/behaviors/luogo.py:55 msgid "help_modalita_accesso" msgstr "" #. Default: "Indicare, se esiste, un nome alternativo per il luogo; questo sarà mostrato affianco al titolo della scheda" -#: design/plone/contenttypes/behaviors/luogo.py:34 +#: design/plone/contenttypes/behaviors/luogo.py:35 msgid "help_nome_alternativo" msgstr "" @@ -1627,28 +1635,8 @@ msgstr "" msgid "help_quartiere" msgstr "" -#. Default: "Indicare un numero di fax della struttura responsabile." -#: design/plone/contenttypes/behaviors/luogo.py:108 -msgid "help_riferimento_fax_struttura" -msgstr "" - -#. Default: "Indicare un indirizzo mail per poter contattare i referenti della struttura responsabile." -#: design/plone/contenttypes/behaviors/luogo.py:119 -msgid "help_riferimento_mail_struttura" -msgstr "" - -#. Default: "Indicare un indirizzo pec per poter contattare i referenti della struttura responsabile." -#: design/plone/contenttypes/behaviors/luogo.py:132 -msgid "help_riferimento_pec_struttura" -msgstr "" - -#. Default: "Indicare il riferimento telefonico per poter contattare i referenti della struttura responsabile." -#: design/plone/contenttypes/behaviors/luogo.py:96 -msgid "help_riferimento_telefonico_struttura" -msgstr "" - -#. Default: "Inserisci una nota per indicare che il contenuto corrente è stato aggiornato.Questo testo può essere visualizzato nei blocchi elenco con determinati layout per informare gli utenti che un determinato contenuto è stato aggiornato. Ad esempio se in un bando sono stati aggiunti dei documenti." -#: design/plone/contenttypes/behaviors/update_note.py:17 +#. Default: "Inserisci una nota per indicare che il contenuto corrente è stato aggiornato. Questo testo può essere visualizzato nei blocchi elenco con determinati layout per informare gli utenti che un determinato contenuto è stato aggiornato. Ad esempio se in un bando sono stati aggiunti dei documenti." +#: design/plone/contenttypes/behaviors/update_note.py:18 msgid "help_update_note" msgstr "" @@ -1663,7 +1651,7 @@ msgid "icona_help" msgstr "" #. Default: "Identificativo" -#: design/plone/contenttypes/interfaces/servizio.py:290 +#: design/plone/contenttypes/interfaces/servizio.py:379 msgid "identificativo" msgstr "" @@ -1678,12 +1666,22 @@ msgid "identificativo_documento_label" msgstr "" #. Default: "Eventuale codice identificativo del servizio." -#: design/plone/contenttypes/interfaces/servizio.py:292 +#: design/plone/contenttypes/interfaces/servizio.py:381 msgid "identificativo_help" msgstr "" +#. Default: "Identificativo" +#: design/plone/contenttypes/behaviors/luogo.py:119 +msgid "identificativo_mibac" +msgstr "" + +#. Default: "Codice identificativo del luogo. Nel MIBAC c'è il codice del DBUnico per i luoghi della cultura e il codice ISIL per le biblioteche. Non deve comparire nel frontend del sito." +#: design/plone/contenttypes/behaviors/luogo.py:121 +msgid "identificativo_mibac_help" +msgstr "" + #. Default: "La dimensione dell'immagine dovrebbe essere di ${size} px" -#: design/plone/contenttypes/restapi/types/adapters.py:31 +#: design/plone/contenttypes/restapi/types/adapters.py:43 msgid "image_size_help" msgstr "" @@ -1692,11 +1690,31 @@ msgstr "" msgid "immagine" msgstr "" +#. Default: "Solo per incarico politico: importi di viaggi di servizio e missioni pagati con fondi pubblici." +#: design/plone/contenttypes/interfaces/incarico.py:34 +msgid "importi_viaggio_servizio_incarico_help" +msgstr "" + +#. Default: "Importi di viaggio e/o servizio" +#: design/plone/contenttypes/interfaces/incarico.py:30 +msgid "importi_viaggio_servizio_incarico_label" +msgstr "" + #. Default: "Importo pagato" #: design/plone/contenttypes/interfaces/ricevuta_pagamento.py:25 msgid "importo_pagato" msgstr "" +#. Default: "Seleziona l'incarico corrente della persona." +#: design/plone/contenttypes/interfaces/persona.py:63 +msgid "incarichi_help" +msgstr "" + +#. Default: "Incarichi" +#: design/plone/contenttypes/interfaces/persona.py:59 +msgid "incarichi_label" +msgstr "" + #. Default: "Inserisci eventuale testo informativo che verrà mostrato in testata." #: design/plone/contenttypes/behaviors/info_testata.py:23 msgid "info_testata_help" @@ -1712,35 +1730,60 @@ msgstr "" msgid "informazioni" msgstr "" +#. Default: "Compensi e trasparenza" +#: design/plone/contenttypes/interfaces/incarico.py:170 +msgid "informazioni_compensi_label" +msgstr "" + #. Default: "Ulteriori informazioni" #: design/plone/contenttypes/behaviors/additional_help_infos.py:28 -#: design/plone/contenttypes/behaviors/evento.py:229 #: design/plone/contenttypes/behaviors/strutture_correlate.py:42 +#: design/plone/contenttypes/interfaces/documento.py:253 msgid "informazioni_label" msgstr "" +#. Default: "Intervallo della fase (es. 1)" +#: design/plone/contenttypes/interfaces/servizio.py:32 +msgid "interval_qt_help" +msgstr "" + +#. Default: "Intervallo" +#: design/plone/contenttypes/interfaces/servizio.py:31 +msgid "interval_qt_label" +msgstr "" + +#. Default: "Ad esempio: ore, giorni, settimane, mesi." +#: design/plone/contenttypes/interfaces/servizio.py:41 +msgid "interval_type_help" +msgstr "" + +#. Default: "Tipo intervallo" +#: design/plone/contenttypes/interfaces/servizio.py:40 +msgid "interval_type_label" +msgstr "" + #. Default: "Se un content-type deve avere una dimensione della leadimage particolare, indicarle qui. Inserire le dimensioni nella forma di esempio PortalType|900x900" -#: design/plone/contenttypes/controlpanels/settings.py:110 +#: design/plone/contenttypes/controlpanels/settings.py:52 msgid "lead_image_dimension_help" msgstr "" #. Default: "Dimensioni lead image" -#: design/plone/contenttypes/controlpanels/settings.py:106 +#: design/plone/contenttypes/controlpanels/settings.py:48 msgid "lead_image_dimension_label" msgstr "" -#. Default: "Servizi o uffici di riferimento" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:27 +#. Default: "Strutture o uffici di riferimento" +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:31 msgid "legami_altre_strutture_label" msgstr "" #. Default: "Selezionare la lista di strutture e/o uffici collegati a questa unità organizzativa." -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:31 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:35 msgid "legami_con_altre_strutture_help" msgstr "" #. Default: "Licenza" -#: design/plone/contenttypes/interfaces/dataset.py:25 +#: design/plone/contenttypes/interfaces/dataset.py:18 msgid "licenza" msgstr "" @@ -1750,27 +1793,27 @@ msgid "licenza_distribuzione" msgstr "" #. Default: "La licenza con il quale viene distribuito questo documento." -#: design/plone/contenttypes/interfaces/documento.py:88 +#: design/plone/contenttypes/interfaces/documento.py:125 msgid "licenza_distribuzione_help" msgstr "" #. Default: "Licenza di distribuzione" -#: design/plone/contenttypes/interfaces/documento.py:87 +#: design/plone/contenttypes/interfaces/documento.py:124 msgid "licenza_distribuzione_label" msgstr "" #. Default: "Link a siti esterni" -#: design/plone/contenttypes/interfaces/servizio.py:258 +#: design/plone/contenttypes/interfaces/servizio.py:347 msgid "link_siti_esterni" msgstr "" #. Default: "Eventuali collegamenti a pagine web, siti, servizi esterni all'ambito Comunale utili all'erogazione del servizio." -#: design/plone/contenttypes/interfaces/servizio.py:260 +#: design/plone/contenttypes/interfaces/servizio.py:349 msgid "link_siti_esterni_help" msgstr "" #. Default: "Link utili" -#: design/plone/contenttypes/interfaces/servizio.py:417 +#: design/plone/contenttypes/interfaces/servizio.py:530 msgid "link_utili_label" msgstr "" @@ -1780,36 +1823,46 @@ msgid "luoghi_correlati_event_help" msgstr "" #. Default: "Seleziona una lista di luoghi citati." -#: design/plone/contenttypes/behaviors/luoghi_correlati.py:18 -#: design/plone/contenttypes/behaviors/news_additional_fields.py:72 +#: design/plone/contenttypes/behaviors/luoghi_correlati.py:19 +#: design/plone/contenttypes/behaviors/news_additional_fields.py:64 msgid "luoghi_correlati_help" msgstr "" #. Default: "Luoghi correlati" -#: design/plone/contenttypes/behaviors/luoghi_correlati.py:17 -#: design/plone/contenttypes/behaviors/news_additional_fields.py:71 +#: design/plone/contenttypes/behaviors/luoghi_correlati.py:18 +#: design/plone/contenttypes/behaviors/news_additional_fields.py:63 msgid "luoghi_correlati_label" msgstr "" #. Default: "Luogo" -#: design/plone/contenttypes/behaviors/address.py:89 -#: design/plone/contenttypes/behaviors/geolocation.py:38 -#: design/plone/contenttypes/behaviors/luoghi_correlati.py:74 +#: design/plone/contenttypes/behaviors/address.py:71 +#: design/plone/contenttypes/behaviors/geolocation.py:34 +#: design/plone/contenttypes/behaviors/luoghi_correlati.py:76 msgid "luogo_label" msgstr "" +#. Default: "Sottotitolo" +#: design/plone/contenttypes/interfaces/servizio.py:26 +msgid "milestone_description_label" +msgstr "" + +#. Default: "Titolo" +#: design/plone/contenttypes/interfaces/servizio.py:21 +msgid "milestone_label" +msgstr "" + #. Default: "Modalita' di accesso" -#: design/plone/contenttypes/behaviors/luogo.py:53 +#: design/plone/contenttypes/behaviors/luogo.py:54 msgid "modalita_accesso" msgstr "" #. Default: "Indicare la modalità di avvio del procedimento." -#: design/plone/contenttypes/behaviors/trasparenza.py:25 +#: design/plone/contenttypes/behaviors/trasparenza.py:26 msgid "modalita_avvio_help" msgstr "" #. Default: "Modalita di avvio" -#: design/plone/contenttypes/behaviors/trasparenza.py:24 +#: design/plone/contenttypes/behaviors/trasparenza.py:25 msgid "modalita_avvio_label" msgstr "" @@ -1819,12 +1872,12 @@ msgid "modalita_pagamento" msgstr "" #. Default: "Indicare le modalità per richiedere informazioni riguardo a questo procedimento." -#: design/plone/contenttypes/behaviors/trasparenza.py:168 +#: design/plone/contenttypes/behaviors/trasparenza.py:169 msgid "modalita_richiesta_informazioni_help" msgstr "" #. Default: "Modalità per richiedere informazioni" -#: design/plone/contenttypes/behaviors/trasparenza.py:163 +#: design/plone/contenttypes/behaviors/trasparenza.py:164 msgid "modalita_richiesta_informazioni_label" msgstr "" @@ -1848,18 +1901,18 @@ msgstr "" msgid "mostra_navigazione_label" msgstr "" -#. Default: "Descrizione del motivo per cui il servizio non è attivo." -#: design/plone/contenttypes/interfaces/servizio.py:44 +#. Default: "Descrizione del motivo per cui il servizio non è attivo. È obbligatorio se il campo precedente è spuntato." +#: design/plone/contenttypes/interfaces/servizio.py:89 msgid "motivo_stato_servizio_help" msgstr "" -#. Default: "Motivo dello stato del servizio nel caso non sia attivo" -#: design/plone/contenttypes/interfaces/servizio.py:39 +#. Default: "Motivo dello stato" +#: design/plone/contenttypes/interfaces/servizio.py:84 msgid "motivo_stato_servizio_label" msgstr "" #. Default: "Nome alternativo" -#: design/plone/contenttypes/behaviors/luogo.py:33 +#: design/plone/contenttypes/behaviors/luogo.py:34 msgid "nome_alternativo" msgstr "" @@ -1869,17 +1922,17 @@ msgid "nome_sede" msgstr "" #. Default: "Seleziona una lista di notizie correlate a questa." -#: design/plone/contenttypes/behaviors/news_additional_fields.py:83 +#: design/plone/contenttypes/behaviors/news_additional_fields.py:75 msgid "notizie_correlate_help" msgstr "" #. Default: "Notizie correlate" -#: design/plone/contenttypes/behaviors/news_additional_fields.py:82 +#: design/plone/contenttypes/behaviors/news_additional_fields.py:74 msgid "notizie_correlate_label" msgstr "" #. Default: "Numero progressivo del comunicato stampa" -#: design/plone/contenttypes/behaviors/news_additional_fields.py:38 +#: design/plone/contenttypes/behaviors/news_additional_fields.py:30 msgid "numero_progressivo_cs_label" msgstr "" @@ -1895,117 +1948,155 @@ msgid "oggetto" msgstr "" #. Default: "Informazioni sugli orari" -#: design/plone/contenttypes/behaviors/evento.py:62 +#: design/plone/contenttypes/behaviors/evento.py:50 msgid "orari" msgstr "" #. Default: "Informazioni sugli orari di svolgimento dell'evento." -#: design/plone/contenttypes/behaviors/evento.py:64 +#: design/plone/contenttypes/behaviors/evento.py:52 msgid "orari_help" msgstr "" #. Default: "Orari di apertura" -#: design/plone/contenttypes/behaviors/contatti.py:86 +#: design/plone/contenttypes/behaviors/luogo.py:151 msgid "orari_label" msgstr "" +#. Default: "Orario per il pubblico" +#: design/plone/contenttypes/behaviors/luogo.py:93 +msgid "orario_pubblico" +msgstr "" + #. Default: "Indicare eventuali orari di accesso al pubblico" -#: design/plone/contenttypes/behaviors/contatti.py:59 +#: design/plone/contenttypes/behaviors/contatti.py:40 +#: design/plone/contenttypes/behaviors/luogo.py:95 msgid "orario_pubblico_help" msgstr "" #. Default: "Orario per il pubblico" -#: design/plone/contenttypes/behaviors/contatti.py:58 +#: design/plone/contenttypes/behaviors/contatti.py:39 msgid "orario_pubblico_label" msgstr "" #. Default: "Se l'evento non è organizzato direttamente dal comune oppure ha anche un organizzatore esterno, indicare il nome del contatto." -#: design/plone/contenttypes/behaviors/evento.py:97 +#: design/plone/contenttypes/behaviors/evento.py:86 msgid "organizzato_da_esterno_help" msgstr "" #. Default: "Organizzatore" -#: design/plone/contenttypes/behaviors/evento.py:95 +#: design/plone/contenttypes/behaviors/evento.py:84 msgid "organizzato_da_esterno_label" msgstr "" #. Default: "Se l'evento è organizzato direttamente dal comune, indicare l'ufficio/ente organizzatore. I dati di contatto verranno presi direttamente dall'ufficio selezionato. Se l'evento non è organizzato direttamente dal comune, o si vogliono sovrascrivere alcuni dati di contatto, utilizzare i seguenti campi." -#: design/plone/contenttypes/behaviors/evento.py:84 +#: design/plone/contenttypes/behaviors/evento.py:74 msgid "organizzato_da_interno_help" msgstr "" #. Default: "Organizzato da" -#: design/plone/contenttypes/behaviors/evento.py:80 +#: design/plone/contenttypes/behaviors/evento.py:70 msgid "organizzato_da_interno_label" msgstr "" #. Default: "Seleziona una lista di organizzazioni a cui la persona appartiene." -#: design/plone/contenttypes/interfaces/persona.py:42 +#: design/plone/contenttypes/interfaces/persona.py:45 msgid "organizzazione_riferimento_help" msgstr "" #. Default: "Organizzazione di riferimento" -#: design/plone/contenttypes/interfaces/persona.py:38 +#: design/plone/contenttypes/interfaces/persona.py:41 msgid "organizzazione_riferimento_label" msgstr "" #. Default: "Organo competente del provvedimento finale." -#: design/plone/contenttypes/behaviors/trasparenza.py:157 +#: design/plone/contenttypes/behaviors/trasparenza.py:158 msgid "organo_competente_provvedimento_finale_help" msgstr "" #. Default: "Organo competente del provvedimento finale" -#: design/plone/contenttypes/behaviors/trasparenza.py:152 +#: design/plone/contenttypes/behaviors/trasparenza.py:153 msgid "organo_competente_provvedimento_finale_label" msgstr "" #. Default: "Indicare le informazioni riguardanti i pagamenti previsti e modalità di pagamento." -#: design/plone/contenttypes/behaviors/trasparenza.py:222 +#: design/plone/contenttypes/behaviors/trasparenza.py:223 msgid "pagamenti_help" msgstr "" #. Default: "Pagamenti previsti e modalità" -#: design/plone/contenttypes/behaviors/trasparenza.py:218 +#: design/plone/contenttypes/behaviors/trasparenza.py:219 msgid "pagamenti_label" msgstr "" +#. Default: "Link a persone dell'amministrazione che interverranno all'evento" +#: design/plone/contenttypes/behaviors/evento.py:118 +msgid "parteciperanno_help" +msgstr "" + +#. Default: "Parteciperanno (Persone)" +#: design/plone/contenttypes/behaviors/evento.py:114 +msgid "parteciperanno_label" +msgstr "" + #. Default: "Indicare l'ente che supporta l'evento, se presente." -#: design/plone/contenttypes/behaviors/evento.py:160 +#: design/plone/contenttypes/behaviors/evento.py:107 msgid "patrocinato_da_help" msgstr "" #. Default: "Patrocinato da" -#: design/plone/contenttypes/behaviors/evento.py:158 +#: design/plone/contenttypes/behaviors/evento.py:105 msgid "patrocinato_da_label" msgstr "" -#. Default: "Indicare un indirizzo pec per poter contattare i referenti." -#: design/plone/contenttypes/behaviors/contatti.py:44 -msgid "pec_help" +#. Default: "Descrizione" +#: design/plone/contenttypes/interfaces/punto_di_contatto.py:27 +msgid "pdc_desc_help" +msgstr "" + +#. Default: "Descrizione" +#: design/plone/contenttypes/interfaces/punto_di_contatto.py:26 +msgid "pdc_desc_label" +msgstr "" + +#. Default: "Tipo" +#: design/plone/contenttypes/interfaces/punto_di_contatto.py:16 +msgid "pdc_type_label" msgstr "" -#. Default: "Pec" -#: design/plone/contenttypes/behaviors/contatti.py:43 -msgid "pec_label" +#. Default: "Contatto" +#: design/plone/contenttypes/interfaces/punto_di_contatto.py:37 +msgid "pdc_value_help" msgstr "" -#. Default: "Elenco delle persone dell'amministrazione che parteciperanno all'evento." -#: design/plone/contenttypes/behaviors/evento.py:53 -msgid "persone_amministrazione_help" +#. Default: "Contatto" +#: design/plone/contenttypes/interfaces/punto_di_contatto.py:36 +msgid "pdc_value_label" +msgstr "" + +#. Default: "Seleziona la persona che ha questo incarico" +#: design/plone/contenttypes/interfaces/incarico.py:47 +#: design/plone/contenttypes/interfaces/punto_di_contatto.py:66 +msgid "persona_incarico_help" +msgstr "" + +#. Default: "La persona che ha la carica e l'incarico" +#: design/plone/contenttypes/interfaces/incarico.py:43 +#: design/plone/contenttypes/interfaces/punto_di_contatto.py:62 +msgid "persona_incarico_label" msgstr "" #. Default: "Persone" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:221 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:215 msgid "persone_label" msgstr "" #. Default: "Seleziona la lista delle persone che compongono la struttura." -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:95 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:87 msgid "persone_struttura_help" msgstr "" #. Default: "Persone che compongono la struttura" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:87 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:79 msgid "persone_struttura_label" msgstr "" @@ -2021,42 +2112,42 @@ msgid "pratica_associata_ricevuta" msgstr "" #. Default: "Prenota un appuntamento" -#: design/plone/contenttypes/interfaces/servizio.py:156 +#: design/plone/contenttypes/interfaces/servizio.py:225 msgid "prenota_appuntamento" msgstr "" #. Default: "Se è possibile prenotare un'appuntamento, indicare le informazioni necessarie e il collegamento al servizio di prenotazione appuntamenti del Comune." -#: design/plone/contenttypes/interfaces/servizio.py:157 +#: design/plone/contenttypes/interfaces/servizio.py:226 msgid "prenota_appuntamento_help" msgstr "" -#. Default: "Prezzo" -#: design/plone/contenttypes/behaviors/evento.py:71 +#. Default: "Costo" +#: design/plone/contenttypes/behaviors/evento.py:59 msgid "prezzo" msgstr "" -#. Default: "Indicare il prezzo dell'evento, se presente, specificando se esistono formati diversi." -#: design/plone/contenttypes/behaviors/evento.py:73 +#. Default: "Eventuale costo dell'evento (se ci sono uno o più biglietti), con link all'acquisto se disponibile" +#: design/plone/contenttypes/behaviors/evento.py:61 msgid "prezzo_help" msgstr "" #. Default: "Indicare, se la procedura è informatizzata online, il riferimento." -#: design/plone/contenttypes/behaviors/trasparenza.py:178 +#: design/plone/contenttypes/behaviors/trasparenza.py:179 msgid "procedura_online_help" msgstr "" #. Default: "Procedura informatizzata online" -#: design/plone/contenttypes/behaviors/trasparenza.py:174 +#: design/plone/contenttypes/behaviors/trasparenza.py:175 msgid "procedura_online_label" msgstr "" #. Default: "Procedure collegate all'esito" -#: design/plone/contenttypes/interfaces/servizio.py:100 +#: design/plone/contenttypes/interfaces/servizio.py:145 msgid "procedure_collegate" msgstr "" #. Default: "Indicare cosa deve fare l'utente del servizio per conoscere l'esito della procedura, e dove eventualmente poter ritirare l'esito." -#: design/plone/contenttypes/interfaces/servizio.py:102 +#: design/plone/contenttypes/interfaces/servizio.py:147 msgid "procedure_collegate_help" msgstr "" @@ -2065,13 +2156,23 @@ msgstr "" msgid "protocollo" msgstr "" +#. Default: "Il numero di protocollo del documento." +#: design/plone/contenttypes/interfaces/documento.py:33 +msgid "protocollo_documento_help" +msgstr "" + +#. Default: "Numero di protocollo" +#: design/plone/contenttypes/interfaces/documento.py:29 +msgid "protocollo_documento_label" +msgstr "" + #. Default: "Eventuale provvedimento finale del procedimento." -#: design/plone/contenttypes/behaviors/trasparenza.py:114 +#: design/plone/contenttypes/behaviors/trasparenza.py:115 msgid "provvedimento_finale_help" msgstr "" #. Default: "Provvedimento del procedimento" -#: design/plone/contenttypes/behaviors/trasparenza.py:109 +#: design/plone/contenttypes/behaviors/trasparenza.py:110 msgid "provvedimento_finale_label" msgstr "" @@ -2080,46 +2181,46 @@ msgstr "" msgid "quartiere" msgstr "" -#. Default: "Reperibilità organizzatore" -#: design/plone/contenttypes/behaviors/evento.py:118 -msgid "reperibilita" -msgstr "" - -#. Default: "Indicare gli orari in cui l'organizzatore è telefonicamente reperibile." -#: design/plone/contenttypes/behaviors/evento.py:120 -msgid "reperibilita_help" -msgstr "" - #. Default: "Indicare dove è possibile reperre la modulistica per il procedimento." -#: design/plone/contenttypes/behaviors/trasparenza.py:211 +#: design/plone/contenttypes/behaviors/trasparenza.py:212 msgid "reperimento_modulistica_help" msgstr "" #. Default: "Dove reperire la modulistica" -#: design/plone/contenttypes/behaviors/trasparenza.py:207 +#: design/plone/contenttypes/behaviors/trasparenza.py:208 msgid "reperimento_modulistica_label" msgstr "" #. Default: "Selezionare il/i responsabile/i della struttura." -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:48 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:52 msgid "responsabile_help" msgstr "" #. Default: "Responsabile" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:43 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:47 msgid "responsabile_label" msgstr "" #. Default: "Responsabile del procedimento" -#: design/plone/contenttypes/behaviors/trasparenza.py:120 +#: design/plone/contenttypes/behaviors/trasparenza.py:121 msgid "responsabile_procedimento" msgstr "" #. Default: "Indicare il responsabile del procedimento." -#: design/plone/contenttypes/behaviors/trasparenza.py:124 +#: design/plone/contenttypes/behaviors/trasparenza.py:125 msgid "responsabile_procedimento_help" msgstr "" +#. Default: "Se è un incarico di responsabilità, specificare l'organizzazione della quale è responsabile in base all'incarico" +#: design/plone/contenttypes/interfaces/incarico.py:81 +msgid "responsabile_struttura_incarico_help" +msgstr "" + +#. Default: "Responsabile della struttura" +#: design/plone/contenttypes/interfaces/incarico.py:77 +msgid "responsabile_struttura_incarico_label" +msgstr "" + #. Default: "Seleziona se mostrare o meno il campo di ricerca in testata." #: design/plone/contenttypes/behaviors/info_testata.py:32 msgid "ricerca_in_testata_help" @@ -2131,12 +2232,12 @@ msgid "ricerca_in_testata_label" msgstr "" #. Default: "Ulteriori informazioni non previste negli altri campi; si può trattare di contatti o note informative la cui conoscenza è indispensabile per la partecipazione al bando" -#: design/plone/contenttypes/interfaces/bando.py:96 +#: design/plone/contenttypes/interfaces/bando.py:97 msgid "riferimenti_bando_agid_help" msgstr "" #. Default: "Ulteriori informazioni" -#: design/plone/contenttypes/interfaces/bando.py:95 +#: design/plone/contenttypes/interfaces/bando.py:96 msgid "riferimenti_bando_agid_label" msgstr "" @@ -2146,122 +2247,87 @@ msgid "riferimenti_normativi" msgstr "" #. Default: "Inserisici del testo di dettaglio per eventuali riferimenti normativi utili a questo documento." -#: design/plone/contenttypes/interfaces/documento.py:100 +#: design/plone/contenttypes/interfaces/documento.py:137 msgid "riferimenti_normativi_documento_help" msgstr "" #. Default: "Riferimenti normativi" -#: design/plone/contenttypes/interfaces/documento.py:96 +#: design/plone/contenttypes/interfaces/documento.py:133 msgid "riferimenti_normativi_documento_label" msgstr "" #. Default: "Indicare eventuali riferimenti normativi." -#: design/plone/contenttypes/behaviors/trasparenza.py:265 +#: design/plone/contenttypes/behaviors/trasparenza.py:266 msgid "riferimenti_normativi_help" msgstr "" #. Default: "Riferimenti normativi" -#: design/plone/contenttypes/behaviors/trasparenza.py:260 +#: design/plone/contenttypes/behaviors/trasparenza.py:261 msgid "riferimenti_normativi_label" msgstr "" -#. Default: "Fax della struttura responsabile" -#: design/plone/contenttypes/behaviors/luogo.py:104 -msgid "riferimento_fax_struttura" -msgstr "" - -#. Default: "E-mail struttura responsabile" -#: design/plone/contenttypes/behaviors/luogo.py:115 -msgid "riferimento_mail_struttura" -msgstr "" - -#. Default: "Pec della struttura responsabile" -#: design/plone/contenttypes/behaviors/luogo.py:128 -msgid "riferimento_pec_struttura" -msgstr "" - -#. Default: "Telefono della struttura responsabile" -#: design/plone/contenttypes/behaviors/luogo.py:92 -msgid "riferimento_telefonico_struttura" -msgstr "" - -#. Default: "Inserisci i valori utilizzabili per il ruolo di una Persona. Se il sito è multilingua, puoi inserire valori diversi a seconda delle lingue del sito." -#: design/plone/contenttypes/controlpanels/settings.py:84 -msgid "ruoli_persona_help" -msgstr "" - -#. Default: "Ruoli Persona" -#: design/plone/contenttypes/controlpanels/settings.py:83 -msgid "ruoli_persona_label" -msgstr "" - -#. Default: "Seleziona il ruolo della persona tra quelli disponibili." -#: design/plone/contenttypes/interfaces/persona.py:29 -msgid "ruolo_help" -msgstr "" - #. Default: "Ruolo" -#: design/plone/contenttypes/interfaces/persona.py:28 +#: design/plone/contenttypes/interfaces/persona.py:135 msgid "ruolo_label" msgstr "" #. Default: "Data entro la quale sarà possibile far pervenire domande e richieste di chiarimento a chi eroga il bando" -#: design/plone/contenttypes/interfaces/bando.py:69 +#: design/plone/contenttypes/interfaces/bando.py:70 msgid "scadenza_domande_bando_help" msgstr "" #. Default: "Termine per le richieste di chiarimenti" -#: design/plone/contenttypes/interfaces/bando.py:65 +#: design/plone/contenttypes/interfaces/bando.py:66 msgid "scadenza_domande_bando_label" msgstr "" #. Default: "Inserire una lista di sezioni per la ricerca." -#: design/plone/contenttypes/controlpanels/settings.py:129 +#: design/plone/contenttypes/controlpanels/settings.py:71 msgid "search_sections_help" msgstr "" #. Default: "Sezioni ricerca" -#: design/plone/contenttypes/controlpanels/settings.py:128 +#: design/plone/contenttypes/controlpanels/settings.py:70 msgid "search_sections_label" msgstr "" -#. Default: "Seleziona il Luogo in cui questa struttura ha sede. Se non è presente un contenuto di tipo Luogo a cui far riferimento, puoi compilare i campi seguenti. Se selezioni un Luogo, puoi usare comunque i campi seguenti per sovrascrivere alcune informazioni." -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:105 +#. Default: "Seleziona il Luogo in cui questa struttura ha sede. Se non è presente creare il Luogo nella sezione dedicata nell'alberatura del sito." +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:97 msgid "sede_help" msgstr "" #. Default: "Sede principale" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:103 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:95 msgid "sede_label" msgstr "" #. Default: "Seleziona una lista di eventuali contenuti di tipo Luogo che sono sedi secondarie di questa struttura. Per queste sedi non sarà possibile sovrascrivere i dati. Nel caso servano informazioni diverse, è possibile usare il campo sottostante." -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:122 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:112 msgid "sedi_secondarie_help" msgstr "" -#. Default: "Sedi secondarie" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:120 +#. Default: "Altre sedi" +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:110 msgid "sedi_secondarie_label" msgstr "" #. Default: "Seleziona la lista dei servizi collegati a questo." -#: design/plone/contenttypes/interfaces/servizio.py:300 +#: design/plone/contenttypes/interfaces/servizio.py:394 msgid "servizi_collegati_help" msgstr "" #. Default: "Servizi collegati" -#: design/plone/contenttypes/interfaces/servizio.py:299 +#: design/plone/contenttypes/interfaces/servizio.py:393 msgid "servizi_collegati_label" msgstr "" #. Default: "Questi servizi non verranno mostrati nel contenuto, ma permetteranno di vedere questo contenuto associato quando si visita il servizio" -#: design/plone/contenttypes/behaviors/servizi_correlati.py:19 +#: design/plone/contenttypes/behaviors/servizi_correlati.py:20 msgid "servizi_correlati_description" msgstr "" #. Default: "Servizi correlati" -#: design/plone/contenttypes/behaviors/servizi_correlati.py:18 +#: design/plone/contenttypes/behaviors/servizi_correlati.py:19 msgid "servizi_correlati_label" msgstr "" @@ -2281,22 +2347,32 @@ msgid "servizio_origine_ricevuta" msgstr "" #. Default: "Settore merceologico" -#: design/plone/contenttypes/interfaces/servizio.py:280 +#: design/plone/contenttypes/interfaces/servizio.py:369 msgid "settore_merceologico" msgstr "" #. Default: "Classificazione del servizio basata su catalogo dei servizi (Classificazione NACE)." -#: design/plone/contenttypes/interfaces/servizio.py:282 +#: design/plone/contenttypes/interfaces/servizio.py:371 msgid "settore_merceologico_help" msgstr "" +#. Default: "Se selezionato, il footer verrà popolato automaticamente con i contenuti di primo livello non esclusi dalla navigazione." +#: design/plone/contenttypes/controlpanels/settings.py:93 +msgid "show_dynamic_folders_in_footer_help" +msgstr "" + +#. Default: "Footer dinamico" +#: design/plone/contenttypes/controlpanels/settings.py:92 +msgid "show_dynamic_folders_in_footer_label" +msgstr "" + #. Default: "Questo è il valore di default per decidere se mostrare o meno la data di modifica nei contenuti che hanno la behavior abilitata. E' poi possibile sovrascrivere il default nei singoli contenuti (nel tab \"Impostazioni\")." -#: design/plone/contenttypes/controlpanels/settings.py:139 +#: design/plone/contenttypes/controlpanels/settings.py:81 msgid "show_modified_default_help" msgstr "" #. Default: "Mostra la data di modifica" -#: design/plone/contenttypes/controlpanels/settings.py:138 +#: design/plone/contenttypes/controlpanels/settings.py:80 msgid "show_modified_default_label" msgstr "" @@ -2311,34 +2387,34 @@ msgid "show_modified_label" msgstr "" #. Default: "Indicare se il procedimento prevede il silenzio assenso o la dichiarazione dell'interessato sostitutiva del provvedimento finale." -#: design/plone/contenttypes/behaviors/trasparenza.py:103 +#: design/plone/contenttypes/behaviors/trasparenza.py:104 msgid "silenzio_assenso_help" msgstr "" #. Default: "Silenzio assenso/Dichiarazione dell'interessato sostitutiva del provvedimento finale" -#: design/plone/contenttypes/behaviors/trasparenza.py:97 +#: design/plone/contenttypes/behaviors/trasparenza.py:98 msgid "silenzio_assenso_label" msgstr "" #. Default: "Inserisci eventuali soggetti esterni, nonché, strutture interne coinvolte nel procedimento." -#: design/plone/contenttypes/behaviors/trasparenza.py:57 +#: design/plone/contenttypes/behaviors/trasparenza.py:58 msgid "soggetti_eserni_help" msgstr "" #. Default: "Soggetti esterni, nonché, strutture interne coinvolte nel procedimento" -#: design/plone/contenttypes/behaviors/trasparenza.py:52 +#: design/plone/contenttypes/behaviors/trasparenza.py:53 msgid "soggetti_eserni_label" msgstr "" #. Default: "Indica un eventuale sottotitolo/titolo alternativo." -#: design/plone/contenttypes/behaviors/evento.py:23 -#: design/plone/contenttypes/interfaces/servizio.py:19 +#: design/plone/contenttypes/behaviors/evento.py:24 +#: design/plone/contenttypes/interfaces/servizio.py:64 msgid "sottotitolo_help" msgstr "" #. Default: "Sottotitolo" -#: design/plone/contenttypes/behaviors/evento.py:22 -#: design/plone/contenttypes/interfaces/servizio.py:18 +#: design/plone/contenttypes/behaviors/evento.py:23 +#: design/plone/contenttypes/interfaces/servizio.py:63 msgid "sottotitolo_label" msgstr "" @@ -2352,273 +2428,188 @@ msgstr "" msgid "stato_pratica" msgstr "" -#. Default: "Indica se il servizio è effettivamente fruibile." -#: design/plone/contenttypes/interfaces/servizio.py:32 +#. Default: "Indica se il servizio è effettivamente fruibile; spuntare se non è fruibile." +#: design/plone/contenttypes/interfaces/servizio.py:77 msgid "stato_servizio_help" msgstr "" -#. Default: "Servizio non attivo" -#: design/plone/contenttypes/interfaces/servizio.py:30 +#. Default: "Servizio non fruibile" +#: design/plone/contenttypes/interfaces/servizio.py:75 msgid "stato_servizio_label" msgstr "" #. Default: "Indicare gli eventuali strumenti di tutela." -#: design/plone/contenttypes/behaviors/trasparenza.py:230 +#: design/plone/contenttypes/behaviors/trasparenza.py:231 msgid "strumenti_tutela_help" msgstr "" #. Default: "Strumenti di tutela" -#: design/plone/contenttypes/behaviors/trasparenza.py:229 +#: design/plone/contenttypes/behaviors/trasparenza.py:230 msgid "strumenti_tutela_label" msgstr "" #. Default: "Struttura" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:211 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:206 msgid "struttura_label" msgstr "" #. Default: "Struttura responsabile" -#: design/plone/contenttypes/behaviors/luogo.py:82 +#: design/plone/contenttypes/behaviors/luogo.py:83 msgid "struttura_responsabile" msgstr "" #. Default: "Struttura responsabile del luogo." -#: design/plone/contenttypes/behaviors/luogo.py:63 +#: design/plone/contenttypes/behaviors/luogo.py:64 msgid "struttura_responsabile_correlati" msgstr "" #. Default: "Indicare la struttura responsabile del luogo qualora sia fra unità organizzative del comune inserite nel sito; altrimenti compilare i campi testuali relativi alla struttura responsabile" -#: design/plone/contenttypes/behaviors/luogo.py:67 +#: design/plone/contenttypes/behaviors/luogo.py:68 msgid "struttura_responsabile_correlati_help" msgstr "" #. Default: "Nome/link al sito web della struttura che gestisce il luogo, se questa non è comunale." -#: design/plone/contenttypes/behaviors/luogo.py:84 +#: design/plone/contenttypes/behaviors/luogo.py:85 msgid "struttura_responsabile_help" msgstr "" #. Default: "Seleziona la lista delle strutture politiche coinvolte." -#: design/plone/contenttypes/behaviors/strutture_correlate.py:25 +#: design/plone/contenttypes/behaviors/strutture_correlate.py:26 msgid "strutture_politiche_help" msgstr "" #. Default: "Indicare gli uffici/enti che supportano l'evento." -#: design/plone/contenttypes/behaviors/evento.py:149 +#: design/plone/contenttypes/behaviors/evento.py:97 msgid "supportato_da_help" msgstr "" #. Default: "Evento supportato da" -#: design/plone/contenttypes/behaviors/evento.py:145 +#: design/plone/contenttypes/behaviors/evento.py:93 msgid "supportato_da_label" msgstr "" #. Default: "Seleziona una lista di argomenti d'interesse per questo contenuto." -#: design/plone/contenttypes/behaviors/argomenti.py:22 +#: design/plone/contenttypes/behaviors/argomenti.py:26 msgid "tassonomia_argomenti_help" msgstr "" -#. Default: "Tassonomia argomenti" -#: design/plone/contenttypes/behaviors/argomenti.py:21 +#. Default: "Argomenti" +#: design/plone/contenttypes/behaviors/argomenti.py:25 msgid "tassonomia_argomenti_label" msgstr "" -#. Default: "Telefono" -#: design/plone/contenttypes/behaviors/evento.py:104 -msgid "telefono_event_help" -msgstr "" - -#. Default: "Indicare un riferimento telefonico per poter contattare gli organizzatori." -#: design/plone/contenttypes/behaviors/evento.py:105 -msgid "telefono_event_label" -msgstr "" - -#. Default: "Indicare un riferimento telefonico per poter contattare i referenti." -#: design/plone/contenttypes/behaviors/contatti.py:19 -msgid "telefono_help" -msgstr "" - -#. Default: "Telefono" -#: design/plone/contenttypes/behaviors/contatti.py:18 -msgid "telefono_label" -msgstr "" - -#. Default: "Contatto telefonico della persona. E' possibile inserire più di un numero. Premendo \"Invio\" o \"tab\" si può passare al successivo da inserire." -#: design/plone/contenttypes/interfaces/persona.py:117 -msgid "telefono_persona_help" -msgstr "" - -#. Default: "Numero di telefono" -#: design/plone/contenttypes/interfaces/persona.py:116 -msgid "telefono_persona_label" -msgstr "" - -#. Default: "Temi" -#: design/plone/contenttypes/interfaces/dataset.py:14 -msgid "temi" -msgstr "" - #. Default: "Tempi e scadenze" -#: design/plone/contenttypes/interfaces/servizio.py:167 +#: design/plone/contenttypes/interfaces/servizio.py:236 msgid "tempi_e_scadenze" msgstr "" #. Default: "Descrivere le informazioni dettagliate riguardo eventuali tempi e scadenze di questo servizio." -#: design/plone/contenttypes/interfaces/servizio.py:169 +#: design/plone/contenttypes/interfaces/servizio.py:238 msgid "tempi_e_scadenze_help" msgstr "" #. Default: "Tempi e scadenze" -#: design/plone/contenttypes/interfaces/servizio.py:395 +#: design/plone/contenttypes/interfaces/servizio.py:508 msgid "tempi_e_scadenze_label" msgstr "" #. Default: "Inserisci il tempo medio del procedimento." -#: design/plone/contenttypes/behaviors/trasparenza.py:91 +#: design/plone/contenttypes/behaviors/trasparenza.py:92 msgid "tempo_medio_help" msgstr "" #. Default: "Tempo medio del procedimento" -#: design/plone/contenttypes/behaviors/trasparenza.py:86 +#: design/plone/contenttypes/behaviors/trasparenza.py:87 msgid "tempo_medio_label" msgstr "" #. Default: "Testata" -#: design/plone/contenttypes/behaviors/argomenti.py:104 +#: design/plone/contenttypes/behaviors/argomenti.py:232 #: design/plone/contenttypes/behaviors/info_testata.py:62 msgid "testata_fieldset_label" msgstr "" -#: design/plone/contenttypes/interfaces/bando.py:28 +#: design/plone/contenttypes/interfaces/bando.py:29 msgid "text_help" msgstr "" #. Default: "Testo" -#: design/plone/contenttypes/interfaces/bando.py:27 +#: design/plone/contenttypes/interfaces/bando.py:28 msgid "text_label" msgstr "" -#. Default: "Tipologia documento" -#: design/plone/contenttypes/interfaces/messaggio.py:49 -msgid "tipologia_documento" -msgstr "" - -#. Default: "Seleziona la tipologia del documento." -#: design/plone/contenttypes/interfaces/documento.py:30 -msgid "tipologia_documento_help" -msgstr "" - -#. Default: "Tipologia del documento" -#: design/plone/contenttypes/interfaces/documento.py:29 -msgid "tipologia_documento_label" -msgstr "" - -#. Default: "Seleziona la tipologia della notizia." -#: design/plone/contenttypes/behaviors/news_additional_fields.py:29 -msgid "tipologia_notizia_help" -msgstr "" - -#. Default: "Tipologia notizia" -#: design/plone/contenttypes/behaviors/news_additional_fields.py:28 -msgid "tipologia_notizia_label" -msgstr "" - -#. Default: "Specificare la tipologia di organizzazione: politica, amminsitrativa o di altro tipo." -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:60 -msgid "tipologia_organizzazione_help" -msgstr "" - -#. Default: "Tipologia organizzazione" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:57 -msgid "tipologia_organizzazione_label" -msgstr "" - -#. Default: "Seleziona la tipologia di persona: politica, amministrativa o di altro tipo." -#: design/plone/contenttypes/interfaces/persona.py:86 -msgid "tipologia_persona_help" -msgstr "" - -#. Default: "Tipologia persona" -#: design/plone/contenttypes/interfaces/persona.py:85 -msgid "tipologia_persona_label" -msgstr "" - -#. Default: "Inserisci i valori utilizzabili per le tipologie di un Documento. Se il sito è multilingua, puoi inserire valori diversi a seconda delle lingue del sito." -#: design/plone/contenttypes/controlpanels/settings.py:46 -msgid "tipologie_documento_help" +#. Default: "Timeline tempi e scadenze" +#: design/plone/contenttypes/interfaces/servizio.py:246 +msgid "timeline_tempi_scadenze" msgstr "" -#. Default: "Tipologie Documento" -#: design/plone/contenttypes/controlpanels/settings.py:45 -msgid "tipologie_documento_label" +#. Default: "Timeline tempi e scadenze del servizio: indicare per ogni scadenza un titolo descrittivo ed un eventuale sottotitolo. Per ogni scadenza, selezionare opzionalmente o l'intervallo (Campi \"Intervallo\" e \"Tipo Intervallo\", es. \"1\" e \"settimana\"), oppure direttamente una data di scadenza (campo: \"Data Scadenza\", esempio 31/12/2023). Se vengono compilati entrambi, ha priorità il campo \"Data Scadenza\"." +#: design/plone/contenttypes/interfaces/servizio.py:249 +msgid "timeline_tempi_scadenze_help" msgstr "" #. Default: "Inserisci i valori utilizzabili per le tipologie di una Notizia. Se il sito è multilingua, puoi inserire valori diversi a seconda delle lingue del sito." -#: design/plone/contenttypes/controlpanels/settings.py:19 +#: design/plone/contenttypes/controlpanels/settings.py:22 msgid "tipologie_notizia_help" msgstr "" #. Default: "Tipologie Notizia" -#: design/plone/contenttypes/controlpanels/settings.py:18 +#: design/plone/contenttypes/controlpanels/settings.py:21 msgid "tipologie_notizia_label" msgstr "" -#. Default: "Inserisci i valori utilizzabili per le tipologie di una Persona. Se il sito è multilingua, puoi inserire valori diversi a seconda delle lingue del sito." -#: design/plone/contenttypes/controlpanels/settings.py:72 -msgid "tipologie_persona_help" -msgstr "" - -#. Default: "Tipologie Persona" -#: design/plone/contenttypes/controlpanels/settings.py:71 -msgid "tipologie_persona_label" -msgstr "" - #. Default: "Inserisci i valori utilizzabili per le tipologie di un' Unità Organizzativa. Se il sito è multilingua, puoi inserire valori diversi a seconda delle lingue del sito." -#: design/plone/contenttypes/controlpanels/settings.py:34 +#: design/plone/contenttypes/controlpanels/settings.py:37 msgid "tipologie_unita_organizzativa_help" msgstr "" #. Default: "Tipologie Unità Organizzativa" -#: design/plone/contenttypes/controlpanels/settings.py:30 +#: design/plone/contenttypes/controlpanels/settings.py:33 msgid "tipologie_unita_organizzativa_label" msgstr "" #. Default: "Titolare" -#: design/plone/contenttypes/interfaces/dataset.py:29 +#: design/plone/contenttypes/interfaces/dataset.py:22 msgid "titolare" msgstr "" #. Default: "Eventuale titolare del potere sostitutivo." -#: design/plone/contenttypes/behaviors/trasparenza.py:243 +#: design/plone/contenttypes/behaviors/trasparenza.py:244 msgid "titolare_potere_sostitutivo_help" msgstr "" #. Default: "Titolare del potere sostitutivo" -#: design/plone/contenttypes/behaviors/trasparenza.py:238 +#: design/plone/contenttypes/behaviors/trasparenza.py:239 msgid "titolare_potere_sostitutivo_label" msgstr "" #. Default: "Trasparenza" -#: design/plone/contenttypes/behaviors/trasparenza.py:292 +#: design/plone/contenttypes/behaviors/trasparenza.py:291 msgid "trasparenza_fieldset_label" msgstr "" +#. Default: "Tipo" +#: design/plone/contenttypes/interfaces/punto_di_contatto.py:17 +msgid "type_help" +msgstr "" + #. Default: "Seleziona l'ufficio responsabile di questo bando." -#: design/plone/contenttypes/interfaces/bando.py:110 +#: design/plone/contenttypes/interfaces/bando.py:111 msgid "ufficio_responsabile_bando_help" msgstr "" #. Default: "Ufficio responsabile del bando" -#: design/plone/contenttypes/interfaces/bando.py:106 +#: design/plone/contenttypes/interfaces/bando.py:107 msgid "ufficio_responsabile_bando_label" msgstr "" #. Default: "Seleziona l'ufficio responsabile di questo documento." -#: design/plone/contenttypes/interfaces/documento.py:43 +#: design/plone/contenttypes/interfaces/documento.py:73 msgid "ufficio_responsabile_documento_help" msgstr "" #. Default: "Ufficio responsabile del documento" -#: design/plone/contenttypes/interfaces/documento.py:39 +#: design/plone/contenttypes/interfaces/documento.py:69 msgid "ufficio_responsabile_documento_label" msgstr "" @@ -2627,13 +2618,13 @@ msgstr "" msgid "ufficio_responsabile_documento_personale" msgstr "" -#. Default: "Uffici responsabili" -#: design/plone/contenttypes/interfaces/servizio.py:216 +#. Default: "Unità organizzativa responsabile" +#: design/plone/contenttypes/interfaces/servizio.py:302 msgid "ufficio_responsabile_erogazione" msgstr "" #. Default: "Seleziona gli uffici responsabili dell'erogazione di questo servizio." -#: design/plone/contenttypes/interfaces/servizio.py:217 +#: design/plone/contenttypes/interfaces/servizio.py:306 msgid "ufficio_responsabile_help" msgstr "" @@ -2664,52 +2655,52 @@ msgstr "" msgid "unita_amministrative_responsabili_help" msgstr "" +#. Default: "Seleziona l'organizzazione presso la quale svolge l'incarico." +#: design/plone/contenttypes/interfaces/incarico.py:64 +msgid "unita_organizzativa_incarico_help" +msgstr "" + +#. Default: "Unità organizzativa" +#: design/plone/contenttypes/interfaces/incarico.py:60 +msgid "unita_organizzativa_incarico_label" +msgstr "" + #. Default: "Descrizione dei compiti assegnati alla struttura." -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:19 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:23 msgid "uo_competenze_help" msgstr "" #. Default: "Competenze" -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:18 +#: design/plone/contenttypes/interfaces/unita_organizzativa.py:22 msgid "uo_competenze_label" msgstr "" -#. Default: "Inserisci eventuali informazioni di contatto aggiuntive non contemplate nei campi precedenti. Utilizza questo campo se ci sono dei contatti aggiuntivi rispetto ai contatti della sede principale. Se inserisci un collegamento con un indirizzo email, aggiungi \"mailto:\" prima dell'indirizzo, per farlo aprire direttamente nel client di posta." -#: design/plone/contenttypes/interfaces/unita_organizzativa.py:139 -msgid "uo_contact_info_description" -msgstr "" - #. Default: "Note di aggiornamento" -#: design/plone/contenttypes/behaviors/update_note.py:16 +#: design/plone/contenttypes/behaviors/update_note.py:17 msgid "update_note_label" msgstr "" +#. Default: "Il valore del punto di contatto: il numero compreso di prefisso internazionale (se telefono), l'account (se social network), l'URL (se sito o pagina web), l'indirizzo email (se email)." +#: design/plone/contenttypes/interfaces/punto_di_contatto.py:54 +msgid "value_punto_contatto_help" +msgstr "" + #. Default: "Vincoli" -#: design/plone/contenttypes/interfaces/servizio.py:196 +#: design/plone/contenttypes/interfaces/servizio.py:282 msgid "vincoli" msgstr "" #. Default: "Descrizione degli eventuali vincoli presenti." -#: design/plone/contenttypes/interfaces/servizio.py:198 +#: design/plone/contenttypes/interfaces/servizio.py:284 msgid "vincoli_help" msgstr "" -#. Default: "Indicare un indirizzo web di riferimento a questo evento." -#: design/plone/contenttypes/behaviors/evento.py:138 -msgid "web_event_help" -msgstr "" - -#. Default: "Sito web" -#: design/plone/contenttypes/behaviors/evento.py:137 -msgid "web_event_label" -msgstr "" - -#. Default: "Indicare un indirizzo web di riferimento." -#: design/plone/contenttypes/behaviors/contatti.py:53 -msgid "web_help" +#. Default: "Mostra i PDF in anteprima" +#: design/plone/contenttypes/interfaces/cartella_modulistica.py:12 +msgid "visualize_files_title" msgstr "" -#. Default: "Sito web" -#: design/plone/contenttypes/behaviors/contatti.py:52 -msgid "web_label" +#. Default: "Permette di aprire l'anteprima di tutti i PDF di questa cartella in una tab separata, altrimenti i PDF vengono scaricati" +#: design/plone/contenttypes/interfaces/cartella_modulistica.py:13 +msgid "visulize_files_description" msgstr "" From 6c859c99388512a7908a8e0497becede49e6ed5a Mon Sep 17 00:00:00 2001 From: daniele-andreotti Date: Tue, 19 Mar 2024 09:09:15 +0100 Subject: [PATCH 438/487] Us 53140 elenco servizi (#250) * updated check-servizi view * updated check-servizi view * updated CHANGES --------- Co-authored-by: Andrea Cecchi --- CHANGES.rst | 3 +- .../browser/utils/check_servizi.py | 195 ++++++++++++------ .../browser/utils/templates/check_servizi.pt | 19 ++ 3 files changed, 152 insertions(+), 65 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index c3bd33df..cc62eca2 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,10 +4,11 @@ Changelog 6.2.2 (unreleased) ------------------ +- @@check-servizi: provides also the full list of servizi. + [daniele] - UnitaOrganizzativa.assessore_riferimento title internationalize. [folix-01] - 6.2.1 (2024-03-07) ------------------ diff --git a/src/design/plone/contenttypes/browser/utils/check_servizi.py b/src/design/plone/contenttypes/browser/utils/check_servizi.py index b918fc2d..bfe3fd5c 100644 --- a/src/design/plone/contenttypes/browser/utils/check_servizi.py +++ b/src/design/plone/contenttypes/browser/utils/check_servizi.py @@ -91,7 +91,15 @@ def plone2volto(self, url): return url.replace(portal_url, frontend_domain, 1) return url - def get_servizi(self): + def get_relation_title(self, information_dict, label): + result = "" + for item in information_dict[label]: + if not item: + continue + result = result + " " + item.to_object.title + return result + + def get_servizi(self, full_report=False): if self.is_anonymous(): return [] pc = api.portal.get_tool("portal_catalog") @@ -129,48 +137,81 @@ def get_servizi(self): "children": [], } - results[parent.title]["children"].append( - { - "title": servizio.title, - "url": self.plone2volto(servizio.absolute_url()), - "data": { - "title": information_dict.get("title") and FLAG or "", - "description": information_dict.get("description") - and FLAG - or "", - "condizioni_di_servizio": information_dict.get( - "condizioni_di_servizio" - ) - and FLAG - or "", - "tassonomia_argomenti": information_dict.get( - "tassonomia_argomenti" - ) - and FLAG - or "", - "a_chi_si_rivolge": information_dict.get("a_chi_si_rivolge") - and FLAG - or "", - "come_si_fa": information_dict.get("come_si_fa") and FLAG or "", - "cosa_si_ottiene": information_dict.get("cosa_si_ottiene") - and FLAG - or "", - "canale_accesso": information_dict.get("canale_accesso") or "", - "cosa_serve": information_dict.get("cosa_serve") and FLAG or "", - "tempi_e_scadenze": information_dict.get("tempi_e_scadenze") - and FLAG - or "", - "ufficio_responsabile": information_dict.get( - "ufficio_responsabile" - ) - and FLAG - or "", - "contact_info": information_dict.get("contact_info") - and FLAG - or "", - }, - } + tassonomia_argomenti = self.get_relation_title( + information_dict, "tassonomia_argomenti" ) + ufficio_responsabile = self.get_relation_title( + information_dict, "ufficio_responsabile" + ) + + contatti = self.get_relation_title(information_dict, "contact_info") + + if full_report: + results[parent.title]["children"].append( + { + "title": servizio.title, + "url": self.plone2volto(servizio.absolute_url()), + "data": { + "title": information_dict.get("title") or "", + "description": information_dict.get("description") or "", + "condizioni_di_servizio": information_dict.get( + "condizioni_di_servizio" + ) + or "", + "tassonomia_argomenti": tassonomia_argomenti or "", + "a_chi_si_rivolge": information_dict.get("a_chi_si_rivolge") + or "", + "come_si_fa": information_dict.get("come_si_fa") or "", + "cosa_si_ottiene": information_dict.get("cosa_si_ottiene") + or "", + "canale_accesso": information_dict.get("canale_accesso") + or "", + "cosa_serve": information_dict.get("cosa_serve") or "", + "tempi_e_scadenze": information_dict.get("tempi_e_scadenze") + or "", + "ufficio_responsabile": ufficio_responsabile or "", + "contact_info": contatti or "", + }, + } + ) + else: + results[parent.title]["children"].append( + { + "title": servizio.title, + "url": self.plone2volto(servizio.absolute_url()), + "data": { + "title": information_dict.get("title") and FLAG or "", + "description": information_dict.get("description") + and FLAG + or "", + "condizioni_di_servizio": information_dict.get( + "condizioni_di_servizio" + ) + and FLAG + or "", + "tassonomia_argomenti": tassonomia_argomenti and FLAG or "", + "a_chi_si_rivolge": information_dict.get("a_chi_si_rivolge") + and FLAG + or "", + "come_si_fa": information_dict.get("come_si_fa") + and FLAG + or "", + "cosa_si_ottiene": information_dict.get("cosa_si_ottiene") + and FLAG + or "", + "canale_accesso": information_dict.get("canale_accesso") + or "", + "cosa_serve": information_dict.get("cosa_serve") + and FLAG + or "", + "tempi_e_scadenze": information_dict.get("tempi_e_scadenze") + and FLAG + or "", + "ufficio_responsabile": ufficio_responsabile and FLAG or "", + "contact_info": contatti and FLAG or "", + }, + } + ) results = dict(sorted(results.items())) for key in results: @@ -203,32 +244,58 @@ def __call__(self): else: EMPTY_ROW = [""] * 11 - servizi = self.get_servizi() + full_report = self.request.form.get("full", False) + servizi = self.get_servizi(full_report) + data = [] for category in servizi: data.append([category] + [""] * 10 + [servizi[category]["url"]]) data.append(HEADER) - for servizio in servizi[category]["children"]: - dati_servizio = [ - servizio["title"], - servizio["data"]["description"] and "V" or "", - servizio["data"]["tassonomia_argomenti"] and "V" or "", - servizio["data"]["a_chi_si_rivolge"] and "V" or "", - servizio["data"]["come_si_fa"] and "V" or "", - servizio["data"]["cosa_si_ottiene"] and "V" or "", - servizio["data"]["canale_accesso"] and "V" or "", - servizio["data"]["cosa_serve"] and "V" or "", - servizio["data"]["tempi_e_scadenze"] and "V" or "", - servizio["data"]["ufficio_responsabile"] and "V" or "", - servizio["data"]["contact_info"] and "V" or "", - servizio["url"], - ] - if cds: - condizioni_di_servizio = ( - servizio["data"]["condizioni_di_servizio"] and "V" or "" - ) - dati_servizio.insert(2, condizioni_di_servizio) - data.append(dati_servizio) + + if full_report: + for servizio in servizi[category]["children"]: + dati_servizio = [ + servizio["title"], + servizio["data"]["description"] or "", + servizio["data"]["tassonomia_argomenti"] or "", + servizio["data"]["a_chi_si_rivolge"] or "", + servizio["data"]["come_si_fa"] or "", + servizio["data"]["cosa_si_ottiene"] or "", + servizio["data"]["canale_accesso"] or "", + servizio["data"]["cosa_serve"] or "", + servizio["data"]["tempi_e_scadenze"] or "", + servizio["data"]["ufficio_responsabile"] or "", + servizio["data"]["contact_info"] or "", + servizio["url"], + ] + if cds: + condizioni_di_servizio = ( + servizio["data"]["condizioni_di_servizio"] or "" + ) + dati_servizio.insert(2, condizioni_di_servizio) + data.append(dati_servizio) + else: + for servizio in servizi[category]["children"]: + dati_servizio = [ + servizio["title"], + servizio["data"]["description"] and "V" or "", + servizio["data"]["tassonomia_argomenti"] and "V" or "", + servizio["data"]["a_chi_si_rivolge"] and "V" or "", + servizio["data"]["come_si_fa"] and "V" or "", + servizio["data"]["cosa_si_ottiene"] and "V" or "", + servizio["data"]["canale_accesso"] and "V" or "", + servizio["data"]["cosa_serve"] and "V" or "", + servizio["data"]["tempi_e_scadenze"] and "V" or "", + servizio["data"]["ufficio_responsabile"] and "V" or "", + servizio["data"]["contact_info"] and "V" or "", + servizio["url"], + ] + if cds: + condizioni_di_servizio = ( + servizio["data"]["condizioni_di_servizio"] or "" + ) + dati_servizio.insert(2, condizioni_di_servizio) + data.append(dati_servizio) data.append(EMPTY_ROW) data.append(EMPTY_ROW) diff --git a/src/design/plone/contenttypes/browser/utils/templates/check_servizi.pt b/src/design/plone/contenttypes/browser/utils/templates/check_servizi.pt index e355d74f..8173df68 100644 --- a/src/design/plone/contenttypes/browser/utils/templates/check_servizi.pt +++ b/src/design/plone/contenttypes/browser/utils/templates/check_servizi.pt @@ -152,6 +152,25 @@ +
+
+ + + + + +
From 17557bc1b1317697c711c99b028351a19d7b753f Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Tue, 19 Mar 2024 09:35:34 +0100 Subject: [PATCH 439/487] Preparing release 6.2.2 --- CHANGES.rst | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index cc62eca2..596d3320 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,7 +1,7 @@ Changelog ========= -6.2.2 (unreleased) +6.2.2 (2024-03-19) ------------------ - @@check-servizi: provides also the full list of servizi. diff --git a/setup.py b/setup.py index 97aa5cd1..913efd6d 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.2.2.dev0", + version="6.2.2", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 9953d00779cff5113f16e5e49363d126f04512c5 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Tue, 19 Mar 2024 09:36:08 +0100 Subject: [PATCH 440/487] Back to development: 6.2.3 --- CHANGES.rst | 6 ++++++ setup.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 596d3320..aeebe506 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,6 +1,12 @@ Changelog ========= +6.2.3 (unreleased) +------------------ + +- Nothing changed yet. + + 6.2.2 (2024-03-19) ------------------ diff --git a/setup.py b/setup.py index 913efd6d..bc4e4d74 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.2.2", + version="6.2.3.dev0", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 5e62cd75f05ab3b794c0cfcbaac66adc55bfe627 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Wed, 10 Apr 2024 17:03:12 +0200 Subject: [PATCH 441/487] image are no longer required in venue --- CHANGES.rst | 3 ++- src/design/plone/contenttypes/restapi/services/types/get.py | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index aeebe506..a03d0971 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,7 +4,8 @@ Changelog 6.2.3 (unreleased) ------------------ -- Nothing changed yet. +- Image are no longer required in venue + [lucabel] 6.2.2 (2024-03-19) diff --git a/src/design/plone/contenttypes/restapi/services/types/get.py b/src/design/plone/contenttypes/restapi/services/types/get.py index c68697d4..206dd81b 100644 --- a/src/design/plone/contenttypes/restapi/services/types/get.py +++ b/src/design/plone/contenttypes/restapi/services/types/get.py @@ -171,7 +171,6 @@ def customize_venue_schema(self, result): Unico modo per spostare il campo "notes" """ result.get("required").append("description") - result.get("required").append("image") result.get("required").append("street") result.get("required").append("city") result.get("required").append("zip_code") From 724099edb2f2ff1b191dddd0b6f037f233684edd Mon Sep 17 00:00:00 2001 From: Mauro Amico Date: Sat, 13 Apr 2024 23:25:59 +0200 Subject: [PATCH 442/487] fix: broken test https://github.com/RedTurtle/design.plone.contenttypes/commit/5e62cd75f05ab3b794c0cfcbaac66adc55bfe627 --- src/design/plone/contenttypes/tests/test_ct_luogo.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/design/plone/contenttypes/tests/test_ct_luogo.py b/src/design/plone/contenttypes/tests/test_ct_luogo.py index 75f9e66a..8e837fba 100644 --- a/src/design/plone/contenttypes/tests/test_ct_luogo.py +++ b/src/design/plone/contenttypes/tests/test_ct_luogo.py @@ -102,7 +102,6 @@ def test_luogo_required_fields(self): "contact_info", "modalita_accesso", "description", - "image", "street", "city", "zip_code", From 329a99006f3b297a878556f136aaa6df20e00f39 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Tue, 16 Apr 2024 14:53:24 +0200 Subject: [PATCH 443/487] fix manifest as suggested by zest.releaser --- MANIFEST.in | 1 + 1 file changed, 1 insertion(+) diff --git a/MANIFEST.in b/MANIFEST.in index f97e1a17..113f5778 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,6 +1,7 @@ graft src/design graft docs include *.rst +include tox.ini global-exclude *.pyc include *.GPL include *.disabled From 593b79b10b7e0b92ff5ce82fd724917bb5ddc45c Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Tue, 16 Apr 2024 14:56:32 +0200 Subject: [PATCH 444/487] Preparing release 6.2.3 --- CHANGES.rst | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index a03d0971..61d08d1e 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,7 +1,7 @@ Changelog ========= -6.2.3 (unreleased) +6.2.3 (2024-04-16) ------------------ - Image are no longer required in venue diff --git a/setup.py b/setup.py index bc4e4d74..5bca6abb 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.2.3.dev0", + version="6.2.3", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From a7f5afceb8169c3edc8ca44ffec088e327d04f4e Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Tue, 16 Apr 2024 14:57:08 +0200 Subject: [PATCH 445/487] Back to development: 6.2.4 --- CHANGES.rst | 6 ++++++ setup.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 61d08d1e..d0c730b2 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,6 +1,12 @@ Changelog ========= +6.2.4 (unreleased) +------------------ + +- Nothing changed yet. + + 6.2.3 (2024-04-16) ------------------ diff --git a/setup.py b/setup.py index 5bca6abb..6f837b56 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.2.3", + version="6.2.4.dev0", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 0f0cd3eec33cc18738b25130022d42ae824b4104 Mon Sep 17 00:00:00 2001 From: Mauro Amico Date: Tue, 16 Apr 2024 15:03:21 +0200 Subject: [PATCH 446/487] blob (#244) * blob * black * update ci * upgrade step * typo * changelog --- .github/workflows/black.yml | 10 ++-- .isort.cfg | 2 + CHANGES.rst | 3 + .../interfaces/documento_personale.py | 6 +- .../contenttypes/interfaces/messaggio.py | 2 +- .../plone/contenttypes/interfaces/persona.py | 2 +- .../interfaces/ricevuta_pagamento.py | 8 ++- .../profiles/default/metadata.xml | 2 +- .../restapi/deserializers/dxfields.py | 10 ++-- .../restapi/services/types/get.py | 24 ++++---- .../contenttypes/upgrades/configure.zcml | 9 +++ .../plone/contenttypes/upgrades/to_7300.py | 55 +++++++++++++++++++ 12 files changed, 103 insertions(+), 30 deletions(-) create mode 100644 .isort.cfg create mode 100644 src/design/plone/contenttypes/upgrades/to_7300.py diff --git a/.github/workflows/black.yml b/.github/workflows/black.yml index d2573b65..f7ba8b97 100644 --- a/.github/workflows/black.yml +++ b/.github/workflows/black.yml @@ -6,20 +6,20 @@ jobs: strategy: fail-fast: false matrix: - python-version: [3.8] + python-version: [3.11] steps: # git checkout - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 # python setup - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v1 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} # python cache - - uses: actions/cache@v1 + - uses: actions/cache@v4 with: path: ~/.cache/pip key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} @@ -28,7 +28,7 @@ jobs: # install black - name: install black - run: pip install black==21.12b0 click==8.0.4 + run: pip install black # run black - name: run black diff --git a/.isort.cfg b/.isort.cfg new file mode 100644 index 00000000..0b113d2c --- /dev/null +++ b/.isort.cfg @@ -0,0 +1,2 @@ +[settings] +profile = plone diff --git a/CHANGES.rst b/CHANGES.rst index d0c730b2..66a235fa 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -10,6 +10,9 @@ Changelog 6.2.3 (2024-04-16) ------------------ +- converted some file and image fields as blob fields + [mamico] + - Image are no longer required in venue [lucabel] diff --git a/src/design/plone/contenttypes/interfaces/documento_personale.py b/src/design/plone/contenttypes/interfaces/documento_personale.py index 00efb253..a142326d 100644 --- a/src/design/plone/contenttypes/interfaces/documento_personale.py +++ b/src/design/plone/contenttypes/interfaces/documento_personale.py @@ -20,9 +20,11 @@ class IDocumentoPersonale(model.Schema): required=True, ) - immagine = field.NamedImage(title=_("immagine", default="Immagine"), required=False) + immagine = field.NamedBlobImage( + title=_("immagine", default="Immagine"), required=False + ) - pratica_associata = field.NamedFile( + pratica_associata = field.NamedBlobFile( title=_("pratica_associata", default="Pratica associata"), required=True, ) diff --git a/src/design/plone/contenttypes/interfaces/messaggio.py b/src/design/plone/contenttypes/interfaces/messaggio.py index 46ce393d..d1e3dd04 100644 --- a/src/design/plone/contenttypes/interfaces/messaggio.py +++ b/src/design/plone/contenttypes/interfaces/messaggio.py @@ -44,7 +44,7 @@ class IMessaggio(model.Schema): required=False, ) - documenti_allegati = field.NamedFile( + documenti_allegati = field.NamedBlobFile( title=_("documenti_allegati", default="Documenti allegati"), required=False, ) diff --git a/src/design/plone/contenttypes/interfaces/persona.py b/src/design/plone/contenttypes/interfaces/persona.py index 2b7e5020..2cd20907 100644 --- a/src/design/plone/contenttypes/interfaces/persona.py +++ b/src/design/plone/contenttypes/interfaces/persona.py @@ -24,7 +24,7 @@ class IPersona(model.Schema, IDesignPloneContentType): """Marker interface for contenttype Persona""" - foto_persona = field.NamedImage( + foto_persona = field.NamedBlobImage( title=_("foto_persona_label", default="Foto della persona"), required=False, description=_( diff --git a/src/design/plone/contenttypes/interfaces/ricevuta_pagamento.py b/src/design/plone/contenttypes/interfaces/ricevuta_pagamento.py index 28340e92..979a57ec 100644 --- a/src/design/plone/contenttypes/interfaces/ricevuta_pagamento.py +++ b/src/design/plone/contenttypes/interfaces/ricevuta_pagamento.py @@ -13,7 +13,7 @@ class IRicevutaPagamento(model.Schema): required=True, ) - stampa_ricevuta = field.NamedFile( + stampa_ricevuta = field.NamedBlobFile( title=_("stampa_ricevuta", default="Stampa ricevuta"), required=True ) @@ -39,7 +39,7 @@ class IRicevutaPagamento(model.Schema): required=False, ) - pratica_associata = field.NamedFile( + pratica_associata = field.NamedBlobFile( title=_("pratica_associata_ricevuta", default="Pratica associata al pagamento"), required=True, ) @@ -53,4 +53,6 @@ class IRicevutaPagamento(model.Schema): required=True, ) - allegato = field.NamedFile(title=_("allegato", default="Allegato"), required=False) + allegato = field.NamedBlobFile( + title=_("allegato", default="Allegato"), required=False + ) diff --git a/src/design/plone/contenttypes/profiles/default/metadata.xml b/src/design/plone/contenttypes/profiles/default/metadata.xml index f6ba447d..66b31642 100644 --- a/src/design/plone/contenttypes/profiles/default/metadata.xml +++ b/src/design/plone/contenttypes/profiles/default/metadata.xml @@ -1,6 +1,6 @@ - 7200 + 7300 profile-redturtle.bandi:default profile-collective.venue:default diff --git a/src/design/plone/contenttypes/restapi/deserializers/dxfields.py b/src/design/plone/contenttypes/restapi/deserializers/dxfields.py index 59947b5e..433241f7 100644 --- a/src/design/plone/contenttypes/restapi/deserializers/dxfields.py +++ b/src/design/plone/contenttypes/restapi/deserializers/dxfields.py @@ -112,11 +112,11 @@ def __call__(self, value): "milestone_description": item.get("milestone_description", ""), "interval_qt": item.get("interval_qt", ""), "interval_type": item.get("interval_type", ""), - "data_scadenza": datetime.strptime( - item["data_scadenza"], "%Y-%m-%d" - ).date() - if item.get("data_scadenza", None) - else None, # noqa + "data_scadenza": ( + datetime.strptime(item["data_scadenza"], "%Y-%m-%d").date() + if item.get("data_scadenza", None) + else None + ), # noqa } timeline.append(entry) diff --git a/src/design/plone/contenttypes/restapi/services/types/get.py b/src/design/plone/contenttypes/restapi/services/types/get.py index 206dd81b..c18ce171 100644 --- a/src/design/plone/contenttypes/restapi/services/types/get.py +++ b/src/design/plone/contenttypes/restapi/services/types/get.py @@ -185,25 +185,25 @@ def customize_venue_schema(self, result): } if "city" in result["properties"]: if not result["properties"]["city"].get("default", ""): - result["properties"]["city"][ - "default" - ] = api.portal.get_registry_record( - "city", interface=IGeolocationDefaults + result["properties"]["city"]["default"] = ( + api.portal.get_registry_record( + "city", interface=IGeolocationDefaults + ) ) if "zip_code" in result["properties"]: if not result["properties"]["zip_code"].get("default", ""): - result["properties"]["zip_code"][ - "default" - ] = api.portal.get_registry_record( - "zip_code", interface=IGeolocationDefaults + result["properties"]["zip_code"]["default"] = ( + api.portal.get_registry_record( + "zip_code", interface=IGeolocationDefaults + ) ) if "street" in result["properties"]: if not result["properties"]["street"].get("default", ""): - result["properties"]["street"][ - "default" - ] = api.portal.get_registry_record( - "street", interface=IGeolocationDefaults + result["properties"]["street"]["default"] = ( + api.portal.get_registry_record( + "street", interface=IGeolocationDefaults + ) ) if "geolocation" in result["properties"]: diff --git a/src/design/plone/contenttypes/upgrades/configure.zcml b/src/design/plone/contenttypes/upgrades/configure.zcml index 7d4fbff9..c3b93f12 100644 --- a/src/design/plone/contenttypes/upgrades/configure.zcml +++ b/src/design/plone/contenttypes/upgrades/configure.zcml @@ -848,4 +848,13 @@ handler=".upgrades.to_7200" /> + + + diff --git a/src/design/plone/contenttypes/upgrades/to_7300.py b/src/design/plone/contenttypes/upgrades/to_7300.py new file mode 100644 index 00000000..ba010d21 --- /dev/null +++ b/src/design/plone/contenttypes/upgrades/to_7300.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- +from .upgrades import logger +from Acquisition import aq_base +from plone import api +from plone.namedfile import file + + +def to_7300(context): + + mapping = { + # portal_type + "Documento Personale": { + # field: "type" + "immagine": "image", + "pratica_associata": "file", + }, + "Messaggio": { + "documenti_allegati": "file", + }, + "Persona": { + "foto_persona": "image", + }, + "RicevutaPagamento": { + "stampa_ricevuta": "file", + "pratica_associata": "file", + "allegato": "file", + }, + } + + mapping_types = { + "image": (file.NamedImage, file.NamedBlobImage), + "file": (file.NamedFile, file.NamedBlobFile), + } + + for portal_type, fields in mapping.items(): + brains = api.content.find(unrestricted=True, portal_type=portal_type) + logger.info("Updating fields for %s %s objects", portal_type, len(brains)) + for brain in brains: + obj = aq_base(brain.getObject()) + for fieldname, _type in fields.items(): + value = getattr(obj, fieldname, None) + # if value: + # import pdb; pdb.set_trace() + if value and isinstance(value, mapping_types[_type][0]): + logger.info("Updated %s for %s", fieldname, brain.getPath()) + setattr( + obj, + fieldname, + mapping_types[_type][1]( + data=value.data, + contentType=value.contentType, + filename=value.filename, + ), + ) + logger.info("Finished updating fields") From 1f1ecac87bbb337ac3403db8460e39faf3cc737c Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Tue, 16 Apr 2024 15:08:05 +0200 Subject: [PATCH 447/487] fix chagelog --- CHANGES.rst | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 66a235fa..18acfa6e 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,15 +4,13 @@ Changelog 6.2.4 (unreleased) ------------------ -- Nothing changed yet. +- converted some file and image fields as blob fields + [mamico] 6.2.3 (2024-04-16) ------------------ -- converted some file and image fields as blob fields - [mamico] - - Image are no longer required in venue [lucabel] From b0aba36d2375c5e0237723f662d58bb89e59b89f Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Tue, 16 Apr 2024 15:08:24 +0200 Subject: [PATCH 448/487] Preparing release 6.2.4 --- CHANGES.rst | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 18acfa6e..5b9acdf7 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,7 +1,7 @@ Changelog ========= -6.2.4 (unreleased) +6.2.4 (2024-04-16) ------------------ - converted some file and image fields as blob fields diff --git a/setup.py b/setup.py index 6f837b56..7a0ac26f 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.2.4.dev0", + version="6.2.4", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 910d9d9e119ee831b9188cb5bd0832974dff206b Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Tue, 16 Apr 2024 15:08:51 +0200 Subject: [PATCH 449/487] Back to development: 6.2.5 --- CHANGES.rst | 6 ++++++ setup.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 5b9acdf7..70466d24 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,6 +1,12 @@ Changelog ========= +6.2.5 (unreleased) +------------------ + +- Nothing changed yet. + + 6.2.4 (2024-04-16) ------------------ diff --git a/setup.py b/setup.py index 7a0ac26f..f124a5af 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.2.4", + version="6.2.5.dev0", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 759fe66a92620fb46e6b6435e87956354ddf7145 Mon Sep 17 00:00:00 2001 From: daniele-andreotti Date: Tue, 16 Apr 2024 16:43:39 +0200 Subject: [PATCH 450/487] check-servizi: fixed check on relation title (#254) --- CHANGES.rst | 3 ++- src/design/plone/contenttypes/browser/utils/check_servizi.py | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 70466d24..3f6d0c67 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,7 +4,8 @@ Changelog 6.2.5 (unreleased) ------------------ -- Nothing changed yet. +- check-servizi: fixed check on relation title. + [daniele] 6.2.4 (2024-04-16) diff --git a/src/design/plone/contenttypes/browser/utils/check_servizi.py b/src/design/plone/contenttypes/browser/utils/check_servizi.py index bfe3fd5c..34f9e390 100644 --- a/src/design/plone/contenttypes/browser/utils/check_servizi.py +++ b/src/design/plone/contenttypes/browser/utils/check_servizi.py @@ -96,6 +96,8 @@ def get_relation_title(self, information_dict, label): for item in information_dict[label]: if not item: continue + if not item.to_object: + continue result = result + " " + item.to_object.title return result From 26ef7a5f762d8504f5f1c54fd7730096992d7246 Mon Sep 17 00:00:00 2001 From: Daniele Andreotti Date: Wed, 17 Apr 2024 11:54:23 +0200 Subject: [PATCH 451/487] Preparing release 6.2.5 --- CHANGES.rst | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 3f6d0c67..f73a5f36 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,7 +1,7 @@ Changelog ========= -6.2.5 (unreleased) +6.2.5 (2024-04-17) ------------------ - check-servizi: fixed check on relation title. diff --git a/setup.py b/setup.py index f124a5af..ea94f315 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.2.5.dev0", + version="6.2.5", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 2be43a654c451411292c326d73f2bbed37773573 Mon Sep 17 00:00:00 2001 From: Daniele Andreotti Date: Wed, 17 Apr 2024 11:54:40 +0200 Subject: [PATCH 452/487] Back to development: 6.2.6 --- CHANGES.rst | 6 ++++++ setup.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index f73a5f36..80127b71 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,6 +1,12 @@ Changelog ========= +6.2.6 (unreleased) +------------------ + +- Nothing changed yet. + + 6.2.5 (2024-04-17) ------------------ diff --git a/setup.py b/setup.py index ea94f315..c4eead6e 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.2.5", + version="6.2.6.dev0", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 103b1d40c30fdb67a250496bc7fa336364d8d8da Mon Sep 17 00:00:00 2001 From: daniele-andreotti Date: Thu, 18 Apr 2024 10:42:14 +0200 Subject: [PATCH 453/487] flaked (#256) --- CHANGES.rst | 3 ++- .../contenttypes/restapi/serializers/punto_di_contatto.py | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 80127b71..c35cf241 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,7 +4,8 @@ Changelog 6.2.6 (unreleased) ------------------ -- Nothing changed yet. +- improved check on relation. + [daniele] 6.2.5 (2024-04-17) diff --git a/src/design/plone/contenttypes/restapi/serializers/punto_di_contatto.py b/src/design/plone/contenttypes/restapi/serializers/punto_di_contatto.py index 95e2f71a..48f5499f 100644 --- a/src/design/plone/contenttypes/restapi/serializers/punto_di_contatto.py +++ b/src/design/plone/contenttypes/restapi/serializers/punto_di_contatto.py @@ -61,7 +61,10 @@ def related_contents(self, field, portal_type): ) for rel in relations: - obj = intids.queryObject(rel.from_id) + try: + obj = intids.queryObject(rel.from_id) + except: # noqa + continue if ( obj is not None and checkPermission("zope2.View", obj) From 13dc36b477e870d33e4bb652b6a55e7c00b42457 Mon Sep 17 00:00:00 2001 From: Daniele Andreotti Date: Thu, 18 Apr 2024 10:44:27 +0200 Subject: [PATCH 454/487] Preparing release 6.2.6 --- CHANGES.rst | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index c35cf241..2b5915aa 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,7 +1,7 @@ Changelog ========= -6.2.6 (unreleased) +6.2.6 (2024-04-18) ------------------ - improved check on relation. diff --git a/setup.py b/setup.py index c4eead6e..ba6471a6 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.2.6.dev0", + version="6.2.6", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From e5a79ec0a5a0ab011ec4bc411956b8797f0f1503 Mon Sep 17 00:00:00 2001 From: Daniele Andreotti Date: Thu, 18 Apr 2024 10:44:52 +0200 Subject: [PATCH 455/487] Back to development: 6.2.7 --- CHANGES.rst | 6 ++++++ setup.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 2b5915aa..7b270ba2 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,6 +1,12 @@ Changelog ========= +6.2.7 (unreleased) +------------------ + +- Nothing changed yet. + + 6.2.6 (2024-04-18) ------------------ diff --git a/setup.py b/setup.py index ba6471a6..bd1f5cbd 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.2.6", + version="6.2.7.dev0", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From d7450ccc5d2cc95cdbc15157d20fc6094cd54d3d Mon Sep 17 00:00:00 2001 From: Andrea Cecchi Date: Mon, 22 Apr 2024 12:09:05 +0200 Subject: [PATCH 456/487] Do not break News serializer if `tipologia_notizia` attribute is missing (#257) * Do not break News serialzier if attribute is missing. * fix in more places --- CHANGES.rst | 3 ++- src/design/plone/contenttypes/patches/baseserializer.py | 2 +- .../plone/contenttypes/restapi/serializers/dxcontent.py | 9 +++++---- .../plone/contenttypes/restapi/serializers/summary.py | 9 +++++---- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 7b270ba2..4fa5669c 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,7 +4,8 @@ Changelog 6.2.7 (unreleased) ------------------ -- Nothing changed yet. +- Do not break News serialzier if `tipologia_notizia` attribute is missing. + [cekk] 6.2.6 (2024-04-18) diff --git a/src/design/plone/contenttypes/patches/baseserializer.py b/src/design/plone/contenttypes/patches/baseserializer.py index 1ac8ca6d..12805939 100644 --- a/src/design/plone/contenttypes/patches/baseserializer.py +++ b/src/design/plone/contenttypes/patches/baseserializer.py @@ -37,7 +37,7 @@ def design_italia_serialize_to_json_call(self, version=None, include_items=True) ttool[self.context.portal_type].Title(), context=self.request ) if self.context.portal_type == "News Item": - if self.context.tipologia_notizia: + if getattr(self.context, "tipologia_notizia", ""): taxonomy = getUtility( ITaxonomy, name="collective.taxonomy.tipologia_notizia" ) diff --git a/src/design/plone/contenttypes/restapi/serializers/dxcontent.py b/src/design/plone/contenttypes/restapi/serializers/dxcontent.py index bae57370..568cc3a3 100644 --- a/src/design/plone/contenttypes/restapi/serializers/dxcontent.py +++ b/src/design/plone/contenttypes/restapi/serializers/dxcontent.py @@ -19,15 +19,16 @@ class MetaTypeSerializer(object): def get_design_meta_type(self): ttool = api.portal.get_tool("portal_types") - if self.context.portal_type == "News Item" and self.context.tipologia_notizia: + tipologia_notizia = getattr(self.context, "tipologia_notizia", "") + if self.context.portal_type == "News Item" and tipologia_notizia: taxonomy = getUtility( ITaxonomy, name="collective.taxonomy.tipologia_notizia" ) taxonomy_voc = taxonomy.makeVocabulary(self.request.get("LANGUAGE")) - if isinstance(self.context.tipologia_notizia, list): - token = self.context.tipologia_notizia[0] + if isinstance(tipologia_notizia, list): + token = tipologia_notizia[0] else: - token = self.context.tipologia_notizia + token = tipologia_notizia title = taxonomy_voc.inv_data.get(token, None) if title and title.startswith(PATH_SEPARATOR): diff --git a/src/design/plone/contenttypes/restapi/serializers/summary.py b/src/design/plone/contenttypes/restapi/serializers/summary.py index 055ba38e..92c31bb3 100644 --- a/src/design/plone/contenttypes/restapi/serializers/summary.py +++ b/src/design/plone/contenttypes/restapi/serializers/summary.py @@ -220,15 +220,16 @@ def is_get_call(self): def get_design_meta_type(self): ttool = api.portal.get_tool("portal_types") if self.context.portal_type == "News Item": - if self.context.tipologia_notizia: + tipologia_notizia = getattr(self.context, "tipologia_notizia", "") + if tipologia_notizia: taxonomy = getUtility( ITaxonomy, name="collective.taxonomy.tipologia_notizia" ) taxonomy_voc = taxonomy.makeVocabulary(self.request.get("LANGUAGE")) - if isinstance(self.context.tipologia_notizia, list): - token = self.context.tipologia_notizia[0] + if isinstance(tipologia_notizia, list): + token = tipologia_notizia[0] else: - token = self.context.tipologia_notizia + token = tipologia_notizia title = taxonomy_voc.inv_data.get(token, None) if title: if title.startswith(PATH_SEPARATOR): From 97dfc93bd200ab13a0ca8e8422514518beb169e6 Mon Sep 17 00:00:00 2001 From: Luca Date: Mon, 22 Apr 2024 12:26:30 +0200 Subject: [PATCH 457/487] fix change_news_type (#255) * fix change_news_type * fix test --- CHANGES.rst | 6 +++- .../browser/utils/change_news_type.py | 28 +++++++++---------- .../browser/utils/templates/utils.pt | 2 +- .../tests/test_change_news_type.py | 4 +-- test_plone60.cfg | 8 ++++++ 5 files changed, 29 insertions(+), 19 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 4fa5669c..03defbc9 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,6 +4,10 @@ Changelog 6.2.7 (unreleased) ------------------ +- Fix change_news_type view; Taxonomy doesn't index values not present in + the taxonomy vocabulary, so we had lot of old values not indexed and not listed + as available type to change. + [lucabel] - Do not break News serialzier if `tipologia_notizia` attribute is missing. [cekk] @@ -19,7 +23,7 @@ Changelog ------------------ - check-servizi: fixed check on relation title. - [daniele] + [daniele] 6.2.4 (2024-04-16) diff --git a/src/design/plone/contenttypes/browser/utils/change_news_type.py b/src/design/plone/contenttypes/browser/utils/change_news_type.py index 237f5ff4..899352a3 100644 --- a/src/design/plone/contenttypes/browser/utils/change_news_type.py +++ b/src/design/plone/contenttypes/browser/utils/change_news_type.py @@ -36,11 +36,17 @@ def news_types(self): return taxonomy.makeVocabulary(self.request.get("LANGUAGE")) def news_types_in_catalog(self): - return api.portal.get_tool("portal_catalog").uniqueValuesFor( - "tipologia_notizia" - ) + types = [news.tipologia_notizia for news in self.news] + types = list(set(types)) + return types def substitute_news_type(self): + # the only way to get all the tipologia_notizia value is to query news + # objects not the brains. Taxonomy doesn't index values not present in + # the taxonomy vocabulary so we have a lot of brain withou tipologia_notizia + self.brains = api.content.find(portal_type="News Item") + self.news = [brain.getObject() for brain in self.brains] + if not self.request.form.get("substitute", ""): return @@ -65,18 +71,10 @@ def substitute_news_type(self): ) return - if old_news_type not in self.news_types_in_catalog(): - self.context.plone_utils.addPortalMessage( - _("The old News Type was not found between available values"), "error" - ) - return - - for news in api.portal.get_tool("portal_catalog")( - tipologia_notizia=old_news_type - ): - news = news.getObject() - news.tipologia_notizia = news_new_type - news.reindexObject(idxs=["tipologia_notizia"]) + for news in self.news: + if news.tipologia_notizia == old_news_type: + news.tipologia_notizia = news_new_type + news.reindexObject(idxs=["tipologia_notizia"]) # update listings for brain in api.portal.get_tool("portal_catalog")(): diff --git a/src/design/plone/contenttypes/browser/utils/templates/utils.pt b/src/design/plone/contenttypes/browser/utils/templates/utils.pt index 1bfdf1d8..ed8d2387 100644 --- a/src/design/plone/contenttypes/browser/utils/templates/utils.pt +++ b/src/design/plone/contenttypes/browser/utils/templates/utils.pt @@ -22,7 +22,7 @@

Content-types

  • - Cambia la Tipologia Notizia + Cambia la Tipologia Notizia

    Questo tool viene usato per cambiare il valore del campo 'Tipologia Notizia' in tutte le notizie che hanno il valore del campo selezionato. Fa anche il giro su tutti i blocchi elenco.

    diff --git a/src/design/plone/contenttypes/tests/test_change_news_type.py b/src/design/plone/contenttypes/tests/test_change_news_type.py index 140c0c4c..d1a3fd10 100644 --- a/src/design/plone/contenttypes/tests/test_change_news_type.py +++ b/src/design/plone/contenttypes/tests/test_change_news_type.py @@ -31,13 +31,13 @@ def setUp(self): self.news_item = api.content.create( type="News Item", title="news item", - tipologia_notizia=["notizia"], + tipologia_notizia="notizia", container=self.portal, ) self.news_item1 = api.content.create( type="News Item", title="news item1", - tipologia_notizia=["notizia"], + tipologia_notizia="notizia", container=self.news_container, ) diff --git a/test_plone60.cfg b/test_plone60.cfg index 7207dc4a..a0b9ce9d 100644 --- a/test_plone60.cfg +++ b/test_plone60.cfg @@ -60,3 +60,11 @@ tomli = 2.0.1 webencodings = 0.5.1 # Added by buildout at 2023-03-22 23:05:32.974075 + +# Added by buildout at 2024-04-19 12:51:02.457936 + +# Required by: +# Plone==6.0.10 +# collective.volto.blocksfield==2.0.0 +# redturtle.bandi==1.4.3 +plone.restapi = 9.6.0 From e813bcd3b8b5917e0a6a8c4ef115e973b030e397 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Mon, 22 Apr 2024 12:28:47 +0200 Subject: [PATCH 458/487] Preparing release 6.2.7 --- CHANGES.rst | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 03defbc9..548e02c1 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,7 +1,7 @@ Changelog ========= -6.2.7 (unreleased) +6.2.7 (2024-04-22) ------------------ - Fix change_news_type view; Taxonomy doesn't index values not present in diff --git a/setup.py b/setup.py index bd1f5cbd..be246dee 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.2.7.dev0", + version="6.2.7", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From a0d06d56ec44bcd18c9a514ba146c164489cfd58 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Mon, 22 Apr 2024 12:29:25 +0200 Subject: [PATCH 459/487] Back to development: 6.2.8 --- CHANGES.rst | 6 ++++++ setup.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 548e02c1..58502195 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,6 +1,12 @@ Changelog ========= +6.2.8 (unreleased) +------------------ + +- Nothing changed yet. + + 6.2.7 (2024-04-22) ------------------ diff --git a/setup.py b/setup.py index be246dee..649333d7 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.2.7", + version="6.2.8.dev0", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 08f02b14b71c5d3d1ff50f209ed7d53f973065a1 Mon Sep 17 00:00:00 2001 From: Luca Date: Mon, 22 Apr 2024 14:13:57 +0200 Subject: [PATCH 460/487] Add date to events in items (#258) * update event summary serialization with start date --- CHANGES.rst | 5 ++++- .../restapi/serializers/summary.py | 2 ++ .../tests/test_summary_serializer.py | 21 +++++++++++++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 58502195..961ec4d1 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,7 +4,10 @@ Changelog 6.2.8 (unreleased) ------------------ -- Nothing changed yet. +- Add start metadata to event summary serialization; + useful when create event with children event: in items list we + have subevents with missing start date + [lucabel] 6.2.7 (2024-04-22) diff --git a/src/design/plone/contenttypes/restapi/serializers/summary.py b/src/design/plone/contenttypes/restapi/serializers/summary.py index 92c31bb3..5e5d98d0 100644 --- a/src/design/plone/contenttypes/restapi/serializers/summary.py +++ b/src/design/plone/contenttypes/restapi/serializers/summary.py @@ -158,6 +158,8 @@ def __call__(self, force_all_metadata=False, force_images=False): res["tipologia_bando"] = getattr(self.context, "tipologia_bando", "") if "bando_state" in metadata_fields or self.show_all_metadata_fields: res["bando_state"] = self.get_bando_state() + if self.context.portal_type == "Event": + res["start"] = json_compatible(self.context.start) if "geolocation" in metadata_fields or self.show_all_metadata_fields: # backward compatibility for some block templates diff --git a/src/design/plone/contenttypes/tests/test_summary_serializer.py b/src/design/plone/contenttypes/tests/test_summary_serializer.py index 00836c73..66696a83 100644 --- a/src/design/plone/contenttypes/tests/test_summary_serializer.py +++ b/src/design/plone/contenttypes/tests/test_summary_serializer.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +from datetime import datetime from design.plone.contenttypes.testing import ( DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING, ) @@ -329,3 +330,23 @@ def test_bando_summary_return_tipologia_bando(self): self.assertEqual(len(items), 1) self.assertNotIn("tipologia_bando", bando.tipologia_bando) + + def test_event_summary(self): + event1 = api.content.create( + container=self.portal, + type="Event", + title="Evento1", + start=datetime(2024, 4, 22, 12, 0), + end=datetime(2024, 5, 22, 13, 0), + ) + api.content.create( + container=event1, + type="Event", + title="Evento2", + start=datetime(2024, 4, 23, 12, 0), + end=datetime(2024, 4, 23, 13, 0), + ) + commit() + resp = self.api_session.get(event1.absolute_url()).json() + subevent = [x for x in resp["items"] if x["@type"] == "Event"][0] + self.assertIn("start", subevent) From 2e917625c017fc2e28fb575d58965d00c6bcdf0e Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Mon, 22 Apr 2024 14:15:08 +0200 Subject: [PATCH 461/487] Preparing release 6.2.8 --- CHANGES.rst | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 961ec4d1..ae068167 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,7 +1,7 @@ Changelog ========= -6.2.8 (unreleased) +6.2.8 (2024-04-22) ------------------ - Add start metadata to event summary serialization; diff --git a/setup.py b/setup.py index 649333d7..306b5182 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.2.8.dev0", + version="6.2.8", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 99b6ba6ef8aaeba2c2a45c150bb66eb1e800461c Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Mon, 22 Apr 2024 14:15:45 +0200 Subject: [PATCH 462/487] Back to development: 6.2.9 --- CHANGES.rst | 6 ++++++ setup.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index ae068167..54faef56 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,6 +1,12 @@ Changelog ========= +6.2.9 (unreleased) +------------------ + +- Nothing changed yet. + + 6.2.8 (2024-04-22) ------------------ diff --git a/setup.py b/setup.py index 306b5182..7a6a7378 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.2.8", + version="6.2.9.dev0", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 5ff10879da70af758b1b5e5e1dfe741dd1612dd4 Mon Sep 17 00:00:00 2001 From: Luca Date: Thu, 2 May 2024 17:22:49 +0200 Subject: [PATCH 463/487] Altri allegati sulla persona (#259) * aggiunto la cartella altri allegati sulla persona * add some fix in order to work with plone 6.0.11 and it's dependencies --- CHANGES.rst | 3 +- setup.py | 1 + .../plone/contenttypes/events/common.py | 5 +++ .../profiles/default/metadata.xml | 2 +- .../restapi/serializers/summary.py | 10 ++++- .../tests/test_substructure_creation.py | 10 +++++ .../tests/test_uo_summary_serializer.py | 6 ++- .../contenttypes/upgrades/configure.zcml | 7 +++ .../plone/contenttypes/upgrades/to_730x.py | 45 +++++++++++++++++++ test_plone60.cfg | 1 + 10 files changed, 85 insertions(+), 5 deletions(-) create mode 100644 src/design/plone/contenttypes/upgrades/to_730x.py diff --git a/CHANGES.rst b/CHANGES.rst index 54faef56..9910347b 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,7 +4,8 @@ Changelog 6.2.9 (unreleased) ------------------ -- Nothing changed yet. +- Aggiunto la cartella "Altri Documenti" sulla persona + [lucabel] 6.2.8 (2024-04-22) diff --git a/setup.py b/setup.py index 7a6a7378..ada821bd 100644 --- a/setup.py +++ b/setup.py @@ -64,6 +64,7 @@ "redturtle.volto>=5.0.0", "redturtle.bandi", "z3c.unconfigure", + "plone.restapi<9.6.1", "eea.api.taxonomy", "openpyxl", "collective.volto.enhancedlinks", diff --git a/src/design/plone/contenttypes/events/common.py b/src/design/plone/contenttypes/events/common.py index 9295226a..44475c88 100644 --- a/src/design/plone/contenttypes/events/common.py +++ b/src/design/plone/contenttypes/events/common.py @@ -120,6 +120,11 @@ }, {"id": "altre-cariche", "title": "Altre cariche", "allowed_types": ("File",)}, {"id": "incarichi", "title": "Incarichi", "allowed_types": ("Incarico",)}, + { + "id": "altri-documenti", + "title": "Altri documenti", + "allowed_types": ("File", "Image", "Link"), + }, ], "Pratica": [ { diff --git a/src/design/plone/contenttypes/profiles/default/metadata.xml b/src/design/plone/contenttypes/profiles/default/metadata.xml index 66b31642..6009331a 100644 --- a/src/design/plone/contenttypes/profiles/default/metadata.xml +++ b/src/design/plone/contenttypes/profiles/default/metadata.xml @@ -1,6 +1,6 @@ - 7300 + 7301 profile-redturtle.bandi:default profile-collective.venue:default diff --git a/src/design/plone/contenttypes/restapi/serializers/summary.py b/src/design/plone/contenttypes/restapi/serializers/summary.py index 5e5d98d0..ac587ef2 100644 --- a/src/design/plone/contenttypes/restapi/serializers/summary.py +++ b/src/design/plone/contenttypes/restapi/serializers/summary.py @@ -183,7 +183,6 @@ def __call__(self, force_all_metadata=False, force_images=False): if self.is_get_call(): res["has_children"] = self.has_children() - if force_images: # TODO: verificare se non c'è il campo o se il campo è null/vuoto ? if not res.get("image_scales") and not res.get("image_field"): @@ -198,7 +197,14 @@ def __call__(self, force_all_metadata=False, force_images=False): res["image_field"] = "preview_image" elif "image" in scales: res["image_field"] = "image" - + # plone.app.contentlisting 3.0.5 sembra fissare un accessor che ci + # fa arrivare uno scale senza image_field. + # avremmo questo problema una volta passati a plone 6.0.11 + elif res.get("image_scales") and not res.get("image_field"): + if "preview_image" in res["image_scales"]: + res["image_field"] = "preview_image" + elif "image" in res["image_scales"]: + res["image_field"] = "image" return res def has_children(self): diff --git a/src/design/plone/contenttypes/tests/test_substructure_creation.py b/src/design/plone/contenttypes/tests/test_substructure_creation.py index 991bc753..4147ac43 100644 --- a/src/design/plone/contenttypes/tests/test_substructure_creation.py +++ b/src/design/plone/contenttypes/tests/test_substructure_creation.py @@ -221,6 +221,7 @@ def test_persona_substructure_created(self): - spese-elettorali - variazione-situazione-patrimoniale" "altre-cariche - incarichi + - altri-documenti """ item = api.content.create( container=self.portal, @@ -239,6 +240,7 @@ def test_persona_substructure_created(self): "variazione-situazione-patrimoniale", "altre-cariche", "incarichi", + "altri-documenti", ], ) @@ -317,6 +319,14 @@ def test_persona_substructure_created(self): self.assertEqual(item["incarichi"].locally_allowed_types, ("Incarico",)) self.assertTrue(item["incarichi"].exclude_from_search) + self.assertEqual(item["altri-documenti"].portal_type, "Document") + self.assertEqual(api.content.get_state(item["altri-documenti"]), "private") + self.assertEqual(item["altri-documenti"].constrain_types_mode, 1) + self.assertIn("File", item["altri-documenti"].locally_allowed_types) + self.assertIn("Link", item["altri-documenti"].locally_allowed_types) + self.assertIn("Image", item["altri-documenti"].locally_allowed_types) + self.assertTrue(item["altri-documenti"].exclude_from_search) + def test_servizio_substructure_created(self): """ Should have: diff --git a/src/design/plone/contenttypes/tests/test_uo_summary_serializer.py b/src/design/plone/contenttypes/tests/test_uo_summary_serializer.py index c4108dd8..a57ed117 100644 --- a/src/design/plone/contenttypes/tests/test_uo_summary_serializer.py +++ b/src/design/plone/contenttypes/tests/test_uo_summary_serializer.py @@ -105,7 +105,11 @@ def test_image_in_uo_serializer(self): res = response.json() uo_children = res["uo_children"][0] self.assertEqual(uo_children["image_field"], None) - self.assertEqual(uo_children["image_scales"], None) + # Plone 6.0.10.1 due to a bug in plone.app.contentlisting (#64 + # from github issue) return None + # Plone 6.0.11 upgrades plone.app.contentlisting to a version + # fixing the problem and the changing the return value to {} + self.assertIn(uo_children["image_scales"], (None, {})) # now, add a preview image filename = os.path.join(os.path.dirname(__file__), "example.png") diff --git a/src/design/plone/contenttypes/upgrades/configure.zcml b/src/design/plone/contenttypes/upgrades/configure.zcml index c3b93f12..0d5f55af 100644 --- a/src/design/plone/contenttypes/upgrades/configure.zcml +++ b/src/design/plone/contenttypes/upgrades/configure.zcml @@ -856,5 +856,12 @@ destination="7300" handler=".to_7300.to_7300" /> + diff --git a/src/design/plone/contenttypes/upgrades/to_730x.py b/src/design/plone/contenttypes/upgrades/to_730x.py new file mode 100644 index 00000000..6f498d84 --- /dev/null +++ b/src/design/plone/contenttypes/upgrades/to_730x.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +from design.plone.contenttypes.utils import create_default_blocks +from plone import api +from Products.CMFPlone.interfaces import ISelectableConstrainTypes + +import logging + + +logger = logging.getLogger(__name__) + +DEFAULT_PROFILE = "profile-design.plone.contenttypes:default" + + +def to_7301(context): + brains = api.content.find(portal_type="Persona") + for brain in brains: + persona = brain.getObject() + FOLDER_ID = "altri-documenti" + if FOLDER_ID not in persona.keys(): + child = api.content.create( + container=persona, + type="Document", + title="Altri documenti", + id=FOLDER_ID, + ) + create_default_blocks(context=child) + else: + child = persona[FOLDER_ID] + + child.exclude_from_search = True + child.reindexObject(idxs=["exclude_from_search"]) + # select constraints + constraintsChild = ISelectableConstrainTypes(child) + constraintsChild.setConstrainTypesMode(1) + constraintsChild.setLocallyAllowedTypes( + ( + "File", + "Image", + "Link", + ) + ) + if api.content.get_state(persona) == "published": + if api.content.get_state(child) != "published": + with api.env.adopt_roles(["Reviewer"]): + api.content.transition(obj=child, transition="publish") diff --git a/test_plone60.cfg b/test_plone60.cfg index a0b9ce9d..59e99e0e 100644 --- a/test_plone60.cfg +++ b/test_plone60.cfg @@ -4,6 +4,7 @@ extends = https://raw.github.com/collective/buildout.plonetest/master/test-6.0.x.cfg https://raw.githubusercontent.com/collective/buildout.plonetest/master/qa.cfg https://raw.githubusercontent.com/RedTurtle/iocomune-backend/main/versions.cfg + https://dist.plone.org/release/6.0.10.1/versions.cfg base.cfg update-versions-file = test_plone60.cfg From 079462dcceff978600f68bcf98c092fe1699bfd9 Mon Sep 17 00:00:00 2001 From: Luca Date: Fri, 3 May 2024 15:18:20 +0200 Subject: [PATCH 464/487] Move to plone 6 0 11 (#260) ready to works with plone 6.0.11 and plone.restapi 9.6.1 --- CHANGES.rst | 6 ++- setup.py | 2 +- .../browser/utils/check_servizi.py | 27 +----------- .../contenttypes/indexers/pagina_argomento.py | 23 +++++++++- .../restapi/deserializers/documento.py | 27 +----------- .../restapi/deserializers/news.py | 27 +----------- .../restapi/deserializers/servizio.py | 27 +----------- .../deserializers/unitaorganizzativa.py | 28 +----------- .../restapi/deserializers/venue.py | 27 +----------- .../plone/contenttypes/upgrades/to_7300.py | 1 - src/design/plone/contenttypes/utils.py | 44 +++++++++++++++++++ test_plone60.cfg | 10 ++++- 12 files changed, 85 insertions(+), 164 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 9910347b..51056e6e 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,7 +4,11 @@ Changelog 6.2.9 (unreleased) ------------------ -- Aggiunto la cartella "Altri Documenti" sulla persona +- Add this folder "Altri Documenti" under "Persona pubblica" + [lucabel] +- Code porting to work with both plone 6.0.10.x and 6.0.11 + due to some core egg update + Code porting to work with the new plone.restapi 9.6.1 version [lucabel] diff --git a/setup.py b/setup.py index ada821bd..c41b390d 100644 --- a/setup.py +++ b/setup.py @@ -64,7 +64,7 @@ "redturtle.volto>=5.0.0", "redturtle.bandi", "z3c.unconfigure", - "plone.restapi<9.6.1", + "plone.restapi", "eea.api.taxonomy", "openpyxl", "collective.volto.enhancedlinks", diff --git a/src/design/plone/contenttypes/browser/utils/check_servizi.py b/src/design/plone/contenttypes/browser/utils/check_servizi.py index 34f9e390..fc74b52a 100644 --- a/src/design/plone/contenttypes/browser/utils/check_servizi.py +++ b/src/design/plone/contenttypes/browser/utils/check_servizi.py @@ -1,15 +1,13 @@ # -*- coding: utf-8 -*- from DateTime import DateTime +from design.plone.contenttypes.utils import text_in_block from openpyxl import Workbook from openpyxl.styles import Alignment from openpyxl.styles import Font from openpyxl.styles import PatternFill from openpyxl.utils import get_column_letter from plone import api -from plone.restapi.behaviors import IBlocks -from plone.restapi.indexers import SearchableText_blocks from Products.Five import BrowserView -from zope.interface import implementer import io @@ -17,29 +15,6 @@ FLAG = '' -def text_in_block(blocks): - @implementer(IBlocks) - class FakeObject(object): - """ - We use a fake object to use SearchableText Indexer - """ - - def Subject(self): - return "" - - def __init__(self, blocks, blocks_layout): - self.blocks = blocks - self.blocks_layout = blocks_layout - self.id = "" - self.title = "" - self.description = "" - - if not blocks: - return None - fakeObj = FakeObject(blocks.get("blocks", ""), blocks.get("blocks_layout", "")) - return SearchableText_blocks(fakeObj)() - - class CheckServizi(BrowserView): cds = None diff --git a/src/design/plone/contenttypes/indexers/pagina_argomento.py b/src/design/plone/contenttypes/indexers/pagina_argomento.py index 839ad4a1..c07e06de 100644 --- a/src/design/plone/contenttypes/indexers/pagina_argomento.py +++ b/src/design/plone/contenttypes/indexers/pagina_argomento.py @@ -1,11 +1,24 @@ # -*- coding: utf-8 -*- from design.plone.contenttypes.interfaces.pagina_argomento import IPaginaArgomento from plone.app.dexterity.textindexer.interfaces import IDynamicTextIndexExtender -from plone.restapi.indexers import SearchableText_blocks from zope.component import adapter from zope.interface import implementer +HAVE_REST_API_PRE_961 = False + +try: + # plone 6.0.11 with last plone.restapi>9.6.0 + from plone.app.contenttypes.indexers import SearchableText + from plone.restapi.indexers import get_blocks_text + from plone.restapi.indexers import text_strip + +except ImportError: + # plone 6.0.10.1 with plone.restapi<9.6.1 + HAVE_REST_API_PRE_961 = True + from plone.restapi.indexers import SearchableText_blocks + + @adapter(IPaginaArgomento) @implementer(IDynamicTextIndexExtender) class SearchableTextExtender(object): @@ -14,4 +27,10 @@ def __init__(self, context): def __call__(self): """Extend the searchable text with blocks""" - return SearchableText_blocks(self.context)() + if HAVE_REST_API_PRE_961: + return SearchableText_blocks(self.context)() + else: + blocks_text = get_blocks_text(self.context) + std_text = SearchableText(self.context) + blocks_text.append(std_text) + return text_strip(blocks_text) diff --git a/src/design/plone/contenttypes/restapi/deserializers/documento.py b/src/design/plone/contenttypes/restapi/deserializers/documento.py index 40a6afa6..1114bc52 100644 --- a/src/design/plone/contenttypes/restapi/deserializers/documento.py +++ b/src/design/plone/contenttypes/restapi/deserializers/documento.py @@ -1,9 +1,8 @@ # -*- coding: utf-8 -*- from design.plone.contenttypes.interfaces.documento import IDocumento -from plone.restapi.behaviors import IBlocks +from design.plone.contenttypes.utils import text_in_block from plone.restapi.deserializer import json_body from plone.restapi.deserializer.dxcontent import DeserializeFromJson -from plone.restapi.indexers import SearchableText_blocks from plone.restapi.interfaces import IDeserializeFromJson from zExceptions import BadRequest from zope.component import adapter @@ -24,30 +23,6 @@ def new_error(message): return {"error": "ValidationError", "message": message} -def text_in_block(blocks): - @implementer(IBlocks) - class FakeObject(object): - """ - We use a fake object to use SearchableText Indexer - """ - - def Subject(self): - return "" - - def __init__(self, blocks, blocks_layout): - self.blocks = blocks - self.blocks_layout = blocks_layout - self.id = "" - self.title = "" - self.description = "" - - if not blocks: - return None - - fakeObj = FakeObject(blocks.get("blocks", ""), blocks.get("blocks_layout", "")) - return SearchableText_blocks(fakeObj)() - - @implementer(IDeserializeFromJson) @adapter(IDocumento, Interface) class DeserializeDocumentoFromJson(DeserializeFromJson): diff --git a/src/design/plone/contenttypes/restapi/deserializers/news.py b/src/design/plone/contenttypes/restapi/deserializers/news.py index 7fa62c4d..d07425f1 100644 --- a/src/design/plone/contenttypes/restapi/deserializers/news.py +++ b/src/design/plone/contenttypes/restapi/deserializers/news.py @@ -1,9 +1,8 @@ # -*- coding: utf-8 -*- +from design.plone.contenttypes.utils import text_in_block from plone.app.contenttypes.interfaces import INewsItem -from plone.restapi.behaviors import IBlocks from plone.restapi.deserializer import json_body from plone.restapi.deserializer.dxcontent import DeserializeFromJson -from plone.restapi.indexers import SearchableText_blocks from plone.restapi.interfaces import IDeserializeFromJson from zExceptions import BadRequest from zope.component import adapter @@ -23,30 +22,6 @@ def new_error(message): return {"error": "ValidationError", "message": message} -def text_in_block(blocks): - @implementer(IBlocks) - class FakeObject(object): - """ - We use a fake object to use SearchableText Indexer - """ - - def Subject(self): - return "" - - def __init__(self, blocks, blocks_layout): - self.blocks = blocks - self.blocks_layout = blocks_layout - self.id = "" - self.title = "" - self.description = "" - - if not blocks: - return None - - fakeObj = FakeObject(blocks.get("blocks", ""), blocks.get("blocks_layout", "")) - return SearchableText_blocks(fakeObj)() - - @implementer(IDeserializeFromJson) @adapter(INewsItem, Interface) class DeserializeNewsFromJson(DeserializeFromJson): diff --git a/src/design/plone/contenttypes/restapi/deserializers/servizio.py b/src/design/plone/contenttypes/restapi/deserializers/servizio.py index 8e05c076..f51b5a5c 100644 --- a/src/design/plone/contenttypes/restapi/deserializers/servizio.py +++ b/src/design/plone/contenttypes/restapi/deserializers/servizio.py @@ -1,9 +1,8 @@ # -*- coding: utf-8 -*- from design.plone.contenttypes.interfaces.servizio import IServizio -from plone.restapi.behaviors import IBlocks +from design.plone.contenttypes.utils import text_in_block from plone.restapi.deserializer import json_body from plone.restapi.deserializer.dxcontent import DeserializeFromJson -from plone.restapi.indexers import SearchableText_blocks from plone.restapi.interfaces import IDeserializeFromJson from zExceptions import BadRequest from zope.component import adapter @@ -27,30 +26,6 @@ def new_error(message): return {"error": "ValidationError", "message": message} -def text_in_block(blocks): - @implementer(IBlocks) - class FakeObject(object): - """ - We use a fake object to use SearchableText Indexer - """ - - def Subject(self): - return "" - - def __init__(self, blocks, blocks_layout): - self.blocks = blocks - self.blocks_layout = blocks_layout - self.id = "" - self.title = "" - self.description = "" - - if not blocks: - return None - - fakeObj = FakeObject(blocks.get("blocks", ""), blocks.get("blocks_layout", "")) - return SearchableText_blocks(fakeObj)() - - @implementer(IDeserializeFromJson) @adapter(IServizio, Interface) class DeserializeServizioFromJson(DeserializeFromJson): diff --git a/src/design/plone/contenttypes/restapi/deserializers/unitaorganizzativa.py b/src/design/plone/contenttypes/restapi/deserializers/unitaorganizzativa.py index 2f041cbb..10c80d88 100644 --- a/src/design/plone/contenttypes/restapi/deserializers/unitaorganizzativa.py +++ b/src/design/plone/contenttypes/restapi/deserializers/unitaorganizzativa.py @@ -1,9 +1,8 @@ # -*- coding: utf-8 -*- from design.plone.contenttypes.interfaces.unita_organizzativa import IUnitaOrganizzativa -from plone.restapi.behaviors import IBlocks +from design.plone.contenttypes.utils import text_in_block from plone.restapi.deserializer import json_body from plone.restapi.deserializer.dxcontent import DeserializeFromJson -from plone.restapi.indexers import SearchableText_blocks from plone.restapi.interfaces import IDeserializeFromJson from zExceptions import BadRequest from zope.component import adapter @@ -21,30 +20,6 @@ def new_error(message): return {"error": "ValidationError", "message": message} -def text_in_block(blocks): - @implementer(IBlocks) - class FakeObject(object): - """ - We use a fake object to use SearchableText Indexer - """ - - def Subject(self): - return "" - - def __init__(self, blocks, blocks_layout): - self.blocks = blocks - self.blocks_layout = blocks_layout - self.id = "" - self.title = "" - self.description = "" - - if not blocks: - return None - - fakeObj = FakeObject(blocks.get("blocks", ""), blocks.get("blocks_layout", "")) - return SearchableText_blocks(fakeObj)() - - @implementer(IDeserializeFromJson) @adapter(IUnitaOrganizzativa, Interface) class DeserializeUnitaOrganizzativaFromJson(DeserializeFromJson): @@ -58,7 +33,6 @@ def __call__( is_post = method == "POST" is_patch = method == "PATCH" errors = [] - if list(data.keys()) != ["ordering"]: title = data.get("title") description = data.get("description") diff --git a/src/design/plone/contenttypes/restapi/deserializers/venue.py b/src/design/plone/contenttypes/restapi/deserializers/venue.py index 96eb9186..92395ef9 100644 --- a/src/design/plone/contenttypes/restapi/deserializers/venue.py +++ b/src/design/plone/contenttypes/restapi/deserializers/venue.py @@ -1,9 +1,8 @@ # -*- coding: utf-8 -*- from collective.venue.interfaces import IVenue -from plone.restapi.behaviors import IBlocks +from design.plone.contenttypes.utils import text_in_block from plone.restapi.deserializer import json_body from plone.restapi.deserializer.dxcontent import DeserializeFromJson -from plone.restapi.indexers import SearchableText_blocks from plone.restapi.interfaces import IDeserializeFromJson from zExceptions import BadRequest from zope.component import adapter @@ -21,30 +20,6 @@ def new_error(message): return {"error": "ValidationError", "message": message} -def text_in_block(blocks): - @implementer(IBlocks) - class FakeObject(object): - """ - We use a fake object to use SearchableText Indexer - """ - - def Subject(self): - return "" - - def __init__(self, blocks, blocks_layout): - self.blocks = blocks - self.blocks_layout = blocks_layout - self.id = "" - self.title = "" - self.description = "" - - if not blocks: - return None - - fakeObj = FakeObject(blocks.get("blocks", ""), blocks.get("blocks_layout", "")) - return SearchableText_blocks(fakeObj)() - - @implementer(IDeserializeFromJson) @adapter(IVenue, Interface) class DeserializeLuogoFromJson(DeserializeFromJson): diff --git a/src/design/plone/contenttypes/upgrades/to_7300.py b/src/design/plone/contenttypes/upgrades/to_7300.py index ba010d21..32b5573f 100644 --- a/src/design/plone/contenttypes/upgrades/to_7300.py +++ b/src/design/plone/contenttypes/upgrades/to_7300.py @@ -6,7 +6,6 @@ def to_7300(context): - mapping = { # portal_type "Documento Personale": { diff --git a/src/design/plone/contenttypes/utils.py b/src/design/plone/contenttypes/utils.py index 734e19b8..2cda35eb 100644 --- a/src/design/plone/contenttypes/utils.py +++ b/src/design/plone/contenttypes/utils.py @@ -1,13 +1,28 @@ # -*- coding: utf-8 -*- from design.plone.contenttypes.controlpanels.settings import IDesignPloneSettings from plone import api +from plone.restapi.behaviors import IBlocks from uuid import uuid4 +from zope.interface import implementer import json import logging import six +HAVE_REST_API_PRE_961 = False + +try: + # plone 6.0.11 with last plone.restapi>9.6.0 + from plone.restapi.indexers import get_blocks_text + from plone.restapi.indexers import text_strip + +except ImportError: + # plone 6.0.10.1 with plone.restapi<9.6.1 + HAVE_REST_API_PRE_961 = True + from plone.restapi.indexers import SearchableText_blocks + + logger = logging.getLogger(__name__) @@ -32,3 +47,32 @@ def create_default_blocks(context): title_uuid = str(uuid4()) context.blocks = {title_uuid: {"@type": "title"}} context.blocks_layout = {"items": [title_uuid]} + + +def text_in_block(blocks): + @implementer(IBlocks) + class FakeObject(object): + """ + We use a fake object to use SearchableText Indexer + """ + + def Subject(self): + return "" + + def __init__(self, blocks, blocks_layout): + self.blocks = blocks + self.blocks_layout = blocks_layout + self.id = "" + self.title = "" + self.description = "" + + if not blocks: + return None + + fakeObj = FakeObject(blocks.get("blocks", ""), blocks.get("blocks_layout", "")) + + if HAVE_REST_API_PRE_961: + return SearchableText_blocks(fakeObj)() + else: + blocks_text = get_blocks_text(fakeObj) + return text_strip(blocks_text) diff --git a/test_plone60.cfg b/test_plone60.cfg index 59e99e0e..60840265 100644 --- a/test_plone60.cfg +++ b/test_plone60.cfg @@ -4,7 +4,6 @@ extends = https://raw.github.com/collective/buildout.plonetest/master/test-6.0.x.cfg https://raw.githubusercontent.com/collective/buildout.plonetest/master/qa.cfg https://raw.githubusercontent.com/RedTurtle/iocomune-backend/main/versions.cfg - https://dist.plone.org/release/6.0.10.1/versions.cfg base.cfg update-versions-file = test_plone60.cfg @@ -68,4 +67,11 @@ webencodings = 0.5.1 # Plone==6.0.10 # collective.volto.blocksfield==2.0.0 # redturtle.bandi==1.4.3 -plone.restapi = 9.6.0 + +# Added by buildout at 2024-05-02 17:26:10.555785 + +# Required by: +# Plone==6.0.11 +# collective.volto.blocksfield==2.0.0 +# design.plone.contenttypes==6.2.9.dev0 +plone.restapi = 9.6.1 From b8420a8b14c0da5d537cdbde47044c2b7118171f Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Mon, 13 May 2024 12:01:25 +0200 Subject: [PATCH 465/487] ci chiedono di usare il CT documento dentro altri-documenti sotto la persona --- src/design/plone/contenttypes/upgrades/to_730x.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/design/plone/contenttypes/upgrades/to_730x.py b/src/design/plone/contenttypes/upgrades/to_730x.py index 6f498d84..d868361a 100644 --- a/src/design/plone/contenttypes/upgrades/to_730x.py +++ b/src/design/plone/contenttypes/upgrades/to_730x.py @@ -35,7 +35,7 @@ def to_7301(context): constraintsChild.setLocallyAllowedTypes( ( "File", - "Image", + "Documento", "Link", ) ) From 3c3ee04f2bd1682a60a68e6211a7f23a4ba8f5d8 Mon Sep 17 00:00:00 2001 From: Mauro Amico Date: Mon, 20 May 2024 22:56:49 +0200 Subject: [PATCH 466/487] fix upgrade step definition --- src/design/plone/contenttypes/upgrades/configure.zcml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/design/plone/contenttypes/upgrades/configure.zcml b/src/design/plone/contenttypes/upgrades/configure.zcml index 0d5f55af..c53c5ea3 100644 --- a/src/design/plone/contenttypes/upgrades/configure.zcml +++ b/src/design/plone/contenttypes/upgrades/configure.zcml @@ -584,7 +584,7 @@ Date: Tue, 21 May 2024 16:59:58 +0200 Subject: [PATCH 467/487] Preparing release 6.2.9 --- CHANGES.rst | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 51056e6e..79c2eee9 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,7 +1,7 @@ Changelog ========= -6.2.9 (unreleased) +6.2.9 (2024-05-21) ------------------ - Add this folder "Altri Documenti" under "Persona pubblica" diff --git a/setup.py b/setup.py index c41b390d..45944b32 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.2.9.dev0", + version="6.2.9", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From e59aa73ba2f4a440e9ae069aa87968c7f75ce10a Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Tue, 21 May 2024 17:00:34 +0200 Subject: [PATCH 468/487] Back to development: 6.2.10 --- CHANGES.rst | 6 ++++++ setup.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 79c2eee9..bd73ac06 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,6 +1,12 @@ Changelog ========= +6.2.10 (unreleased) +------------------- + +- Nothing changed yet. + + 6.2.9 (2024-05-21) ------------------ diff --git a/setup.py b/setup.py index 45944b32..8027c832 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.2.9", + version="6.2.10.dev0", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 9974f663d8b3d0435ecf085967983247554f8987 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Fri, 7 Jun 2024 14:30:18 +0200 Subject: [PATCH 469/487] Index rassegna (#263) * aggiunto reindex parent e aggiunto type al parent --------- Co-authored-by: Luca Bellenghi --- CHANGES.rst | 2 + .../plone/contenttypes/events/configure.zcml | 6 +++ .../plone/contenttypes/events/events.py | 8 ++++ .../plone/contenttypes/indexers/common.py | 1 + .../contenttypes/indexers/configure.zcml | 5 +++ .../plone/contenttypes/indexers/events.py | 7 +++ .../contenttypes/profiles/default/catalog.xml | 6 ++- .../profiles/default/metadata.xml | 2 +- .../profiles/default/registry/criteria.xml | 15 +++++++ .../restapi/serializers/dxcontent.py | 1 + .../contenttypes/upgrades/configure.zcml | 21 +++++++++ .../plone/contenttypes/upgrades/to_730x.py | 45 ++++++++++++++++++- 12 files changed, 116 insertions(+), 3 deletions(-) create mode 100644 src/design/plone/contenttypes/events/events.py diff --git a/CHANGES.rst b/CHANGES.rst index bd73ac06..ea555f80 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -16,6 +16,8 @@ Changelog due to some core egg update Code porting to work with the new plone.restapi 9.6.1 version [lucabel] +- Add rassegna index to events + [lucabel] 6.2.8 (2024-04-22) diff --git a/src/design/plone/contenttypes/events/configure.zcml b/src/design/plone/contenttypes/events/configure.zcml index 2752fbf2..8c796db8 100644 --- a/src/design/plone/contenttypes/events/configure.zcml +++ b/src/design/plone/contenttypes/events/configure.zcml @@ -31,4 +31,10 @@ zope.lifecycleevent.interfaces.IObjectAddedEvent" handler=".common.createSubfolders" /> + + diff --git a/src/design/plone/contenttypes/events/events.py b/src/design/plone/contenttypes/events/events.py new file mode 100644 index 00000000..1afaab7b --- /dev/null +++ b/src/design/plone/contenttypes/events/events.py @@ -0,0 +1,8 @@ +from Acquisition import aq_inner, aq_parent + + +def EventModified(dx_event, event): + parent = aq_parent(aq_inner(dx_event)) + if parent.portal_type == "Event": + parent.reindexObject(idxs=["rassegna"]) + return diff --git a/src/design/plone/contenttypes/indexers/common.py b/src/design/plone/contenttypes/indexers/common.py index 802c76d2..327f7a5d 100644 --- a/src/design/plone/contenttypes/indexers/common.py +++ b/src/design/plone/contenttypes/indexers/common.py @@ -34,6 +34,7 @@ def parent(context): "title": obj_parent.Title(), "UID": obj_parent.UID(), "@id": obj_parent.absolute_url(), + "@type": obj_parent.portal_type, } diff --git a/src/design/plone/contenttypes/indexers/configure.zcml b/src/design/plone/contenttypes/indexers/configure.zcml index 76f35000..74795f3d 100644 --- a/src/design/plone/contenttypes/indexers/configure.zcml +++ b/src/design/plone/contenttypes/indexers/configure.zcml @@ -77,6 +77,11 @@ factory=".common.exclude_from_search" name="exclude_from_search" /> + + diff --git a/src/design/plone/contenttypes/indexers/events.py b/src/design/plone/contenttypes/indexers/events.py index 1c8a8cd5..651f1f9f 100644 --- a/src/design/plone/contenttypes/indexers/events.py +++ b/src/design/plone/contenttypes/indexers/events.py @@ -10,3 +10,10 @@ def event_location(context, **kw): luoghi_correlati = filter(bool, luoghi_correlati) luoghi_correlati_title = [x.UID() for x in luoghi_correlati] return luoghi_correlati_title + + +@indexer(IEvent) +def rassegna(context, **kw): + """ """ + children = context.values() + return "Event" in [child.portal_type for child in children] diff --git a/src/design/plone/contenttypes/profiles/default/catalog.xml b/src/design/plone/contenttypes/profiles/default/catalog.xml index a37b9a79..4b22d503 100644 --- a/src/design/plone/contenttypes/profiles/default/catalog.xml +++ b/src/design/plone/contenttypes/profiles/default/catalog.xml @@ -57,7 +57,10 @@ - + + + + @@ -71,6 +74,7 @@ + - 7301 + 7304 profile-redturtle.bandi:default profile-collective.venue:default diff --git a/src/design/plone/contenttypes/profiles/default/registry/criteria.xml b/src/design/plone/contenttypes/profiles/default/registry/criteria.xml index 32972a24..730d900a 100644 --- a/src/design/plone/contenttypes/profiles/default/registry/criteria.xml +++ b/src/design/plone/contenttypes/profiles/default/registry/criteria.xml @@ -464,6 +464,21 @@ Metadata + + Evento Rassegna + Esclude le rassegne dai listing + True + False + + plone.app.querystring.operation.boolean.isTrue + plone.app.querystring.operation.boolean.isFalse + + Metadata + + + + + + diff --git a/src/design/plone/contenttypes/upgrades/to_730x.py b/src/design/plone/contenttypes/upgrades/to_730x.py index d868361a..a4f9a45c 100644 --- a/src/design/plone/contenttypes/upgrades/to_730x.py +++ b/src/design/plone/contenttypes/upgrades/to_730x.py @@ -2,7 +2,7 @@ from design.plone.contenttypes.utils import create_default_blocks from plone import api from Products.CMFPlone.interfaces import ISelectableConstrainTypes - +import transaction import logging @@ -11,6 +11,18 @@ DEFAULT_PROFILE = "profile-design.plone.contenttypes:default" +def update_profile(context, profile, run_dependencies=True): + context.runImportStepFromProfile(DEFAULT_PROFILE, profile, run_dependencies) + + +def update_catalog(context): + update_profile(context, "catalog") + + +def update_registry(context): + update_profile(context, "plone.app.registry", run_dependencies=False) + + def to_7301(context): brains = api.content.find(portal_type="Persona") for brain in brains: @@ -43,3 +55,34 @@ def to_7301(context): if api.content.get_state(child) != "published": with api.env.adopt_roles(["Reviewer"]): api.content.transition(obj=child, transition="publish") + + +def to_7302(context): + update_catalog(context) + brains = api.content.find(portal_type="Event") + tot = len(brains) + i = 0 + for brain in brains: + i += 1 + if i % 100 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + event = brain.getObject() + event.reindexObject(idxs=["rassegna"]) + + +def to_7303(context): + update_registry(context) + logger.info("Update registry") + + +def to_7304(context): + brains = context.portal_catalog() + tot = len(brains) + i = 0 + for brain in brains: + i += 1 + if i % 100 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + transaction.commit() + doc = brain.getObject() + doc.reindexObject(idxs=["parent"]) From 153cee81c48a174184c137dfbdb0a278744d5479 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Mon, 10 Jun 2024 11:52:54 +0200 Subject: [PATCH 470/487] Add importi_viaggi_servizio as block field in Incarico response (#262) * Add importi_viaggi_servizio as block field in Incarico response * black --- .pre-commit-config.yaml | 8 ++++---- CHANGES.rst | 3 ++- .../plone/contenttypes/restapi/serializers/summary.py | 7 +++++++ 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b4ab1c2e..b10f5fc8 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -8,13 +8,13 @@ default_stages: [commit, push] repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.4.0 + rev: v4.6.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer - id: check-yaml - repo: https://github.com/psf/black - rev: 23.7.0 + rev: 24.4.2 hooks: - id: black # args: ["--line-length=88", "--check", "--diff", "--force-exclude=migrations", "src/"] @@ -22,7 +22,7 @@ repos: types: [python] entry: black - repo: https://github.com/PyCQA/flake8.git - rev: "6.1.0" + rev: "7.0.0" hooks: - id: flake8 name: flake8 @@ -31,7 +31,7 @@ repos: types: [python] args: ["--max-complexity=30", "--max-line-length=88", "--ignore=DJ01,DJ08,W503,ANN101", "--exclude=docs/*", "src/", "setup.py"] - repo: https://github.com/pycqa/isort - rev: 5.12.0 + rev: 5.13.2 hooks: - id: isort name: isort (python) diff --git a/CHANGES.rst b/CHANGES.rst index ea555f80..3de8e52a 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,7 +4,8 @@ Changelog 6.2.10 (unreleased) ------------------- -- Nothing changed yet. +- Add importi_viaggio_servizio field as block field in Incarico response + [eikichi18] 6.2.9 (2024-05-21) diff --git a/src/design/plone/contenttypes/restapi/serializers/summary.py b/src/design/plone/contenttypes/restapi/serializers/summary.py index ac587ef2..19bba858 100644 --- a/src/design/plone/contenttypes/restapi/serializers/summary.py +++ b/src/design/plone/contenttypes/restapi/serializers/summary.py @@ -325,6 +325,13 @@ def __call__(self, **kwargs): else: res["compensi"] = json_compatible([]) + if "importi_viaggio_servizio" not in res: + res["importi_viaggio_servizio"] = json_compatible( + self.context.importi_viaggio_servizio + ) + else: + res["importi_viaggio_servizio"] = json_compatible([]) + if safe_hasattr(self.context, "compensi-file"): compensi_folder = getattr(self.context, "compensi-file") res["compensi_file"] = [] From 4a8077caf06b7194107bd3dadc45544e642709e9 Mon Sep 17 00:00:00 2001 From: Luca Date: Tue, 11 Jun 2024 16:38:10 +0200 Subject: [PATCH 471/487] remove file from addable types in servizio/modulistica folder (#264) * remove file from addable types in servizio/modulistica folder * fix typo --- CHANGES.rst | 10 +++++---- .../plone/contenttypes/events/common.py | 2 +- .../profiles/default/metadata.xml | 2 +- .../tests/test_substructure_creation.py | 2 +- .../contenttypes/upgrades/configure.zcml | 7 ++++++ .../plone/contenttypes/upgrades/to_730x.py | 22 +++++++++++++++++++ 6 files changed, 38 insertions(+), 7 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 3de8e52a..96f54fc0 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -6,7 +6,12 @@ Changelog - Add importi_viaggio_servizio field as block field in Incarico response [eikichi18] - +- Add rassegna index to events + [lucabel] +- Remove File from addable type in Servizio / modulistica folder. As stated + by AGID team we can't add File in this folder but link to modules in + "Documenti e Dati" section + [lucabel] 6.2.9 (2024-05-21) ------------------ @@ -17,9 +22,6 @@ Changelog due to some core egg update Code porting to work with the new plone.restapi 9.6.1 version [lucabel] -- Add rassegna index to events - [lucabel] - 6.2.8 (2024-04-22) ------------------ diff --git a/src/design/plone/contenttypes/events/common.py b/src/design/plone/contenttypes/events/common.py index 44475c88..2f4a1a06 100644 --- a/src/design/plone/contenttypes/events/common.py +++ b/src/design/plone/contenttypes/events/common.py @@ -138,7 +138,7 @@ { "id": "modulistica", "title": "Modulistica", - "allowed_types": ("File", "Link"), + "allowed_types": ("Link",), }, {"id": "allegati", "title": "Allegati", "allowed_types": ("File", "Link")}, ], diff --git a/src/design/plone/contenttypes/profiles/default/metadata.xml b/src/design/plone/contenttypes/profiles/default/metadata.xml index c63caa09..1492c7cf 100644 --- a/src/design/plone/contenttypes/profiles/default/metadata.xml +++ b/src/design/plone/contenttypes/profiles/default/metadata.xml @@ -1,6 +1,6 @@ - 7304 + 7305 profile-redturtle.bandi:default profile-collective.venue:default diff --git a/src/design/plone/contenttypes/tests/test_substructure_creation.py b/src/design/plone/contenttypes/tests/test_substructure_creation.py index 4147ac43..1991a0dc 100644 --- a/src/design/plone/contenttypes/tests/test_substructure_creation.py +++ b/src/design/plone/contenttypes/tests/test_substructure_creation.py @@ -347,7 +347,7 @@ def test_servizio_substructure_created(self): self.assertEqual(item["modulistica"].portal_type, "Document") self.assertEqual(api.content.get_state(item["modulistica"]), "private") self.assertEqual(item["modulistica"].constrain_types_mode, 1) - self.assertEqual(item["modulistica"].locally_allowed_types, ("File", "Link")) + self.assertEqual(item["modulistica"].locally_allowed_types, ("Link",)) self.assertTrue(item["modulistica"].exclude_from_search) self.assertEqual(item["allegati"].portal_type, "Document") diff --git a/src/design/plone/contenttypes/upgrades/configure.zcml b/src/design/plone/contenttypes/upgrades/configure.zcml index 9562d151..ed3c6708 100644 --- a/src/design/plone/contenttypes/upgrades/configure.zcml +++ b/src/design/plone/contenttypes/upgrades/configure.zcml @@ -884,5 +884,12 @@ destination="7304" handler=".to_730x.to_7304" /> + diff --git a/src/design/plone/contenttypes/upgrades/to_730x.py b/src/design/plone/contenttypes/upgrades/to_730x.py index a4f9a45c..e51f2547 100644 --- a/src/design/plone/contenttypes/upgrades/to_730x.py +++ b/src/design/plone/contenttypes/upgrades/to_730x.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- from design.plone.contenttypes.utils import create_default_blocks +from design.plone.contenttypes.events.common import SUBFOLDERS_MAPPING from plone import api from Products.CMFPlone.interfaces import ISelectableConstrainTypes import transaction @@ -86,3 +87,24 @@ def to_7304(context): transaction.commit() doc = brain.getObject() doc.reindexObject(idxs=["parent"]) + + +def to_7305(context): + mapping = SUBFOLDERS_MAPPING["Servizio"] + mapping = [folder for folder in mapping if folder["id"] == "modulistica"][0] + brains = api.content.find(portal_type="Servizio") + tot = len(brains) + i = 0 + for brain in brains: + i += 1 + if i % 100 == 0: + logger.info("Progress: {}/{}".format(i, tot)) + transaction.commit() + servizio = brain.getObject() + FOLDER_ID = "modulistica" + if FOLDER_ID not in servizio.keys(): + continue + child = servizio[FOLDER_ID] + constraintsChild = ISelectableConstrainTypes(child) + constraintsChild.setConstrainTypesMode(1) + constraintsChild.setLocallyAllowedTypes(mapping["allowed_types"]) From 3c188e33187db17ddd59cef641f9b83f51495a1d Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Tue, 11 Jun 2024 16:44:17 +0200 Subject: [PATCH 472/487] Preparing release 6.2.10 --- CHANGES.rst | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 96f54fc0..eac455b8 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,7 +1,7 @@ Changelog ========= -6.2.10 (unreleased) +6.2.10 (2024-06-11) ------------------- - Add importi_viaggio_servizio field as block field in Incarico response diff --git a/setup.py b/setup.py index 8027c832..15b146cc 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.2.10.dev0", + version="6.2.10", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 0290e6c122d97fa0e95aa3d5c84874906359fcb1 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Tue, 11 Jun 2024 16:44:52 +0200 Subject: [PATCH 473/487] Back to development: 6.2.11 --- CHANGES.rst | 6 ++++++ setup.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index eac455b8..fb3d6be5 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,6 +1,12 @@ Changelog ========= +6.2.11 (unreleased) +------------------- + +- Nothing changed yet. + + 6.2.10 (2024-06-11) ------------------- diff --git a/setup.py b/setup.py index 15b146cc..010251c4 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.2.10", + version="6.2.11.dev0", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From b91b8f4cf7d7e868e9decac5e2e94225810233c3 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Mon, 17 Jun 2024 14:30:08 +0200 Subject: [PATCH 474/487] fix: fixed limit in query for ScadenziarioDayPost service (#265) --- CHANGES.rst | 3 ++- .../contenttypes/restapi/services/scadenziario/post.py | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index fb3d6be5..f86ec8de 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,7 +4,8 @@ Changelog 6.2.11 (unreleased) ------------------- -- Nothing changed yet. +- Fix limit in query for service in ScadenziarioDayPost service + [eikichi18] 6.2.10 (2024-06-11) diff --git a/src/design/plone/contenttypes/restapi/services/scadenziario/post.py b/src/design/plone/contenttypes/restapi/services/scadenziario/post.py index e19720c1..1f8072aa 100644 --- a/src/design/plone/contenttypes/restapi/services/scadenziario/post.py +++ b/src/design/plone/contenttypes/restapi/services/scadenziario/post.py @@ -218,12 +218,12 @@ def reply(self): end = None # qui ce l'abbiamo per forza start if "start" in query_for_catalog: - start = query_for_catalog["start"]["query"] + start = query_for_catalog["start"]["query"][0] if "end" in query_for_catalog: - end = query_for_catalog["end"]["query"] + end = query_for_catalog["start"]["query"][1] expanded_events = self.expand_events(events, 3, start, end) - start_date = start[0].strftime("%Y/%m/%d") + start_date = start.strftime("%Y/%m/%d") correct_events = [] for x in expanded_events: if start_date == x.start.strftime("%Y/%m/%d"): From 571d142c3eb2585d211d357e9d2e9768cbf2f128 Mon Sep 17 00:00:00 2001 From: Filippo Campi Date: Mon, 17 Jun 2024 15:57:16 +0200 Subject: [PATCH 475/487] chore: disallow other objs creation inside Persona and Incarico ct (#266) * chore: disallower other objs creation inside Persona and Incarico ct * add upgrade step + flake * fix: tests * removed useless notation __all__ --- CHANGES.rst | 1 + .../plone/contenttypes/events/common.py | 322 ++++++++++-------- .../profiles/default/metadata.xml | 2 +- .../profiles/default/types/Incarico.xml | 6 +- .../profiles/default/types/Persona.xml | 6 +- .../contenttypes/tests/test_ct_persona.py | 3 +- .../contenttypes/upgrades/configure.zcml | 7 + .../plone/contenttypes/upgrades/to_730x.py | 14 +- 8 files changed, 206 insertions(+), 155 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index f86ec8de..392c6fdd 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,6 +4,7 @@ Changelog 6.2.11 (unreleased) ------------------- +- Disallower other objs creation in Persona and Incarico ct. - Fix limit in query for service in ScadenziarioDayPost service [eikichi18] diff --git a/src/design/plone/contenttypes/events/common.py b/src/design/plone/contenttypes/events/common.py index 2f4a1a06..70d69fbc 100644 --- a/src/design/plone/contenttypes/events/common.py +++ b/src/design/plone/contenttypes/events/common.py @@ -6,145 +6,171 @@ SUBFOLDERS_MAPPING = { - "Bando": [ - {"id": "documenti", "title": "Documenti", "type": "Bando Folder Deepening"}, - { - "id": "comunicazioni", - "title": "Comunicazioni", - "type": "Bando Folder Deepening", - }, - {"id": "esiti", "title": "Esiti", "type": "Bando Folder Deepening"}, - ], - "Documento": [ - { - "id": "multimedia", - "title": "Multimedia", - "type": "Document", - "allowed_types": ("Image",), - }, - ], - "Event": [ - { - "id": "immagini", - "title": "Immagini", - "allowed_types": ("Image", "Link"), - "publish": True, - }, - { - "id": "video", - "title": "Video", - "allowed_types": ("Link",), - "publish": True, - }, - { - "id": "sponsor_evento", - "title": "Sponsor Evento", - "allowed_types": ("Link",), - "publish": True, - }, - { - "id": "documenti", - "title": "Allegati", - "allowed_types": ("File",), - "publish": True, - }, - ], - "Incarico": [ - {"id": "compensi-file", "title": "Compensi", "allowed": ("File",)}, - { - "id": "importi-di-viaggio-e-o-servizi", - "title": "Importi di viaggio e/o servizi", - "allowed_types": ("File",), - }, - ], - "Venue": [ - { - "id": "multimedia", - "title": "Multimedia", - "type": "Folder", - "allowed_types": ( - "Image", - "Link", - ), - "publish": True, - } - ], - "News Item": [ - { - "id": "multimedia", - "title": "Multimedia", - "allowed_types": ( - "Image", - "Link", - ), - }, - { - "id": "documenti-allegati", - "title": "Documenti allegati", - "allowed_types": ( - "File", - "Image", - ), - }, - ], - "Persona": [ - { - "id": "foto-e-attivita-politica", - "title": "Foto e attività politica", - "allowed_types": ("Image",), - }, - { - "id": "curriculum-vitae", - "title": "Curriculum vitae", - "allowed_types": ("File",), - }, - { - "id": "situazione-patrimoniale", - "title": "Situazione patrimoniale", - "allowed_types": ("File",), - }, - { - "id": "dichiarazione-dei-redditi", - "title": "Dichiarazione dei redditi", - "allowed_types": ("File",), - }, - { - "id": "spese-elettorali", - "title": "Spese elettorali", - "allowed_types": ("File",), - }, - { - "id": "variazione-situazione-patrimoniale", - "title": "Variazione situazione patrimoniale", - "allowed_types": ("File",), - }, - {"id": "altre-cariche", "title": "Altre cariche", "allowed_types": ("File",)}, - {"id": "incarichi", "title": "Incarichi", "allowed_types": ("Incarico",)}, - { - "id": "altri-documenti", - "title": "Altri documenti", - "allowed_types": ("File", "Image", "Link"), - }, - ], - "Pratica": [ - { - "id": "allegati", - "title": "Allegati", - "type": "Folder", - "allowed_types": ("File",), - } - ], - "Servizio": [ - { - "id": "modulistica", - "title": "Modulistica", - "allowed_types": ("Link",), - }, - {"id": "allegati", "title": "Allegati", "allowed_types": ("File", "Link")}, - ], - "UnitaOrganizzativa": [ - {"id": "allegati", "title": "Allegati", "allowed_types": ("File",)}, - ], + "Bando": { + "content": [ + {"id": "documenti", "title": "Documenti", "type": "Bando Folder Deepening"}, + { + "id": "comunicazioni", + "title": "Comunicazioni", + "type": "Bando Folder Deepening", + }, + {"id": "esiti", "title": "Esiti", "type": "Bando Folder Deepening"}, + ], + }, + "Documento": { + "content": [ + { + "id": "multimedia", + "title": "Multimedia", + "type": "Document", + "allowed_types": ("Image",), + }, + ], + }, + "Event": { + "content": [ + { + "id": "immagini", + "title": "Immagini", + "allowed_types": ("Image", "Link"), + "publish": True, + }, + { + "id": "video", + "title": "Video", + "allowed_types": ("Link",), + "publish": True, + }, + { + "id": "sponsor_evento", + "title": "Sponsor Evento", + "allowed_types": ("Link",), + "publish": True, + }, + { + "id": "documenti", + "title": "Allegati", + "allowed_types": ("File",), + "publish": True, + }, + ], + }, + "Incarico": { + "content": [ + {"id": "compensi-file", "title": "Compensi", "allowed": ("File",)}, + { + "id": "importi-di-viaggio-e-o-servizi", + "title": "Importi di viaggio e/o servizi", + "allowed_types": ("File",), + }, + ], + "allowed_types": [], + }, + "Venue": { + "content": [ + { + "id": "multimedia", + "title": "Multimedia", + "type": "Folder", + "allowed_types": ( + "Image", + "Link", + ), + "publish": True, + } + ], + }, + "News Item": { + "content": [ + { + "id": "multimedia", + "title": "Multimedia", + "allowed_types": ( + "Image", + "Link", + ), + }, + { + "id": "documenti-allegati", + "title": "Documenti allegati", + "allowed_types": ( + "File", + "Image", + ), + }, + ], + }, + "Persona": { + "content": [ + { + "id": "foto-e-attivita-politica", + "title": "Foto e attività politica", + "allowed_types": ("Image",), + }, + { + "id": "curriculum-vitae", + "title": "Curriculum vitae", + "allowed_types": ("File",), + }, + { + "id": "situazione-patrimoniale", + "title": "Situazione patrimoniale", + "allowed_types": ("File",), + }, + { + "id": "dichiarazione-dei-redditi", + "title": "Dichiarazione dei redditi", + "allowed_types": ("File",), + }, + { + "id": "spese-elettorali", + "title": "Spese elettorali", + "allowed_types": ("File",), + }, + { + "id": "variazione-situazione-patrimoniale", + "title": "Variazione situazione patrimoniale", + "allowed_types": ("File",), + }, + { + "id": "altre-cariche", + "title": "Altre cariche", + "allowed_types": ("File",), + }, + {"id": "incarichi", "title": "Incarichi", "allowed_types": ("Incarico",)}, + { + "id": "altri-documenti", + "title": "Altri documenti", + "allowed_types": ("File", "Image", "Link"), + }, + ], + "allowed_types": [], + }, + "Pratica": { + "content": [ + { + "id": "allegati", + "title": "Allegati", + "type": "Folder", + "allowed_types": ("File",), + } + ], + }, + "Servizio": { + "content": [ + { + "id": "modulistica", + "title": "Modulistica", + "allowed_types": ("Link",), + }, + {"id": "allegati", "title": "Allegati", "allowed_types": ("File", "Link")}, + ], + }, + "UnitaOrganizzativa": { + "content": [ + {"id": "allegati", "title": "Allegati", "allowed_types": ("File",)}, + ], + }, } @@ -167,7 +193,8 @@ def createSubfolders(context, event): subfolders_mapping = SUBFOLDERS_MAPPING.get(context.portal_type, []) if not subfolders_mapping: return - for mapping in subfolders_mapping: + + for mapping in subfolders_mapping.get("content", {}): if mapping["id"] not in context.keys(): portal_type = mapping.get("type", "Document") child = api.content.create( @@ -184,10 +211,19 @@ def createSubfolders(context, event): child.reindexObject(idxs=["exclude_from_search"]) # select constraints if mapping.get("allowed_types", ()): - constraintsChild = ISelectableConstrainTypes(child) - constraintsChild.setConstrainTypesMode(1) - constraintsChild.setLocallyAllowedTypes(mapping["allowed_types"]) + constraints_child = ISelectableConstrainTypes(child) + constraints_child.setConstrainTypesMode(1) + constraints_child.setLocallyAllowedTypes(mapping["allowed_types"]) if mapping.get("publish", False): with api.env.adopt_roles(["Reviewer"]): api.content.transition(obj=child, transition="publish") + + allowed_types = subfolders_mapping.get("allowed_types", None) + if allowed_types is not None and not isinstance(allowed_types, list): + raise ValueError("Subfolder map is not well formed") + + if isinstance(allowed_types, list): + constraints_context = ISelectableConstrainTypes(context) + constraints_context.setConstrainTypesMode(1) + constraints_context.setLocallyAllowedTypes(allowed_types) diff --git a/src/design/plone/contenttypes/profiles/default/metadata.xml b/src/design/plone/contenttypes/profiles/default/metadata.xml index 1492c7cf..e6d1c9bc 100644 --- a/src/design/plone/contenttypes/profiles/default/metadata.xml +++ b/src/design/plone/contenttypes/profiles/default/metadata.xml @@ -1,6 +1,6 @@ - 7305 + 7306 profile-redturtle.bandi:default profile-collective.venue:default diff --git a/src/design/plone/contenttypes/profiles/default/types/Incarico.xml b/src/design/plone/contenttypes/profiles/default/types/Incarico.xml index d5c91cf8..e9d2de49 100644 --- a/src/design/plone/contenttypes/profiles/default/types/Incarico.xml +++ b/src/design/plone/contenttypes/profiles/default/types/Incarico.xml @@ -20,12 +20,9 @@ True - False + True - design.plone.contenttypes.AddIncarico @@ -56,6 +53,7 @@ + diff --git a/src/design/plone/contenttypes/profiles/default/types/Persona.xml b/src/design/plone/contenttypes/profiles/default/types/Persona.xml index 8e4ef5cf..9297bd92 100644 --- a/src/design/plone/contenttypes/profiles/default/types/Persona.xml +++ b/src/design/plone/contenttypes/profiles/default/types/Persona.xml @@ -20,12 +20,9 @@ True - False + True - design.plone.contenttypes.AddPersona @@ -57,6 +54,7 @@ + diff --git a/src/design/plone/contenttypes/tests/test_ct_persona.py b/src/design/plone/contenttypes/tests/test_ct_persona.py index fdaea25f..5db886c2 100644 --- a/src/design/plone/contenttypes/tests/test_ct_persona.py +++ b/src/design/plone/contenttypes/tests/test_ct_persona.py @@ -65,6 +65,7 @@ def test_behaviors_enabled_for_persona(self): "plone.translatable", "kitconcept.seo", "plone.versioning", + "plone.constraintypes", ), ) @@ -216,7 +217,7 @@ def test_atto_di_nomina_incarico(self): ) commit() atto_nomina = api.content.create( - container=incarico, type="Documento", title="Atto di nomina" + container=self.portal, type="Documento", title="Atto di nomina" ) commit() intids = getUtility(IIntIds) diff --git a/src/design/plone/contenttypes/upgrades/configure.zcml b/src/design/plone/contenttypes/upgrades/configure.zcml index ed3c6708..d766a20d 100644 --- a/src/design/plone/contenttypes/upgrades/configure.zcml +++ b/src/design/plone/contenttypes/upgrades/configure.zcml @@ -891,5 +891,12 @@ destination="7305" handler=".to_730x.to_7305" /> + diff --git a/src/design/plone/contenttypes/upgrades/to_730x.py b/src/design/plone/contenttypes/upgrades/to_730x.py index e51f2547..85a4ad49 100644 --- a/src/design/plone/contenttypes/upgrades/to_730x.py +++ b/src/design/plone/contenttypes/upgrades/to_730x.py @@ -1,10 +1,11 @@ # -*- coding: utf-8 -*- -from design.plone.contenttypes.utils import create_default_blocks from design.plone.contenttypes.events.common import SUBFOLDERS_MAPPING +from design.plone.contenttypes.utils import create_default_blocks from plone import api from Products.CMFPlone.interfaces import ISelectableConstrainTypes -import transaction + import logging +import transaction logger = logging.getLogger(__name__) @@ -24,6 +25,10 @@ def update_registry(context): update_profile(context, "plone.app.registry", run_dependencies=False) +def update_types(context): + update_profile(context, "typeinfo") + + def to_7301(context): brains = api.content.find(portal_type="Persona") for brain in brains: @@ -108,3 +113,8 @@ def to_7305(context): constraintsChild = ISelectableConstrainTypes(child) constraintsChild.setConstrainTypesMode(1) constraintsChild.setLocallyAllowedTypes(mapping["allowed_types"]) + + +def to_7306(context): + logger.info("Disallow add other objs in Persona and Incarico ct") + update_types(context) From 87205c03b8aaa8e2ff1fc789fd868cbc885d3d1d Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Mon, 24 Jun 2024 10:29:00 +0200 Subject: [PATCH 476/487] Preparing release 6.2.11 --- CHANGES.rst | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 392c6fdd..f7c9354f 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,7 +1,7 @@ Changelog ========= -6.2.11 (unreleased) +6.2.11 (2024-06-24) ------------------- - Disallower other objs creation in Persona and Incarico ct. diff --git a/setup.py b/setup.py index 010251c4..1ecd1af0 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.2.11.dev0", + version="6.2.11", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 3fa6a12488ab42597353276b3178c4f03805fe16 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Mon, 24 Jun 2024 10:29:24 +0200 Subject: [PATCH 477/487] Back to development: 6.2.12 --- CHANGES.rst | 6 ++++++ setup.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index f7c9354f..8253f401 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,6 +1,12 @@ Changelog ========= +6.2.12 (unreleased) +------------------- + +- Nothing changed yet. + + 6.2.11 (2024-06-24) ------------------- diff --git a/setup.py b/setup.py index 1ecd1af0..dc8f2efa 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.2.11", + version="6.2.12.dev0", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 18b3dc72bd7111833e07a824065d9d24c9ba264d Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Mon, 24 Jun 2024 14:03:01 +0200 Subject: [PATCH 478/487] fix upgrade step --- CHANGES.rst | 3 ++- src/design/plone/contenttypes/upgrades/to_730x.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 8253f401..052fdec1 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,7 +4,8 @@ Changelog 6.2.12 (unreleased) ------------------- -- Nothing changed yet. +- Fix problem with upgrade step to 7305 + [lucabel] 6.2.11 (2024-06-24) diff --git a/src/design/plone/contenttypes/upgrades/to_730x.py b/src/design/plone/contenttypes/upgrades/to_730x.py index 85a4ad49..5ec2ca47 100644 --- a/src/design/plone/contenttypes/upgrades/to_730x.py +++ b/src/design/plone/contenttypes/upgrades/to_730x.py @@ -96,7 +96,7 @@ def to_7304(context): def to_7305(context): mapping = SUBFOLDERS_MAPPING["Servizio"] - mapping = [folder for folder in mapping if folder["id"] == "modulistica"][0] + mapping = [folder for folder in mapping.get('content') if folder["id"] == "modulistica"][0] # noqa brains = api.content.find(portal_type="Servizio") tot = len(brains) i = 0 From 1652bcd060e697811cd3b5682d8c322b52c75256 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Mon, 24 Jun 2024 14:03:39 +0200 Subject: [PATCH 479/487] Preparing release 6.2.12 --- CHANGES.rst | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 052fdec1..61d1dc54 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,7 +1,7 @@ Changelog ========= -6.2.12 (unreleased) +6.2.12 (2024-06-24) ------------------- - Fix problem with upgrade step to 7305 diff --git a/setup.py b/setup.py index dc8f2efa..9ab48611 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.2.12.dev0", + version="6.2.12", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 4b4fc91a3c91273e39d94edf0dbbe366d51e25eb Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Mon, 24 Jun 2024 14:04:10 +0200 Subject: [PATCH 480/487] Back to development: 6.2.13 --- CHANGES.rst | 6 ++++++ setup.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 61d1dc54..bc91a3a5 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,6 +1,12 @@ Changelog ========= +6.2.13 (unreleased) +------------------- + +- Nothing changed yet. + + 6.2.12 (2024-06-24) ------------------- diff --git a/setup.py b/setup.py index 9ab48611..617b9dea 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.2.12", + version="6.2.13.dev0", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From 9cc2b87099528de6d4f1a7d7603ccf046e4fbd71 Mon Sep 17 00:00:00 2001 From: Andrea Cecchi Date: Thu, 27 Jun 2024 17:14:12 +0200 Subject: [PATCH 481/487] =?UTF-8?q?Set=20=20field=20as=20primary,=20so=20w?= =?UTF-8?q?e=20call=20@@download=20on=20the=20content,=20that=20fil?= =?UTF-8?q?=E2=80=A6=20(#268)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGES.rst | 3 ++- src/design/plone/contenttypes/behaviors/multi_file.py | 2 ++ .../plone/contenttypes/restapi/serializers/dxcontent.py | 1 - src/design/plone/contenttypes/upgrades/to_730x.py | 6 +++++- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index bc91a3a5..e422efc6 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,7 +4,8 @@ Changelog 6.2.13 (unreleased) ------------------- -- Nothing changed yet. +- Set `file_principale` field as primary, so we call @@download on the content, that file will be downloaded automatically. + [cekk] 6.2.12 (2024-06-24) diff --git a/src/design/plone/contenttypes/behaviors/multi_file.py b/src/design/plone/contenttypes/behaviors/multi_file.py index 11e306b4..90dbc1fa 100644 --- a/src/design/plone/contenttypes/behaviors/multi_file.py +++ b/src/design/plone/contenttypes/behaviors/multi_file.py @@ -41,6 +41,8 @@ class IMultiFileSchema(model.Schema): required=False, ) + model.primary("file_principale") + @provider(IFormFieldProvider) class IMultiFile(IMultiFileSchema): diff --git a/src/design/plone/contenttypes/restapi/serializers/dxcontent.py b/src/design/plone/contenttypes/restapi/serializers/dxcontent.py index a87880c6..568cc3a3 100644 --- a/src/design/plone/contenttypes/restapi/serializers/dxcontent.py +++ b/src/design/plone/contenttypes/restapi/serializers/dxcontent.py @@ -51,7 +51,6 @@ def __call__(self, version=None, include_items=True): @adapter(IDexterityContainer, IDesignPloneContenttypesLayer) class SerializeFolderToJson(BaseFolderSerializer, MetaTypeSerializer): def __call__(self, version=None, include_items=True): - result = super(SerializeFolderToJson, self).__call__( version=version, include_items=include_items ) diff --git a/src/design/plone/contenttypes/upgrades/to_730x.py b/src/design/plone/contenttypes/upgrades/to_730x.py index 5ec2ca47..5d5dcf3a 100644 --- a/src/design/plone/contenttypes/upgrades/to_730x.py +++ b/src/design/plone/contenttypes/upgrades/to_730x.py @@ -96,7 +96,11 @@ def to_7304(context): def to_7305(context): mapping = SUBFOLDERS_MAPPING["Servizio"] - mapping = [folder for folder in mapping.get('content') if folder["id"] == "modulistica"][0] # noqa + mapping = [ + folder for folder in mapping.get("content") if folder["id"] == "modulistica" + ][ + 0 + ] # noqa brains = api.content.find(portal_type="Servizio") tot = len(brains) i = 0 From 9b9a6f2ae9313b2e7ccfba9e18bf644089204f14 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Mon, 8 Jul 2024 15:18:09 +0200 Subject: [PATCH 482/487] override plone.app.contenttypes listing.pt template due to error rendering events --- CHANGES.rst | 2 + ....contenttypes.browser.templates.listing.pt | 194 ++++++++++++++++++ 2 files changed, 196 insertions(+) create mode 100644 src/design/plone/contenttypes/browser/overrides/plone.app.contenttypes.browser.templates.listing.pt diff --git a/CHANGES.rst b/CHANGES.rst index e422efc6..622dff11 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -6,6 +6,8 @@ Changelog - Set `file_principale` field as primary, so we call @@download on the content, that file will be downloaded automatically. [cekk] +- Override listing.pt from plone.app.contenttypes due to error rendering event + [lucabel] 6.2.12 (2024-06-24) diff --git a/src/design/plone/contenttypes/browser/overrides/plone.app.contenttypes.browser.templates.listing.pt b/src/design/plone/contenttypes/browser/overrides/plone.app.contenttypes.browser.templates.listing.pt new file mode 100644 index 00000000..055f47dd --- /dev/null +++ b/src/design/plone/contenttypes/browser/overrides/plone.app.contenttypes.browser.templates.listing.pt @@ -0,0 +1,194 @@ + + + + + + +
    +
    The body
    +
    + + + + + +
    + + + + + +
    + +
    + + + + +
    + + + + + — + Oslo + + — + + + + + + by + + Bob Dobalina + + + + + + — + last modified + + August 16, 2001 at 23:35:59 + + + + + + Place custom listing info for custom types here + + + + +
    +
    + +

    + description +

    +
    + +
    + + + +
    +
    + +
    +
    +
    +
    + +
    + +
    + + +

    + There are currently no items in this folder. +

    +
    + +
    +
    + +
    +
    + + + From 8050b9766ff4056cdb06ce6f3cec07c001f82cc0 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Mon, 8 Jul 2024 15:20:25 +0200 Subject: [PATCH 483/487] Preparing release 6.2.13 --- CHANGES.rst | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 622dff11..93db8018 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,7 +1,7 @@ Changelog ========= -6.2.13 (unreleased) +6.2.13 (2024-07-08) ------------------- - Set `file_principale` field as primary, so we call @@download on the content, that file will be downloaded automatically. diff --git a/setup.py b/setup.py index 617b9dea..33c5a77e 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.2.13.dev0", + version="6.2.13", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From a4458c138abffab4c93b99dfc0741dc6e165db65 Mon Sep 17 00:00:00 2001 From: Luca Bellenghi Date: Mon, 8 Jul 2024 15:21:24 +0200 Subject: [PATCH 484/487] Back to development: 6.2.14 --- CHANGES.rst | 6 ++++++ setup.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 93db8018..a771dd3e 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,6 +1,12 @@ Changelog ========= +6.2.14 (unreleased) +------------------- + +- Nothing changed yet. + + 6.2.13 (2024-07-08) ------------------- diff --git a/setup.py b/setup.py index 33c5a77e..4b60cc35 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ setup( name="design.plone.contenttypes", - version="6.2.13", + version="6.2.14.dev0", description="DesignItalia contenty types", long_description=long_description, long_description_content_type="text/markdown", From ed5034d565ed2896c90492a1efbd1c9fb8d69ec8 Mon Sep 17 00:00:00 2001 From: Mauro Amico Date: Wed, 10 Jul 2024 01:12:50 +0200 Subject: [PATCH 485/487] sast --- .github/workflows/bandit.yml | 24 ++++++++++++++++++++++++ .gitignore | 1 + src/.bandit | 3 +++ 3 files changed, 28 insertions(+) create mode 100644 .github/workflows/bandit.yml create mode 100644 src/.bandit diff --git a/.github/workflows/bandit.yml b/.github/workflows/bandit.yml new file mode 100644 index 00000000..06708054 --- /dev/null +++ b/.github/workflows/bandit.yml @@ -0,0 +1,24 @@ +name: Security check - Bandit + +on: push + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Security check - Bandit + uses: ioggstream/bandit-report-artifacts@v1.7.4 + with: + project_path: src + # ignore_failure: true + + # This is optional + #- name: Security check report artifacts + # uses: actions/upload-artifact@v4 + # with: + # name: Security report + # path: output/security_report.txt + diff --git a/.gitignore b/.gitignore index 032b4ebf..fee94b0b 100644 --- a/.gitignore +++ b/.gitignore @@ -43,6 +43,7 @@ reports/ !.gitkeep !.travis.yml !src/design +!src/.bandit pyvenv.cfg .Python .history/ diff --git a/src/.bandit b/src/.bandit new file mode 100644 index 00000000..0a55d307 --- /dev/null +++ b/src/.bandit @@ -0,0 +1,3 @@ +[bandit] +exclude = locales,tests +skips = B410 From a2b3cdb935b379b053a3ed1530fd1bc86e54a4ab Mon Sep 17 00:00:00 2001 From: Andrea Cecchi Date: Wed, 10 Jul 2024 15:14:57 +0200 Subject: [PATCH 486/487] Fix 7306 upgrade step (#269) * Fix to_7306 upgrade-step to be more specific on types configuration * fix upgrade-step --------- Co-authored-by: Luca --- CHANGES.rst | 2 ++ src/design/plone/contenttypes/upgrades/to_730x.py | 14 ++++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index a771dd3e..9dc0d6f2 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -12,6 +12,8 @@ Changelog - Set `file_principale` field as primary, so we call @@download on the content, that file will be downloaded automatically. [cekk] +- Fix `to_7306`` upgrade-step to be more specific on types configuration. + [cekk] - Override listing.pt from plone.app.contenttypes due to error rendering event [lucabel] diff --git a/src/design/plone/contenttypes/upgrades/to_730x.py b/src/design/plone/contenttypes/upgrades/to_730x.py index 5d5dcf3a..1bea0aa3 100644 --- a/src/design/plone/contenttypes/upgrades/to_730x.py +++ b/src/design/plone/contenttypes/upgrades/to_730x.py @@ -120,5 +120,15 @@ def to_7305(context): def to_7306(context): - logger.info("Disallow add other objs in Persona and Incarico ct") - update_types(context) + logger.info("Enable plone.constraintypes behavior and filter types") + + portal_types = api.portal.get_tool(name="portal_types") + behavior = "plone.constraintypes" + for ct in ["Persona", "Incarico"]: + portal_type = portal_types.get(ct, None) + if portal_type: + portal_type.filter_content_types = True + behaviors = list(portal_type.behaviors) + if behavior not in behaviors: + behaviors.append(behavior) + portal_type.behaviors = tuple(behaviors) From 39d5cf27a06f3820679c4141f7b438632fda17a9 Mon Sep 17 00:00:00 2001 From: Andrea Cecchi Date: Wed, 10 Jul 2024 16:27:30 +0200 Subject: [PATCH 487/487] Fix security problems for bandit (#270) --- CHANGES.rst | 3 ++- .../contenttypes/restapi/serializers/punto_di_contatto.py | 4 ++-- .../contenttypes/restapi/services/scadenziario/post.py | 2 +- .../plone/contenttypes/restapi/services/types/get.py | 4 +++- src/design/plone/contenttypes/upgrades/upgrades.py | 3 ++- .../contenttypes/vocabularies/argomenti_vocabulary.py | 8 ++++++-- .../vocabularies/controlapanel_vocabularies.py | 2 +- 7 files changed, 17 insertions(+), 9 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 9dc0d6f2..f2414164 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,7 +4,8 @@ Changelog 6.2.14 (unreleased) ------------------- -- Nothing changed yet. +- Fix security problems for bandit. + [cekk] 6.2.13 (2024-07-08) diff --git a/src/design/plone/contenttypes/restapi/serializers/punto_di_contatto.py b/src/design/plone/contenttypes/restapi/serializers/punto_di_contatto.py index 48f5499f..10d827e8 100644 --- a/src/design/plone/contenttypes/restapi/serializers/punto_di_contatto.py +++ b/src/design/plone/contenttypes/restapi/serializers/punto_di_contatto.py @@ -63,8 +63,8 @@ def related_contents(self, field, portal_type): for rel in relations: try: obj = intids.queryObject(rel.from_id) - except: # noqa - continue + except Exception: + obj = None if ( obj is not None and checkPermission("zope2.View", obj) diff --git a/src/design/plone/contenttypes/restapi/services/scadenziario/post.py b/src/design/plone/contenttypes/restapi/services/scadenziario/post.py index 1f8072aa..06670a08 100644 --- a/src/design/plone/contenttypes/restapi/services/scadenziario/post.py +++ b/src/design/plone/contenttypes/restapi/services/scadenziario/post.py @@ -64,7 +64,7 @@ def expand_events( """ - assert ret_mode is not RET_MODE_BRAINS + assert ret_mode is not RET_MODE_BRAINS # nosec exp_result = [] for it in events: diff --git a/src/design/plone/contenttypes/restapi/services/types/get.py b/src/design/plone/contenttypes/restapi/services/types/get.py index c18ce171..09b20cd5 100644 --- a/src/design/plone/contenttypes/restapi/services/types/get.py +++ b/src/design/plone/contenttypes/restapi/services/types/get.py @@ -9,6 +9,8 @@ from zope.interface import implementer from zope.publisher.interfaces import IPublishTraverse +import ast + class FieldsetsMismatchError(Exception): """Exception thrown when we try to reorder fieldsets, but the order list is @@ -208,7 +210,7 @@ def customize_venue_schema(self, result): if "geolocation" in result["properties"]: if not result["properties"]["geolocation"].get("default", {}): - result["properties"]["geolocation"]["default"] = eval( + result["properties"]["geolocation"]["default"] = ast.literal_eval( api.portal.get_registry_record( "geolocation", interface=IGeolocationDefaults ) diff --git a/src/design/plone/contenttypes/upgrades/upgrades.py b/src/design/plone/contenttypes/upgrades/upgrades.py index 0702a58b..7f379bd1 100644 --- a/src/design/plone/contenttypes/upgrades/upgrades.py +++ b/src/design/plone/contenttypes/upgrades/upgrades.py @@ -464,7 +464,8 @@ def to_3000(context): json.dumps({"it": value}), interface=IDesignPloneSettings, ) - except Exception: + except Exception: # nosec + # do not do anything continue context.runAllImportStepsFromProfile("profile-design.plone.contenttypes:to_3000") diff --git a/src/design/plone/contenttypes/vocabularies/argomenti_vocabulary.py b/src/design/plone/contenttypes/vocabularies/argomenti_vocabulary.py index a07d25ff..498e62ab 100644 --- a/src/design/plone/contenttypes/vocabularies/argomenti_vocabulary.py +++ b/src/design/plone/contenttypes/vocabularies/argomenti_vocabulary.py @@ -15,7 +15,9 @@ def __call__(self, context): [x.Title for x in api.content.find(portal_type="Pagina Argomento")] ) values = sorted(list(values)) - terms = [SimpleTerm(value="", token="", title="-- seleziona un valore --")] + terms = [ + SimpleTerm(value="", token="", title="-- seleziona un valore --") # nosec + ] # nosec for value in values: terms.append(SimpleTerm(value=value, token=value, title=value)) @@ -30,7 +32,9 @@ def __call__(self, context): arguments = api.content.find( portal_type="Pagina Argomento", sort_on="sortable_title" ) - terms = [SimpleTerm(value="", token="", title="-- seleziona un valore --")] + terms = [ + SimpleTerm(value="", token="", title="-- seleziona un valore --") # nosec + ] # nosec for x in arguments: terms.append(SimpleTerm(value=x.UID, token=x.UID, title=x.Title)) diff --git a/src/design/plone/contenttypes/vocabularies/controlapanel_vocabularies.py b/src/design/plone/contenttypes/vocabularies/controlapanel_vocabularies.py index 8c762911..eeee18bd 100644 --- a/src/design/plone/contenttypes/vocabularies/controlapanel_vocabularies.py +++ b/src/design/plone/contenttypes/vocabularies/controlapanel_vocabularies.py @@ -22,7 +22,7 @@ def __call__(self, context): terms = [SimpleTerm(value=x, token=x, title=x) for x in values] terms.insert( 0, - SimpleTerm(value="", token="", title="-- seleziona un valore --"), + SimpleTerm(value="", token="", title="-- seleziona un valore --"), # nosec ) return SimpleVocabulary(terms)