diff --git a/pms/models/pms_folio.py b/pms/models/pms_folio.py index 5ec54f9c0..d7949ffa2 100644 --- a/pms/models/pms_folio.py +++ b/pms/models/pms_folio.py @@ -204,17 +204,32 @@ class PmsFolio(models.Model): ondelete="restrict", check_pms_properties=True, ) - channel_type_id = fields.Many2one( - string="Direct Sale Channel", - help="Only allowed if the field of sale channel channel_type is 'direct'", - readonly=False, + # channel_type_id = fields.Many2one( + # string="Direct Sale Channel", + # help="Only allowed if the field of sale channel channel_type is 'direct'", + # readonly=False, + # store=True, + # comodel_name="pms.sale.channel", + # domain=[("channel_type", "=", "direct")], + # ondelete="restrict", + # compute="_compute_channel_type_id", + # check_pms_properties=True, + # ) + sale_channel_ids = fields.Many2many( + string="Sale Channels", + help="Sale Channels through which reservations were managed", store=True, + compute="_compute_sale_channel_ids", comodel_name="pms.sale.channel", - domain=[("channel_type", "=", "direct")], - ondelete="restrict", - compute="_compute_channel_type_id", - check_pms_properties=True, ) + sale_channel_origin_id = fields.Many2one( + string="Sale Channel Origin", + help="Sale Channel through which folio was created, the original", + comodel_name="pms.sale.channel", + store=True, + compute="_compute_sale_channel_origin_id", + ) + transaction_ids = fields.Many2many( string="Transactions", help="Payments made through payment acquirer", @@ -1049,10 +1064,17 @@ class PmsFolio(models.Model): folio.commission = folio.commission + reservation.commission_amount @api.depends("agency_id") - def _compute_channel_type_id(self): + def _compute_sale_channel_origin_id(self): for folio in self: if folio.agency_id: - folio.channel_type_id = folio.agency_id.sale_channel_id.id + folio.sale_channel_origin_id = folio.agency_id.sale_channel_id.id + + @api.depends("reservation_ids", "reservation_ids.sale_channel_ids") + def _compute_sale_channel_ids(self): + for record in self: + record.sale_channel_ids = [ + (6, 0, record.mapped("reservation_ids.sale_channel_origin_id.id")) + ] @api.depends("sale_line_ids.invoice_lines") def _compute_get_invoiced(self): @@ -1491,17 +1513,17 @@ class PmsFolio(models.Model): ("sale_line_ids.invoice_lines.move_id", operator, value), ] - @api.constrains("agency_id", "channel_type_id") - def _check_only_one_channel(self): - for record in self: - if ( - record.agency_id - and record.channel_type_id.channel_type - != record.agency_id.sale_channel_id.channel_type - ): - raise models.ValidationError( - _("The Sale Channel does not correspond to the agency's") - ) + # @api.constrains("agency_id", "channel_type_id") + # def _check_only_one_channel(self): + # for record in self: + # if ( + # record.agency_id + # and record.channel_type_id.channel_type + # != record.agency_id.sale_channel_id.channel_type + # ): + # raise models.ValidationError( + # _("The Sale Channel does not correspond to the agency's") + # ) @api.constrains("name") def _check_required_partner_name(self): @@ -1523,6 +1545,23 @@ class PmsFolio(models.Model): result.access_token = result._portal_ensure_token() return result + def write(self, vals): + reservations_to_update = self.env["pms.reservation"] + if "sale_channel_origin_id" in vals: + for record in self: + for reservation in record.reservation_ids: + if ( + reservation.sale_channel_origin_id + == self.sale_channel_origin_id + ): + reservations_to_update += reservation + res = super(PmsFolio, self).write(vals) + if reservations_to_update: + reservations_to_update.sale_channel_origin_id = vals[ + "sale_channel_origin_id" + ] + return res + def action_pay(self): self.ensure_one() self.ensure_one() diff --git a/pms/models/pms_reservation.py b/pms/models/pms_reservation.py index 94ee17dd0..ade2a0447 100644 --- a/pms/models/pms_reservation.py +++ b/pms/models/pms_reservation.py @@ -124,13 +124,37 @@ class PmsReservation(models.Model): depends=["folio_id.agency_id"], tracking=True, ) - channel_type_id = fields.Many2one( - string="Channel Type", - help="Sales Channel through which the reservation was managed", - readonly=False, + sale_channel_ids = fields.Many2many( + string="Sale Channels", + help="Sale Channels through which reservation lines were managed", store=True, - related="folio_id.channel_type_id", - tracking=True, + compute="_compute_sale_channel_ids", + comodel_name="pms.sale.channel", + ) + sale_channel_origin_id = fields.Many2one( + string="Sale Channel Origin", + help="Sale Channel through which reservation was created, the original", + store=True, + readonly=False, + compute="_compute_sale_channel_origin_id", + default=lambda self: self._get_default_sale_channel_origin(), + comodel_name="pms.sale.channel", + ) + force_update_origin = fields.Boolean( + string="Update Sale Channel Origin", + help="This field is for force update in sale channel " + "origin of folio and another reservations", + store=True, + readonly=False, + compute="_compute_force_update_origin", + ) + is_origin_channel_check_visible = fields.Boolean( + string="Update Sale Channel Origin", + help="This field is for force update in sale channel " + "origin of folio and another reservations", + store=True, + readonly=False, + compute="_compute_is_origin_channel_check_visible", ) closure_reason_id = fields.Many2one( string="Closure Reason", @@ -1608,6 +1632,38 @@ class PmsReservation(models.Model): else: record.lang = self.env["res.lang"].get_installed() + + @api.depends("reservation_line_ids", "reservation_line_ids.sale_channel_id") + def _compute_sale_channel_ids(self): + for record in self: + record.sale_channel_ids = [ + (6, 0, record.mapped("reservation_line_ids.sale_channel_id.id")) + ] + + @api.depends("agency_id") + def _compute_sale_channel_origin_id(self): + for record in self: + # if record.folio_id.sale_channel_origin_id and not record.sale_channel_origin_id: + # record.sale_channel_origin_id = record.folio_id.sale_channel_origin_id + if record.agency_id: + record.sale_channel_origin_id = record.agency_id.sale_channel_id + + @api.depends("sale_channel_origin_id") + def _compute_is_origin_channel_check_visible(self): + for record in self: + if ( + record.sale_channel_origin_id != record.folio_id.sale_channel_origin_id + and record.folio_id + ): + record.is_origin_channel_check_visible = True + else: + record.is_origin_channel_check_visible = False + + @api.depends("sale_channel_origin_id") + def _compute_force_update_origin(self): + for record in self: + record.force_update_origin = True + def _search_allowed_checkin(self, operator, value): if operator not in ("=",): raise UserError( @@ -1674,6 +1730,17 @@ class PmsReservation(models.Model): segmentation_ids = folio.segmentation_ids return segmentation_ids + def _get_default_sale_channel_origin(self): + folio = False + sale_channel_origin_id = False + if "default_folio_id" in self._context: + folio = self.env["pms.folio"].search( + [("id", "=", self._context["default_folio_id"])] + ) + if folio and folio.sale_channel_origin_id: + sale_channel_origin_id = folio.sale_channel_origin_id + return sale_channel_origin_id + def check_in_out_dates(self): """ 1.-When date_order is less then checkin date or @@ -1943,12 +2010,18 @@ class PmsReservation(models.Model): elif vals.get("reservation_type") != "out": raise ValidationError(_("Partner contact name is required")) vals.update(default_vals) - elif "pms_property_id" in vals and ( - "partner_name" in vals or "partner_id" in vals or "agency_id" in vals + elif ( + "pms_property_id" in vals + and ("sale_channel_origin_id" in vals or "agency_id" in vals) + and ("partner_name" in vals or "partner_id" in vals or "agency_id" in vals) ): folio_vals = { "pms_property_id": vals["pms_property_id"], } + if vals.get("sale_channel_origin_id"): + folio_vals["sale_channel_origin_id"] = vals.get( + "sale_channel_origin_id" + ) if vals.get("partner_id"): folio_vals["partner_id"] = vals.get("partner_id") elif vals.get("agency_id"): @@ -1981,7 +2054,11 @@ class PmsReservation(models.Model): ) else: - raise ValidationError(_("The Property are mandatory in the reservation")) + raise ValidationError( + _( + "The Property and Sale Channel Origin are mandatory in the reservation" + ) + ) if vals.get("name", _("New")) == _("New") or "name" not in vals: folio_sequence = ( max(folio.mapped("reservation_ids.folio_sequence")) + 1 @@ -2004,13 +2081,24 @@ class PmsReservation(models.Model): return record def write(self, vals): - asset = super(PmsReservation, self).write(vals) + folios_to_update_channel = self.env["pms.folio"] + lines_to_update_channel = self.env["pms.reservation.line"] + if "sale_channel_origin_id" in vals: + folios_to_update_channel = self.get_folios_to_update_channel(vals) + lines_to_update_channel = self.get_lines_to_update_channel(vals) + res = super(PmsReservation, self).write(vals) + if folios_to_update_channel: + folios_to_update_channel.sale_channel_origin_id = vals[ + "sale_channel_origin_id" + ] + if lines_to_update_channel: + lines_to_update_channel.sale_channel_id = vals["sale_channel_origin_id"] self._check_services(vals) # Only check if adult to avoid to check capacity in intermediate states (p.e. flush) # that not take access to possible extra beds service in vals if "adults" in vals: self._check_capacity() - return asset + return res def _check_services(self, vals): # If we create a reservation with board service and other service at the same time, @@ -2019,6 +2107,30 @@ class PmsReservation(models.Model): if "board_service_room_id" in vals and "service_ids" in vals: self._compute_service_ids() + def get_folios_to_update_channel(self, vals): + folios_to_update_channel = self.env["pms.folio"] + for folio in self.mapped("folio_id"): + if ( + any( + res.sale_channel_origin_id == folio.sale_channel_origin_id + for res in self.filtered(lambda r: r.folio_id == folio) + ) + and vals["sale_channel_origin_id"] != folio.sale_channel_origin_id.id + and ("force_update_origin" in vals and vals.get("force_update_origin")) + ): + folios_to_update_channel += folio + return folios_to_update_channel + + def get_lines_to_update_channel(self, vals): + lines_to_update_channel = self.env["pms.reservation.line"] + for record in self: + for line in record.reservation_line_ids: + if line.sale_channel_id == record.sale_channel_origin_id and ( + vals["sale_channel_origin_id"] != line.sale_channel_id.id + ): + lines_to_update_channel += line + return lines_to_update_channel + def update_prices(self): self.ensure_one() for line in self.reservation_line_ids: diff --git a/pms/models/pms_reservation_line.py b/pms/models/pms_reservation_line.py index aa64e0d1b..367c95fcf 100644 --- a/pms/models/pms_reservation_line.py +++ b/pms/models/pms_reservation_line.py @@ -112,6 +112,12 @@ class PmsReservationLine(models.Model): store=True, readonly=False, compute="_compute_overbooking", + sale_channel_id = fields.Many2one( + string="Sale Channel", + help="Sale Channel through which reservation line was created", + comodel_name="pms.sale.channel", + ondelete="restrict", + check_pms_properties=True, ) _sql_constraints = [ ( @@ -483,6 +489,10 @@ class PmsReservationLine(models.Model): records = super().create(vals_list) for line in records: reservation = line.reservation_id + # Set default channel + if not line.sale_channel_id: + line.sale_channel_id = reservation.sale_channel_origin_id.id + # Update quota self.env["pms.availability.plan"].update_quota( pricelist_id=reservation.pricelist_id.id, room_type_id=reservation.room_type_id.id, diff --git a/pms/views/pms_folio_views.xml b/pms/views/pms_folio_views.xml index c835bdda5..72a5bd734 100644 --- a/pms/views/pms_folio_views.xml +++ b/pms/views/pms_folio_views.xml @@ -348,10 +348,16 @@ name="agency_id" attrs="{'invisible': [('reservation_type', 'not in', 'normal')]}" /> + + - + + + + + + - + + + + + + + diff --git a/pms/views/pms_reservation_views.xml b/pms/views/pms_reservation_views.xml index b77a394fa..ce3db2d6b 100644 --- a/pms/views/pms_reservation_views.xml +++ b/pms/views/pms_reservation_views.xml @@ -441,17 +441,25 @@ options="{'no_create': True,'no_open': True}" attrs="{'invisible': [('reservation_type','in',('out'))]}" /> - + + + + @@ -491,6 +499,7 @@ name="cancel_discount" attrs="{'column_invisible': [('parent.state','!=','cancel')]}" /> + @@ -786,7 +795,8 @@ - + + @@ -1014,12 +1024,12 @@ name="agency" context="{'group_by':'agency_id'}" /> - + + + + + + - + + + + + + +