mirror of
https://github.com/OCA/pms.git
synced 2025-01-29 00:17:45 +02:00
415 lines
14 KiB
Python
415 lines
14 KiB
Python
from datetime import timedelta
|
|
|
|
from odoo import _, api, fields, models
|
|
from odoo.exceptions import ValidationError
|
|
|
|
|
|
class PmsHouseKeepingTask(models.Model):
|
|
_name = "pms.housekeeping.task"
|
|
|
|
name = fields.Char(string="Name", required=True)
|
|
room_id = fields.Many2one(
|
|
comodel_name="pms.room",
|
|
string="Room",
|
|
required=True,
|
|
ondelete="restrict",
|
|
)
|
|
task_type_id = fields.Many2one(
|
|
comodel_name="pms.housekeeping.task.type",
|
|
string="Task Type",
|
|
required=True,
|
|
ondelete="restrict",
|
|
)
|
|
task_date = fields.Date(
|
|
string="Date",
|
|
required=True,
|
|
)
|
|
state = fields.Selection(
|
|
selection=[
|
|
("pending", "Pending"),
|
|
("to_do", "To Do"),
|
|
("in_progress", "In Progress"),
|
|
("done", "Done"),
|
|
("cancel", "Cancel"),
|
|
],
|
|
string="State",
|
|
required=True,
|
|
default="pending",
|
|
)
|
|
priority = fields.Integer(
|
|
string="Priority",
|
|
default=0,
|
|
computed="_compute_priority",
|
|
store=True,
|
|
readonly=False,
|
|
)
|
|
cleaning_comments = fields.Text(string="Cleaning Comments")
|
|
housekeeper_ids = fields.Many2many(
|
|
comodel_name="hr.employee",
|
|
relation="pms_housekeeping_task_hr_employee_rel",
|
|
column1="task_id",
|
|
column2="employee_id",
|
|
string="Housekeepers",
|
|
domain="[('job_id.name', '=', 'Housekeeper')]",
|
|
compute="_compute_housekeeper_ids",
|
|
store=True,
|
|
readonly=False,
|
|
)
|
|
parent_id = fields.Many2one(
|
|
string="Parent Task",
|
|
help="Indicates that this task is a child of another task",
|
|
comodel_name="pms.housekeeping.task",
|
|
domain="[('id', '!=', id)]",
|
|
)
|
|
parent_state = fields.Char(
|
|
string="Parent State",
|
|
compute="_compute_parent_state",
|
|
)
|
|
child_ids = fields.One2many(
|
|
string="Child Tasks",
|
|
help="Indicates that this task has child tasks",
|
|
comodel_name="pms.housekeeping.task",
|
|
inverse_name="parent_id",
|
|
)
|
|
cancellation_type_id = fields.Many2one(
|
|
comodel_name="pms.housekeeping.cancellation.type",
|
|
string="Cancellation Type",
|
|
ondelete="restrict",
|
|
)
|
|
pending_allowed = fields.Boolean(
|
|
string="Is pending allowed",
|
|
compute="_compute_pending_allowed",
|
|
)
|
|
to_do_allowed = fields.Boolean(
|
|
string="Is To Do Allowed",
|
|
compute="_compute_to_do_allowed",
|
|
)
|
|
cancel_allowed = fields.Boolean(
|
|
string="Is Cancel Allowed",
|
|
compute="_compute_cancel_allowed",
|
|
)
|
|
in_progress_allowed = fields.Boolean(
|
|
string="Is In Progress Allowed",
|
|
compute="_compute_in_progress_allowed",
|
|
)
|
|
done_allowed = fields.Boolean(
|
|
string="Is Done Allowed",
|
|
compute="_compute_done_allowed",
|
|
)
|
|
allowed_housekeeper_ids = fields.Many2many(
|
|
comodel_name="hr.employee",
|
|
string="Allowed Housekeepers",
|
|
compute="_compute_allowed_housekeeper_ids",
|
|
)
|
|
|
|
@api.constrains("task_date")
|
|
def _check_task_date(self):
|
|
for rec in self:
|
|
if rec.task_date < fields.Date.today():
|
|
raise ValidationError(
|
|
_("Task Date must be greater than or equal to today")
|
|
)
|
|
|
|
@api.constrains("parent_id")
|
|
def _check_parent_id(self):
|
|
for rec in self:
|
|
if rec.parent_id.parent_id:
|
|
raise ValidationError(_("Parent task cannot have a parent task"))
|
|
|
|
@api.constrains("housekeeper_ids")
|
|
def _check_housekeeper_ids(self):
|
|
for rec in self:
|
|
if rec.housekeeper_ids:
|
|
for housekeeper in rec.housekeeper_ids:
|
|
if housekeeper not in rec.allowed_housekeeper_ids:
|
|
raise ValidationError(
|
|
_("The housekeeper should belong to the room's property.")
|
|
)
|
|
|
|
def action_cancel(self):
|
|
for rec in self:
|
|
rec.state = "cancel"
|
|
|
|
def action_to_do(self):
|
|
for rec in self:
|
|
rec.state = "to_do"
|
|
rec.cancellation_type_id = False
|
|
|
|
def action_done(self):
|
|
for rec in self:
|
|
rec.state = "done"
|
|
rec.cancellation_type_id = False
|
|
|
|
def action_in_progress(self):
|
|
for rec in self:
|
|
rec.state = "in_progress"
|
|
rec.cancellation_type_id = False
|
|
|
|
def action_pending(self):
|
|
for rec in self:
|
|
rec.state = "pending"
|
|
rec.cancellation_type_id = False
|
|
|
|
@api.onchange("state")
|
|
def _onchange_state(self):
|
|
for rec in self:
|
|
if rec.state == "cancel":
|
|
rec.child_ids.state = "cancel"
|
|
elif rec.state != "done":
|
|
rec.child_ids.state = "pending"
|
|
|
|
@api.depends("parent_id.state")
|
|
def _compute_parent_state(self):
|
|
for rec in self:
|
|
rec.parent_state = rec.parent_id.state if rec.parent_id else False
|
|
|
|
@api.depends("task_date", "state")
|
|
def _compute_pending_allowed(self):
|
|
for rec in self:
|
|
if (
|
|
rec.task_date
|
|
and rec.state == "cancel"
|
|
and (
|
|
rec.task_date > fields.Date.today()
|
|
or (
|
|
(rec.parent_state and rec.parent_state != "done")
|
|
or not rec.parent_state
|
|
)
|
|
)
|
|
):
|
|
rec.pending_allowed = True
|
|
else:
|
|
rec.pending_allowed = False
|
|
|
|
@api.depends("task_date", "state")
|
|
def _compute_to_do_allowed(self):
|
|
for rec in self:
|
|
if (
|
|
rec.task_date
|
|
and rec.task_date == fields.Date.today()
|
|
and rec.state in ("cancel", "pending", "done", "in_progress")
|
|
and (
|
|
(rec.parent_state and rec.parent_state == "done")
|
|
or not rec.parent_state
|
|
)
|
|
):
|
|
rec.to_do_allowed = True
|
|
else:
|
|
rec.to_do_allowed = False
|
|
|
|
@api.depends("state")
|
|
def _compute_cancel_allowed(self):
|
|
for rec in self:
|
|
if rec.state in ("to_do", "pending"):
|
|
rec.cancel_allowed = True
|
|
else:
|
|
rec.cancel_allowed = False
|
|
|
|
@api.depends("state")
|
|
def _compute_in_progress_allowed(self):
|
|
for rec in self:
|
|
if rec.state == "to_do":
|
|
rec.in_progress_allowed = True
|
|
else:
|
|
rec.in_progress_allowed = False
|
|
|
|
@api.depends("state")
|
|
def _compute_done_allowed(self):
|
|
for rec in self:
|
|
if rec.state == "in_progress":
|
|
rec.done_allowed = True
|
|
else:
|
|
rec.done_allowed = False
|
|
|
|
@api.depends("room_id", "task_type_id")
|
|
def _compute_housekeeper_ids(self):
|
|
for rec in self:
|
|
housekeeper_ids = False
|
|
if rec.room_id or rec.task_type_id:
|
|
housekeeper_ids = self.env["hr.employee"].search(
|
|
[("pre_assigned_room_ids", "in", [rec.room_id.id])]
|
|
)
|
|
if not housekeeper_ids:
|
|
housekeeper_ids = (
|
|
self.env["pms.housekeeping.task.type"]
|
|
.search([("id", "=", rec.task_type_id.id)])
|
|
.housekeeper_ids
|
|
)
|
|
rec.housekeeper_ids = housekeeper_ids
|
|
|
|
@api.depends("task_type_id")
|
|
def _compute_priority(self):
|
|
for rec in self:
|
|
if rec.task_type_id:
|
|
rec.priority = rec.task_type_id.priority
|
|
else:
|
|
rec.priority = False
|
|
|
|
@api.depends("room_id")
|
|
def _compute_allowed_housekeeper_ids(self):
|
|
for rec in self:
|
|
domain = [("job_id.name", "=", "Housekeeper")]
|
|
if rec.room_id:
|
|
domain = [
|
|
("job_id.name", "=", "Housekeeper"),
|
|
"|",
|
|
("property_ids", "in", rec.room_id.pms_property_id.ids),
|
|
("property_ids", "=", False),
|
|
]
|
|
rec.allowed_housekeeper_ids = self.env["hr.employee"].search(domain).ids
|
|
|
|
@api.model
|
|
def create(self, vals):
|
|
task_type_id = vals.get("task_type_id")
|
|
pms_housekeeping_task_type = self.env["pms.housekeeping.task.type"].browse(
|
|
task_type_id
|
|
)
|
|
room_id = vals.get("room_id")
|
|
pms_room = self.env["pms.room"].browse(room_id)
|
|
pms_room.housekeeping_state = (
|
|
"to_inspect" if pms_housekeeping_task_type.is_inspection else "dirty"
|
|
)
|
|
|
|
return super(PmsHouseKeepingTask, self).create(vals)
|
|
|
|
@api.model
|
|
def generate_tasks(self, pms_property_id):
|
|
for room in self.env["pms.room"].search(
|
|
[("pms_property_id", "=", pms_property_id.id)]
|
|
):
|
|
for task_type in self.env["pms.housekeeping.task.type"].search(
|
|
[
|
|
"|",
|
|
("pms_property_ids", "in", [pms_property_id.id]),
|
|
("pms_property_ids", "=", False),
|
|
],
|
|
order="priority asc",
|
|
):
|
|
if task_type.is_checkout:
|
|
reservations_with_checkout_today = self.env[
|
|
"pms.reservation"
|
|
].search(
|
|
[
|
|
("checkout", "=", fields.Date.today()),
|
|
]
|
|
)
|
|
reservation_line_with_checkout_today = self.env[
|
|
"pms.reservation.line"
|
|
].search(
|
|
[
|
|
(
|
|
"reservation_id",
|
|
"in",
|
|
reservations_with_checkout_today.ids,
|
|
),
|
|
("room_id", "=", room.id),
|
|
]
|
|
)
|
|
if reservation_line_with_checkout_today:
|
|
self.create_housekeeping_tasks(room, task_type)
|
|
break
|
|
|
|
if task_type.is_overnight:
|
|
reservation_line_today = self.env["pms.reservation.line"].search(
|
|
[
|
|
("room_id", "=", room.id),
|
|
("date", "=", fields.Date.today() + timedelta(days=-1)),
|
|
("occupies_availability", "=", True),
|
|
]
|
|
)
|
|
if reservation_line_today and len(reservation_line_today) == 1:
|
|
reservation_checkin = (
|
|
self.env["pms.reservation"]
|
|
.browse(reservation_line_today.reservation_id.id)
|
|
.checkin
|
|
)
|
|
|
|
days_between_checkin_and_today = (
|
|
fields.Date.today()
|
|
) - reservation_checkin
|
|
if (
|
|
days_between_checkin_and_today.days
|
|
% task_type.days_after_clean_overnight
|
|
== 0
|
|
):
|
|
self.create_housekeeping_tasks(room, task_type)
|
|
break
|
|
if task_type.is_checkin:
|
|
reservations_with_checkin_today = self.env[
|
|
"pms.reservation"
|
|
].search(
|
|
[
|
|
("checkin", "=", fields.Date.today()),
|
|
]
|
|
)
|
|
reservation_line_with_checkout_today = self.env[
|
|
"pms.reservation.line"
|
|
].search(
|
|
[
|
|
(
|
|
"reservation_id",
|
|
"in",
|
|
reservations_with_checkin_today.ids,
|
|
),
|
|
("room_id", "=", room.id),
|
|
]
|
|
)
|
|
if reservation_line_with_checkout_today:
|
|
self.create_housekeeping_tasks(room, task_type)
|
|
break
|
|
if task_type.is_empty:
|
|
previous_reservations = self.env["pms.reservation"].search(
|
|
[
|
|
("checkout", "<", fields.Date.today()),
|
|
("pms_property_id", "=", pms_property_id.id),
|
|
]
|
|
)
|
|
checkouts = (
|
|
self.env["pms.reservation.line"]
|
|
.search(
|
|
[
|
|
("reservation_id", "in", previous_reservations.ids),
|
|
("room_id", "=", room.id),
|
|
],
|
|
)
|
|
.mapped("date")
|
|
)
|
|
|
|
if checkouts:
|
|
last_checkout = max(checkouts)
|
|
days_between_last_checkout_and_today = (fields.Date.today()) - (
|
|
last_checkout + timedelta(days=1)
|
|
)
|
|
if (
|
|
days_between_last_checkout_and_today.days
|
|
% task_type.days_after_clean_empty
|
|
== 0
|
|
):
|
|
self.create_housekeeping_tasks(room, task_type)
|
|
break
|
|
|
|
def create_housekeeping_tasks(self, room, task_type):
|
|
task = self.env["pms.housekeeping.task"].create(
|
|
{
|
|
"name": task_type.name + " " + room.name,
|
|
"room_id": room.id,
|
|
"task_type_id": task_type.id,
|
|
"task_date": fields.Date.today(),
|
|
}
|
|
)
|
|
|
|
for task_type_child in task_type.child_ids:
|
|
self.env["pms.housekeeping.task"].create(
|
|
{
|
|
"name": task_type_child.name + " " + room.name,
|
|
"task_type_id": task_type_child.id,
|
|
"room_id": room.id,
|
|
"task_date": fields.Date.today(),
|
|
"parent_id": task.id,
|
|
}
|
|
)
|
|
|
|
def generate_task_properties(self):
|
|
for pms_property in self.env["pms.property"].search([]):
|
|
self.generate_tasks(pms_property)
|