From ceb2f4ef9deabd4dadce5114bafadaafa62982a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dar=C3=ADo=20Lodeiros?= Date: Sat, 23 Apr 2022 08:59:26 +0200 Subject: [PATCH] [IMP]pms: refact compute folio sale lines --- pms/models/folio_sale_line.py | 4 +- pms/models/pms_folio.py | 369 +++++++++++++++++++++------------- pms/views/pms_folio_views.xml | 9 +- 3 files changed, 232 insertions(+), 150 deletions(-) diff --git a/pms/models/folio_sale_line.py b/pms/models/folio_sale_line.py index 1965b0c63..28947f216 100644 --- a/pms/models/folio_sale_line.py +++ b/pms/models/folio_sale_line.py @@ -14,7 +14,9 @@ from odoo.tools.misc import get_lang class FolioSaleLine(models.Model): _name = "folio.sale.line" _description = "Folio Sale Line" - _order = "folio_id, sequence, reservation_order desc, service_order, date_order" + _order = ( + "folio_id, sequence, reservation_order desc, service_order, name, date_order" + ) _check_company_auto = True folio_id = fields.Many2one( diff --git a/pms/models/pms_folio.py b/pms/models/pms_folio.py index dafffc482..2f1a9f90e 100644 --- a/pms/models/pms_folio.py +++ b/pms/models/pms_folio.py @@ -809,20 +809,61 @@ class PmsFolio(models.Model): ) def _compute_sale_line_ids(self): for folio in self: + sale_lines_vals = [] if folio.reservation_type == "normal": + sale_lines_vals_to_drop = [] for reservation in folio.reservation_ids: # RESERVATION LINES - # res = self.env['pms.reservation'].browse(reservation.id) - self.generate_reservation_lines_sale_lines(folio, reservation) - + reservation_sale_lines = [] + reservation_sale_lines_to_drop = [] + if reservation.reservation_line_ids: + ( + reservation_sale_lines, + reservation_sale_lines_to_drop, + ) = self._get_reservation_sale_lines( + folio, reservation, sequence=reservation.folio_sequence + ) + if reservation_sale_lines: + sale_lines_vals.extend(reservation_sale_lines) + if reservation_sale_lines_to_drop: + sale_lines_vals_to_drop.extend(reservation_sale_lines_to_drop) # RESERVATION SERVICES - self.generate_reservation_services_sale_lines(folio, reservation) - + service_sale_lines = [] + service_sale_lines_to_drop = [] + if reservation.service_ids: + ( + service_sale_lines, + service_sale_lines_to_drop, + ) = self._get_service_sale_lines( + folio, + reservation, + sequence=reservation.folio_sequence + + len(reservation_sale_lines), + ) + if service_sale_lines: + sale_lines_vals.extend(service_sale_lines) + if service_sale_lines_to_drop: + sale_lines_vals_to_drop.extend(service_sale_lines_to_drop) # FOLIO SERVICES - self.generate_folio_services_sale_lines(folio) - else: - for reservation in folio.reservation_ids: - reservation.sale_line_ids = False + if folio.service_ids.filtered(lambda r: not r.reservation_id): + service_sale_lines = False + service_sale_lines_to_drop = False + ( + service_sale_lines, + service_sale_lines_to_drop, + ) = self._get_folio_services_sale_lines( + folio, sequence=len(sale_lines_vals) + ) + if service_sale_lines: + sale_lines_vals.extend(service_sale_lines) + if service_sale_lines_to_drop: + sale_lines_vals_to_drop.extend(service_sale_lines_to_drop) + if sale_lines_vals: + folio.sale_line_ids = sale_lines_vals + if sale_lines_vals_to_drop: + self.env["folio.sale.line"].browse(sale_lines_vals_to_drop).unlink() + if not sale_lines_vals: + folio.sale_line_ids = False @api.depends("pms_property_id") def _compute_company_id(self): @@ -2135,9 +2176,10 @@ class PmsFolio(models.Model): } @api.model - def generate_reservation_lines_sale_lines(self, folio, reservation): + def _get_reservation_sale_lines(self, folio, reservation, sequence): + sale_reservation_vals = [] if not reservation.sale_line_ids.filtered(lambda x: x.name == reservation.name): - reservation.sale_line_ids = [ + sale_reservation_vals.append( ( 0, 0, @@ -2150,9 +2192,23 @@ class PmsFolio(models.Model): "price_unit": 0, "tax_ids": False, "folio_id": folio.id, + "reservation_id": reservation.id, + "sequence": sequence, }, ) - ] + ) + else: + sale_reservation_vals.append( + ( + 1, + reservation.sale_line_ids.filtered( + lambda x: x.name == reservation.name + ).id, + { + "sequence": sequence, + }, + ) + ) expected_reservation_lines = self.env["pms.reservation.line"].read_group( [ ("reservation_id", "=", reservation.id), @@ -2169,15 +2225,22 @@ class PmsFolio(models.Model): ) for index, item in enumerate(expected_reservation_lines): + sequence += 1 lines_to = self.env["pms.reservation.line"].search(item["__domain"]) final_discount = self.concat_discounts( item["discount"], item["cancel_discount"] ) if current_sale_line_ids and index <= (len(current_sale_line_ids) - 1): - current_sale_line_ids[index].price_unit = item["price"] - current_sale_line_ids[index].discount = final_discount - current_sale_line_ids[index].reservation_line_ids = lines_to.ids + current = { + "price_unit": item["price"], + "discount": final_discount, + "reservation_line_ids": [(6, 0, lines_to.ids)], + "sequence": sequence, + } + sale_reservation_vals.append( + (1, current_sale_line_ids[index].id, current) + ) else: new = { "reservation_id": reservation.id, @@ -2187,16 +2250,162 @@ class PmsFolio(models.Model): "product_id": reservation.room_type_id.product_id.id, "tax_ids": [(6, 0, reservation.tax_ids.ids)], "reservation_line_ids": [(6, 0, lines_to.ids)], + "sequence": sequence, } - reservation.sale_line_ids = [(0, 0, new)] + sale_reservation_vals.append((0, 0, new)) + folio_sale_lines_to_remove = [] if len(expected_reservation_lines) < len(current_sale_line_ids): folio_sale_lines_to_remove = [ value.id for index, value in enumerate(current_sale_line_ids) if index > (len(expected_reservation_lines) - 1) ] - for fsl in folio_sale_lines_to_remove: - self.env["folio.sale.line"].browse(fsl).unlink() + return sale_reservation_vals, folio_sale_lines_to_remove + + @api.model + def _get_service_sale_lines(self, folio, reservation, sequence): + sale_service_vals = [] + folio_sale_lines_to_remove = [] + for service in reservation.service_ids: + expected_reservation_services = self.env["pms.service.line"].read_group( + [ + ("reservation_id", "=", reservation.id), + ("service_id", "=", service.id), + ("cancel_discount", "<", 100), + ], + ["price_unit", "discount", "cancel_discount"], + ["price_unit", "discount", "cancel_discount"], + lazy=False, + ) + current_sale_service_ids = reservation.sale_line_ids.filtered( + lambda x: x.reservation_id.id == reservation.id + and not x.display_type + and x.service_id.id == service.id + ) + + for index, item in enumerate(expected_reservation_services): + lines_to = self.env["pms.service.line"].search(item["__domain"]) + final_discount = self.concat_discounts( + item["discount"], item["cancel_discount"] + ) + + if current_sale_service_ids and index <= ( + len(current_sale_service_ids) - 1 + ): + current = { + "price_unit": item["price_unit"], + "discount": final_discount, + "service_line_ids": [(6, 0, lines_to.ids)], + "sequence": sequence, + } + sale_service_vals.append( + (1, current_sale_service_ids[index].id, current) + ) + else: + new = { + "service_id": service.id, + "price_unit": item["price_unit"], + "discount": final_discount, + "folio_id": folio.id, + "reservation_id": reservation.id, + "service_line_ids": [(6, 0, lines_to.ids)], + "product_id": service.product_id.id, + "tax_ids": [(6, 0, service.tax_ids.ids)], + "sequence": sequence, + } + sale_service_vals.append((0, 0, new)) + sequence = sequence + 1 + if len(expected_reservation_services) < len(current_sale_service_ids): + folio_sale_lines_to_remove = [ + value.id + for index, value in enumerate(current_sale_service_ids) + if index > (len(expected_reservation_services) - 1) + ] + return sale_service_vals, folio_sale_lines_to_remove + + @api.model + def _get_folio_services_sale_lines(self, folio, sequence): + folio_services = folio.service_ids.filtered(lambda x: not x.reservation_id) + sale_folio_lines = [] + sale_folio_lines_to_remove = [] + if folio_services: + if not folio.sale_line_ids.filtered(lambda x: x.name == _("Others")): + folio.sale_line_ids = [ + ( + 0, + False, + { + "display_type": "line_section", + "product_id": False, + "product_uom_qty": 0, + "discount": 0, + "price_unit": 0, + "tax_ids": False, + "name": _("Others"), + "sequence": sequence, + }, + ) + ] + for folio_service in folio_services: + sequence += 1 + expected_folio_services = self.env["pms.service.line"].read_group( + [ + ("service_id.folio_id", "=", folio.id), + ("service_id", "=", folio_service.id), + ("reservation_id", "=", False), + ("cancel_discount", "<", 100), + ], + ["price_unit", "discount", "cancel_discount"], + ["price_unit", "discount", "cancel_discount"], + lazy=False, + ) + current_folio_service_ids = folio.sale_line_ids.filtered( + lambda x: x.service_id.folio_id.id == folio.id + and not x.display_type + and not x.reservation_id + and x.service_id.id == folio_service.id + ) + + for index, item in enumerate(expected_folio_services): + lines_to = self.env["pms.service.line"].search(item["__domain"]) + final_discount = self.concat_discounts( + item["discount"], item["cancel_discount"] + ) + if current_folio_service_ids and index <= ( + len(current_folio_service_ids) - 1 + ): + current = { + "price_unit": item["price_unit"], + "discount": final_discount, + "reservation_line_ids": [(6, 0, lines_to.ids)], + "sequence": sequence, + } + sale_folio_lines.append( + (1, current_folio_service_ids[index].id, current) + ) + else: + new = { + "service_id": folio_service.id, + "price_unit": item["price_unit"], + "discount": final_discount, + "folio_id": folio.id, + "service_line_ids": [(6, 0, lines_to.ids)], + "product_id": folio_service.product_id.id, + "tax_ids": [(6, 0, folio_service.tax_ids.ids)], + "sequence": sequence, + } + sale_folio_lines.append((0, 0, new)) + if len(expected_folio_services) < len(current_folio_service_ids): + sale_folio_lines_to_remove = [ + value.id + for index, value in enumerate(current_folio_service_ids) + if index > (len(expected_folio_services) - 1) + ] + else: + sale_folio_lines_to_remove = folio.sale_line_ids.filtered( + lambda x: x.name == _("Others") + ) + return sale_folio_lines, sale_folio_lines_to_remove @api.model def _prepare_down_payment_section_line(self, **optional_values): @@ -2234,130 +2443,6 @@ class PmsFolio(models.Model): ) return UserError(msg) - @api.model - def generate_reservation_services_sale_lines(self, folio, reservation): - for service in reservation.service_ids: - expected_reservation_services = self.env["pms.service.line"].read_group( - [ - ("reservation_id", "=", reservation.id), - ("service_id", "=", service.id), - ("cancel_discount", "<", 100), - ], - ["price_unit", "discount", "cancel_discount"], - ["price_unit", "discount", "cancel_discount"], - lazy=False, - ) - current_sale_service_ids = reservation.sale_line_ids.filtered( - lambda x: x.reservation_id.id == reservation.id - and not x.display_type - and x.service_id.id == service.id - ) - - for index, item in enumerate(expected_reservation_services): - lines_to = self.env["pms.service.line"].search(item["__domain"]) - final_discount = self.concat_discounts( - item["discount"], item["cancel_discount"] - ) - - if current_sale_service_ids and index <= ( - len(current_sale_service_ids) - 1 - ): - current_sale_service_ids[index].price_unit = item["price_unit"] - current_sale_service_ids[index].discount = final_discount - current_sale_service_ids[index].service_line_ids = lines_to.ids - else: - new = { - "service_id": service.id, - "price_unit": item["price_unit"], - "discount": final_discount, - "folio_id": folio.id, - "service_line_ids": [(6, 0, lines_to.ids)], - "product_id": service.product_id.id, - "tax_ids": [(6, 0, service.tax_ids.ids)], - } - reservation.sale_line_ids = [(0, 0, new)] - if len(expected_reservation_services) < len(current_sale_service_ids): - folio_sale_lines_to_remove = [ - value.id - for index, value in enumerate(current_sale_service_ids) - if index > (len(expected_reservation_services) - 1) - ] - for fsl in folio_sale_lines_to_remove: - self.env["folio.sale.line"].browse(fsl).unlink() - - @api.model - def generate_folio_services_sale_lines(self, folio): - folio_services = folio.service_ids.filtered(lambda x: not x.reservation_id) - if folio_services: - if not folio.sale_line_ids.filtered(lambda x: x.name == _("Others")): - folio.sale_line_ids = [ - ( - 0, - False, - { - "display_type": "line_section", - "product_id": False, - "product_uom_qty": 0, - "discount": 0, - "price_unit": 0, - "tax_ids": False, - "name": _("Others"), - }, - ) - ] - for folio_service in folio_services: - expected_folio_services = self.env["pms.service.line"].read_group( - [ - ("service_id.folio_id", "=", folio.id), - ("service_id", "=", folio_service.id), - ("reservation_id", "=", False), - ("cancel_discount", "<", 100), - ], - ["price_unit", "discount", "cancel_discount"], - ["price_unit", "discount", "cancel_discount"], - lazy=False, - ) - current_folio_service_ids = folio.sale_line_ids.filtered( - lambda x: x.service_id.folio_id.id == folio.id - and not x.display_type - and not x.reservation_id - and x.service_id.id == folio_service.id - ) - - for index, item in enumerate(expected_folio_services): - lines_to = self.env["pms.service.line"].search(item["__domain"]) - final_discount = self.concat_discounts( - item["discount"], item["cancel_discount"] - ) - if current_folio_service_ids and index <= ( - len(current_folio_service_ids) - 1 - ): - current_folio_service_ids[index].price_unit = item["price_unit"] - current_folio_service_ids[index].discount = final_discount - current_folio_service_ids[index].service_line_ids = lines_to.ids - else: - new = { - "service_id": folio_service.id, - "price_unit": item["price_unit"], - "discount": final_discount, - "folio_id": folio.id, - "service_line_ids": [(6, 0, lines_to.ids)], - "product_id": folio_service.product_id.id, - "tax_ids": [(6, 0, folio_service.tax_ids.ids)], - } - folio.sale_line_ids = [(0, 0, new)] - if len(expected_folio_services) < len(current_folio_service_ids): - folio_sale_lines_to_remove = [ - value.id - for index, value in enumerate(current_folio_service_ids) - if index > (len(expected_folio_services) - 1) - ] - for fsl in folio_sale_lines_to_remove: - self.env["folio.sale.line"].browse(fsl).unlink() - else: - to_unlink = folio.sale_line_ids.filtered(lambda x: x.name == _("Others")) - to_unlink.unlink() - @api.model def concat_discounts(self, discount, cancel_discount): discount_factor = 1.0 diff --git a/pms/views/pms_folio_views.xml b/pms/views/pms_folio_views.xml index 4c271e244..41254ca2e 100644 --- a/pms/views/pms_folio_views.xml +++ b/pms/views/pms_folio_views.xml @@ -488,14 +488,9 @@ - +