diff --git a/app/broadcast_areas/__init__.py b/app/broadcast_areas/__init__.py index 5c10f6228..0631f37cd 100644 --- a/app/broadcast_areas/__init__.py +++ b/app/broadcast_areas/__init__.py @@ -89,6 +89,41 @@ class BroadcastArea(SortableMixin): id = parent_broadcast_area.id +class CustomBroadcastArea: + + # We don’t yet have a way to estimate the number of phones in a + # user-defined polygon + count_of_phones = 0 + + def __init__(self, *, name, polygons=None): + self.name = name + self._polygons = polygons or [] + + @property + def polygons(self): + return Polygons( + # Polygons in the DB are stored with the coordinate pair + # order flipped – this flips them back again + Polygons(self._polygons).as_coordinate_pairs_lat_long + ) + + simple_polygons = polygons + + +class CustomBroadcastAreas(SerialisedModelCollection): + model = CustomBroadcastArea + + def __init__(self, *, areas, polygons): + self.items = areas + self._polygons = polygons + + def __getitem__(self, index): + return self.model( + name=self.items[index], + polygons=self._polygons if index == 0 else None, + ) + + class BroadcastAreaLibrary(SerialisedModelCollection, SortableMixin, GetItemByIdMixin): model = BroadcastArea diff --git a/app/models/broadcast_message.py b/app/models/broadcast_message.py index 569bb36bb..eda45fa53 100644 --- a/app/models/broadcast_message.py +++ b/app/models/broadcast_message.py @@ -5,7 +5,7 @@ from notifications_utils.template import BroadcastPreviewTemplate from orderedset import OrderedSet from werkzeug.utils import cached_property -from app.broadcast_areas import broadcast_area_libraries +from app.broadcast_areas import CustomBroadcastAreas, broadcast_area_libraries from app.broadcast_areas.polygons import Polygons from app.formatters import round_to_significant_figures from app.models import JSONModel, ModelList @@ -45,6 +45,10 @@ class BroadcastMessage(JSONModel): return True if not self.starts_at and other.starts_at: return False + if self.updated_at and not other.updated_at: + return self.updated_at < other.created_at + if not self.updated_at and other.updated_at: + return self.created_at < other.updated_at return self.updated_at < other.updated_at @classmethod @@ -74,7 +78,20 @@ class BroadcastMessage(JSONModel): @property def areas(self): - return self.get_areas(areas=self._dict['areas']) + library_areas = self.get_areas(areas=self._dict['areas']) + + if library_areas: + if len(library_areas) != len(self._dict['areas']): + raise RuntimeError( + f'BroadcastMessage has {len(self._dict["areas"])} areas ' + f'but {len(library_areas)} found in the library' + ) + return library_areas + + return CustomBroadcastAreas( + areas=self._dict['areas'], + polygons=self._dict['simple_polygons'], + ) @property def parent_areas(self): @@ -124,7 +141,7 @@ class BroadcastMessage(JSONModel): @cached_property def created_by(self): - return User.from_id(self.created_by_id) + return User.from_id(self.created_by_id) if self.created_by_id else None @cached_property def approved_by(self): diff --git a/app/templates/views/broadcast/macros/area-map.html b/app/templates/views/broadcast/macros/area-map.html index 196f4c447..737cd24c0 100644 --- a/app/templates/views/broadcast/macros/area-map.html +++ b/app/templates/views/broadcast/macros/area-map.html @@ -20,7 +20,9 @@ alert
  • - {% if broadcast_message.count_of_phones == broadcast_message.count_of_phones_likely %} + {% if broadcast_message.count_of_phones == 0 %} + Unknown number of phones + {% elif broadcast_message.count_of_phones == broadcast_message.count_of_phones_likely %} {{ broadcast_message.count_of_phones|format_thousands }} phones estimated {% else %} {{ broadcast_message.count_of_phones|format_thousands }} to {{ broadcast_message.count_of_phones_likely|format_thousands }} phones diff --git a/app/templates/views/broadcast/view-message.html b/app/templates/views/broadcast/view-message.html index 2004729d0..08be7e083 100644 --- a/app/templates/views/broadcast/view-message.html +++ b/app/templates/views/broadcast/view-message.html @@ -19,10 +19,15 @@ {% block service_page_title %} {% if broadcast_message.status == 'pending-approval' %} - {% if broadcast_message.created_by == current_user and current_user.has_permissions('send_messages') %} + {% if broadcast_message.created_by and broadcast_message.created_by == current_user and current_user.has_permissions('send_messages') %} {{ broadcast_message.template.name }} is waiting for approval {% elif current_user.has_permissions('send_messages') %} - {{ broadcast_message.created_by.name }} wants to broadcast + {% if broadcast_message.created_by %} + {{ broadcast_message.created_by.name }} + {% else %} + An API call + {% endif %} + wants to broadcast {{ broadcast_message.template.name }} {% else %} This alert is waiting for approval @@ -37,7 +42,7 @@ {{ govukBackLink({ "href": back_link }) }} {% if broadcast_message.status == 'pending-approval' %} - {% if broadcast_message.created_by == current_user and current_user.has_permissions('send_messages') %} + {% if broadcast_message.created_by and broadcast_message.created_by == current_user and current_user.has_permissions('send_messages') %}