mirror of
https://github.com/OCA/pms.git
synced 2025-01-29 00:17:45 +02:00
[WIP] pms-housekeeping: wip method to create automated tasksÇ
This commit is contained in:
committed by
Darío Lodeiros
parent
ade0673c81
commit
30f0748cb8
@@ -7,7 +7,7 @@ Housekeeping
|
||||
!! This file is generated by oca-gen-addon-readme !!
|
||||
!! changes will be overwritten. !!
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
!! source digest: sha256:4807e347dd2088e7cfafc8201f1105b6162c3f0793e9b87f570b6ba38c1756e7
|
||||
!! source digest: sha256:ad6a062413114aacf03fe2fbca31a04c8247dd80589f13cc1f21d890a478f2eb
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
"data": [
|
||||
"security/ir.model.access.csv",
|
||||
"data/pms_housekeeping_data.xml",
|
||||
"data/cron_jobs.xml",
|
||||
"views/hr_employee_views.xml",
|
||||
"views/pms_housekeeping_task_type_views.xml",
|
||||
"views/pms_housekeeping_views.xml",
|
||||
|
||||
16
pms_housekeeping/data/cron_jobs.xml
Normal file
16
pms_housekeeping/data/cron_jobs.xml
Normal 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>
|
||||
@@ -1,7 +1,8 @@
|
||||
# Copyright 2020 Jose Luis Algara (Alda Hotels <https://www.aldahotels.es>)
|
||||
# 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):
|
||||
@@ -13,9 +14,47 @@ class HrEmployee(models.Model):
|
||||
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")
|
||||
|
||||
@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")
|
||||
def _compute_job_name(self):
|
||||
for record in self:
|
||||
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
|
||||
)
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
from datetime import timedelta
|
||||
|
||||
from odoo import _, api, fields, models
|
||||
from odoo.exceptions import ValidationError
|
||||
|
||||
@@ -103,6 +105,12 @@ class PmsHouseKeepingTask(models.Model):
|
||||
_("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):
|
||||
for rec in self:
|
||||
rec.state = "cancel"
|
||||
@@ -235,3 +243,144 @@ class PmsHouseKeepingTask(models.Model):
|
||||
)
|
||||
|
||||
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)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from odoo import fields, models
|
||||
from odoo import _, api, fields, models
|
||||
from odoo.exceptions import ValidationError
|
||||
|
||||
|
||||
class PmsHouseKeepingTaskType(models.Model):
|
||||
@@ -24,7 +25,6 @@ class PmsHouseKeepingTaskType(models.Model):
|
||||
column1="task_type_id",
|
||||
column2="employee_id",
|
||||
string="Housekeepers",
|
||||
domain="[('job_id.name', '=', 'Housekeeper')]",
|
||||
)
|
||||
parent_id = fields.Many2one(
|
||||
string="Parent Task Type",
|
||||
@@ -32,4 +32,63 @@ class PmsHouseKeepingTaskType(models.Model):
|
||||
comodel_name="pms.housekeeping.task.type",
|
||||
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")
|
||||
|
||||
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
|
||||
|
||||
@@ -367,7 +367,7 @@ ul.auto-toc {
|
||||
!! This file is generated by oca-gen-addon-readme !!
|
||||
!! 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&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>
|
||||
|
||||
2
pms_housekeeping/tests/__init__.py
Normal file
2
pms_housekeeping/tests/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
||||
from . import test_pms_housekeeping_task
|
||||
from . import test_pms_hr_employee
|
||||
63
pms_housekeeping/tests/common.py
Normal file
63
pms_housekeeping/tests/common.py
Normal 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"})
|
||||
466
pms_housekeeping/tests/test_pms_housekeeping_task.py
Normal file
466
pms_housekeeping/tests/test_pms_housekeeping_task.py
Normal 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,
|
||||
}
|
||||
)
|
||||
92
pms_housekeeping/tests/test_pms_hr_employee.py
Normal file
92
pms_housekeeping/tests/test_pms_hr_employee.py
Normal 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])]
|
||||
@@ -9,8 +9,10 @@
|
||||
name="pre_assigned_room_ids"
|
||||
widget="many2many_tags"
|
||||
attrs="{'invisible': [('job_name', '!=', 'Housekeeper')]}"
|
||||
domain="[('id', 'in', allowed_pre_assigned_room_ids)]"
|
||||
/>
|
||||
<field name="job_name" invisible="1" />
|
||||
<field name="allowed_pre_assigned_room_ids" invisible="1" />
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -54,7 +54,13 @@
|
||||
<field name="name" />
|
||||
<field name="is_automated" />
|
||||
<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="description" />
|
||||
</group>
|
||||
|
||||
Reference in New Issue
Block a user