[WIP] pms-housekeeping: wip method to create automated tasksÇ

This commit is contained in:
miguelpadin
2024-02-20 17:46:48 +00:00
committed by Darío Lodeiros
parent ade0673c81
commit 30f0748cb8
13 changed files with 901 additions and 6 deletions

View File

@@ -7,7 +7,7 @@ Housekeeping
!! This file is generated by oca-gen-addon-readme !! !! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !! !! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:4807e347dd2088e7cfafc8201f1105b6162c3f0793e9b87f570b6ba38c1756e7 !! source digest: sha256:ad6a062413114aacf03fe2fbca31a04c8247dd80589f13cc1f21d890a478f2eb
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png

View File

@@ -17,6 +17,7 @@
"data": [ "data": [
"security/ir.model.access.csv", "security/ir.model.access.csv",
"data/pms_housekeeping_data.xml", "data/pms_housekeeping_data.xml",
"data/cron_jobs.xml",
"views/hr_employee_views.xml", "views/hr_employee_views.xml",
"views/pms_housekeeping_task_type_views.xml", "views/pms_housekeeping_task_type_views.xml",
"views/pms_housekeeping_views.xml", "views/pms_housekeeping_views.xml",

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<!-- Generate housekeeping tasks-->
<record model="ir.cron" id="generate_tasks">
<field name="name">Generate Housekeeping Tasks</field>
<field name="interval_number">1</field>
<field name="user_id" ref="base.user_root" />
<field name="interval_type">days</field>
<field name="numbercall">-1</field>
<field name="doall" eval="False" />
<field name="state">code</field>
<field name="model_id" ref="model_pms_housekeeping_task" />
<field name="nextcall" eval="(DateTime.now() + timedelta(days=1)).strftime('%Y-%m-%d 05:00:00')" />
<field name="code">model.generate_task_properties()</field>
</record>
</odoo>

View File

@@ -1,7 +1,8 @@
# Copyright 2020 Jose Luis Algara (Alda Hotels <https://www.aldahotels.es>) # Copyright 2020 Jose Luis Algara (Alda Hotels <https://www.aldahotels.es>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, fields, models from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
class HrEmployee(models.Model): class HrEmployee(models.Model):
@@ -13,9 +14,47 @@ class HrEmployee(models.Model):
help="Rooms pre assigned to this employee", help="Rooms pre assigned to this employee",
) )
allowed_pre_assigned_room_ids = fields.Many2many(
comodel_name="pms.room",
string="Allowed Pre Assigned Rooms",
help="Rooms allowed to be pre assigned to this employee",
compute="_compute_allowed_pre_assigned_room_ids",
)
job_name = fields.Char(string="Job Name", compute="_compute_job_name") job_name = fields.Char(string="Job Name", compute="_compute_job_name")
@api.constrains("pre_assigned_room_ids")
def _check_pre_assigned_room_ids(self):
for record in self:
if record.pre_assigned_room_ids:
for room in record.pre_assigned_room_ids:
if room not in record.allowed_pre_assigned_room_ids:
raise ValidationError(
_("The room should belong to the employee's property.")
)
@api.constrains("pre_assigned_room_ids")
def _check_job_id(self):
for record in self:
if (
record.job_id
and record.job_id
!= self.env.ref("pms_housekeeping.housekeeping_job_id")
and record.pre_assigned_room_ids
):
raise ValidationError(_("The job position should be Housekeeper."))
@api.depends("job_id") @api.depends("job_id")
def _compute_job_name(self): def _compute_job_name(self):
for record in self: for record in self:
record.job_name = record.job_id.name record.job_name = record.job_id.name
@api.depends("property_ids")
def _compute_allowed_pre_assigned_room_ids(self):
for record in self:
domain = []
if record.property_ids:
domain.append(("pms_property_id", "in", record.property_ids.ids))
record.allowed_pre_assigned_room_ids = (
self.env["pms.room"].search(domain).ids
)

View File

@@ -1,3 +1,5 @@
from datetime import timedelta
from odoo import _, api, fields, models from odoo import _, api, fields, models
from odoo.exceptions import ValidationError from odoo.exceptions import ValidationError
@@ -103,6 +105,12 @@ class PmsHouseKeepingTask(models.Model):
_("Task Date must be greater than or equal to today") _("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"))
def action_cancel(self): def action_cancel(self):
for rec in self: for rec in self:
rec.state = "cancel" rec.state = "cancel"
@@ -235,3 +243,144 @@ class PmsHouseKeepingTask(models.Model):
) )
return super(PmsHouseKeepingTask, self).create(vals) 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)

View File

@@ -1,4 +1,5 @@
from odoo import fields, models from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
class PmsHouseKeepingTaskType(models.Model): class PmsHouseKeepingTaskType(models.Model):
@@ -24,7 +25,6 @@ class PmsHouseKeepingTaskType(models.Model):
column1="task_type_id", column1="task_type_id",
column2="employee_id", column2="employee_id",
string="Housekeepers", string="Housekeepers",
domain="[('job_id.name', '=', 'Housekeeper')]",
) )
parent_id = fields.Many2one( parent_id = fields.Many2one(
string="Parent Task Type", string="Parent Task Type",
@@ -32,4 +32,63 @@ class PmsHouseKeepingTaskType(models.Model):
comodel_name="pms.housekeeping.task.type", comodel_name="pms.housekeeping.task.type",
domain="[('id', '!=', id)]", domain="[('id', '!=', id)]",
) )
child_ids = fields.One2many(
string="Child Task Types",
comodel_name="pms.housekeeping.task.type",
inverse_name="parent_id",
)
is_inspection = fields.Boolean(string="Inspection") is_inspection = fields.Boolean(string="Inspection")
pms_property_ids = fields.Many2many(
comodel_name="pms.property",
relation="pms_housekeeping_task_type_pms_property_rel",
column1="task_type_id",
column2="property_id",
string="Properties",
)
allowed_housekeeper_ids = fields.Many2many(
comodel_name="hr.employee",
relation="pms_housekeeping_task_type_allowed_hr_employee_rel",
column1="task_type_id",
column2="employee_id",
string="Allowed Employees",
compute="_compute_allowed_housekeeper_ids",
)
@api.constrains("is_overnight", "days_after_clean_overnight")
def _check_days_after_clean_overnight(self):
for record in self:
if record.is_overnight and record.days_after_clean_overnight <= 0:
raise ValidationError(
_("Days After Clean Overnight should be greater than 0")
)
@api.constrains("is_empty", "days_after_clean_empty")
def _check_days_after_clean_empty(self):
for record in self:
if record.is_empty and record.days_after_clean_empty <= 0:
raise ValidationError(
_("Days After Clean Empty should be greater than 0")
)
@api.constrains("parent_id")
def _check_parent_id(self):
for rec in self:
if rec.parent_id.parent_id:
raise ValidationError(
_("Parent task type cannot have a parent task type")
)
@api.depends("pms_property_ids")
def _compute_allowed_housekeeper_ids(self):
for record in self:
domain = []
if record.pms_property_ids:
domain = [
"|",
("property_ids", "in", record.pms_property_ids.ids),
("property_ids", "in", False),
]
domain.append(("job_id.name", "=", "Housekeeper"))
record.allowed_housekeeper_ids = self.env["hr.employee"].search(domain).ids

View File

@@ -367,7 +367,7 @@ ul.auto-toc {
!! This file is generated by oca-gen-addon-readme !! !! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !! !! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:4807e347dd2088e7cfafc8201f1105b6162c3f0793e9b87f570b6ba38c1756e7 !! source digest: sha256:ad6a062413114aacf03fe2fbca31a04c8247dd80589f13cc1f21d890a478f2eb
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/pms/tree/14.0/pms_housekeeping"><img alt="OCA/pms" src="https://img.shields.io/badge/github-OCA%2Fpms-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/pms-14-0/pms-14-0-pms_housekeeping"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/pms&amp;target_branch=14.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p> <p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/pms/tree/14.0/pms_housekeeping"><img alt="OCA/pms" src="https://img.shields.io/badge/github-OCA%2Fpms-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/pms-14-0/pms-14-0-pms_housekeeping"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/pms&amp;target_branch=14.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p>This module adds housekeeping feature to property management system (PMS).</p> <p>This module adds housekeeping feature to property management system (PMS).</p>

View File

@@ -0,0 +1,2 @@
from . import test_pms_housekeeping_task
from . import test_pms_hr_employee

View File

@@ -0,0 +1,63 @@
from odoo.tests import common
class TestPms(common.SavepointCase):
def setUp(self):
super().setUp()
# delete all previous pms.housekeeping.task.type records (only for the test purpose)
self.env["pms.housekeeping.task.type"].search([]).unlink()
# create a sale channel
self.sale_channel1 = self.env["pms.sale.channel"].create(
{
"name": "Door",
"channel_type": "direct",
}
)
self.availability_plan1 = self.env["pms.availability.plan"].create(
{
"name": "Availability Plan 1",
}
)
self.pricelist1 = self.env["product.pricelist"].create(
{
"name": "Pricelist 1",
"availability_plan_id": self.availability_plan1.id,
"is_pms_available": True,
}
)
self.company1 = self.env["res.company"].create(
{
"name": "Company 1",
}
)
self.pms_property1 = self.env["pms.property"].create(
{
"name": "Property 1",
"company_id": self.company1.id,
"default_pricelist_id": self.pricelist1.id,
}
)
self.room_type_class1 = self.env["pms.room.type.class"].create(
{
"name": "Room Type Class 1",
"default_code": "RTC1",
}
)
self.room_type1 = self.env["pms.room.type"].create(
{
"name": "Room type 1",
"default_code": "c1",
"company_id": self.company1.id,
"class_id": self.room_type_class1.id,
}
)
self.room1 = self.env["pms.room"].create(
{
"name": "Room 101",
"pms_property_id": self.pms_property1.id,
"room_type_id": self.room_type1.id,
}
)
# create partner
self.partner1 = self.env["res.partner"].create({"name": "Ana"})

View File

@@ -0,0 +1,466 @@
from datetime import datetime, timedelta
from freezegun import freeze_time
from odoo.exceptions import ValidationError
from .common import TestPms
class TestPmsHousekeepingTask(TestPms):
def setUp(self):
super().setUp()
@freeze_time("2000-01-04")
def test_no_create_overnight_task_when_it_shouldnt_when_no_overnight(self):
# ARRANGE
# create task type
self.env["pms.housekeeping.task.type"].create(
{
"name": "Task Type 1",
"is_overnight": True,
"days_after_clean_overnight": 2,
}
)
# ACT
# call method to create task
self.env["pms.housekeeping.task"].generate_tasks(self.pms_property1)
# ASSERT
# search for the task
housekeeping_task = self.env["pms.housekeeping.task"].search(
[("room_id", "=", self.room1.id)]
)
# Verify that the housekeeping task is not created
self.assertFalse(housekeeping_task, "Housekeeping task shouldn't be created")
@freeze_time("2000-01-10")
def test_create_overnight_task_when_it_should_be_created_with_different_dates(self):
# ARRANGE
# create reservation with checkin today
self.env["pms.reservation"].create(
{
"checkin": datetime.today(),
"checkout": datetime.today() + timedelta(days=7),
"room_type_id": self.room_type1.id,
"partner_id": self.partner1.id,
"pms_property_id": self.pms_property1.id,
"pricelist_id": self.pricelist1.id,
"sale_channel_origin_id": self.sale_channel1.id,
}
)
# create task type
self.env["pms.housekeeping.task.type"].create(
{
"name": "Task Type 1",
"is_overnight": True,
"days_after_clean_overnight": 2,
}
)
# Define a list of dates to iterate over
test_dates = [
"2000-01-12",
"2000-01-14",
"2000-01-16",
]
for test_date in test_dates:
with self.subTest(test_date=test_date):
# Freeze time to the current test date
with freeze_time(test_date):
# ACT
# call method to create task
self.env["pms.housekeeping.task"].generate_tasks(self.pms_property1)
# ASSERT
# search for the task
housekeeping_task = self.env["pms.housekeeping.task"].search(
[("room_id", "=", self.room1.id), ("task_date", "=", test_date)]
)
# Verify that the housekeeping task is created
self.assertTrue(
housekeeping_task, "Housekeeping task should be created"
)
@freeze_time("2000-01-10")
def test_create_overnight_task_when_it_shouldnt_be_created_with_different_dates(
self,
):
# ARRANGE
# create reservation with checkin today
self.env["pms.reservation"].create(
{
"checkin": datetime.today(),
"checkout": datetime.today() + timedelta(days=7),
"room_type_id": self.room_type1.id,
"partner_id": self.partner1.id,
"pms_property_id": self.pms_property1.id,
"pricelist_id": self.pricelist1.id,
"sale_channel_origin_id": self.sale_channel1.id,
}
)
# create task type
self.env["pms.housekeeping.task.type"].create(
{
"name": "Task Type 1",
"is_overnight": True,
"days_after_clean_overnight": 2,
}
)
# Define a list of dates to iterate over
test_dates = [
"2000-01-11",
"2000-01-13",
"2000-01-15",
]
for test_date in test_dates:
with self.subTest(test_date=test_date):
# Freeze time to the current test date
with freeze_time(test_date):
# ACT
# call method to create task
self.env["pms.housekeeping.task"].generate_tasks(self.pms_property1)
# ASSERT
# search for the task
housekeeping_task = self.env["pms.housekeeping.task"].search(
[("room_id", "=", self.room1.id), ("task_date", "=", test_date)]
)
# Verify that the housekeeping task is created
self.assertFalse(
housekeeping_task, "Housekeeping task shouldn't be created"
)
###################
@freeze_time("2000-01-04")
def test_no_create_empty_task_when_it_shouldnt_when_no_empty(self):
# ARRANGE
# create task type
self.env["pms.housekeeping.task.type"].create(
{
"name": "Task Type 1",
"is_empty": True,
"days_after_clean_empty": 2,
}
)
# ACT
# call method to create task
self.env["pms.housekeeping.task"].generate_tasks(self.pms_property1)
# ASSERT
# search for the task
housekeeping_task = self.env["pms.housekeeping.task"].search(
[("room_id", "=", self.room1.id)]
)
# Verify that the housekeeping task is not created
self.assertFalse(housekeeping_task, "Housekeeping task shouldn't be created")
@freeze_time("2000-02-11")
def test_create_empty_task_when_it_should_be_created_with_different_dates(self):
# ARRANGE
# create reservation with checkout today - 10 days
self.env["pms.reservation"].create(
{
"checkin": datetime.today() + timedelta(days=-20),
"checkout": datetime.today() + timedelta(days=-10),
"room_type_id": self.room_type1.id,
"partner_id": self.partner1.id,
"pms_property_id": self.pms_property1.id,
"pricelist_id": self.pricelist1.id,
"sale_channel_origin_id": self.sale_channel1.id,
}
)
# create task type
self.env["pms.housekeeping.task.type"].create(
{"name": "Task Type 1", "is_empty": True, "days_after_clean_empty": 2}
)
# Define a list of dates to iterate over
test_dates = [
"2000-02-03",
"2000-02-05",
"2000-02-07",
]
for test_date in test_dates:
with self.subTest(test_date=test_date):
# Freeze time to the current test date
with freeze_time(test_date):
# ACT
# call method to create task
self.env["pms.housekeeping.task"].generate_tasks(self.pms_property1)
# ASSERT
# search for the task
housekeeping_task = self.env["pms.housekeeping.task"].search(
[("room_id", "=", self.room1.id), ("task_date", "=", test_date)]
)
# Verify that the housekeeping task is created
self.assertTrue(
housekeeping_task, "Housekeeping task should be created"
)
@freeze_time("2000-02-11")
def test_create_empty_task_when_it_shouldnt_be_created_with_different_dates(self):
# ARRANGE
# create reservation with checkout today - 10 days
self.env["pms.reservation"].create(
{
"checkin": datetime.today() + timedelta(days=-20),
"checkout": datetime.today() + timedelta(days=-10),
"room_type_id": self.room_type1.id,
"partner_id": self.partner1.id,
"pms_property_id": self.pms_property1.id,
"pricelist_id": self.pricelist1.id,
"sale_channel_origin_id": self.sale_channel1.id,
}
)
# create task type
self.env["pms.housekeeping.task.type"].create(
{"name": "Task Type 1", "is_empty": True, "days_after_clean_empty": 2}
)
# Define a list of dates to iterate over
test_dates = [
"2000-02-02",
"2000-02-04",
"2000-02-06",
]
for test_date in test_dates:
with self.subTest(test_date=test_date):
# Freeze time to the current test date
with freeze_time(test_date):
# ACT
# call method to create task
self.env["pms.housekeeping.task"].generate_tasks(self.pms_property1)
# ASSERT
# search for the task
housekeeping_task = self.env["pms.housekeeping.task"].search(
[("room_id", "=", self.room1.id), ("task_date", "=", test_date)]
)
# Verify that the housekeeping task is created
self.assertFalse(
housekeeping_task, "Housekeeping task should be created"
)
@freeze_time("2000-01-04")
def test_create_checkin_task_when_it_should_when_checkin(self):
# ARRANGE
# create task type
self.env["pms.housekeeping.task.type"].create(
{
"name": "Task Type 1",
"is_checkin": True,
}
)
# create reservation with checkin today
self.env["pms.reservation"].create(
{
"checkin": datetime.today(),
"checkout": datetime.today() + timedelta(days=3),
"room_type_id": self.room_type1.id,
"partner_id": self.partner1.id,
"pms_property_id": self.pms_property1.id,
"pricelist_id": self.pricelist1.id,
"sale_channel_origin_id": self.sale_channel1.id,
}
)
# ACT
# call method to create task
self.env["pms.housekeeping.task"].generate_tasks(self.pms_property1)
# ASSERT
# search for the task
housekeeping_task = self.env["pms.housekeeping.task"].search(
[("room_id", "=", self.room1.id)]
)
# Verify that the housekeeping task is not created
self.assertTrue(housekeeping_task, "Housekeeping task should be created")
@freeze_time("2000-01-04")
def test_no_create_checkin_task_when_it_shouldnt_when_no_checkin(self):
# ARRANGE
# create task type
self.env["pms.housekeeping.task.type"].create(
{
"name": "Task Type 1",
"is_checkin": True,
}
)
# ACT
# call method to create task
self.env["pms.housekeeping.task"].generate_tasks(self.pms_property1)
# ASSERT
# search for the task
housekeeping_task = self.env["pms.housekeeping.task"].search(
[("room_id", "=", self.room1.id)]
)
# Verify that the housekeeping task is not created
self.assertFalse(housekeeping_task, "Housekeeping task shouldn't be created")
@freeze_time("2000-01-04")
def test_create_checkout_task_when_it_should_when_checkout(self):
# ARRANGE
# create task type
self.env["pms.housekeeping.task.type"].create(
{
"name": "Task Type 1",
"is_checkout": True,
}
)
# create reservation with checkout today
self.env["pms.reservation"].create(
{
"checkin": datetime.today() + timedelta(days=-3),
"checkout": datetime.today(),
"room_type_id": self.room_type1.id,
"partner_id": self.partner1.id,
"pms_property_id": self.pms_property1.id,
"pricelist_id": self.pricelist1.id,
"sale_channel_origin_id": self.sale_channel1.id,
}
)
# ACT
# call method to create task
self.env["pms.housekeeping.task"].generate_tasks(self.pms_property1)
# ASSERT
# search for the task
housekeeping_task = self.env["pms.housekeeping.task"].search(
[("room_id", "=", self.room1.id)]
)
# Verify that the housekeeping task is not created
self.assertTrue(housekeeping_task, "Housekeeping task should be created")
@freeze_time("2000-01-04")
def test_no_create_checkout_task_when_it_shouldnt_when_no_checkout(self):
# ARRANGE
# create task type
self.env["pms.housekeeping.task.type"].create(
{
"name": "Task Type 1",
"is_checkout": True,
}
)
# ACT
# call method to create task
self.env["pms.housekeeping.task"].generate_tasks(self.pms_property1)
# ASSERT
# search for the task
housekeeping_task = self.env["pms.housekeeping.task"].search(
[("room_id", "=", self.room1.id)]
)
# Verify that the housekeeping task is not created
self.assertFalse(housekeeping_task, "Housekeeping task shouldn't be created")
@freeze_time("2000-01-04")
def test_create_task_type_childs(self):
# ARRANGE
# create task type
parent_task_type = self.env["pms.housekeeping.task.type"].create(
{
"name": "Task Type Parent",
"is_checkout": True,
}
)
child_task_type = self.env["pms.housekeeping.task.type"].create(
{
"name": "Task Type Child",
"is_checkout": True,
"parent_id": parent_task_type.id,
}
)
# create reservation with checkout today
self.env["pms.reservation"].create(
{
"checkin": datetime.today() + timedelta(days=-3),
"checkout": datetime.today(),
"room_type_id": self.room_type1.id,
"partner_id": self.partner1.id,
"pms_property_id": self.pms_property1.id,
"pricelist_id": self.pricelist1.id,
"sale_channel_origin_id": self.sale_channel1.id,
}
)
# ACT
# call method to create task
self.env["pms.housekeeping.task"].generate_tasks(self.pms_property1)
# ASSERT
# search for the task
housekeeping_task = self.env["pms.housekeeping.task"].search(
[("room_id", "=", self.room1.id), ("task_type_id", "=", child_task_type.id)]
)
# Verify that the housekeeping task is not created
self.assertTrue(housekeeping_task, "Child housekeeping task should be created")
def test_no_create_task_type_childs(self):
# ARRANGE
# create task type
self.env["pms.housekeeping.task.type"].create(
{
"name": "Task Type Parent",
"is_checkout": True,
}
)
# create reservation with checkout today
self.env["pms.reservation"].create(
{
"checkin": datetime.today() + timedelta(days=-3),
"checkout": datetime.today(),
"room_type_id": self.room_type1.id,
"partner_id": self.partner1.id,
"pms_property_id": self.pms_property1.id,
"pricelist_id": self.pricelist1.id,
"sale_channel_origin_id": self.sale_channel1.id,
}
)
# ACT
# call method to create task
self.env["pms.housekeeping.task"].generate_tasks(self.pms_property1)
# ASSERT
# search for the task
housekeeping_task = self.env["pms.housekeeping.task"].search(
[("room_id", "=", self.room1.id)]
)
# Verify that the housekeeping task childs is not created
self.assertFalse(
housekeeping_task.child_ids, "Child housekeeping task shouldn´t be created"
)
def test_days_after_clean_overnight_constraint(self):
# ARRANGE, ACT & ASSERT
# create task type and verify that the constraint is raised
with self.assertRaises(
ValidationError, msg="Days After Clean Overnight should be greater than 0"
):
self.env["pms.housekeeping.task.type"].create(
{
"name": "Task Type 1",
"is_overnight": True,
"days_after_clean_overnight": 0,
}
)
def test_days_after_clean_empty_constraint(self):
# ARRANGE, ACT & ASSERT
# create task type and verify that the constraint is raised
with self.assertRaises(
ValidationError, msg="Days After Clean Overnight should be greater than 0"
):
self.env["pms.housekeeping.task.type"].create(
{
"name": "Task Type 1",
"is_empty": True,
"days_after_clean_empty": 0,
}
)

View File

@@ -0,0 +1,92 @@
from odoo.exceptions import ValidationError
from .common import TestPms
class TestPmsHrEmployee(TestPms):
def setUp(self):
super().setUp()
def test_employee_pre_assigned_room_inconsistent(self):
# ARRANGE
self.pms_property2 = self.env["pms.property"].create(
{
"name": "Property 2",
"company_id": self.company1.id,
"default_pricelist_id": self.pricelist1.id,
}
)
self.room2 = self.env["pms.room"].create(
{
"name": "Room 202",
"pms_property_id": self.pms_property2.id,
"room_type_id": self.room_type1.id,
}
)
# ACT & ASSERT
with self.assertRaises(
ValidationError, msg="The room should belong to the employee's property."
):
self.hr_employee = self.env["hr.employee"].create(
{
"name": "Test Employee",
"company_id": self.company1.id,
"job_id": self.env.ref("pms_housekeeping.housekeeping_job_id").id,
"property_ids": [(6, 0, [self.pms_property1.id])],
"pre_assigned_room_ids": [(6, 0, [self.room2.id])],
}
)
def test_employee_pre_assigned_room_consistent_with_property(self):
# ARRANGE
self.hr_employee = self.env["hr.employee"].create(
{
"name": "Test Employee",
"company_id": self.company1.id,
"job_id": self.env.ref("pms_housekeeping.housekeeping_job_id").id,
"property_ids": [(6, 0, [self.pms_property1.id])],
}
)
# ACT
self.hr_employee.pre_assigned_room_ids = [(6, 0, [self.room1.id])]
# ASSERT
self.assertTrue(
self.hr_employee.pre_assigned_room_ids, "Pre assigned room is not consistent with property"
)
def test_employee_pre_assigned_room_consistent_without_properties(self):
# ARRANGE
self.hr_employee = self.env["hr.employee"].create(
{
"name": "Test Employee",
"company_id": self.company1.id,
"job_id": self.env.ref("pms_housekeeping.housekeeping_job_id").id,
}
)
# ACT
self.hr_employee.pre_assigned_room_ids = [(6, 0, [self.room1.id])]
# ASSERT
self.assertTrue(
self.hr_employee.pre_assigned_room_ids, "Pre assigned room is not consistent without properties"
)
def test_not_pre_assigned_room_no_housekeeper_employee(self):
# ARRANGE
self.hr_employee = self.env["hr.employee"].create(
{
"name": "Test Employee",
"company_id": self.company1.id,
"job_id": self.env.ref("hr.job_trainee").id,
}
)
# ACT & ASSERT
with self.assertRaises(
ValidationError, msg="The job position should be Housekeeper."
):
self.hr_employee.pre_assigned_room_ids = [(6, 0, [self.room1.id])]

View File

@@ -9,8 +9,10 @@
name="pre_assigned_room_ids" name="pre_assigned_room_ids"
widget="many2many_tags" widget="many2many_tags"
attrs="{'invisible': [('job_name', '!=', 'Housekeeper')]}" attrs="{'invisible': [('job_name', '!=', 'Housekeeper')]}"
domain="[('id', 'in', allowed_pre_assigned_room_ids)]"
/> />
<field name="job_name" invisible="1" /> <field name="job_name" invisible="1" />
<field name="allowed_pre_assigned_room_ids" invisible="1" />
</xpath> </xpath>
</field> </field>
</record> </record>

View File

@@ -54,7 +54,13 @@
<field name="name" /> <field name="name" />
<field name="is_automated" /> <field name="is_automated" />
<field name="is_inspection" /> <field name="is_inspection" />
<field name="housekeeper_ids" widget="many2many_tags" /> <field
name="housekeeper_ids"
widget="many2many_tags"
domain="[('id', 'in', allowed_housekeeper_ids)]"
/>
<field name="pms_property_ids" widget="many2many_tags" />
<field name="allowed_housekeeper_ids" invisible="1" />
<field name="parent_id" /> <field name="parent_id" />
<field name="description" /> <field name="description" />
</group> </group>