Skip to content

Commit

Permalink
Add facade email address to addressees in pno emails
Browse files Browse the repository at this point in the history
  • Loading branch information
VincentAntoine committed Sep 23, 2024
1 parent 31d260a commit 52dfbd9
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 12 deletions.
3 changes: 3 additions & 0 deletions datascience/src/pipeline/entities/pnos.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class PnoToRender:
catch_onboard: List[dict]
port_locode: str
port_name: str
facade: str
predicted_arrival_datetime_utc: datetime
predicted_landing_datetime_utc: datetime
trip_gears: List[dict]
Expand Down Expand Up @@ -113,6 +114,7 @@ class PreRenderedPno:
catch_onboard: pd.DataFrame
port_locode: str
port_name: str
facade: str
predicted_arrival_datetime_utc: datetime
predicted_landing_datetime_utc: datetime
trip_gears: List[FishingGear]
Expand Down Expand Up @@ -204,6 +206,7 @@ class RenderedPno:
is_being_sent: bool
trip_segments: list
port_locode: str
facade: str
source: PnoSource
html_for_pdf: Optional[str] = None
pdf_document: Optional[bytes] = None
Expand Down
22 changes: 22 additions & 0 deletions datascience/src/pipeline/flows/distribute_pnos.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,15 @@ def extract_pnos_to_generate(
return (pnos, generation_needed)


@task(checkpoint=False)
def extract_facade_email_addresses() -> dict:
df = extract(
db_name="monitorfish_remote",
query_filepath="monitorfish/facade_email_addresses.sql",
)
return df.set_index("facade").email_address.to_dict()


@task(checkpoint=False)
def to_pnos_to_render(pnos: pd.DataFrame) -> List[PnoToRender]:
records = pnos.to_dict(orient="records")
Expand Down Expand Up @@ -247,6 +256,7 @@ def format_sr_list(sr_list: list) -> str:
catch_onboard=sum_by_species,
port_locode=pno.port_locode,
port_name=pno.port_name,
facade=pno.facade,
predicted_arrival_datetime_utc=pno.predicted_arrival_datetime_utc,
predicted_landing_datetime_utc=pno.predicted_landing_datetime_utc,
trip_gears=trip_gears,
Expand Down Expand Up @@ -474,6 +484,7 @@ def format_nullable_datetime(d: datetime, format: str = date_format):
is_being_sent=pno.is_being_sent,
trip_segments=pno.trip_segments,
port_locode=pno.port_locode,
facade=pno.facade,
source=pno.source,
html_for_pdf=html_for_pdf,
pdf_document=pdf,
Expand Down Expand Up @@ -536,6 +547,7 @@ def attribute_addressees(
units_targeting_vessels: pd.DataFrame,
units_ports_and_segments_subscriptions: pd.DataFrame,
control_units_contacts: pd.DataFrame,
facade_email_addresses: dict,
) -> RenderedPno:
"""
Returns a copy of the input `RenderedPno`'s with its `control_unit_ids`,
Expand All @@ -560,6 +572,9 @@ def attribute_addressees(
`unit_subscribed_segments`
control_units_contacts (pd.DataFrame): DataFrame with columns
`control_unit_id`, `emails` and `phone_numbers`
facade_email_addresses (dict): dictionnary with facade names as keys and FMC
facade email addresses as values. The email address of the corresponding
facade will be added to addressees in PNO emails.
Returns:
RenderedPno: copy of the input `pno_to_distribute` with addressees added
Expand Down Expand Up @@ -622,6 +637,10 @@ def attribute_addressees(
)
)
)
if emails:
facade_email_address = facade_email_addresses.get(pno_to_distribute.facade)
if facade_email_address:
emails.append(facade_email_address)

phone_numbers = sorted(
set(
Expand Down Expand Up @@ -995,11 +1014,14 @@ def make_manual_prior_notifications_statement(

with case(distribution_needed, True):
# Distribute PNOs
facade_email_addresses = extract_facade_email_addresses()

pnos_with_addressees = attribute_addressees.map(
pnos_to_distribute,
unmapped(units_targeting_vessels),
unmapped(units_ports_and_segments_subscriptions),
control_units_contacts=unmapped(control_units_contacts),
facade_email_addresses=unmapped(facade_email_addresses),
)

email = create_email.map(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
SELECT DISTINCT ON (facade)
facade,
email_address
FROM facade_areas_subdivided
ORDER BY facade
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ acknowledged_deleted_messages AS (
r.value->'catchOnboard' AS catch_onboard,
r.value->>'port' AS port_locode,
p.port_name,
p.facade,
(r.value->>'predictedArrivalDatetimeUtc')::TIMESTAMPTZ AT TIME ZONE 'UTC' AS predicted_arrival_datetime_utc,
(r.value->>'predictedLandingDatetimeUtc')::TIMESTAMPTZ AT TIME ZONE 'UTC' AS predicted_landing_datetime_utc,
r.trip_gears,
Expand Down Expand Up @@ -109,6 +110,7 @@ UNION ALL
r.value->'catchOnboard' AS catch_onboard,
r.value->>'port' AS port_locode,
p.port_name,
p.facade,
(r.value->>'predictedArrivalDatetimeUtc')::TIMESTAMPTZ AT TIME ZONE 'UTC' AS predicted_arrival_datetime_utc,
(r.value->>'predictedLandingDatetimeUtc')::TIMESTAMPTZ AT TIME ZONE 'UTC' AS predicted_landing_datetime_utc,
(CASE WHEN jsonb_typeof(r.trip_gears) = 'array' THEN r.trip_gears ELSE '[]'::jsonb END) AS trip_gears,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ DELETE FROM public.ports;

INSERT INTO public.ports (
country_code_iso2, region, locode, port_name, is_active, facade) VALUES
( 'FR', '56', 'FAKE', 'Fake Port initially active', true, NULL),
( 'FR', '56', 'FAKE', 'Fake Port initially active', true, 'NAMO'),
( 'FR', '56', 'PNO_PORT', 'Fake Port with PNO', false, NULL),
( 'FR', '56', 'LAN_PORT', 'Fake Port with LAN', false, NULL),
( 'FR', '999', 'FRCQF', 'Somewhere over the rainbow', false, NULL),
( 'FR', '999', 'FRBES', 'Somewhere over the hill', false, NULL),
( 'FR', '56', 'LAN_PORT', 'Fake Port with LAN', false, 'NAMO'),
( 'FR', '999', 'FRCQF', 'Somewhere over the rainbow', false, 'NAMO'),
( 'FR', '999', 'FRBES', 'Somewhere over the hill', false, 'SA'),
( 'FR', '999', 'FRDPE', 'Somewhere over the clouds', false, NULL),
( 'FR', '999', 'FRDKK', 'Somewhere over the swell', false, NULL),
( 'FR', '999', 'FRLEH', 'Somewhere over the ocean', false, NULL),
( 'FR', '999', 'FRZJZ', 'Somewhere over the top', false, NULL),
( 'FR', '999', 'FRDKK', 'Somewhere over the swell', false, 'NAMO'),
( 'FR', '999', 'FRLEH', 'Somewhere over the ocean', false, 'SA'),
( 'FR', '999', 'FRZJZ', 'Somewhere over the top', false, 'SA'),
( 'FR', '999', 'GBPHD', 'Port with facade', false, 'MEMN');
42 changes: 37 additions & 5 deletions datascience/tests/test_pipeline/test_flows/test_distribute_pnos.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
attribute_addressees,
create_email,
create_sms,
extract_facade_email_addresses,
extract_fishing_gear_names,
extract_pnos_to_generate,
extract_species_names,
Expand Down Expand Up @@ -415,6 +416,7 @@ def extracted_pnos() -> pd.DataFrame:
"Somewhere over the swell",
"Somewhere over the ocean",
],
"facade": ["NAMO", "SA", "NAMO", "SA", None, "SA", None, "NAMO", "SA"],
"predicted_arrival_datetime_utc": [
datetime(2020, 5, 6, 11, 41, 3, 340000),
datetime(2020, 5, 6, 11, 41, 3, 340000),
Expand Down Expand Up @@ -685,6 +687,7 @@ def pno_to_render_1() -> PnoToRender:
],
port_locode="FRCQF",
port_name="Somewhere over the rainbow",
facade="NAMO",
predicted_arrival_datetime_utc=datetime(2020, 5, 6, 11, 41, 3, 340000),
predicted_landing_datetime_utc=datetime(2020, 5, 6, 16, 40),
trip_gears=[
Expand Down Expand Up @@ -778,6 +781,7 @@ def pre_rendered_pno_1(pre_rendered_pno_1_catch_onboard) -> PreRenderedPno:
catch_onboard=pre_rendered_pno_1_catch_onboard,
port_locode="FRCQF",
port_name="Somewhere over the rainbow",
facade="NAMO",
predicted_arrival_datetime_utc=datetime(2020, 5, 6, 11, 41, 3, 340000),
predicted_landing_datetime_utc=datetime(2020, 5, 6, 16, 40),
trip_gears=[
Expand Down Expand Up @@ -832,6 +836,7 @@ def pno_to_render_2() -> PnoToRender:
catch_onboard=None,
port_locode="FRZJZ",
port_name="Somewhere over the top",
facade="SA",
predicted_arrival_datetime_utc=datetime(2020, 5, 6, 11, 41, 3, 340000),
predicted_landing_datetime_utc=pd.NaT,
trip_gears=[],
Expand Down Expand Up @@ -869,6 +874,7 @@ def pre_rendered_pno_2() -> PreRenderedPno:
catch_onboard=None,
port_locode="FRZJZ",
port_name="Somewhere over the top",
facade="SA",
predicted_arrival_datetime_utc=datetime(2020, 5, 6, 11, 41, 3, 340000),
predicted_landing_datetime_utc=None,
trip_gears=[],
Expand Down Expand Up @@ -903,6 +909,7 @@ def pno_pdf_document_to_distribute_targeted_vessel_and_segments() -> RenderedPno
FleetSegment("NWW02", "Autres"),
],
port_locode="FRZJZ",
facade="NAMO",
source=PnoSource.MANUAL,
generation_datetime_utc=datetime(2023, 5, 6, 23, 52, 0),
pdf_document=b"PDF Document",
Expand All @@ -920,7 +927,7 @@ def pno_pdf_document_to_distribute_targeted_vessel_and_segments_assigned(
pno_pdf_document_to_distribute_targeted_vessel_and_segments,
control_unit_ids={1, 2, 3},
phone_numbers=["'00 11 22 33 44 55", "44 44 44 44 44"],
emails=["alternative@email", "some.email@control.unit.4"],
emails=["alternative@email", "some.email@control.unit.4", "namo@email"],
)


Expand All @@ -935,6 +942,7 @@ def pno_pdf_document_to_distribute_receive_all_pnos_from_port() -> RenderedPno:
is_being_sent=True,
trip_segments=[],
port_locode="FRDPE",
facade="Unknown facade",
source=PnoSource.MANUAL,
generation_datetime_utc=datetime(2023, 6, 6, 23, 50, 0),
pdf_document=b"PDF Document",
Expand Down Expand Up @@ -965,6 +973,7 @@ def pno_pdf_document_to_distribute_without_addressees() -> RenderedPno:
is_being_sent=True,
trip_segments=[],
port_locode="FRDKK",
facade="SA",
source=PnoSource.MANUAL,
generation_datetime_utc=datetime(2023, 6, 6, 23, 50, 0),
pdf_document=b"PDF Document",
Expand Down Expand Up @@ -995,6 +1004,7 @@ def pno_pdf_document_to_distribute_verified() -> RenderedPno:
is_being_sent=True,
trip_segments=[],
port_locode="FRLEH",
facade="NAMO",
source=PnoSource.MANUAL,
generation_datetime_utc=datetime(2023, 6, 6, 23, 50, 0),
pdf_document=b"PDF Document",
Expand All @@ -1009,7 +1019,7 @@ def pno_pdf_document_to_distribute_verified_assigned(
return dataclasses.replace(
pno_pdf_document_to_distribute_verified,
control_unit_ids={2, 3},
emails=["alternative@email", "some.email@control.unit.4"],
emails=["alternative@email", "some.email@control.unit.4", "namo@email"],
phone_numbers=["'00 11 22 33 44 55", "44 44 44 44 44"],
)

Expand Down Expand Up @@ -1055,6 +1065,7 @@ def logbook_rendered_pno():
is_being_sent=True,
trip_segments=["Segment1", "Segment2"],
port_locode="FRBOL",
facade="NAMO",
source=PnoSource.LOGBOOK,
html_for_pdf="<html>Html for PDF</html>",
pdf_document=b"PDF document",
Expand All @@ -1078,6 +1089,7 @@ def manual_rendered_pno():
is_being_sent=True,
trip_segments=["Segment3"],
port_locode="FRBOL",
facade="SA",
source=PnoSource.MANUAL,
html_for_pdf="<html>Html for PDF manual</html>",
pdf_document=b"PDF document manual",
Expand Down Expand Up @@ -1222,6 +1234,11 @@ def pnos_to_reset() -> List[RenderedPno]:
return [RenderedPno()]


@pytest.fixture
def facade_email_addresses() -> dict:
return {"NAMO": "namo@email", "SA": "sa@email"}


def test_extract_pnos_to_generate(reset_test_data, extracted_pnos):
approximate_datetime_columns = [
"operation_datetime_utc",
Expand Down Expand Up @@ -1256,6 +1273,11 @@ def test_extract_fishing_gear_names(reset_test_data, fishing_gear_names):
assert res == fishing_gear_names


def test_extract_facade_email_addresses(reset_test_data, facade_email_addresses):
res = extract_facade_email_addresses.run()
assert res == facade_email_addresses


def test_to_pnos_to_render(extracted_pnos):
res = to_pnos_to_render.run(pnos=extracted_pnos)
assert len(res) == 9
Expand Down Expand Up @@ -1481,6 +1503,7 @@ def test_load_pno_pdf_documents(reset_test_data):
is_being_sent=is_being_sent,
trip_segments=[],
port_locode="FRBOL",
facade="NAMO",
source=PnoSource.LOGBOOK,
generation_datetime_utc=datetime(2020, 5, 6, 8, 52, 42),
pdf_document=pdf,
Expand Down Expand Up @@ -1557,12 +1580,14 @@ def test_attribute_addressees_uses_target_vessels_and_segments(
pno_units_targeting_vessels,
pno_units_ports_and_segments_subscriptions,
control_units_contacts,
facade_email_addresses,
):
res = attribute_addressees.run(
pno_pdf_document_to_distribute_targeted_vessel_and_segments,
pno_units_targeting_vessels,
pno_units_ports_and_segments_subscriptions,
control_units_contacts,
facade_email_addresses,
)
assert res == pno_pdf_document_to_distribute_targeted_vessel_and_segments_assigned

Expand All @@ -1573,12 +1598,14 @@ def test_attribute_addressees_uses_receive_all_pnos_from_port(
pno_units_targeting_vessels,
pno_units_ports_and_segments_subscriptions,
control_units_contacts,
facade_email_addresses,
):
res = attribute_addressees.run(
pno_pdf_document_to_distribute_receive_all_pnos_from_port,
pno_units_targeting_vessels,
pno_units_ports_and_segments_subscriptions,
control_units_contacts,
facade_email_addresses,
)
assert res == pno_pdf_document_to_distribute_receive_all_pnos_from_port_assigned

Expand All @@ -1589,12 +1616,14 @@ def test_attribute_addressees_returns_empty_addressees(
pno_units_targeting_vessels,
pno_units_ports_and_segments_subscriptions,
control_units_contacts,
facade_email_addresses,
):
res = attribute_addressees.run(
pno_pdf_document_to_distribute_without_addressees,
pno_units_targeting_vessels,
pno_units_ports_and_segments_subscriptions,
control_units_contacts,
facade_email_addresses,
)
assert res == pno_pdf_document_to_distribute_without_addressees_assigned

Expand All @@ -1605,12 +1634,14 @@ def test_attribute_addressees_when_is_verified(
pno_units_targeting_vessels,
pno_units_ports_and_segments_subscriptions,
control_units_contacts,
facade_email_addresses,
):
res = attribute_addressees.run(
pno_pdf_document_to_distribute_verified,
pno_units_targeting_vessels,
pno_units_ports_and_segments_subscriptions,
control_units_contacts,
facade_email_addresses,
)
assert res == pno_pdf_document_to_distribute_verified_assigned

Expand Down Expand Up @@ -1639,7 +1670,8 @@ def test_create_email(
assert pno_to_send.message["To"] == "pno.test@email.fr"
else:
assert (
pno_to_send.message["To"] == "alternative@email, some.email@control.unit.4"
pno_to_send.message["To"]
== "alternative@email, some.email@control.unit.4, namo@email"
)
assert pno_to_send.message["From"] == "monitorfish@test.email"
assert pno_to_send.message["Cc"] is None
Expand Down Expand Up @@ -1972,7 +2004,7 @@ class UnexpectedFailureOfDeath(Exception):
assert len(initial_pdf_documents) == 8
assert len(initial_sent_messages) == 0
assert len(final_pdf_documents) == 14
assert len(final_sent_messages) == 12
assert len(final_sent_messages) == 15

if is_integration:
assert final_sent_messages.success.all()
Expand All @@ -1995,7 +2027,7 @@ class UnexpectedFailureOfDeath(Exception):
== CommunicationMeans.EMAIL.value
]
)
== 7
== 10
)
assert final_sent_messages.loc[
(
Expand Down

0 comments on commit 52dfbd9

Please sign in to comment.