From 5f3408bd8bfcb4e737dca2a54fe06cb207972b47 Mon Sep 17 00:00:00 2001 From: Mark Pittaway Date: Wed, 6 Mar 2024 16:15:16 +1100 Subject: [PATCH] [SDESK-7191] fix: Autopost Planning linked to posted Event when created from list view If the config is enabled in the EventProfile --- server/planning/content_profiles/utils.py | 7 +++ server/planning/events/events_post.py | 5 +- server/planning/events/events_tests.py | 65 ++++++++++++++++++++++- server/planning/planning/planning.py | 18 ++++++- server/planning/types/content_profiles.py | 1 + 5 files changed, 90 insertions(+), 6 deletions(-) diff --git a/server/planning/content_profiles/utils.py b/server/planning/content_profiles/utils.py index 5aef4e141..eb1c0cd63 100644 --- a/server/planning/content_profiles/utils.py +++ b/server/planning/content_profiles/utils.py @@ -89,3 +89,10 @@ def __init__(self): self.events = ContentProfileData("event") self.planning = ContentProfileData("planning") self.coverages = ContentProfileData("coverage") + + +def is_post_planning_with_event_enabled() -> bool: + try: + return get_planning_schema("event")["schema"]["related_plannings"]["planning_auto_publish"] is True + except (KeyError, TypeError): + return False diff --git a/server/planning/events/events_post.py b/server/planning/events/events_post.py index 41e6264a0..171c87b0d 100644 --- a/server/planning/events/events_post.py +++ b/server/planning/events/events_post.py @@ -18,8 +18,8 @@ enqueue_planning_item, get_version_item_for_post, ) - from planning.utils import try_cast_object_id +from planning.content_profiles.utils import is_post_planning_with_event_enabled class EventsPostResource(EventsResource): @@ -205,10 +205,9 @@ def publish_event(self, event, version): def post_related_plannings(self, plannings, new_post_state): planning_post_service = get_resource_service("planning_post") planning_spike_service = get_resource_service("planning_spike") - event_profile_schema = get_resource_service("planning_types").find_one(req=None, name="event").get("schema", {}) docs = [] if new_post_state != POST_STATE.CANCELLED: - if event_profile_schema.get("related_plannings", {}).get("planning_auto_publish"): + if is_post_planning_with_event_enabled(): docs = [ { "planning": planning[config.ID_FIELD], diff --git a/server/planning/events/events_tests.py b/server/planning/events/events_tests.py index bf393a081..8fcd203f9 100644 --- a/server/planning/events/events_tests.py +++ b/server/planning/events/events_tests.py @@ -5,7 +5,7 @@ from superdesk import get_resource_service from superdesk.utc import utcnow from planning.tests import TestCase -from planning.common import format_address +from planning.common import format_address, POST_STATE from planning.item_lock import LockService from planning.events.events import generate_recurring_dates @@ -532,3 +532,66 @@ def test_planning_item_is_published_with_events(self): self.assertEqual(len([planning_item]), 1) self.assertEqual(planning_item.get("state"), "scheduled") assert now <= planning_item.get("versionposted") < now + timedelta(seconds=5) + + def test_new_planning_is_published_when_adding_to_published_event(self): + events_service = get_resource_service("events") + planning_service = get_resource_service("planning") + + with self.app.app_context(): + self.app.data.insert( + "planning_types", + [ + { + "_id": "event", + "name": "event", + "editor": {"related_plannings": {"enabled": True}}, + "schema": {"related_plannings": {"planning_auto_publish": True}}, + } + ], + ) + event_id = events_service.post( + [ + { + "type": "event", + "occur_status": { + "qcode": "eocstat:eos5", + "name": "Planned, occurs certainly", + "label": "Planned, occurs certainly", + }, + "dates": { + "start": datetime(2099, 11, 21, 11, 00, 00, tzinfo=pytz.UTC), + "end": datetime(2099, 11, 21, 12, 00, 00, tzinfo=pytz.UTC), + "tz": "Australia/Sydney", + }, + "state": "draft", + "name": "Demo", + } + ] + )[0] + get_resource_service("events_post").post( + [ + { + "event": event_id, + "pubstatus": "usable", + "update_method": "single", + } + ] + ) + planning_id = planning_service.post( + [ + { + "planning_date": datetime(2099, 11, 21, 12, 00, 00, tzinfo=pytz.UTC), + "name": "Demo 1", + "type": "planning", + "event_item": event_id, + } + ] + )[0] + + event_item = events_service.find_one(req=None, _id=event_id) + self.assertIsNotNone(event_item) + self.assertEqual(event_item["pubstatus"], POST_STATE.USABLE) + + planning_item = planning_service.find_one(req=None, _id=planning_id) + self.assertIsNotNone(planning_item) + self.assertEqual(planning_item["pubstatus"], POST_STATE.USABLE) diff --git a/server/planning/planning/planning.py b/server/planning/planning/planning.py index 7d822c796..4e130b57c 100644 --- a/server/planning/planning/planning.py +++ b/server/planning/planning/planning.py @@ -60,12 +60,13 @@ UPDATE_SINGLE, UPDATE_FUTURE, UPDATE_ALL, + POST_STATE, ) from superdesk.utc import utcnow from itertools import chain from planning.planning_notifications import PlanningNotifications from superdesk.utc import utc_to_local -from planning.content_profiles.utils import is_field_enabled +from planning.content_profiles.utils import is_field_enabled, is_post_planning_with_event_enabled from superdesk import Resource from lxml import etree from io import BytesIO @@ -186,10 +187,12 @@ def on_create(self, docs): def on_created(self, docs): session_id = get_auth().get("_id") + post_planning_with_event = is_post_planning_with_event_enabled() for doc in docs: + plan_id = str(doc.get(config.ID_FIELD)) push_notification( "planning:created", - item=str(doc.get(config.ID_FIELD)), + item=plan_id, user=str(doc.get("original_creator", "")), added_agendas=doc.get("agendas") or [], removed_agendas=[], @@ -198,6 +201,17 @@ def on_created(self, docs): ) self._update_event_history(doc) planning_created.send(self, item=doc) + + event_id = doc.get("event_item") + if event_id and post_planning_with_event: + event = get_resource_service("events").find_one(req=None, _id=event_id) + if not event: + logger.warning(f"Failed to find linked event {event_id} for planning {plan_id}") + elif event.get("pubstatus") == POST_STATE.USABLE: + updates = doc.copy() + updates["pubstatus"] = POST_STATE.USABLE + update_post_item(updates, doc) + self.generate_related_assignments(docs) def _update_event_history(self, doc): diff --git a/server/planning/types/content_profiles.py b/server/planning/types/content_profiles.py index 244cedab1..0ebadf274 100644 --- a/server/planning/types/content_profiles.py +++ b/server/planning/types/content_profiles.py @@ -14,6 +14,7 @@ class ContentFieldSchema(TypedDict, total=False): multilingual: bool field_type: str + planning_auto_publish: bool # Only available in ``related_plannings`` field class ContentFieldEditor(TypedDict):