diff --git a/pms/data/cron_jobs.xml b/pms/data/cron_jobs.xml
index 2cd3c2029..ec067d944 100644
--- a/pms/data/cron_jobs.xml
+++ b/pms/data/cron_jobs.xml
@@ -61,5 +61,45 @@
/>
model.update_daily_priority_reservation()
+
+
+ Send Confirmation Email
+ 5
+
+ minutes
+
+ -1
+
+ code
+
+
+ model.send_confirmation_mail()
+
+
+ Send Modification Email
+ 5
+
+ minutes
+
+ -1
+
+ code
+
+
+ model.send_modification_mail()
+
+
+ Send Cancellation Email
+ 5
+
+
+ minutes
+ -1
+
+ code
+
+
+ model.send_cancelation_mail()
+
diff --git a/pms/models/mail_compose_message.py b/pms/models/mail_compose_message.py
index e76de0ec6..0e74c8757 100644
--- a/pms/models/mail_compose_message.py
+++ b/pms/models/mail_compose_message.py
@@ -36,8 +36,10 @@ class MailComposeMessage(models.TransientModel):
# folio.reservation_ids = cmds
res = super(MailComposeMessage, self).send_mail(auto_commit=auto_commit)
if self._context.get("record_id"):
- reservation = self.env["pms.reservation"].search(
+ folio = self.env["pms.folio"].search(
[("id", "=", self._context.get("record_id"))]
)
- reservation.is_mail_send = True
+ reservations = folio.reservation_ids
+ for reservation in reservations:
+ reservation.is_mail_send = True
return res
diff --git a/pms/models/pms_folio.py b/pms/models/pms_folio.py
index 68c8e769e..811d0bf90 100644
--- a/pms/models/pms_folio.py
+++ b/pms/models/pms_folio.py
@@ -499,6 +499,20 @@ class PmsFolio(models.Model):
inverse_name="folio_possible_customer_id",
)
+ first_checkin = fields.Date(
+ string="First Folio Checkin",
+ readonly=False,
+ store=True,
+ compute="_compute_first_checkin",
+ )
+
+ last_checkout = fields.Date(
+ string="Last Folio Checkout",
+ readonly=False,
+ store=True,
+ compute="_compute_last_checkout",
+ )
+
def name_get(self):
result = []
for folio in self:
@@ -1060,6 +1074,20 @@ class PmsFolio(models.Model):
else:
record.possible_existing_customer_ids = False
+ @api.depends("reservation_ids", "reservation_ids.checkin")
+ def _compute_first_checkin(self):
+ for record in self:
+ if record.reservation_ids:
+ checkins = record.reservation_ids.mapped("checkin")
+ record.first_checkin = min(checkins)
+
+ @api.depends("reservation_ids", "reservation_ids.checkout")
+ def _compute_last_checkout(self):
+ for record in self:
+ if record.reservation_ids:
+ checkouts = record.reservation_ids.mapped("checkout")
+ record.last_checkout = max(checkouts)
+
def _search_invoice_ids(self, operator, value):
if operator == "in" and value:
self.env.cr.execute(
@@ -1251,18 +1279,162 @@ class PmsFolio(models.Model):
if self.env.context.get("confirm_all_reservations"):
self.reservation_ids.confirm()
- # if self.env.context.get('send_email'):
- # self.force_quotation_send()
-
- # create an analytic account if at least an expense product
- # if any([expense_policy != 'no' for expense_policy in
- # self.sale_line_ids.mapped('product_id.expense_policy')]):
- # if not self.analytic_account_id:
- # self._create_analytic_account()
return True
# CHECKIN/OUT PROCESS
+ @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")
+ )
+ 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
+
+ @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")
+ )
+ 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
+
+ @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:
+ template = (
+ reservation.pms_property_id.property_canceled_template
+ )
+ subject = template._render_field(
+ "subject",
+ [6, 0, reservation.id],
+ compute_lang=True,
+ post_process=True,
+ )[reservation.id]
+ body = template._render_field(
+ "body_html",
+ [6, 0, reservation.id],
+ compute_lang=True,
+ post_process=True,
+ )[reservation.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
+
def action_view_invoice(self):
invoices = self.mapped("move_ids")
action = self.env["ir.actions.actions"]._for_xml_id(
diff --git a/pms/models/pms_property.py b/pms/models/pms_property.py
index 16d9209b2..7f2be5011 100644
--- a/pms/models/pms_property.py
+++ b/pms/models/pms_property.py
@@ -122,32 +122,27 @@ class PmsProperty(models.Model):
privacy_policy = fields.Html(string="Privacy Policy", help="Mail privacy policy ")
property_confirmed_template = fields.Many2one(
- string="Confirmation Template",
+ string="Confirmation Email",
help="Confirmation email template",
comodel_name="mail.template",
- default=lambda self: self.env["mail.template"]
- .search([("name", "=", "Confirmed Reservation")])
- .id,
)
property_modified_template = fields.Many2one(
- string="Modification Template",
+ string="Modification Email",
help="Modification email template",
comodel_name="mail.template",
- default=lambda self: self.env["mail.template"]
- .search([("name", "=", "Modified Reservation")])
- .id,
)
property_canceled_template = fields.Many2one(
- string="Cancellation Template",
+ string="Cancellation Email",
help="Cancellation email template",
comodel_name="mail.template",
- default=lambda self: self.env["mail.template"]
- .search([("name", "=", "Cancelled Reservation")])
- .id,
)
+ is_confirmed_auto_mail = fields.Boolean(string="Auto Send Confirmation Mail")
+ is_modified_auto_mail = fields.Boolean(string="Auto Send Modification Mail")
+ is_canceled_auto_mail = fields.Boolean(string="Auto Send Cancellation Mail")
+
@api.depends_context(
"checkin",
"checkout",
diff --git a/pms/models/pms_reservation.py b/pms/models/pms_reservation.py
index b4132fcfd..a215ecf82 100644
--- a/pms/models/pms_reservation.py
+++ b/pms/models/pms_reservation.py
@@ -1727,38 +1727,36 @@ class PmsReservation(models.Model):
def action_open_mail_composer(self):
self.ensure_one()
template = False
+ pms_property = self.pms_property_id
if (
not self.is_mail_send
and not self.is_modified_reservation
and self.state not in "cancel"
):
- template = self.env.ref(
- "pms.confirmed_reservation_email", raise_if_not_found=False
- )
+ if pms_property.property_confirmed_template:
+ template = pms_property.property_confirmed_template
elif (
not self.is_mail_send
and self.is_modified_reservation
and self.state not in "cancel"
):
- template = self.env.ref(
- "pms.modified_reservation_email", raise_if_not_found=False
- )
+ if pms_property.property_modified_template:
+ template = pms_property.property_modified_template
elif not self.is_mail_send and self.state in "cancel":
- template = self.env.ref(
- "pms.cancelled_reservation_email", raise_if_not_found=False
- )
+ if pms_property.property_canceled_template:
+ template = pms_property.property_canceled_template
compose_form = self.env.ref(
"mail.email_compose_message_wizard_form", raise_if_not_found=False
)
ctx = dict(
- model="pms.reservation",
- default_res_model="pms.reservation",
- default_res_id=self.id,
+ model="pms.folio",
+ default_res_model="pms.folio",
+ default_res_id=self.folio_id.id,
template_id=template and template.id or False,
composition_mode="comment",
partner_ids=[self.partner_id.id],
force_email=True,
- record_id=self.id,
+ record_id=self.folio_id.id,
)
return {
"name": _("Send Confirmed Reservation Mail "),
diff --git a/pms/views/pms_property_views.xml b/pms/views/pms_property_views.xml
index b89e4c6d0..f1ba521dc 100644
--- a/pms/views/pms_property_views.xml
+++ b/pms/views/pms_property_views.xml
@@ -86,10 +86,44 @@
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+