From 69b40ccb9c053a7faa65efd4410924d9fa75388c Mon Sep 17 00:00:00 2001 From: Sara Lago Date: Mon, 30 Nov 2020 10:08:32 +0100 Subject: [PATCH] [IMP] add commissions on reservation and folio --- pms/data/pms_data.xml | 8 ++-- pms/models/pms_folio.py | 45 +++++++++++++++++----- pms/models/pms_reservation.py | 48 +++++++++++++++++------- pms/models/res_partner.py | 3 ++ pms/tests/__init__.py | 1 + pms/tests/test_pms_folio.py | 58 +++++++++++++++++++++++++++++ pms/views/pms_reservation_views.xml | 24 ++++++------ pms/views/res_partner_views.xml | 27 +++++++++++--- 8 files changed, 170 insertions(+), 44 deletions(-) create mode 100644 pms/tests/test_pms_folio.py diff --git a/pms/data/pms_data.xml b/pms/data/pms_data.xml index 3152d83f7..7eafee0f0 100644 --- a/pms/data/pms_data.xml +++ b/pms/data/pms_data.xml @@ -37,19 +37,19 @@ Door - Direct + direct Phone - Direct + direct Mail - Direct + direct Agency - Indirect + indirect diff --git a/pms/models/pms_folio.py b/pms/models/pms_folio.py index 6ee800782..a760de0a0 100644 --- a/pms/models/pms_folio.py +++ b/pms/models/pms_folio.py @@ -50,7 +50,9 @@ class PmsFolio(models.Model): pms_property_id = fields.Many2one( "pms.property", default=_get_default_pms_property, required=True ) - partner_id = fields.Many2one("res.partner", tracking=True, ondelete="restrict") + partner_id = fields.Many2one( + "res.partner", compute="_compute_partner_id", tracking=True, ondelete="restrict" + ) reservation_ids = fields.One2many( "pms.reservation", "folio_id", @@ -102,6 +104,13 @@ class PmsFolio(models.Model): readonly=False, help="Pricelist for current folio.", ) + commission = fields.Float( + string="Commission", + compute="_compute_commission", + store=True, + readonly=True, + default=0, + ) user_id = fields.Many2one( "res.users", string="Salesperson", @@ -282,17 +291,26 @@ class PmsFolio(models.Model): folio.reservation_ids.filtered(lambda a: a.state != "cancelled") ) - @api.depends("partner_id") + @api.depends("partner_id", "agency_id") def _compute_pricelist_id(self): for folio in self: - pricelist_id = ( - folio.partner_id.property_product_pricelist - and folio.partner_id.property_product_pricelist.id - or self.env.user.pms_property_id.default_pricelist_id.id - ) + if folio.partner_id and folio.partner_id.property_product_pricelist: + pricelist_id = folio.partner_id.property_product_pricelist.id + else: + pricelist_id = self.env.user.pms_property_id.default_pricelist_id.id if folio.pricelist_id.id != pricelist_id: # TODO: Warning change de pricelist? folio.pricelist_id = pricelist_id + if folio.agency_id and folio.agency_id.apply_pricelist: + pricelist_id = folio.agency_id.property_product_pricelist.id + + @api.depends("agency_id") + def _compute_partner_id(self): + for folio in self: + if folio.agency_id and folio.agency_id.invoice_agency: + folio.partner_id = folio.agency_id.id + elif not folio.partner_id: + folio.partner_id = False @api.depends("partner_id") def _compute_user_id(self): @@ -311,11 +329,20 @@ class PmsFolio(models.Model): self.payment_term_id = False for folio in self: folio.payment_term_id = ( - self.partner_id.property_payment_term_id - and self.partner_id.property_payment_term_id.id + folio.partner_id.property_payment_term_id + and folio.partner_id.property_payment_term_id.id or False ) + @api.depends("reservation_ids") + def _compute_commission(self): + for folio in self: + for reservation in folio.reservation_ids: + if reservation.commission_amount != 0: + folio.commission += reservation.commission_amount + else: + folio.commission = 0 + @api.depends( "state", "reservation_ids.invoice_status", "service_ids.invoice_status" ) diff --git a/pms/models/pms_reservation.py b/pms/models/pms_reservation.py index 9c71e2f00..22cbff138 100644 --- a/pms/models/pms_reservation.py +++ b/pms/models/pms_reservation.py @@ -192,6 +192,17 @@ class PmsReservation(models.Model): store=True, readonly=False, ) + commission_percent = fields.Float( + string="Commission percent (%)", + compute="_compute_commission_percent", + store=True, + readonly=False, + ) + commission_amount = fields.Float( + string="Commission amount", + compute="_compute_commission_amount", + store=True, + ) # TODO: Warning Mens to update pricelist checkin_partner_ids = fields.One2many("pms.checkin.partner", "reservation_id") segmentation_ids = fields.Many2many( @@ -438,7 +449,7 @@ class PmsReservation(models.Model): ) reservation.allowed_room_ids = rooms_available - @api.depends("reservation_type") + @api.depends("reservation_type", "agency_id") def _compute_partner_id(self): for reservation in self: if reservation.reservation_type == "out": @@ -447,6 +458,8 @@ class PmsReservation(models.Model): reservation.partner_id = reservation.folio_id.partner_id else: reservation.partner_id = False + if not reservation.partner_id and reservation.agency_id: + reservation.partner_id = reservation.agency_id @api.depends("partner_id") def _compute_partner_invoice_id(self): @@ -525,6 +538,26 @@ class PmsReservation(models.Model): # TODO: Warning change de pricelist? reservation.pricelist_id = pricelist_id + @api.depends("agency_id") + def _compute_commission_percent(self): + for reservation in self: + if reservation.agency_id: + reservation.commission_percent = ( + reservation.agency_id.default_commission + ) + else: + reservation.commission_percent = 0 + + @api.depends("commission_percent", "price_total") + def _compute_commission_amount(self): + for reservation in self: + if reservation.commission_percent > 0: + reservation.commission_amount = ( + reservation.price_total * reservation.commission_percent + ) + else: + reservation.commission_amount = 0 + # REVIEW: Dont run with set room_type_id -> room_id(compute)-> No set adults¿? @api.depends("preferred_room_id") def _compute_adults(self): @@ -824,21 +857,11 @@ class PmsReservation(models.Model): @api.model def create(self, vals): - if "folio_id" in vals and "channel_type_id" not in vals: + if "folio_id" in vals: folio = self.env["pms.folio"].browse(vals["folio_id"]) - channel_type_id = ( - vals["channel_type_id"] - if "channel_type_id" in vals - else folio.channel_type_id - ) - partner_id = ( - vals["partner_id"] if "partner_id" in vals else folio.partner_id.id - ) - vals.update({"channel_type_id": channel_type_id, "partner_id": partner_id}) elif "partner_id" in vals: folio_vals = { "partner_id": int(vals.get("partner_id")), - "channel_type_id": vals.get("channel_type_id"), } # Create the folio in case of need # (To allow to create reservations direct) @@ -847,7 +870,6 @@ class PmsReservation(models.Model): { "folio_id": folio.id, "reservation_type": vals.get("reservation_type"), - "channel_type_id": vals.get("channel_type_id"), } ) record = super(PmsReservation, self).create(vals) diff --git a/pms/models/res_partner.py b/pms/models/res_partner.py index 33461f377..d13b1f299 100644 --- a/pms/models/res_partner.py +++ b/pms/models/res_partner.py @@ -27,6 +27,9 @@ class ResPartner(models.Model): ondelete="restrict", domain=[("channel_type", "=", "indirect")], ) + default_commission = fields.Integer("Commission") + apply_pricelist = fields.Boolean("Apply Pricelist") + invoice_agency = fields.Boolean("Invoice Agency") # Compute and Search methods def _compute_reservations_count(self): diff --git a/pms/tests/__init__.py b/pms/tests/__init__.py index 77e4bb457..682b252be 100644 --- a/pms/tests/__init__.py +++ b/pms/tests/__init__.py @@ -22,3 +22,4 @@ from . import test_pms_reservation from . import test_pms_pricelist from . import test_pms_sale_channel +from . import test_pms_folio diff --git a/pms/tests/test_pms_folio.py b/pms/tests/test_pms_folio.py new file mode 100644 index 000000000..cd1bd45ac --- /dev/null +++ b/pms/tests/test_pms_folio.py @@ -0,0 +1,58 @@ +import datetime + +from freezegun import freeze_time + +from .common import TestHotel + +freeze_time("2000-02-02") + + +class TestPmsFolio(TestHotel): + def test_commission_and_partner_correct(self): + # ARRANGE + PmsFolio = self.env["pms.folio"] + PmsReservation = self.env["pms.reservation"] + PmsPartner = self.env["res.partner"] + PmsSaleChannel = self.env["pms.sale.channel"] + # ACT + saleChannel = PmsSaleChannel.create( + {"name": "saleChannel1", "channel_type": "indirect"} + ) + agency = PmsPartner.create( + { + "name": "partner1", + "is_agency": True, + "invoice_agency": True, + "default_commission": 15, + "sale_channel_id": saleChannel.id, + } + ) + + reservation = PmsReservation.create( + { + "checkin": datetime.datetime.now(), + "checkout": datetime.datetime.now() + datetime.timedelta(days=3), + "agency_id": agency.id, + } + ) + folio = PmsFolio.create( + { + "agency_id": agency.id, + "reservation_ids": [reservation.id], + } + ) + + commission = 0 + for reservation in folio: + commission += reservation.commission_amount + + # ASSERT + self.assertEqual( + folio.commission, + commission, + "Folio commission don't math with his reservation commission", + ) + if folio.agency_id: + self.assertEqual( + folio.agency_id, folio.partner_id, "Agency has to be the partner" + ) diff --git a/pms/views/pms_reservation_views.xml b/pms/views/pms_reservation_views.xml index a49fc2c60..612bf4ff3 100644 --- a/pms/views/pms_reservation_views.xml +++ b/pms/views/pms_reservation_views.xml @@ -243,19 +243,6 @@ 'readonly': [('partner_id', '!=', False), ('mobile','!=', False)]}" /> - + + + + + - + - + + + > + + + + + + + +