Merge PR #135 into 14.0

Signed-off-by DarioLodeiros
This commit is contained in:
OCA-git-bot
2022-08-16 08:52:23 +00:00
16 changed files with 415 additions and 243 deletions

View File

@@ -47,3 +47,4 @@ from . import res_partner_id_number
from . import pms_automated_mails
from . import payment_transaction
from . import res_partner_id_category
from . import pms_team

View File

@@ -9,11 +9,28 @@ class MailComposeMessage(models.TransientModel):
def send_mail(self, auto_commit=False):
res = super(MailComposeMessage, self).send_mail(auto_commit=auto_commit)
if self._context.get("record_id"):
folio = self.env["pms.folio"].search(
[("id", "=", self._context.get("record_id"))]
)
if (
self._context.get("default_model") == "pms.folio"
and self._context.get("active_model") == "pms.reservation"
):
folio = self.env["pms.folio"].browse(self._context.get("default_res_id"))
reservations = folio.reservation_ids
for reservation in reservations:
reservation.to_send_mail = False
elif (
self._context.get("default_model") == "pms.reservation"
or self._context.get("default_model") == "pms.checkin.partner"
) and self._context.get("active_model") == "pms.reservation":
reservation = self.env["pms.reservation"].browse(
self._context.get("active_id")
)
reservation.to_send_mail = False
elif (
self._context.get("default_model") == "pms.checkin.partner"
and self._context.get("active_model") == "pms.reservation"
):
reservation = self.env["pms.reservation"].search(
self._context.get("default_res_id")
)
reservation.to_send_mail = False
return res

View File

@@ -61,11 +61,11 @@ class PmsAutomatedMails(models.Model):
string="Moment",
help="Moment in relation to the action in which the email will be sent",
selection=[
("in_act", "In the act"),
("before", "Before"),
("after", "After"),
("in_act", "In the act"),
],
default="before",
default="in_act",
)
active = fields.Boolean(
@@ -94,6 +94,9 @@ class PmsAutomatedMails(models.Model):
"usage": "ir_cron",
"model_id": dict_val["model_id"],
}
if action == "checkout":
code = "record.send_exit_email(" + str(template_id) + ")"
action_server_vals.update({"state": "code", "code": code})
action_server = self.env["ir.actions.server"].create(action_server_vals)
automated_actions_vals = {
"active": active,
@@ -127,7 +130,7 @@ class PmsAutomatedMails(models.Model):
result = super(PmsAutomatedMails, self).write(vals)
is_create = False
if (
self.action in ("creation", "write", "cancel", "invoice")
self.action in ("creation", "write", "cancel", "invoice", "checkout")
and self.moment == "before"
):
raise UserError(_("The moment for this action cannot be 'Before'"))
@@ -142,6 +145,9 @@ class PmsAutomatedMails(models.Model):
"usage": "ir_cron",
"model_id": dict_val["model_id"],
}
if vals.get("action") == "checkout":
code = "record.send_exit_email(" + str(self.template_id) + ")"
action_server_vals.update({"state": "code", "code": code})
action_server.write(action_server_vals)
automated_actions_vals = {
"active": self.active,
@@ -181,14 +187,14 @@ class PmsAutomatedMails(models.Model):
@api.model
def _get_auto_action_fields_in_creation_action(self, moment, time):
model_field = False
model_id = self.env["ir.model"].search([("model", "=", "pms.reservation")]).id
model_id = self.env["ir.model"].search([("model", "=", "pms.folio")]).id
if moment == "in_act":
trigger = "on_create"
time = 0
else:
trigger = "on_time"
model_field = self.env["ir.model.fields"].search(
[("model", "=", "pms.reservation"), ("name", "=", "create_date")]
[("model", "=", "pms.folio"), ("name", "=", "create_date")]
)
result = {
"model_id": model_id,
@@ -240,16 +246,20 @@ class PmsAutomatedMails(models.Model):
@api.model
def _get_auto_action_fields_in_checkout_action(self, moment, time):
model_id = self.env["ir.model"].search([("model", "=", "pms.reservation")]).id
trigger = "on_time"
model_field = self.env["ir.model.fields"].search(
[("model", "=", "pms.reservation"), ("name", "=", "checkout")]
model_id = (
self.env["ir.model"].search([("model", "=", "pms.checkin.partner")]).id
)
trigger = "on_write"
model_field = self.env["ir.model.fields"].search(
[("model", "=", "pms.checkin.partner"), ("name", "=", "state")]
)
if moment == "before":
time = time * (-1)
if moment == "in_act":
trigger = "on_write"
time = 0
else:
trigger = "on_time"
model_field = self.env["ir.model.fields"].search(
[("model", "=", "pms.checkin.partner"), ("name", "=", "departure")]
)
result = {
"model_id": model_id,
"trigger": trigger,
@@ -308,14 +318,21 @@ class PmsAutomatedMails(models.Model):
dict_val = {}
if action == "creation":
dict_val = self._get_auto_action_fields_in_creation_action(moment, time)
filter_domain = [
("first_checkin", ">=", str(fields.date.today())),
("reservation_ids.to_send_mail", "=", True),
]
elif action == "write" or action == "cancel":
dict_val = self._get_auto_action_fields_in_write_or_cancel_action(
moment, time
)
if action == "cancel":
filter_domain = [
("state", "=", "cancelled"),
("state", "=", "cancel"),
]
trigger_fields = self.env["ir.model.fields"].search(
[("model", "=", "pms.reservation"), ("name", "=", "state")]
)
elif action == "checkin":
dict_val = self._get_auto_action_fields_in_checkin_action(moment, time)
if moment == "in_act":
@@ -330,11 +347,15 @@ class PmsAutomatedMails(models.Model):
dict_val = self._get_auto_action_fields_in_checkout_action(moment, time)
if moment == "in_act":
trigger_fields = self.env["ir.model.fields"].search(
[("model", "=", "pms.reservation"), ("name", "=", "state")]
[("model", "=", "pms.checkin.partner"), ("name", "=", "state")]
)
filter_pre_domain = [("state", "=", "onboard")]
filter_domain = [
("state", "=", "out"),
("state", "=", "done"),
]
else:
filter_domain = [
("state", "=", "done"),
]
elif action == "payment":
dict_val = self._get_auto_action_fields_in_payment_action(moment, time)

View File

@@ -16,7 +16,7 @@ from odoo.tools.safe_eval import safe_eval
class PmsCheckinPartner(models.Model):
_name = "pms.checkin.partner"
_description = "Partner Checkins"
_inherit = ["portal.mixin"]
_inherit = ["mail.thread", "mail.activity.mixin", "portal.mixin"]
_rec_name = "identifier"
identifier = fields.Char(
@@ -833,7 +833,7 @@ class PmsCheckinPartner(models.Model):
for record in self.filtered(lambda c: c.state == "onboard"):
vals = {
"state": "done",
"departure": record.reservation_id.checkout,
"departure": fields.Datetime.now(),
}
record.update(vals)
return True
@@ -937,3 +937,39 @@ class PmsCheckinPartner(models.Model):
)
invitation_mail.send()
def send_exit_email(self, template_id):
template = self.env["mail.template"].browse(template_id)
if self.email:
template.send_mail(
self.id,
force_send=True,
raise_exception=False,
email_values={"email_to": self.email, "auto_delete": False},
)
body = template._render_field(
"body_html", [6, 0, self.id], compute_lang=True, post_process=True
)[self.id]
self.reservation_id.message_post(body=body)
if self.reservation_id.to_send_mail:
emails = self.reservation_id.checkin_partner_ids.mapped("email")
if (
self.reservation_id.partner_id
and self.reservation_id.partner_id.email
and self.reservation_id.partner_id.email not in emails
):
template.send_mail(
self.partner_id.id,
force_send=True,
raise_exception=False,
email_values={
"email_to": self.reservation_id.email,
"auto_delete": False,
},
)
body = template._render_field(
"body_html", [6, 0, self.id], compute_lang=True, post_process=True
)[self.id]
self.reservation_id.message_post(body=body)
self.reservation_id.to_send_mail = False

View File

@@ -14,8 +14,6 @@ from odoo.exceptions import AccessError, UserError, ValidationError
from odoo.tools import float_compare, float_is_zero
from odoo.tools.misc import get_lang
from odoo.addons.base.models.ir_mail_server import MailDeliveryException
_logger = logging.getLogger(__name__)
@@ -1525,157 +1523,109 @@ class PmsFolio(models.Model):
# CHECKIN/OUT PROCESS
@api.model
def send_confirmation_mail(self):
folios = self.env["pms.folio"].search(
[
("pms_property_id.is_confirmed_auto_mail", "=", True),
("reservation_ids.to_send_mail", "=", True),
("reservation_ids.is_modified_reservation", "=", False),
("reservation_ids.state", "!=", "cancel"),
]
)
for folio in folios:
if folio.email and folio.create_date.date() == fields.Date.today():
template = folio.pms_property_id.property_confirmed_template
try:
template.send_mail(
folio.id, force_send=True, email_values={"auto_delete": False}
)
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": "1281",
"func": "send_confirmation_email",
"message": "Confirmation Mail Delivery Failed",
}
)
for reservation in folio.reservation_ids:
reservation.to_send_mail = False
@api.model
def send_modification_mail(self):
folios = self.env["pms.folio"].search(
[
("pms_property_id.is_modified_auto_mail", "=", True),
("reservation_ids.to_send_mail", "=", True),
("reservation_ids.is_modified_reservation", "=", True),
("reservation_ids.state", "!=", "cancel"),
]
)
for folio in folios:
if folio.email:
template = folio.pms_property_id.property_modified_template
try:
template.send_mail(
folio.id, force_send=True, email_values={"auto_delete": False}
)
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": "1311",
"func": "send_modification_email",
"message": "Modification Mail Delivery Failed",
}
)
for reservation in folio.reservation_ids:
reservation.to_send_mail = False
@api.model
def send_cancelation_mail(self):
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 reservation.email:
if (
not reservation.to_send_mail
and reservation.email
and reservation.state not in "out"
):
template = (
reservation.pms_property_id.property_canceled_template
)
try:
template.send_mail(
reservation.id,
force_send=True,
email_values={"auto_delete": False},
)
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": "1345",
"func": "send_cancelation_email",
"message": "Cancellation Mail Delivery Failed",
}
)
reservation.to_send_mail = False
def action_open_mail_composer(self):
self.ensure_one()
template = False
pms_property = self.pms_property_id
if (
all(reservation.to_send_mail for reservation in self.reservation_ids)
and not all(
reservation.is_modified_reservation
for reservation in self.reservation_ids
)
and all(
reservation.state not in "cancel"
for reservation in self.reservation_ids
)
res_ids = []
partner_ids = []
if all(
reservation.to_send_mail
and not reservation.is_modified_reservation
and reservation.state in "confirm"
for reservation in self.reservation_ids
):
if pms_property.property_confirmed_template:
template = pms_property.property_confirmed_template
elif (
any(reservation.to_send_mail for reservation in self.reservation_ids)
and any(
reservation.is_modified_reservation
for reservation in self.reservation_ids
)
and all(
reservation.state not in "cancel"
for reservation in self.reservation_ids
)
):
if pms_property.property_modified_template:
template = pms_property.property_modified_template
if self.pms_property_id.property_confirmed_template:
template = self.pms_property_id.property_confirmed_template
else:
raise ValidationError(
_(
"You must select a confirmation template "
"in the email configuration menu of the property"
)
)
model = "pms.folio"
partner_ids = [self.partner_id.id]
res_id = self.id
composition_mode = "comment"
elif any(
reservation.to_send_mail for reservation in self.reservation_ids
) and any(
reservation.state in "cancel" for reservation in self.reservation_ids
reservation.to_send_mail and reservation.is_modified_reservation
for reservation in self.reservation_ids
) and all(
reservation.state not in "cancel" for reservation in self.reservation_ids
):
if pms_property.property_canceled_template:
template = pms_property.property_canceled_template
if self.pms_property_id.property_modified_template:
template = self.pms_property_id.property_modified_template
else:
raise ValidationError(
_(
"You must select a modification template "
"in the email configuration menu of the property"
)
)
model = "pms.folio"
partner_ids = [self.partner_id.id]
res_id = self.id
composition_mode = "comment"
elif any(
reservation.to_send_mail and reservation.state in "cancel"
for reservation in self.reservation_ids
):
if self.pms_property_id.property_canceled_template:
template = self.pms_property_id.property_canceled_template
else:
raise ValidationError(
_(
"You must select a cancelation template "
"in the email configuration menu of the property"
)
)
model = "pms.reservation"
composition_mode = "mass_mail"
for reservation in self.reservation_ids:
if reservation.state in "cancel" and reservation.to_send_mail:
partner_ids.append(reservation.partner_id.id)
res_ids.append(reservation.id)
elif any(
reservation.to_send_mail and reservation.state in "done"
for reservation in self.reservation_ids
):
if self.pms_property_id.property_exit_template:
template = self.pms_property_id.property_exit_template
else:
raise ValidationError(
_(
"You must select a exit template in "
"the email configuration menu of the property"
)
)
model = "pms.checkin.partner"
composition_mode = "mass_mail"
for checkin_partner in self.checkin_partner_ids:
if (
checkin_partner.state == "done"
and checkin_partner.reservation_id.to_send_mail
):
partner_ids.append(checkin_partner.partner_id.id)
res_ids.append(checkin_partner.id)
compose_form = self.env.ref(
"mail.email_compose_message_wizard_form", raise_if_not_found=False
)
ctx = dict(
model="pms.folio",
default_model="pms.folio",
default_res_id=self.id,
model=model,
default_model=model,
default_template_id=template and template.id or False,
composition_mode="comment",
partner_ids=[self.partner_id.id],
default_composition_mode=composition_mode,
partner_ids=partner_ids,
force_email=True,
record_id=self.id,
)
if composition_mode == "comment":
ctx.update(
default_res_id=res_id,
record_id=res_id,
)
else:
ctx.update(
active_ids=res_ids,
)
return {
"name": _("Send Mail "),
"type": "ir.actions.act_window",

View File

@@ -126,6 +126,11 @@ class PmsProperty(models.Model):
comodel_name="mail.template",
)
property_exit_template = fields.Many2one(
string="Exit Email",
comodel_name="mail.template",
)
property_canceled_template = fields.Many2one(
string="Cancellation Email",
help="Cancellation email template",
@@ -134,6 +139,7 @@ class PmsProperty(models.Model):
is_confirmed_auto_mail = fields.Boolean(string="Auto Send Confirmation Mail")
is_modified_auto_mail = fields.Boolean(string="Auto Send Modification Mail")
is_exit_auto_mail = fields.Boolean(string="Auto Send Exit Mail")
is_canceled_auto_mail = fields.Boolean(string="Auto Send Cancellation Mail")
default_invoicing_policy = fields.Selection(

View File

@@ -655,10 +655,11 @@ class PmsReservation(models.Model):
inverse_name="reservation_possible_customer_id",
)
to_send_mail = fields.Boolean(
string="Mail Sent",
string="To Send Mail",
compute="_compute_to_send_mail",
readonly=False,
store=True,
default=False,
)
is_modified_reservation = fields.Boolean(
@@ -1515,9 +1516,13 @@ 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 not record.to_send_mail:
elif (
record._origin.checkin != record.checkin
or record._origin.checkout != record.checkout
) and not record.to_send_mail:
record.is_modified_reservation = True
record.to_send_mail = True
for reservations in record.folio_id.reservation_ids:
reservations.to_send_mail = True
else:
record.is_modified_reservation = False
@@ -1529,13 +1534,13 @@ class PmsReservation(models.Model):
else:
record.lang = self.env["res.lang"].get_installed()
@api.depends("reservation_type")
@api.depends("reservation_type", "state")
def _compute_to_send_mail(self):
for record in self:
if record.state in ("confirm", "done", "cancel"):
record.to_send_mail = True
if record.reservation_type == "out":
record.to_send_mail = False
else:
record.to_send_mail = True
def _search_allowed_checkin(self, operator, value):
if operator not in ("=",):
@@ -1996,7 +2001,6 @@ class PmsReservation(models.Model):
else:
record.state = "cancel"
record.folio_id._compute_amount()
record.to_send_mail = True
def action_assign(self):
for record in self:

15
pms/models/pms_team.py Normal file
View File

@@ -0,0 +1,15 @@
from odoo import fields, models
class PmsTeam(models.Model):
_name = "pms.team"
_inherit = ["mail.thread"]
_description = "PMS Team"
_check_pms_properties_auto = True
name = fields.Char("PMS Team", required=True)
sequence = fields.Integer("Sequence", default=10)
active = fields.Boolean(default=True)
pms_property_id = fields.Many2one("pms.property", string="Property")
user_id = fields.Many2one("res.users", string="Team Leader")
member_ids = fields.One2many("res.users", "pms_team_id", string="Channel Members")

View File

@@ -276,6 +276,8 @@ class ResPartner(models.Model):
vat_document_types.append((doc_type.name, doc_type.name))
return vat_document_types
team_id = fields.Many2one("pms.team", "PMS Team")
@api.depends("pms_checkin_partner_ids", "pms_checkin_partner_ids.gender")
def _compute_gender(self):
if hasattr(super(), "_compute_gender"):

View File

@@ -25,6 +25,8 @@ class ResUsers(models.Model):
domain="[('company_id','in',company_ids)]",
)
pms_team_id = fields.Many2one("pms.team", "User's PMS Team")
@api.model
def get_active_property_ids(self):
# TODO: Require performance test and security (dont allow any property id)