mirror of
https://github.com/OCA/pms.git
synced 2025-01-29 00:17:45 +02:00
432 lines
15 KiB
Python
432 lines
15 KiB
Python
from datetime import timedelta
|
|
|
|
from odoo import api, fields, models
|
|
|
|
|
|
class WizardFolioChanges(models.TransientModel):
|
|
|
|
_name = "wizard.folio.changes"
|
|
_description = "Folio Changes"
|
|
|
|
folio_id = fields.Many2one(
|
|
string="Folio",
|
|
default=lambda self: self._default_folio_id(),
|
|
comodel_name="pms.folio",
|
|
)
|
|
modification_type = fields.Selection(
|
|
string="Modification Type",
|
|
selection=[
|
|
("reservations", "Reservations"),
|
|
("dates", "Dates"),
|
|
("services", "Services Prices"),
|
|
],
|
|
default="reservations",
|
|
)
|
|
room_type_filter_ids = fields.Many2many(
|
|
string="Room types",
|
|
default=lambda self: self._default_room_type_filter_ids(),
|
|
comodel_name="pms.room.type",
|
|
relation="folio_changes_room_type_rel",
|
|
column1="folio_changes_id",
|
|
column2="room_type_ids",
|
|
domain="[('id', 'in', allowed_room_type_ids)]",
|
|
)
|
|
allowed_room_type_ids = fields.Many2many(
|
|
string="Allowed Room Types",
|
|
comodel_name="pms.room.type",
|
|
relation="folio_changes_allowed_room_type_rel",
|
|
column1="folio_changes_id",
|
|
column2="allowed_room_type_ids",
|
|
compute="_compute_allowed_room_type_ids",
|
|
)
|
|
change_from_date = fields.Date(
|
|
string="Apply From",
|
|
default=lambda self: self.default_change_from_date(),
|
|
)
|
|
change_to_date = fields.Date(
|
|
string="Apply To",
|
|
default=lambda self: self.default_change_to_date(),
|
|
)
|
|
reservation_ids = fields.Many2many(
|
|
string="Reservations",
|
|
default=lambda self: self._default_reservation_ids(),
|
|
comodel_name="pms.reservation",
|
|
relation="folio_changes_reservation_rel",
|
|
column1="folio_changes_id",
|
|
column2="reservation_ids",
|
|
domain="[('id', 'in', allowed_reservation_ids)]",
|
|
)
|
|
allowed_reservation_ids = fields.Many2many(
|
|
string="Allowed Reservations",
|
|
comodel_name="pms.reservation",
|
|
relation="folio_changes_allowed_reservation_rel",
|
|
column1="folio_changes_id",
|
|
column2="allowed_reservation_ids",
|
|
compute="_compute_allowed_reservation_ids",
|
|
)
|
|
service_ids = fields.Many2many(
|
|
string="Services",
|
|
default=lambda self: self._default_service_ids(),
|
|
comodel_name="pms.service",
|
|
relation="folio_changes_service_rel",
|
|
column1="folio_changes_id",
|
|
column2="service_ids",
|
|
domain="[('id', 'in', allowed_service_ids)]",
|
|
)
|
|
allowed_service_ids = fields.Many2many(
|
|
string="Allowed Services",
|
|
comodel_name="pms.service",
|
|
relation="folio_changes_allowed_service_rel",
|
|
column1="folio_changes_id",
|
|
column2="allowed_service_ids",
|
|
compute="_compute_allowed_service_ids",
|
|
)
|
|
apply_new_checkin = fields.Boolean(
|
|
string="Apply Checkin Update",
|
|
default=False,
|
|
)
|
|
new_checkin = fields.Date(
|
|
string="New Checkin",
|
|
default=lambda self: self.default_change_new_checkin(),
|
|
)
|
|
|
|
apply_new_checkout = fields.Boolean(
|
|
string="Apply Checkout Update",
|
|
default=False,
|
|
)
|
|
new_checkout = fields.Date(
|
|
string="New Checkout",
|
|
default=lambda self: self.default_change_new_checkout(),
|
|
)
|
|
nights = fields.Integer(
|
|
string="Nights",
|
|
compute="_compute_nights",
|
|
)
|
|
dates_incongruence = fields.Boolean(
|
|
string="Dates incrongruence",
|
|
help="Indicates that there are reservations with different checkin and/or checkout",
|
|
compute="_compute_dates_incongruence",
|
|
store=True,
|
|
)
|
|
apply_price = fields.Boolean(
|
|
string="Apply Price update",
|
|
default=False,
|
|
)
|
|
new_price = fields.Float(
|
|
string="New Price",
|
|
)
|
|
|
|
apply_discount = fields.Boolean(
|
|
string="Apply Discount update",
|
|
default=False,
|
|
)
|
|
new_discount = fields.Float(
|
|
string="New Discount %",
|
|
)
|
|
|
|
apply_partner_id = fields.Boolean(
|
|
string="Apply Customer",
|
|
default=False,
|
|
)
|
|
new_partner_id = fields.Many2one(
|
|
string="Customer",
|
|
comodel_name="res.partner",
|
|
)
|
|
|
|
apply_pricelist_id = fields.Boolean(
|
|
string="Apply Pricelist",
|
|
default=False,
|
|
)
|
|
new_pricelist_id = fields.Many2one(
|
|
string="Pricelist",
|
|
comodel_name="product.pricelist",
|
|
domain="[('is_pms_available', '=', True)]",
|
|
)
|
|
|
|
apply_board_service = fields.Boolean(
|
|
string="Add Board Service to reservations",
|
|
default=False,
|
|
)
|
|
new_board_service_id = fields.Many2one(
|
|
string="New Board Service",
|
|
comodel_name="pms.board.service",
|
|
)
|
|
|
|
apply_service = fields.Boolean(
|
|
string="Add Service to reservations",
|
|
default=False,
|
|
)
|
|
new_service_id = fields.Many2one(
|
|
string="New Service",
|
|
comodel_name="product.product",
|
|
domain="[('sale_ok','=',True)]",
|
|
)
|
|
|
|
apply_day_qty = fields.Boolean(
|
|
string="Change cuantity service per day",
|
|
help="If not set, it will use the default product day qty",
|
|
default=False,
|
|
)
|
|
day_qty = fields.Integer(
|
|
string="Quantity per day",
|
|
)
|
|
|
|
apply_on_monday = fields.Boolean(
|
|
string="Apply Availability Rule on mondays",
|
|
default=False,
|
|
)
|
|
apply_on_tuesday = fields.Boolean(
|
|
string="Apply Availability Rule on tuesdays",
|
|
default=False,
|
|
)
|
|
apply_on_wednesday = fields.Boolean(
|
|
string="Apply Availability Rule on wednesdays",
|
|
default=False,
|
|
)
|
|
apply_on_thursday = fields.Boolean(
|
|
string="Apply Availability Rule on thursdays",
|
|
default=False,
|
|
)
|
|
apply_on_friday = fields.Boolean(
|
|
string="Apply Availability Rule on fridays",
|
|
default=False,
|
|
)
|
|
apply_on_saturday = fields.Boolean(
|
|
string="Apply Availability Rule on saturdays",
|
|
default=False,
|
|
)
|
|
apply_on_sunday = fields.Boolean(
|
|
string="Apply Availability Rule on sundays",
|
|
default=False,
|
|
)
|
|
apply_on_all_week = fields.Boolean(
|
|
string="Apply Availability Rule for the whole week",
|
|
default=True,
|
|
)
|
|
|
|
def _default_folio_id(self):
|
|
folio_id = self._context.get("active_id")
|
|
folio = self.env["pms.folio"].browse(folio_id)
|
|
return folio
|
|
|
|
def _default_reservation_ids(self):
|
|
folio_id = self._context.get("active_id")
|
|
folio = self.env["pms.folio"].browse(folio_id)
|
|
return folio.reservation_ids
|
|
|
|
def _default_room_type_filter_ids(self):
|
|
folio_id = self._context.get("active_id")
|
|
folio = self.env["pms.folio"].browse(folio_id)
|
|
return self.env["pms.room.type"].browse(
|
|
folio.mapped("reservation_ids.room_type_id.id")
|
|
)
|
|
|
|
def default_change_new_checkin(self):
|
|
folio_id = self._context.get("active_id")
|
|
folio = self.env["pms.folio"].browse(folio_id)
|
|
return min(folio.reservation_ids.mapped("checkin"), default=False)
|
|
|
|
def default_change_new_checkout(self):
|
|
folio_id = self._context.get("active_id")
|
|
folio = self.env["pms.folio"].browse(folio_id)
|
|
return max(folio.reservation_ids.mapped("checkout"), default=False)
|
|
|
|
def _default_service_ids(self):
|
|
folio_id = self._context.get("active_id")
|
|
folio = self.env["pms.folio"].browse(folio_id)
|
|
return folio.service_ids
|
|
|
|
def default_change_from_date(self):
|
|
folio_id = self._context.get("active_id")
|
|
folio = self.env["pms.folio"].browse(folio_id)
|
|
return min(folio.reservation_ids.mapped("checkin"), default=False)
|
|
|
|
def default_change_to_date(self):
|
|
folio_id = self._context.get("active_id")
|
|
folio = self.env["pms.folio"].browse(folio_id)
|
|
return max(folio.reservation_ids.mapped("checkout"), default=False)
|
|
|
|
@api.depends("new_checkin", "new_checkout")
|
|
def _compute_nights(self):
|
|
for record in self:
|
|
record.nights = (record.new_checkout - record.new_checkin).days
|
|
|
|
@api.depends("reservation_ids")
|
|
def _compute_dates_incongruence(self):
|
|
self.dates_incongruence = False
|
|
for record in self:
|
|
if (
|
|
len(set(record.reservation_ids.mapped("checkin"))) > 1
|
|
or len(set(record.reservation_ids.mapped("checkout"))) > 1
|
|
):
|
|
record.dates_incongruence = True
|
|
|
|
@api.depends("folio_id")
|
|
def _compute_allowed_reservation_ids(self):
|
|
self.ensure_one()
|
|
self.allowed_reservation_ids = self.folio_id.reservation_ids
|
|
|
|
@api.depends("folio_id")
|
|
def _compute_allowed_service_ids(self):
|
|
self.ensure_one()
|
|
self.allowed_service_ids = self.folio_id.service_ids
|
|
|
|
@api.depends("folio_id")
|
|
def _compute_allowed_room_type_ids(self):
|
|
self.ensure_one()
|
|
self.allowed_room_type_ids = self.env["pms.room.type"].browse(
|
|
self.folio_id.mapped("reservation_ids.room_type_id.id")
|
|
)
|
|
|
|
@api.onchange("room_type_filter_ids")
|
|
def _onchange_room_type_filter_ids(self):
|
|
self.service_ids = self.folio_id.service_ids.filtered(
|
|
lambda s: s.reservation_id
|
|
and s.reservation_id.room_type_id.id in self.room_type_filter_ids.ids
|
|
)
|
|
self.reservation_ids = self.folio_id.reservation_ids.filtered(
|
|
lambda r: r.room_type_id.id in self.room_type_filter_ids.ids
|
|
)
|
|
|
|
@api.onchange("reservation_ids")
|
|
def _onchange_reservations_ids(self):
|
|
self.new_checkin = min(self.reservation_ids.mapped("checkin"), default=False)
|
|
self.new_checkout = max(self.reservation_ids.mapped("checkout"), default=False)
|
|
|
|
def button_change(self):
|
|
week_days_to_apply = (
|
|
self.apply_on_monday,
|
|
self.apply_on_tuesday,
|
|
self.apply_on_wednesday,
|
|
self.apply_on_thursday,
|
|
self.apply_on_friday,
|
|
self.apply_on_saturday,
|
|
self.apply_on_sunday,
|
|
)
|
|
if self.modification_type == "dates":
|
|
self._update_dates(
|
|
reservations=self.reservation_ids,
|
|
new_checkin=self.new_checkin,
|
|
new_checkout=self.new_checkout,
|
|
)
|
|
else:
|
|
dates = [
|
|
self.change_from_date + timedelta(days=d)
|
|
for d in range((self.change_to_date - self.change_from_date).days + 1)
|
|
]
|
|
if self.modification_type == "reservations":
|
|
reservation_lines = self.reservation_ids.reservation_line_ids
|
|
if not self.apply_on_all_week:
|
|
reservation_lines = reservation_lines.filtered(
|
|
lambda x: week_days_to_apply[x.date.timetuple()[6]]
|
|
and x.date in dates
|
|
)
|
|
if self.apply_discount or self.apply_price:
|
|
self._update_reservations(
|
|
reservation_lines=reservation_lines,
|
|
new_price=self.apply_price and self.new_price,
|
|
new_discount=self.apply_discount and self.new_discount,
|
|
)
|
|
if self.apply_board_service and self.new_board_service_id:
|
|
self._add_board_service(
|
|
reservations=self.reservation_ids,
|
|
new_board_service_id=self.new_board_service_id.id,
|
|
)
|
|
if self.apply_service and self.new_service_id:
|
|
self._add_service(
|
|
reservations=self.reservation_ids,
|
|
new_service_id=self.new_service_id.id,
|
|
day_qty=self.day_qty if self.apply_day_qty else -1,
|
|
)
|
|
if self.apply_pricelist_id and self.new_pricelist_id:
|
|
self.reservation_ids.pricelist_id = self.new_pricelist_id
|
|
self.folio_id.pricelist_id = self.new_pricelist_id
|
|
if self.apply_partner_id and self.new_partner_id:
|
|
self.reservation_ids.partner_id = self.new_partner_id
|
|
if not self.folio_id.partner_id:
|
|
self.folio_id.partner_id = self.new_partner_id
|
|
elif self.modification_type == "services":
|
|
service_lines = self.service_ids.service_line_ids
|
|
if not self.apply_on_all_week:
|
|
reservation_lines = service_lines.filtered(
|
|
lambda x: week_days_to_apply[x.date.timetuple()[6]]
|
|
and x.date in dates
|
|
)
|
|
self._update_services(
|
|
service_lines=service_lines,
|
|
new_price=self.apply_price and self.new_price,
|
|
new_discount=self.apply_discount and self.new_discount,
|
|
)
|
|
|
|
def _update_dates(self, reservations, new_checkin, new_checkout):
|
|
for res in reservations:
|
|
if new_checkin and new_checkout:
|
|
res.write({"checkin": new_checkin, "checkout": new_checkout})
|
|
elif new_checkin:
|
|
res.checkin = new_checkin
|
|
elif new_checkout:
|
|
res.checkout = new_checkout
|
|
|
|
def _update_reservations(
|
|
self, reservation_lines, new_price=False, new_discount=False
|
|
):
|
|
line_vals = {}
|
|
if new_price:
|
|
line_vals["price"] = new_price
|
|
if new_discount:
|
|
line_vals["discount"] = new_discount
|
|
if line_vals:
|
|
reservation_lines.write(line_vals)
|
|
|
|
def _add_board_service(self, reservations, new_board_service_id):
|
|
for reservation in reservations:
|
|
if new_board_service_id in reservation.room_type_id.mapped(
|
|
"board_service_room_type_ids.pms_board_service_id.id"
|
|
):
|
|
reservation.board_service_room_id = (
|
|
reservation.room_type_id.board_service_room_type_ids.filtered(
|
|
lambda x: x.pms_board_service_id.id == new_board_service_id
|
|
and (
|
|
reservation.folio_id.pms_property_id.id
|
|
== x.pms_property_id.ids
|
|
)
|
|
and (
|
|
not x.pricelist_ids
|
|
or reservation.pricelist_id.id in x.pricelist_ids.ids
|
|
)
|
|
)
|
|
)
|
|
|
|
def _add_service(self, reservations, new_service_id, day_qty):
|
|
old_services = reservations.service_ids
|
|
reservations.write(
|
|
{
|
|
"service_ids": [
|
|
(
|
|
0,
|
|
0,
|
|
{
|
|
"product_id": new_service_id,
|
|
},
|
|
)
|
|
]
|
|
}
|
|
)
|
|
new_services = reservations.service_ids - old_services
|
|
# Use -1 to set default qty qty per day
|
|
if day_qty > -1:
|
|
new_services.day_qty = day_qty
|
|
|
|
def _update_services(
|
|
self, service_lines, new_price=False, new_discount=False, new_day_qty=False
|
|
):
|
|
line_vals = {}
|
|
if new_price:
|
|
line_vals["price_unit"] = new_price
|
|
if new_discount:
|
|
line_vals["discount"] = new_discount
|
|
if new_day_qty:
|
|
line_vals["day_qty"] = new_day_qty
|
|
if line_vals:
|
|
service_lines.write(line_vals)
|