[DONE] pms: allow to select the rules to be overridden (#67)

* [IMP] pms: allow to select the rules to be overridden

* [FIX] pms: fix pricelist bug last commit
This commit is contained in:
Miguel Padin
2021-03-19 17:19:17 +01:00
committed by Darío Lodeiros
parent e3b19793f1
commit bd49db24f0
4 changed files with 511 additions and 108 deletions

View File

@@ -230,6 +230,49 @@ class TestPmsWizardMassiveChanges(TestHotel):
"Rule not created on correct day of week", "Rule not created on correct day of week",
) )
@freeze_time("1980-12-01")
def test_no_overwrite_values_not_setted(self):
# TEST CASE
# A rule value shouldnt overwrite with the default values
# another rules for the same day and room type
# ARRANGE
self.create_common_scenario()
date = fields.date.today()
initial_quota = 20
self.env["pms.room.type.availability.rule"].create(
{
"availability_plan_id": self.test_availability_plan.id,
"room_type_id": self.test_room_type_double.id,
"date": date,
"quota": initial_quota,
"pms_property_id": self.test_property.id,
}
)
vals_wizard = {
"massive_changes_on": "availability_plan",
"availability_plan_id": self.test_availability_plan.id,
"start_date": date,
"end_date": date,
"room_type_id": self.test_room_type_double.id,
"apply_max_avail": True,
"max_avail": 2,
"pms_property_ids": [self.test_property.id],
}
# ACT
self.env["pms.massive.changes.wizard"].create(
vals_wizard
).apply_massive_changes()
# ASSERT
self.assertEqual(
self.test_availability_plan.rule_ids[0].quota,
initial_quota,
"A rule value shouldnt overwrite with the default values "
"another rules for the same day and room type",
)
# MASSIVE CHANGE WIZARD TESTS ON PRICELIST ITEMS # MASSIVE CHANGE WIZARD TESTS ON PRICELIST ITEMS
@freeze_time("1980-12-01") @freeze_time("1980-12-01")

View File

@@ -430,11 +430,7 @@
<field name="name" /> <field name="name" />
<field name="partner_id" select="1" /> <field name="partner_id" select="1" />
<field name="date_order" select="1" /> <field name="date_order" select="1" />
<field <field name="user_id" optional="show" widget="many2one_avatar_user" />
name="create_uid"
optional="show"
widget="many2one_avatar_user"
/>
<field name="reservation_ids" widget="many2many_tags" /> <field name="reservation_ids" widget="many2many_tags" />
<field name="amount_total" sum="Total amount" /> <field name="amount_total" sum="Total amount" />
<field name="pending_amount" sum="Total debt" /> <field name="pending_amount" sum="Total debt" />

View File

@@ -1,6 +1,7 @@
import datetime import datetime
from odoo import api, fields, models from odoo import api, fields, models
from odoo.osv import expression
class AvailabilityWizard(models.TransientModel): class AvailabilityWizard(models.TransientModel):
@@ -24,7 +25,7 @@ class AvailabilityWizard(models.TransientModel):
) )
massive_changes_on = fields.Selection( massive_changes_on = fields.Selection(
[("pricelist", "Pricelist"), ("availability_plan", "Availability Plan")], [("pricelist", "Pricelist"), ("availability_plan", "Availability Plan")],
string="Massive changes on", string="On",
default="availability_plan", default="availability_plan",
required=True, required=True,
) )
@@ -41,11 +42,11 @@ class AvailabilityWizard(models.TransientModel):
comodel_name="product.pricelist", compute="_compute_allowed_pricelist_ids" comodel_name="product.pricelist", compute="_compute_allowed_pricelist_ids"
) )
start_date = fields.Date( start_date = fields.Date(
string="From:", string="From",
required=True, required=True,
) )
end_date = fields.Date( end_date = fields.Date(
string="To:", string="To",
required=True, required=True,
) )
room_type_id = fields.Many2one(comodel_name="pms.room.type", string="Room Type") room_type_id = fields.Many2one(comodel_name="pms.room.type", string="Room Type")
@@ -122,6 +123,51 @@ class AvailabilityWizard(models.TransientModel):
string="Apply Availability Rule for the whole week", string="Apply Availability Rule for the whole week",
default=True, default=True,
) )
apply_min_stay = fields.Boolean(
string="Apply changes to Min. Stay",
default=False,
)
apply_min_stay_arrival = fields.Boolean(
string="Apply changes to Min. Stay Arrival",
default=False,
)
apply_max_stay = fields.Boolean(
string="Apply changes to Max. Stay",
default=False,
)
apply_max_stay_arrival = fields.Boolean(
string="Apply changes to Max. Stay Arrival",
default=False,
)
apply_quota = fields.Boolean(
string="Apply changes to Quota",
default=False,
)
apply_max_avail = fields.Boolean(
string="Apply changes to Max. Avail.",
default=False,
)
apply_closed = fields.Boolean(
string="Apply changes to Closed",
default=False,
)
apply_closed_arrival = fields.Boolean(
string="Apply changes to Closed Arrival",
default=False,
)
apply_closed_departure = fields.Boolean(
string="Apply changes to Closed Departure",
default=False,
)
rules_to_overwrite = fields.One2many( rules_to_overwrite = fields.One2many(
comodel_name="pms.room.type.availability.rule", comodel_name="pms.room.type.availability.rule",
compute="_compute_rules_to_overwrite", compute="_compute_rules_to_overwrite",
@@ -171,6 +217,24 @@ class AvailabilityWizard(models.TransientModel):
"apply_on_sunday", "apply_on_sunday",
"apply_on_all_week", "apply_on_all_week",
"availability_plan_id", "availability_plan_id",
"apply_quota",
"apply_max_avail",
"apply_min_stay",
"apply_min_stay_arrival",
"apply_max_stay",
"apply_max_stay_arrival",
"apply_closed",
"apply_closed_arrival",
"apply_closed_departure",
"min_stay",
"max_stay",
"min_stay_arrival",
"max_stay_arrival",
"closed",
"closed_arrival",
"closed_departure",
"quota",
"max_avail",
) )
def _compute_rules_to_overwrite(self): def _compute_rules_to_overwrite(self):
for record in self: for record in self:
@@ -193,6 +257,14 @@ class AvailabilityWizard(models.TransientModel):
if record.end_date: if record.end_date:
domain.append(("date", "<=", record.end_date)) domain.append(("date", "<=", record.end_date))
domain_overwrite = self.build_domain_rules()
if len(domain_overwrite):
if len(domain_overwrite) == 1:
domain.append(domain_overwrite[0][0])
else:
domain_overwrite = expression.OR(domain_overwrite)
domain.extend(domain_overwrite)
week_days_to_apply = ( week_days_to_apply = (
record.apply_on_monday, record.apply_on_monday,
record.apply_on_tuesday, record.apply_on_tuesday,
@@ -307,12 +379,41 @@ class AvailabilityWizard(models.TransientModel):
record.pricelist_items_to_overwrite record.pricelist_items_to_overwrite
) )
def build_domain_rules(self):
for record in self:
domain_overwrite = []
if record.apply_min_stay:
domain_overwrite.append([("min_stay", "!=", record.min_stay)])
if record.apply_max_stay:
domain_overwrite.append([("max_stay", "!=", record.max_stay)])
if record.apply_min_stay_arrival:
domain_overwrite.append(
[("min_stay_arrival", "!=", record.min_stay_arrival)]
)
if record.apply_max_stay_arrival:
domain_overwrite.append(
[("max_stay_arrival", "!=", record.max_stay_arrival)]
)
if record.apply_quota:
domain_overwrite.append([("quota", "!=", record.quota)])
if record.apply_max_avail:
domain_overwrite.append([("max_avail", "!=", record.max_avail)])
if record.apply_closed:
domain_overwrite.append([("closed", "!=", record.closed)])
if record.apply_closed_arrival:
domain_overwrite.append(
[("closed_arrival", "!=", record.closed_arrival)]
)
if record.apply_closed_departure:
domain_overwrite.append(
[("closed_departure", "!=", record.closed_departure)]
)
return domain_overwrite
# actions # actions
def apply_massive_changes(self): def apply_massive_changes(self):
for record in self: for record in self:
# remove old rules
record.rules_to_overwrite.unlink()
record.pricelist_items_to_overwrite.unlink() record.pricelist_items_to_overwrite.unlink()
week_days_to_apply = ( week_days_to_apply = (
record.apply_on_monday, record.apply_on_monday,
@@ -349,6 +450,7 @@ class AvailabilityWizard(models.TransientModel):
for room_type in room_types: for room_type in room_types:
for pms_property in record.pms_property_ids: for pms_property in record.pms_property_ids:
if record.massive_changes_on == "pricelist": if record.massive_changes_on == "pricelist":
self.env["product.pricelist.item"].create( self.env["product.pricelist.item"].create(
{ {
"pricelist_id": record.pricelist_id.id, "pricelist_id": record.pricelist_id.id,
@@ -364,23 +466,82 @@ class AvailabilityWizard(models.TransientModel):
) )
else: else:
avail_plan_id = record.availability_plan_id.id avail_plan_id = record.availability_plan_id.id
self.env["pms.room.type.availability.rule"].create( vals = {}
{ vals.update(
"availability_plan_id": avail_plan_id, {"min_stay": record.min_stay}
"date": date, if record.apply_min_stay
"room_type_id": room_type.id, else {}
"quota": record.quota,
"max_avail": record.max_avail,
"min_stay": record.min_stay,
"min_stay_arrival": record.min_stay_arrival,
"max_stay": record.max_stay,
"max_stay_arrival": record.max_stay_arrival,
"closed": record.closed,
"closed_arrival": record.closed_arrival,
"closed_departure": record.closed_departure,
"pms_property_id": pms_property.id,
}
) )
vals.update(
{"min_stay_arrival": record.min_stay_arrival}
if record.apply_min_stay_arrival
else {}
)
vals.update(
{"max_stay": record.max_stay}
if record.apply_max_stay
else {}
)
vals.update(
{"max_stay_arrival": record.max_stay_arrival}
if record.apply_max_stay_arrival
else {}
)
vals.update(
{"quota": record.quota} if record.apply_quota else {}
)
vals.update(
{"max_avail": record.max_avail}
if record.apply_max_avail
else {}
)
vals.update(
{"closed": record.closed} if record.apply_closed else {}
)
vals.update(
{"closed_arrival": record.closed_arrival}
if record.apply_closed_arrival
else {}
)
vals.update(
{"closed_departure": record.closed_departure}
if record.apply_closed_departure
else {}
)
if date in record.rules_to_overwrite.mapped(
"date"
) and room_type in record.rules_to_overwrite.mapped(
"room_type_id"
):
overwrite = record.rules_to_overwrite.search(
[
("room_type_id", "=", room_type.id),
("date", "=", date),
]
)
overwrite.write(vals)
else:
self.env["pms.room.type.availability.rule"].create(
{
"availability_plan_id": avail_plan_id,
"date": date,
"room_type_id": room_type.id,
"quota": record.quota,
"max_avail": record.max_avail,
"min_stay": record.min_stay,
"min_stay_arrival": record.min_stay_arrival,
"max_stay": record.max_stay,
"max_stay_arrival": record.max_stay_arrival,
"closed": record.closed,
"closed_arrival": record.closed_arrival,
"closed_departure": record.closed_departure,
"pms_property_id": pms_property.id,
}
)
if ( if (
record.massive_changes_on == "pricelist" record.massive_changes_on == "pricelist"
and not record.pricelist_readonly and not record.pricelist_readonly

View File

@@ -6,11 +6,12 @@
<field name="arch" type="xml"> <field name="arch" type="xml">
<form class="pt-1"> <form class="pt-1">
<group> <group>
<field name="avail_readonly" invisible="1" /> <field name="massive_changes_on" invisible="1" />
<field name="pricelist_readonly" invisible="1" /> <field name="avail_readonly" invisible="1" />
<field name="pricelist_readonly" invisible="1" />
</group> </group>
<div class="row"> <div class="row">
<div class="col-5 "> <div class="col-6">
<group> <group>
<field <field
name="start_date" name="start_date"
@@ -22,15 +23,15 @@
widget="daterange" widget="daterange"
options="{'related_start_date': 'start_date'}" options="{'related_start_date': 'start_date'}"
/> />
</group>
</div>
<div class="col-5">
<group class="">
<field name="pms_property_ids" widget="many2many_tags" />
<field <field
name="massive_changes_on" name="massive_changes_on"
attrs="{'invisible':['|', ('avail_readonly','=',True), ('pricelist_readonly', '=', True)]}" attrs="{'invisible':['|', ('avail_readonly','=',True), ('pricelist_readonly', '=', True)]}"
/> />
</group>
</div>
<div class="col-6">
<group class="">
<field name="pms_property_ids" widget="many2many_tags" />
<field <field
name="availability_plan_id" name="availability_plan_id"
class="mr-5" class="mr-5"
@@ -59,9 +60,9 @@
</div> </div>
</div> </div>
<field name="allowed_pricelist_ids" invisible="1" /> <field name="allowed_pricelist_ids" invisible="1" />
<b>Days:</b>
<div class="row"> <div class="row">
<div class="col-12"> <div class="col-12">
<group>
<table class="table table-bordered text-center"> <table class="table table-bordered text-center">
<thead> <thead>
<tr> <tr>
@@ -79,110 +80,262 @@
<tr> <tr>
<td> <td>
<field <field
name="apply_on_all_week" name="apply_on_all_week"
widget="boolean_toggle" widget="boolean_toggle"
/> />
</td> </td>
<td> <td>
<field <field
name="apply_on_sunday" name="apply_on_sunday"
widget="boolean_toggle" widget="boolean_toggle"
attrs="{'invisible':[('apply_on_all_week','=',True)]}" attrs="{'invisible':[('apply_on_all_week','=',True)]}"
/> />
</td> </td>
<td> <td>
<field <field
name="apply_on_monday" name="apply_on_monday"
widget="boolean_toggle" widget="boolean_toggle"
attrs="{'invisible':[('apply_on_all_week','=',True)]}" attrs="{'invisible':[('apply_on_all_week','=',True)]}"
/> />
</td> </td>
<td> <td>
<field <field
name="apply_on_tuesday" name="apply_on_tuesday"
widget="boolean_toggle" widget="boolean_toggle"
attrs="{'invisible':[('apply_on_all_week','=',True)]}" attrs="{'invisible':[('apply_on_all_week','=',True)]}"
/> />
</td> </td>
<td> <td>
<field <field
name="apply_on_wednesday" name="apply_on_wednesday"
widget="boolean_toggle" widget="boolean_toggle"
attrs="{'invisible':[('apply_on_all_week','=',True)]}" attrs="{'invisible':[('apply_on_all_week','=',True)]}"
/> />
</td> </td>
<td> <td>
<field <field
name="apply_on_thursday" name="apply_on_thursday"
widget="boolean_toggle" widget="boolean_toggle"
attrs="{'invisible':[('apply_on_all_week','=',True)]}" attrs="{'invisible':[('apply_on_all_week','=',True)]}"
/> />
</td> </td>
<td> <td>
<field <field
name="apply_on_friday" name="apply_on_friday"
widget="boolean_toggle" widget="boolean_toggle"
attrs="{'invisible':[('apply_on_all_week','=',True)]}" attrs="{'invisible':[('apply_on_all_week','=',True)]}"
/> />
</td> </td>
<td> <td>
<field <field
name="apply_on_saturday" name="apply_on_saturday"
widget="boolean_toggle" widget="boolean_toggle"
attrs="{'invisible':[('apply_on_all_week','=',True)]}" attrs="{'invisible':[('apply_on_all_week','=',True)]}"
/> />
</td> </td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
</group>
</div> </div>
</div> </div>
<b <span attrs="{'invisible':[('massive_changes_on','=','pricelist')]}">
attrs="{'invisible':['|','|', ('massive_changes_on','=','pricelist'), ('avail_readonly','=',True), ('pricelist_readonly', '=', True)]}" <b>Rules to apply:</b>
> <div class="row">
Rules to apply: <div class="col-4 pr-0">
</b> <div class="border h-100 pt-2 px-2">
<div class="row">
<div <div class="col-2">
class="row" <field
attrs="{'invisible':[('massive_changes_on','=','pricelist')]}" name="apply_min_stay"
> widget="boolean_toggle"
/>
<div class="col-4"> </div>
<group> <div class="col-6">
<field string="Min. Stay" name="min_stay" /> <label for="min_stay" />
<field string="Max. Stay" name="max_stay" /> </div>
</group> <div class="col-4">
<field
name="min_stay"
nolabel="1"
attrs="{'invisible':[('apply_min_stay','=',False)], 'required':[('apply_min_stay','=',True)]}"
/>
</div>
</div>
</div>
</div> </div>
<div class="col-5 pr-0">
<div class="col-4"> <div class="border h-100 pt-2 px-2 ">
<group> <div class="row">
<field string="Min. Stay Arrival" name="min_stay_arrival" /> <div class="col-2">
<field string="Max. Stay Arrival" name="max_stay_arrival" /> <field
</group> name="apply_min_stay_arrival"
widget="boolean_toggle"
/>
</div>
<div class="col-6">
<label for="min_stay_arrival" />
</div>
<div class="col-4">
<field
name="min_stay_arrival"
nolabel="1"
attrs="{'invisible':[('apply_min_stay_arrival','=',False)],'required':[('apply_min_stay_arrival','=',True)]}"
/>
</div>
</div>
</div>
</div> </div>
<div class="col-4"> <div class="col-3">
<group> <div class="border h-100 pt-2 px-2">
<field string="Closed" name="closed" /> <div class="row">
<field string="Closed Arrival" name="closed_arrival" /> <div class="col-3">
<field string="Closed departure" name="closed_departure" /> <field
</group> name="apply_closed"
</div> widget="boolean_toggle"
<div class="col-4"> />
<group> </div>
<field string="Quota" name="quota" /> <div class="col-9">
</group> <field
</div> name="closed"
<div class="col-4"> attrs="{'readonly':[('apply_closed','=',False)]}"
<group> />
<field string="Max. Avail." name="max_avail" /> <label for="closed" />
</group> </div>
</div>
</div>
</div> </div>
</div> </div>
<div class="row pt-3">
<div class="col-4 pr-0">
<div class="border h-100 pt-2 px-2 ">
<div class="row">
<div class="col-2">
<field
name="apply_max_stay"
widget="boolean_toggle"
/>
</div>
<div class="col-6">
<label for="max_stay" />
</div>
<div class="col-4">
<field
name="max_stay"
nolabel="1"
attrs="{'invisible':[('apply_max_stay','=',False)], 'required':[('apply_max_stay','=',True)]}"
/>
</div>
</div>
</div>
</div>
<div class="col-5 pr-0">
<div class="border h-100 pt-2 px-2 ">
<div class="row">
<div class="col-2">
<field
name="apply_max_stay_arrival"
widget="boolean_toggle"
/>
</div>
<div class="col-6">
<label for="max_stay_arrival" />
</div>
<div class="col-4">
<field
name="max_stay_arrival"
nolabel="1"
attrs="{'invisible':[('apply_max_stay_arrival','=',False)], 'required':[('apply_max_stay_arrival','=',True)]}"
/>
</div>
</div>
</div>
</div>
<div class="col-3">
<div class="border h-100 pt-2 px-2">
<div class="row">
<div class="col-3">
<field
name="apply_closed_arrival"
widget="boolean_toggle"
/>
</div>
<div class="col-9">
<field
name="closed_arrival"
attrs="{'readonly':[('apply_closed_arrival','=',False)]}"
/>
<label for="closed_arrival" />
</div>
</div>
</div>
</div>
</div>
<div class="row pt-4">
<div class="col-4 pr-0">
<div class="border h-100 pt-2 px-2 ">
<div class="row">
<div class="col-2">
<field name="apply_quota" widget="boolean_toggle" />
</div>
<div class="col-6">
<label for="quota" />
</div>
<div class="col-4">
<field
name="quota"
nolabel="1"
attrs="{'invisible':[('apply_quota','=',False)], 'required':[('apply_quota','=',True)]}"
/>
</div>
</div>
</div>
</div>
<div class="col-5 pr-0">
<div class="border h-100 pt-2 px-2">
<div class="row">
<div class="col-2">
<field
name="apply_max_avail"
widget="boolean_toggle"
/>
</div>
<div class="col-6">
<label for="max_avail" />
</div>
<div class="col-4">
<field
name="max_avail"
nolabel="1"
attrs="{'invisible':[('apply_max_avail','=',False)],'required':[('apply_max_avail','=',True)]}"
/>
</div>
</div>
</div>
</div>
<div class="col-3">
<div class="border h-100 pt-2 px-2">
<div class="row">
<div class="col-3">
<field
name="apply_closed_departure"
widget="boolean_toggle"
/>
</div>
<div class="col-9">
<field
name="closed_departure"
attrs="{'readonly':[('apply_closed_departure','=',False)]}"
/>
<label for="closed_departure" />
</div>
</div>
</div>
</div>
</div>
</span>
<br />
<div <div
class="row"
attrs="{'invisible':[('massive_changes_on','=','availability_plan')]}" attrs="{'invisible':[('massive_changes_on','=','availability_plan')]}"
> >
<div class="col-4"> <div class="col-4">
@@ -193,7 +346,10 @@
</group> </group>
</div> </div>
</div> </div>
<b attrs="{'invisible':[('massive_changes_on','=','pricelist')]}"> <b
attrs="{'invisible':[('massive_changes_on','=','pricelist')]}"
class="mt-5"
>
<span style="text-decoration:underline;"> <span style="text-decoration:underline;">
<field name="num_rules_to_overwrite" /> <field name="num_rules_to_overwrite" />
</span> </span>
@@ -213,8 +369,55 @@
</b> </b>
<field <field
name="rules_to_overwrite" name="rules_to_overwrite"
nolabel="1"
attrs="{'invisible':[('massive_changes_on','=','pricelist')]}" attrs="{'invisible':[('massive_changes_on','=','pricelist')]}"
/> >
<tree>
<field name="date" />
<field name="room_type_id" />
<field
name="quota"
attrs="{'column_invisible':[('parent.apply_quota', '==', False)]}"
/>
<field
name="max_avail"
attrs="{'column_invisible':[('parent.apply_max_avail', '==', False)]}"
/>
<field
name="min_stay"
attrs="{'column_invisible':[('parent.apply_min_stay', '==', False)]}"
/>
<field
name="max_stay"
attrs="{'column_invisible':[('parent.apply_max_stay', '==', False)]}"
/>
<field
name="min_stay_arrival"
attrs="{'column_invisible':[('parent.apply_min_stay_arrival', '==', False)]}"
/>
<field
name="max_stay_arrival"
attrs="{'column_invisible':[('parent.apply_max_stay_arrival', '==', False)]}"
/>
<field
name="closed"
attrs="{'column_invisible':[('parent.apply_closed', '==', False)]}"
/>
<field
name="closed_arrival"
attrs="{'column_invisible':[('parent.apply_closed_arrival', '==', False)]}"
/>
<field
name="closed_departure"
attrs="{'column_invisible':[('parent.apply_closed_departure', '==', False)]}"
/>
</tree>
</field>
<field <field
name="pricelist_items_to_overwrite" name="pricelist_items_to_overwrite"
nolabel="1" nolabel="1"