From f653dbbb18cf33e7066e2cdeddcb604da059bc85 Mon Sep 17 00:00:00 2001 From: Emanuel Cino Date: Tue, 14 Apr 2026 14:22:48 +0200 Subject: [PATCH] T3096 Refactor letters display - ADD new field for tracking date of Exit communication sent to sponsor - FIX is_final_letter field --- .../__manifest__.py | 2 +- .../migrations/14.0.1.2.0/post-migration.py | 44 +++++++++++++++++++ .../models/contracts.py | 1 + .../models/partner_communication.py | 10 +++++ sbc_compassion/models/correspondence.py | 6 +-- sbc_compassion/views/correspondence_view.xml | 6 ++- 6 files changed, 63 insertions(+), 6 deletions(-) create mode 100644 partner_communication_compassion/migrations/14.0.1.2.0/post-migration.py diff --git a/partner_communication_compassion/__manifest__.py b/partner_communication_compassion/__manifest__.py index a28824250..39450cdae 100644 --- a/partner_communication_compassion/__manifest__.py +++ b/partner_communication_compassion/__manifest__.py @@ -29,7 +29,7 @@ # pylint: disable=C8101 { "name": "Compassion Partner Communications", - "version": "14.0.1.1.1", + "version": "14.0.1.2.0", "category": "Other", "author": "Compassion CH", "license": "AGPL-3", diff --git a/partner_communication_compassion/migrations/14.0.1.2.0/post-migration.py b/partner_communication_compassion/migrations/14.0.1.2.0/post-migration.py new file mode 100644 index 000000000..de206d221 --- /dev/null +++ b/partner_communication_compassion/migrations/14.0.1.2.0/post-migration.py @@ -0,0 +1,44 @@ +from datetime import datetime + +from dateutil.relativedelta import relativedelta +from openupgradelib import openupgrade + + +@openupgrade.migrate() +def migrate(env, version): + openupgrade.logged_query( + env.cr, + """ + UPDATE recurring_contract + SET exit_communication_sent = COALESCE (sds_state_date, end_date, write_date) + WHERE state = 'terminated' + AND (end_date IS NULL OR end_date <= CURRENT_DATE - INTERVAL '6 months') + """, + ) + six_month_ago = datetime.today() - relativedelta(months=6) + terminated_sponsorships = env["recurring.contract"].search( + [ + ("state", "=", "terminated"), + ("end_date", ">", six_month_ago), + ] + ) + exit_configs = env.ref( + "partner_communication_compassion.lifecycle_child_planned_exit" + ) + env.ref("partner_communication_compassion.lifecycle_child_unplanned_exit") + for contract in terminated_sponsorships: + exit_dates = env["partner.communication.job"].search_read( + [ + ("config_id", "in", exit_configs.ids), + ("state", "=", "done"), + ("sent_date", "!=", False), + ( + "partner_id", + "in", + (contract.partner_id + contract.correspondent_id).ids, + ), + ("object_ids", "like", contract.id), + ], + ["sent_date"], + ) + if exit_dates: + contract.exit_communication_sent = max(r["sent_date"] for r in exit_dates) diff --git a/partner_communication_compassion/models/contracts.py b/partner_communication_compassion/models/contracts.py index fbdd13b05..e7ccd9cbf 100644 --- a/partner_communication_compassion/models/contracts.py +++ b/partner_communication_compassion/models/contracts.py @@ -35,6 +35,7 @@ class RecurringContract(models.Model): help="Indicates a new picture was received and not yet " "transmitted to the sponsor." ) + exit_communication_sent = fields.Datetime() @api.onchange("origin_id", "correspondent_id") def _do_not_send_letter_to_transfer(self): diff --git a/partner_communication_compassion/models/partner_communication.py b/partner_communication_compassion/models/partner_communication.py index 260f3c679..4a79be589 100644 --- a/partner_communication_compassion/models/partner_communication.py +++ b/partner_communication_compassion/models/partner_communication.py @@ -163,6 +163,16 @@ def send(self): if biennials: for child in biennials.get_objects(): child.sponsorship_ids[0].new_picture = False + exit_confs = self.env.ref( + "partner_communication_compassion.lifecycle_child_planned_exit" + ) + self.env.ref( + "partner_communication_compassion.lifecycle_child_unplanned_exit" + ) + exits = self.filtered(lambda j: j.state == "done" and j.config_id in exit_confs) + if exits: + exits.get_objects().write( + {"exit_communication_sent": fields.Datetime.now()} + ) return res def cancel(self): diff --git a/sbc_compassion/models/correspondence.py b/sbc_compassion/models/correspondence.py index 411e8f6ce..36952a30a 100644 --- a/sbc_compassion/models/correspondence.py +++ b/sbc_compassion/models/correspondence.py @@ -427,11 +427,9 @@ def _get_uuid(self): return str(uuid.uuid4()) def _compute_is_final_letter(self): + final_type = self.env.ref("sbc_compassion.correspondence_type_final") for letter in self: - letter.is_final_letter = ( - "Final Letter" in letter.communication_type_ids.mapped("name") - or letter.sponsorship_state != "active" - ) + letter.is_final_letter = final_type in letter.communication_type_ids def _compute_preferred_dpi(self): for letter in self: diff --git a/sbc_compassion/views/correspondence_view.xml b/sbc_compassion/views/correspondence_view.xml index 8cffeb47e..78b4c8198 100644 --- a/sbc_compassion/views/correspondence_view.xml +++ b/sbc_compassion/views/correspondence_view.xml @@ -3,7 +3,10 @@ correspondence.tree correspondence - + @@ -11,6 +14,7 @@ +