[IMP]pms: refactor workflow mails

This commit is contained in:
Darío Lodeiros
2022-09-06 11:07:58 +02:00
parent d9adc1258f
commit 10eb95def7
16 changed files with 297 additions and 682 deletions

View File

@@ -16,21 +16,5 @@ class MailComposeMessage(models.TransientModel):
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
reservation.to_send_confirmation_mail = False
return res

View File

@@ -1,388 +1,9 @@
from odoo import _, api, fields, models
from odoo.exceptions import UserError
from odoo import fields, models
class PmsAutomatedMails(models.Model):
_name = "pms.automated.mails"
_description = "Automatic Mails"
# TODO: Model to delete
name = fields.Char(string="Name", help="Name of the automated mail.", required=True)
pms_property_ids = fields.Many2many(
string="Property",
help="Properties with access to the element;"
" if not set, all properties can access",
comodel_name="pms.property",
)
automated_actions_id = fields.Many2one(
string="Automated Actions",
help="automated action that is created when creating automated emails ",
comodel_name="base.automation",
)
time = fields.Integer(string="Time", help="Amount of time")
time_type = fields.Selection(
string="Time Range",
help="Type of date range",
selection=[
("minutes", "Minutes"),
("hour", "Hour"),
("day", "Days"),
("month", "Months"),
],
default="day",
)
template_id = fields.Many2one(
string="Template",
help="The template that will be sent by email",
comodel_name="mail.template",
required=True,
)
action = fields.Selection(
string="Action",
help="The action that will cause the email to be sent ",
selection=[
("creation", "Reservation creation"),
("write", "Reservation modification"),
("cancel", "Reservation cancellation"),
("checkin", "Checkin"),
("checkout", "Checkout"),
("payment", "Payment"),
("invoice", "Invoice"),
],
default="creation",
required=True,
)
moment = fields.Selection(
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"),
],
default="in_act",
)
active = fields.Boolean(
string="Active", help="Indicates if the automated mail is active", default=True
)
@api.model
def create(self, vals):
name = vals.get("name")
action = vals.get("action")
time = vals.get("time")
date_range_type = vals.get("time_type")
template_id = vals.get("template_id")
active = vals.get("active")
moment = vals.get("moment")
properties = vals.get("pms_property_ids")
is_create = True
if action in ("creation", "write", "cancel", "invoice") and moment == "before":
raise UserError(_("The moment for this action cannot be 'Before'"))
dict_val = self._prepare_automated_actions_id(
action, time, moment, properties, is_create
)
action_server_vals = {
"name": name,
"state": "email",
"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,
"action_server_id": action_server.id,
"trigger": dict_val["trigger"],
"filter_domain": dict_val["filter_domain"],
"filter_pre_domain": dict_val["filter_pre_domain"],
"trg_date_range": dict_val["time"],
"trg_date_range_type": date_range_type,
"template_id": template_id,
}
model_field = dict_val["model_field"]
if model_field:
automated_actions_vals.update(
{
"trg_date_id": dict_val["model_field"].id,
}
)
trigger_field = dict_val["trigger_fields"]
if trigger_field:
automated_actions_vals.update(
{
"trigger_field_ids": dict_val["trigger_fields"].ids,
}
)
automated_action = self.env["base.automation"].create(automated_actions_vals)
vals.update({"automated_actions_id": automated_action.id})
return super(PmsAutomatedMails, self).create(vals)
def write(self, vals):
result = super(PmsAutomatedMails, self).write(vals)
is_create = False
if (
self.action in ("creation", "write", "cancel", "invoice", "checkout")
and self.moment == "before"
):
raise UserError(_("The moment for this action cannot be 'Before'"))
dict_val = self._prepare_automated_actions_id(
self.action, self.time, self.moment, self.pms_property_ids, is_create
)
automated_actions_id = self.automated_actions_id
action_server = automated_actions_id.action_server_id
action_server_vals = {
"name": self.name,
"state": "email",
"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,
"action_server_id": action_server.id,
"trigger": dict_val["trigger"],
"filter_domain": dict_val["filter_domain"],
"filter_pre_domain": dict_val["filter_pre_domain"],
"trg_date_range": dict_val["time"],
"trg_date_range_type": self.time_type,
"template_id": self.template_id,
}
model_field = dict_val["model_field"]
if model_field:
automated_actions_vals.update(
{
"trg_date_id": dict_val["model_field"].id,
}
)
trigger_field = dict_val["trigger_fields"]
if trigger_field:
automated_actions_vals.update(
{
"trigger_field_ids": dict_val["trigger_fields"].ids,
}
)
automated_actions_id.write(automated_actions_vals)
vals.update({"automated_actions_id": automated_actions_id.id})
return result
def unlink(self):
automated_actions_id = self.automated_actions_id
action_server = automated_actions_id.action_server_id
automated_actions_id.unlink()
action_server.unlink()
return super(PmsAutomatedMails, self).unlink()
@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.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.folio"), ("name", "=", "create_date")]
)
result = {
"model_id": model_id,
"trigger": trigger,
"model_field": model_field,
"time": time,
}
return result
@api.model
def _get_auto_action_fields_in_write_or_cancel_action(self, moment, time):
model_field = False
model_id = self.env["ir.model"].search([("model", "=", "pms.reservation")]).id
if moment == "in_act":
trigger = "on_write"
time = 0
else:
trigger = "on_time"
model_field = self.env["ir.model.fields"].search(
[("model", "=", "pms.reservation"), ("name", "=", "write_date")]
)
result = {
"model_id": model_id,
"trigger": trigger,
"model_field": model_field,
"time": time,
}
return result
@api.model
def _get_auto_action_fields_in_checkin_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", "=", "checkin")]
)
if moment == "before":
time = time * (-1)
if moment == "in_act":
trigger = "on_write"
time = 0
result = {
"model_id": model_id,
"trigger": trigger,
"model_field": model_field,
"time": time,
}
return result
@api.model
def _get_auto_action_fields_in_checkout_action(self, moment, time):
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 == "in_act":
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,
"model_field": model_field,
"time": time,
}
return result
@api.model
def _get_auto_action_fields_in_payment_action(self, moment, time):
model_field = False
model_id = (
self.env["ir.model"]
.search([("model", "=", "account.payment"), ("transient", "=", False)])
.id
)
if moment == "in_act":
trigger = "on_create"
time = 0
else:
trigger = "on_time"
model_field = self.env["ir.model.fields"].search(
[("model", "=", "account.payment"), ("name", "=", "date")]
)
if moment == "before":
time = time * (-1)
result = {
"model_id": model_id,
"trigger": trigger,
"model_field": model_field,
"time": time,
}
return result
@api.model
def _get_auto_action_fields_in_invoice_action(self, moment, time):
trigger = False
model_id = self.env["ir.model"].search([("model", "=", "account.move")]).id
if moment == "in_act":
trigger = "on_create"
time = 0
result = {
"model_id": model_id,
"time": time,
"trigger": trigger,
"model_field": False,
}
return result
def _prepare_automated_actions_id(
self, action, time, moment, properties, is_create
):
filter_domain = []
filter_pre_domain = []
trigger_fields = False
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", "=", "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":
trigger_fields = self.env["ir.model.fields"].search(
[("model", "=", "pms.reservation"), ("name", "=", "state")]
)
filter_pre_domain = [("state", "=", "confirm")]
filter_domain = [
("state", "=", "onboard"),
]
elif action == "checkout":
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.checkin.partner"), ("name", "=", "state")]
)
filter_pre_domain = [("state", "=", "onboard")]
filter_domain = [
("state", "=", "done"),
]
else:
filter_domain = [
("state", "=", "done"),
]
elif action == "payment":
dict_val = self._get_auto_action_fields_in_payment_action(moment, time)
elif action == "invoice":
dict_val = self._get_auto_action_fields_in_invoice_action(moment, time)
filter_domain = [
("folio_ids", "!=", False),
]
pms_property_ids = self._get_pms_property_ids(properties, is_create)
if pms_property_ids:
filter_domain.append(("pms_property_id", "in", pms_property_ids))
result = {
"trigger": dict_val["trigger"],
"model_field": dict_val["model_field"],
"trigger_fields": trigger_fields,
"filter_pre_domain": filter_pre_domain,
"filter_domain": filter_domain,
"time": dict_val["time"],
"model_id": dict_val["model_id"],
}
return result
def _get_pms_property_ids(self, properties, is_create):
pms_property_ids = []
if is_create:
pms_property_ids = properties[0][2]
else:
for pms_property in properties:
pms_property_ids.append(pms_property.id)
return pms_property_ids

View File

@@ -540,27 +540,38 @@ class PmsFolio(models.Model):
compute="_compute_document_id",
ondelete="restrict",
)
possible_existing_customer_ids = fields.One2many(
string="Possible existing customer",
compute="_compute_possible_existing_customer_ids",
comodel_name="res.partner",
inverse_name="folio_possible_customer_id",
)
first_checkin = fields.Date(
string="First Folio Checkin",
readonly=False,
store=True,
compute="_compute_first_checkin",
)
days_to_checkin = fields.Integer(
string="Days to Checkin",
help="""Technical field to facilitate
filtering by dates related to checkin""",
compute="_compute_days_to_checkin",
search="_search_days_to_checkin",
)
last_checkout = fields.Date(
string="Last Folio Checkout",
readonly=False,
store=True,
compute="_compute_last_checkout",
)
days_to_checkout = fields.Integer(
string="Days to Checkout",
help="""Technical field to facilitate
filtering by dates related to checkout""",
compute="_compute_days_to_checkout",
search="_search_days_to_checkout",
)
autoinvoice_date = fields.Date(
string="Autoinvoice Date",
compute="_compute_autoinvoice_date",
@@ -1411,6 +1422,18 @@ class PmsFolio(models.Model):
checkins = record.reservation_ids.mapped("checkin")
record.first_checkin = min(checkins)
def _compute_days_to_checkin(self):
for record in self:
record.days_to_checkin = (record.first_checkin - fields.Date.today()).days
def _search_days_to_checkin(self, operator, value):
target_date = fields.Date.today() + timedelta(days=value)
if operator in ("=", ">=", ">", "<=", "<"):
return [("first_checkin", operator, target_date)]
raise UserError(
_("Unsupported operator %s for searching on date") % (operator,)
)
@api.depends("reservation_ids", "reservation_ids.checkout")
def _compute_last_checkout(self):
for record in self:
@@ -1418,6 +1441,18 @@ class PmsFolio(models.Model):
checkouts = record.reservation_ids.mapped("checkout")
record.last_checkout = max(checkouts)
def _compute_days_to_checkout(self):
for record in self:
record.days_to_checkout = (record.last_checkout - fields.Date.today()).days
def _search_days_to_checkout(self, operator, value):
target_date = fields.Date.today() + timedelta(days=value)
if operator in ("=", ">=", ">", "<=", "<"):
return [("last_checkout", operator, target_date)]
raise UserError(
_("Unsupported operator %s for searching on date") % (operator,)
)
@api.depends("agency_id")
def _compute_invoice_to_agengy(self):
for record in self:
@@ -1597,94 +1632,26 @@ class PmsFolio(models.Model):
return True
# CHECKIN/OUT PROCESS
# MAIL FLOWS
def action_open_mail_composer(self):
def action_open_confirmation_mail_composer(self):
self.ensure_one()
res_id = False
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 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"
)
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 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 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
)
)
model = "pms.folio"
partner_ids = [self.partner_id.id]
res_id = self.id
composition_mode = "comment"
ctx = dict(
model=model,
default_model=model,
@@ -1693,6 +1660,103 @@ class PmsFolio(models.Model):
partner_ids=partner_ids,
force_email=True,
)
return self.action_open_mail_composer(ctx, res_id=res_id, res_ids=res_ids)
def action_open_modification_mail_composer(self):
self.ensure_one()
res_id = False
res_ids = []
partner_ids = []
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"
ctx = dict(
model=model,
default_model=model,
default_template_id=template and template.id or False,
default_composition_mode=composition_mode,
partner_ids=partner_ids,
force_email=True,
)
return self.action_open_mail_composer(ctx, res_id=res_id, res_ids=res_ids)
def action_open_exit_mail_composer(self):
self.ensure_one()
res_id = False
res_ids = []
partner_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":
partner_ids.append(checkin_partner.partner_id.id)
res_ids.append(checkin_partner.id)
ctx = dict(
model=model,
default_model=model,
default_template_id=template and template.id or False,
default_composition_mode=composition_mode,
partner_ids=partner_ids,
force_email=True,
)
return self.action_open_mail_composer(ctx, res_id=res_id, res_ids=res_ids)
def action_open_cancelation_mail_composer(self):
self.ensure_one()
res_id = False
res_ids = []
partner_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 == "cancel":
partner_ids.append(reservation.partner_id.id)
res_ids.append(reservation.id)
ctx = dict(
model=model,
default_model=model,
default_template_id=template and template.id or False,
default_composition_mode=composition_mode,
partner_ids=partner_ids,
force_email=True,
)
return self.action_open_mail_composer(ctx, res_id=res_id, res_ids=res_ids)
def action_open_mail_composer(self, ctx, res_id=False, res_ids=False):
compose_form = self.env.ref(
"mail.email_compose_message_wizard_form", raise_if_not_found=False
)
composition_mode = ctx.get("default_composition_mode")
if composition_mode == "comment":
ctx.update(
default_res_id=res_id,

View File

@@ -195,7 +195,6 @@ class PmsProperty(models.Model):
copy=False,
comodel_name="res.users",
ondelete="restrict",
tracking=True,
)
member_ids = fields.One2many(
string="Team Members",

View File

@@ -303,7 +303,7 @@ class PmsReservation(models.Model):
tax_ids = fields.Many2many(
string="Taxes",
help="Taxes applied in the reservation",
readonly="False",
readonly=False,
store=True,
compute="_compute_tax_ids",
comodel_name="account.tax",
@@ -656,20 +656,43 @@ class PmsReservation(models.Model):
comodel_name="res.partner",
inverse_name="reservation_possible_customer_id",
)
to_send_mail = fields.Boolean(
string="To Send Mail",
compute="_compute_to_send_mail",
avoid_mails = fields.Boolean(
string="Avoid comunication mails",
help="Field to indicate not sent mail comunications",
compute="_compute_avoid_mails",
readonly=False,
store=True,
default=False,
)
is_modified_reservation = fields.Boolean(
string="Is A Modified Reservation",
compute="_compute_is_modified_reservation",
to_send_confirmation_mail = fields.Boolean(
string="To Send Confirmation Mail",
compute="_compute_to_send_confirmation_mail",
readonly=False,
store=True,
)
to_send_modification_mail = fields.Boolean(
string="To Send Modification Mail",
compute="_compute_to_send_modification_mail",
readonly=False,
store=True,
)
to_send_exit_mail = fields.Boolean(
string="To Send Exit Mail",
compute="_compute_to_send_exit_mail",
readonly=False,
store=True,
)
to_send_cancelation_mail = fields.Boolean(
string="To Send Cancelation Mail",
compute="_compute_to_send_cancelation_mail",
readonly=False,
store=True,
)
overnight_room = fields.Boolean(
related="room_type_id.overnight_room",
store=True,
@@ -1529,20 +1552,53 @@ class PmsReservation(models.Model):
else:
record.possible_existing_customer_ids = False
@api.depends("checkin", "checkout")
def _compute_is_modified_reservation(self):
@api.depends("reservation_type")
def _compute_avoid_mails(self):
for record in self:
if record.state in "draft":
record.is_modified_reservation = False
elif (
record._origin.checkin != record.checkin
or record._origin.checkout != record.checkout
) and not record.to_send_mail:
record.is_modified_reservation = True
for reservations in record.folio_id.reservation_ids:
reservations.to_send_mail = True
if record.reservation_type == "out":
record.avoid_mails = True
elif not record.avoid_mails:
record.avoid_mails = False
@api.depends("reservation_type", "state")
def _compute_to_send_confirmation_mail(self):
for record in self:
if record.state in ("confirm") and not record.avoid_mails:
record.to_send_confirmation_mail = True
else:
record.is_modified_reservation = False
record.to_send_confirmation_mail = False
@api.depends("checkin", "checkout")
def _compute_to_send_modification_mail(self):
for record in self:
if (
record.state == "confirm"
and not record.to_send_confirmation_mail
and not record.avoid_mails
and (
record._origin.checkin != record.checkin
or record._origin.checkout != record.checkout
)
):
record.to_send_modification_mail = True
else:
record.to_send_modification_mail = False
@api.depends("reservation_type", "state")
def _compute_to_send_exit_mail(self):
for record in self:
if record.state in ("done") and not record.avoid_mails:
record.to_send_exit_mail = True
else:
record.to_send_exit_mail = False
@api.depends("reservation_type", "state")
def _compute_to_send_cancelation_mail(self):
for record in self:
if record.state in ("cancel") and not record.avoid_mails:
record.to_send_cancelation_mail = True
else:
record.to_send_cancelation_mail = False
@api.depends("partner_id")
def _compute_lang(self):
@@ -1552,14 +1608,6 @@ class PmsReservation(models.Model):
else:
record.lang = self.env["res.lang"].get_installed()
@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
def _search_allowed_checkin(self, operator, value):
if operator not in ("=",):
raise UserError(
@@ -1832,8 +1880,17 @@ class PmsReservation(models.Model):
},
}
def action_open_mail_composer(self):
return self.folio_id.action_open_mail_composer()
def action_open_confirmation_mail_composer(self):
return self.folio_id.action_open_confirmation_mail_composer()
def action_open_modification_mail_composer(self):
return self.folio_id.action_open_modification_mail_composer()
def action_open_exit_mail_composer(self):
return self.folio_id.action_open_exit_mail_composer()
def action_open_cancelation_mail_composer(self):
return self.folio_id.action_open_cancelation_mail_composer()
def open_wizard_several_partners(self):
ctx = dict(

View File

@@ -1,13 +1,11 @@
# Copyright 2017 Alexandre Díaz
# Copyright 2017 Dario Lodeiros
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import logging
from datetime import timedelta
from odoo import _, api, fields, models
_logger = logging.getLogger(__name__)
class PmsService(models.Model):
_name = "pms.service"
@@ -298,8 +296,7 @@ class PmsService(models.Model):
service.name = name
@api.depends(
"reservation_id.checkin",
"reservation_id.checkout",
"reservation_id.reservation_line_ids",
"product_id",
"reservation_id.adults",
)

View File

@@ -2,10 +2,13 @@
# Copyright 2017 Dario Lodeiros
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import datetime
import logging
from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
_logger = logging.getLogger(__name__)
class PmsServiceLine(models.Model):
_name = "pms.service.line"