From 9eeaee2aa760c7ce7e5efaa99e6437c05fb76ab5 Mon Sep 17 00:00:00 2001 From: braisab Date: Thu, 2 Dec 2021 22:27:21 +0100 Subject: [PATCH 1/4] [REF]pms: refactoring iteration of folios in send mail --- pms/models/pms_folio.py | 218 +++++++++++++++++++--------------------- 1 file changed, 102 insertions(+), 116 deletions(-) diff --git a/pms/models/pms_folio.py b/pms/models/pms_folio.py index 98e5e3006..48b4eb30a 100644 --- a/pms/models/pms_folio.py +++ b/pms/models/pms_folio.py @@ -3,6 +3,7 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). import logging +from datetime import datetime from itertools import groupby from odoo import _, api, fields, models @@ -513,6 +514,13 @@ class PmsFolio(models.Model): compute="_compute_last_checkout", ) + date_creation = fields.Date( + string="Creation Date", + readonly=False, + store=True, + compute="_compute_date_creation", + ) + def name_get(self): result = [] for folio in self: @@ -1088,6 +1096,12 @@ class PmsFolio(models.Model): checkouts = record.reservation_ids.mapped("checkout") record.last_checkout = max(checkouts) + @api.depends("create_date") + def _compute_date_creation(self): + for record in self: + if record.create_date: + record.date_creation = datetime.strftime(record.create_date, "%Y-%m-%d") + def _search_invoice_ids(self, operator, value): if operator == "in" and value: self.env.cr.execute( @@ -1286,125 +1300,98 @@ class PmsFolio(models.Model): @api.model def send_confirmation_mail(self): - folios = self.env["pms.folio"].search([]) - if folios and all( - is_confirmed_auto_mail - for is_confirmed_auto_mail in folios.pms_property_id.mapped( - "is_confirmed_auto_mail" - ) - ): - for folio in folios: - create_date = folio.create_date.date() - if ( - folio.state in "confirm" - and create_date == fields.Date.today() - and all( - not mail_send - for mail_send in folio.reservation_ids.mapped("is_mail_send") + today = fields.Date.today() + folios = self.env["pms.folio"].search( + [ + ("pms_property_id.is_confirmed_auto_mail", "=", True), + ("reservation_ids.is_mail_send", "=", False), + ("reservation_ids.is_modified_reservation", "=", False), + ("date_creation", "=", today), + ] + ) + for folio in folios: + if folio.email: + template = folio.pms_property_id.property_confirmed_template + subject = template._render_field( + "subject", + [6, 0, folio.id], + compute_lang=True, + )[folio.id] + body = template._render_field( + "body_html", + [6, 0, folio.id], + compute_lang=True, + )[folio.id] + mail = ( + folio.env["mail.mail"] + .sudo() + .create( + { + "subject": subject, + "body_html": body, + "email_from": folio.pms_property_id.partner_id.email, + "email_to": folio.email, + } ) - and all( - not is_modified_reservation - for is_modified_reservation in folio.reservation_ids.mapped( - "is_modified_reservation" - ) - ) - ): - template = folio.pms_property_id.property_confirmed_template - subject = template._render_field( - "subject", - [6, 0, folio.id], - compute_lang=True, - post_process=True, - )[folio.id] - body = template._render_field( - "body_html", - [6, 0, folio.id], - compute_lang=True, - post_process=True, - )[folio.id] - invitation_mail = ( - folio.env["mail.mail"] - .sudo() - .create( - { - "subject": subject, - "body_html": body, - "email_from": folio.pms_property_id.partner_id.email, - "email_to": folio.email, - } - ) - ) - invitation_mail.send() - for reservation in folio.reservation_ids: - reservation.is_mail_send = True + ) + mail.send() + for reservation in folio.reservation_ids: + reservation.is_mail_send = True @api.model def send_modification_mail(self): - folios = self.env["pms.folio"].search([]) - if folios and all( - is_modified_auto_mail - for is_modified_auto_mail in folios.pms_property_id.mapped( - "is_modified_auto_mail" - ) - ): - for folio in folios: - if ( - folio.state in ("confirm", "onboard") - and any( - not mail_send - for mail_send in folio.reservation_ids.mapped("is_mail_send") + folios = self.env["pms.folio"].search( + [ + ("pms_property_id.is_modified_auto_mail", "=", True), + ("reservation_ids.is_mail_send", "=", False), + ("reservation_ids.is_modified_reservation", "=", True), + ] + ) + for folio in folios: + if folio.email: + template = folio.pms_property_id.property_modified_template + subject = template._render_field( + "subject", + [6, 0, folio.id], + compute_lang=True, + post_process=True, + )[folio.id] + body = template._render_field( + "body_html", + [6, 0, folio.id], + compute_lang=True, + post_process=True, + )[folio.id] + mail = ( + folio.env["mail.mail"] + .sudo() + .create( + { + "subject": subject, + "body_html": body, + "email_from": folio.pms_property_id.partner_id.email, + "email_to": folio.email, + } ) - and any( - is_modified_reservation - for is_modified_reservation in folio.reservation_ids.mapped( - "is_modified_reservation" - ) - ) - ): - template = folio.pms_property_id.property_modified_template - subject = template._render_field( - "subject", - [6, 0, folio.id], - compute_lang=True, - post_process=True, - )[folio.id] - body = template._render_field( - "body_html", - [6, 0, folio.id], - compute_lang=True, - post_process=True, - )[folio.id] - invitation_mail = ( - folio.env["mail.mail"] - .sudo() - .create( - { - "subject": subject, - "body_html": body, - "email_from": folio.pms_property_id.partner_id.email, - "email_to": folio.email, - } - ) - ) - invitation_mail.send() - for reservation in folio.reservation_ids: - reservation.is_mail_send = True + ) + mail.send() + for reservation in folio.reservation_ids: + reservation.is_mail_send = True @api.model def send_cancelation_mail(self): - folios = self.env["pms.folio"].search([]) - if folios and all( - is_canceled_auto_mail - for is_canceled_auto_mail in folios.pms_property_id.mapped( - "is_canceled_auto_mail" - ) - ): - for folio in folios: - reservations = folio.reservation_ids.filtered( - lambda r: r.state in "cancel" - ) - for reservation in reservations: - if not reservation.is_mail_send: + folios = self.env["pms.folio"].search( + [("pms_property_id.is_canceled_auto_mail", "=", True)] + ) + for folio in folios: + reservations = folio.reservation_ids.filtered(lambda r: r.state in "cancel") + for reservation in reservations: + if folio.email: + if ( + not reservation.is_mail_send + and reservation.email + and reservation.state not in "out" + ): template = ( reservation.pms_property_id.property_canceled_template ) @@ -1420,7 +1407,7 @@ class PmsFolio(models.Model): compute_lang=True, post_process=True, )[reservation.id] - invitation_mail = ( + mail = ( folio.env["mail.mail"] .sudo() .create( @@ -1428,13 +1415,12 @@ class PmsFolio(models.Model): "subject": subject, "body_html": body, "email_from": folio.pms_property_id.partner_id.email, - "email_to": folio.email, + "email_to": reservation.email, } ) ) - invitation_mail.send() - for reservation in folio.reservation_ids: - reservation.is_mail_send = True + mail.send() + reservation.is_mail_send = True def action_view_invoice(self): invoices = self.mapped("move_ids") From dea8670fd828df0401c67a72a7066304f816b4cc Mon Sep 17 00:00:00 2001 From: braisab Date: Fri, 3 Dec 2021 02:26:51 +0100 Subject: [PATCH 2/4] [REF]pms: refactoring not send mail to out, not mail reservations && added logging if has email delivery --- pms/models/pms_folio.py | 51 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 47 insertions(+), 4 deletions(-) diff --git a/pms/models/pms_folio.py b/pms/models/pms_folio.py index 48b4eb30a..9c7ec3fc7 100644 --- a/pms/models/pms_folio.py +++ b/pms/models/pms_folio.py @@ -10,6 +10,8 @@ from odoo import _, api, fields, models from odoo.exceptions import AccessError, UserError, ValidationError from odoo.tools import float_is_zero +from odoo.addons.base.models.ir_mail_server import MailDeliveryException + _logger = logging.getLogger(__name__) @@ -1303,6 +1305,7 @@ class PmsFolio(models.Model): today = fields.Date.today() folios = self.env["pms.folio"].search( [ + ("reservation_type", "!=", "out"), ("pms_property_id.is_confirmed_auto_mail", "=", True), ("reservation_ids.is_mail_send", "=", False), ("reservation_ids.is_modified_reservation", "=", False), @@ -1334,7 +1337,20 @@ class PmsFolio(models.Model): } ) ) - mail.send() + try: + mail.send() + except MailDeliveryException: + self.env["ir.logging"].create( + { + "name": "Failed to send confirmation email to " + + folio.email, + "type": "server", + "path": "pms/pms/models/pms_folio.py", + "line": "1339", + "func": "send_confirmation_email", + "message": "Confirmation Mail Delivery Failed", + } + ) for reservation in folio.reservation_ids: reservation.is_mail_send = True @@ -1342,6 +1358,7 @@ class PmsFolio(models.Model): def send_modification_mail(self): folios = self.env["pms.folio"].search( [ + ("reservation_type", "!=", "out"), ("pms_property_id.is_modified_auto_mail", "=", True), ("reservation_ids.is_mail_send", "=", False), ("reservation_ids.is_modified_reservation", "=", True), @@ -1374,7 +1391,20 @@ class PmsFolio(models.Model): } ) ) - mail.send() + try: + mail.send() + except MailDeliveryException: + self.env["ir.logging"].create( + { + "name": "Failed to send modification email to " + + folio.email, + "type": "server", + "path": "pms/pms/models/pms_folio.py", + "line": "1391", + "func": "send_modification_email", + "message": "Modification Mail Delivery Failed", + } + ) for reservation in folio.reservation_ids: reservation.is_mail_send = True @@ -1386,7 +1416,7 @@ class PmsFolio(models.Model): for folio in folios: reservations = folio.reservation_ids.filtered(lambda r: r.state in "cancel") for reservation in reservations: - if folio.email: + if reservation.email: if ( not reservation.is_mail_send and reservation.email @@ -1419,7 +1449,20 @@ class PmsFolio(models.Model): } ) ) - mail.send() + try: + mail.send() + except MailDeliveryException: + self.env["ir.logging"].create( + { + "name": "Failed to send cancellation email to " + + reservation.email, + "type": "server", + "path": "pms/pms/models/pms_folio.py", + "line": "1450", + "func": "send_cancelation_email", + "message": "Cancellation Mail Delivery Failed", + } + ) reservation.is_mail_send = True def action_view_invoice(self): From 5cd69c498c1c38ce9b2eaf32c1f0d5711bc0a0aa Mon Sep 17 00:00:00 2001 From: braisab Date: Fri, 10 Dec 2021 21:06:02 +0100 Subject: [PATCH 3/4] [REF] changed field is_mail_send to to_send_mail --- pms/migrations/14.0.2.22.1/post-migrate.py | 2 ++ pms/models/mail_compose_message.py | 15 +------------ pms/models/pms_folio.py | 25 ++++++++-------------- pms/models/pms_reservation.py | 14 ++++++------ pms/tests/test_pms_reservation.py | 4 ++-- pms/views/pms_reservation_views.xml | 8 +++---- 6 files changed, 25 insertions(+), 43 deletions(-) create mode 100644 pms/migrations/14.0.2.22.1/post-migrate.py diff --git a/pms/migrations/14.0.2.22.1/post-migrate.py b/pms/migrations/14.0.2.22.1/post-migrate.py new file mode 100644 index 000000000..73a658c1e --- /dev/null +++ b/pms/migrations/14.0.2.22.1/post-migrate.py @@ -0,0 +1,2 @@ +def migrate(cr, version): + cr.execute("UPDATE pms_reservation SET to_send_mail = NOT is_mail_send") diff --git a/pms/models/mail_compose_message.py b/pms/models/mail_compose_message.py index 0e74c8757..3f2070e04 100644 --- a/pms/models/mail_compose_message.py +++ b/pms/models/mail_compose_message.py @@ -21,19 +21,6 @@ class MailComposeMessage(models.TransientModel): return res def send_mail(self, auto_commit=False): - # if ( - # self._context.get("default_model") == "pms.folio" - # and self._context.get("default_res_id") - # and self._context.get("mark_so_as_sent") - # ): - # # TODO: WorkFlow Mails - # folio = self.env["pms.folio"].browse([self._context["default_res_id"]]) - # if folio: - # cmds = [ - # (1, lid, {"to_send": False}) for lid in folio.reservation_ids.ids - # ] - # if any(cmds): - # folio.reservation_ids = cmds res = super(MailComposeMessage, self).send_mail(auto_commit=auto_commit) if self._context.get("record_id"): folio = self.env["pms.folio"].search( @@ -41,5 +28,5 @@ class MailComposeMessage(models.TransientModel): ) reservations = folio.reservation_ids for reservation in reservations: - reservation.is_mail_send = True + reservation.to_send_mail = False return res diff --git a/pms/models/pms_folio.py b/pms/models/pms_folio.py index 9c7ec3fc7..07b7b4c9f 100644 --- a/pms/models/pms_folio.py +++ b/pms/models/pms_folio.py @@ -516,13 +516,6 @@ class PmsFolio(models.Model): compute="_compute_last_checkout", ) - date_creation = fields.Date( - string="Creation Date", - readonly=False, - store=True, - compute="_compute_date_creation", - ) - def name_get(self): result = [] for folio in self: @@ -1302,18 +1295,17 @@ class PmsFolio(models.Model): @api.model def send_confirmation_mail(self): - today = fields.Date.today() folios = self.env["pms.folio"].search( [ ("reservation_type", "!=", "out"), ("pms_property_id.is_confirmed_auto_mail", "=", True), - ("reservation_ids.is_mail_send", "=", False), + ("reservation_ids.to_send_mail", "=", True), ("reservation_ids.is_modified_reservation", "=", False), - ("date_creation", "=", today), + ("reservation_ids.state", "!=", "cancel"), ] ) for folio in folios: - if folio.email: + if folio.email and folio.create_date.date() == fields.Date.today(): template = folio.pms_property_id.property_confirmed_template subject = template._render_field( "subject", @@ -1352,7 +1344,7 @@ class PmsFolio(models.Model): } ) for reservation in folio.reservation_ids: - reservation.is_mail_send = True + reservation.to_send_mail = False @api.model def send_modification_mail(self): @@ -1360,8 +1352,9 @@ class PmsFolio(models.Model): [ ("reservation_type", "!=", "out"), ("pms_property_id.is_modified_auto_mail", "=", True), - ("reservation_ids.is_mail_send", "=", False), + ("reservation_ids.to_send_mail", "=", True), ("reservation_ids.is_modified_reservation", "=", True), + ("reservation_ids.state", "!=", "cancel"), ] ) for folio in folios: @@ -1406,7 +1399,7 @@ class PmsFolio(models.Model): } ) for reservation in folio.reservation_ids: - reservation.is_mail_send = True + reservation.to_send_mail = False @api.model def send_cancelation_mail(self): @@ -1418,7 +1411,7 @@ class PmsFolio(models.Model): for reservation in reservations: if reservation.email: if ( - not reservation.is_mail_send + not reservation.to_send_mail and reservation.email and reservation.state not in "out" ): @@ -1463,7 +1456,7 @@ class PmsFolio(models.Model): "message": "Cancellation Mail Delivery Failed", } ) - reservation.is_mail_send = True + reservation.to_send_mail = False def action_view_invoice(self): invoices = self.mapped("move_ids") diff --git a/pms/models/pms_reservation.py b/pms/models/pms_reservation.py index 388e9a529..57ebca0a1 100644 --- a/pms/models/pms_reservation.py +++ b/pms/models/pms_reservation.py @@ -643,7 +643,7 @@ class PmsReservation(models.Model): comodel_name="res.partner", inverse_name="reservation_possible_customer_id", ) - is_mail_send = fields.Boolean(string="Mail Sent", default=False) + to_send_mail = fields.Boolean(string="Mail Sent", default=True) is_modified_reservation = fields.Boolean( string="Is A Modified Reservation", @@ -1470,9 +1470,9 @@ class PmsReservation(models.Model): for record in self: if record.state in "draft": record.is_modified_reservation = False - elif record.state in ("confirm", "onboard") and record.is_mail_send: + elif record.state in ("confirm", "onboard") and not record.to_send_mail: record.is_modified_reservation = True - record.is_mail_send = False + record.to_send_mail = True else: record.is_modified_reservation = False @@ -1730,20 +1730,20 @@ class PmsReservation(models.Model): template = False pms_property = self.pms_property_id if ( - not self.is_mail_send + self.to_send_mail and not self.is_modified_reservation and self.state not in "cancel" ): if pms_property.property_confirmed_template: template = pms_property.property_confirmed_template elif ( - not self.is_mail_send + self.to_send_mail and self.is_modified_reservation and self.state not in "cancel" ): if pms_property.property_modified_template: template = pms_property.property_modified_template - elif not self.is_mail_send and self.state in "cancel": + elif self.to_send_mail and self.state in "cancel": if pms_property.property_canceled_template: template = pms_property.property_canceled_template compose_form = self.env.ref( @@ -1931,7 +1931,7 @@ class PmsReservation(models.Model): else: record.state = "cancel" record.folio_id._compute_amount() - record.is_mail_send = False + record.to_send_mail = True def action_assign(self): for record in self: diff --git a/pms/tests/test_pms_reservation.py b/pms/tests/test_pms_reservation.py index 939df2aae..7cee7e2cf 100644 --- a/pms/tests/test_pms_reservation.py +++ b/pms/tests/test_pms_reservation.py @@ -3462,7 +3462,7 @@ class TestPmsReservations(TestPms): ---------------------- A reservation is created. The checkin and checkout fields of the reservation are modified. The state of the boolean - is_mail_send is changed to True so that the compute of + to_send_mail is changed to False so that the compute of the is_modified_reservation field is activated correctly and it is verified that the state of this field is True. """ @@ -3482,7 +3482,7 @@ class TestPmsReservations(TestPms): # ACT writed_checkin = fields.date.today() + datetime.timedelta(days=4) writed_checkout = fields.date.today() + datetime.timedelta(days=6) - reservation.is_mail_send = True + reservation.to_send_mail = False reservation.update( { "checkin": writed_checkin, diff --git a/pms/views/pms_reservation_views.xml b/pms/views/pms_reservation_views.xml index 53216b050..3aa79c172 100644 --- a/pms/views/pms_reservation_views.xml +++ b/pms/views/pms_reservation_views.xml @@ -47,22 +47,22 @@ name="action_open_mail_composer" string="Send Confirmation Email " type="object" - attrs="{'invisible':['|','|',('is_mail_send', '=', True),('is_modified_reservation', '=', True),('state', 'in', 'cancel')]}" + attrs="{'invisible':['|','|',('to_send_mail', '=', False),('is_modified_reservation', '=', True),('state', 'in', 'cancel')]}" />