diff --git a/pms/i18n/es.po b/pms/i18n/es.po
index e9e5f6710e..94f07db640 100644
--- a/pms/i18n/es.po
+++ b/pms/i18n/es.po
@@ -5912,6 +5912,13 @@ msgstr "Facturar a la agencia"
msgid "Invoice Count"
msgstr "Recuento de facturas"
+#. module: pms
+#: model:ir.model.fields,field_description:pms.field_pms_property__invoice_extras_to_agency
+#: model:ir.model.fields,field_description:pms.field_res_partner__invoice_extras_to_agency
+#: model:ir.model.fields,field_description:pms.field_res_users__invoice_extras_to_agency
+msgid "Invoice Extras to Agency"
+msgstr "Facturar extras a la agencia"
+
#. module: pms
#: model_terms:ir.ui.view,arch_db:pms.view_folio_advance_payment_inv
msgid "Invoice Folio Order"
@@ -7465,6 +7472,19 @@ msgstr "Solo servicios"
msgid "Only allowed if the field of partner is_agency is True"
msgstr "Solo se permite si el campo del partner is_agency es True"
+#. module: pms
+#: model:ir.model.fields,help:pms.field_pms_property__invoice_extras_to_agency
+#: model:ir.model.fields,help:pms.field_res_partner__invoice_extras_to_agency
+#: model:ir.model.fields,help:pms.field_res_users__invoice_extras_to_agency
+msgid ""
+"Only for agencies invoiced always. Unchecked: the agency is invoiced the "
+"nights and the board services, and the guest the extra services. Checked: "
+"the agency is also invoiced the extra services."
+msgstr ""
+"Solo para agencias con «Facturar a la agencia: Siempre». Desmarcado: a la "
+"agencia se le facturan las noches y el régimen, y al huésped los servicios "
+"extra. Marcado: a la agencia se le facturan también los servicios extra."
+
#. module: pms
#: model:ir.model.constraint,message:pms.constraint_pms_availability_room_type_registry_unique
msgid ""
diff --git a/pms/i18n/pms.pot b/pms/i18n/pms.pot
index 0e74171113..bf950b4e4f 100644
--- a/pms/i18n/pms.pot
+++ b/pms/i18n/pms.pot
@@ -5477,6 +5477,13 @@ msgstr ""
msgid "Invoice Count"
msgstr ""
+#. module: pms
+#: model:ir.model.fields,field_description:pms.field_pms_property__invoice_extras_to_agency
+#: model:ir.model.fields,field_description:pms.field_res_partner__invoice_extras_to_agency
+#: model:ir.model.fields,field_description:pms.field_res_users__invoice_extras_to_agency
+msgid "Invoice Extras to Agency"
+msgstr ""
+
#. module: pms
#: model_terms:ir.ui.view,arch_db:pms.view_folio_advance_payment_inv
msgid "Invoice Folio Order"
@@ -6993,6 +7000,16 @@ msgstr ""
msgid "Only allowed if the field of partner is_agency is True"
msgstr ""
+#. module: pms
+#: model:ir.model.fields,help:pms.field_pms_property__invoice_extras_to_agency
+#: model:ir.model.fields,help:pms.field_res_partner__invoice_extras_to_agency
+#: model:ir.model.fields,help:pms.field_res_users__invoice_extras_to_agency
+msgid ""
+"Only for agencies invoiced always. Unchecked: the agency is invoiced the "
+"nights and the board services, and the guest the extra services. Checked: "
+"the agency is also invoiced the extra services."
+msgstr ""
+
#. module: pms
#: model:ir.model.constraint,message:pms.constraint_pms_availability_room_type_registry_unique
msgid ""
diff --git a/pms/models/pms_service.py b/pms/models/pms_service.py
index 6aeb84d908..7f26e4df8e 100644
--- a/pms/models/pms_service.py
+++ b/pms/models/pms_service.py
@@ -507,6 +507,7 @@ def _compute_default_invoice_to(self):
agency
and agency.invoice_to_agency == "always"
and agency.sale_channel_id == record.sale_channel_origin_id
+ and (record.is_board_service or agency.invoice_extras_to_agency)
):
record.default_invoice_to = agency
elif not record.default_invoice_to:
diff --git a/pms/models/res_partner.py b/pms/models/res_partner.py
index 1cb7744d3c..ed59504ed0 100644
--- a/pms/models/res_partner.py
+++ b/pms/models/res_partner.py
@@ -56,6 +56,12 @@ class ResPartner(models.Model):
default="never",
required=True,
)
+ invoice_extras_to_agency = fields.Boolean(
+ string="Invoice Extras to Agency",
+ help="Only for agencies invoiced always. Unchecked: the agency is invoiced "
+ "the nights and the board services, and the guest the extra services. "
+ "Checked: the agency is also invoiced the extra services.",
+ )
pms_property_ids = fields.Many2many(
string="Properties",
help="Properties with access to the element"
diff --git a/pms/tests/test_pms_service.py b/pms/tests/test_pms_service.py
index 193ee099c3..e4835db834 100644
--- a/pms/tests/test_pms_service.py
+++ b/pms/tests/test_pms_service.py
@@ -1067,3 +1067,111 @@ def test_change_origin_folio_no_change_origin_service(self):
self.folio1.service_ids.mapped("sale_channel_origin_id"),
"sale_channel_origin_id of that service mustn't be changed",
)
+
+ def _create_agency_reservation(self, **agency_vals):
+ """Half board reservation of an agency that is always invoiced"""
+ sale_channel = self.env["pms.sale.channel"].create(
+ {"name": "Tour Operator", "channel_type": "indirect"}
+ )
+ agency = self.env["res.partner"].create(
+ {
+ "name": "Agency",
+ "is_agency": True,
+ "sale_channel_id": sale_channel.id,
+ "invoice_to_agency": "always",
+ **agency_vals,
+ }
+ )
+ board_service = self.env["pms.board.service"].create(
+ {
+ "name": "Half Board",
+ "default_code": "HB",
+ "pms_property_ids": [self.pms_property1.id],
+ }
+ )
+ self.env["pms.board.service.line"].create(
+ {
+ "product_id": self.env["product.product"].create({"name": "Dinner"}).id,
+ "pms_board_service_id": board_service.id,
+ "amount": 20,
+ "adults": True,
+ }
+ )
+ board_service_room_type = self.env["pms.board.service.room.type"].create(
+ {
+ "pms_room_type_id": self.room_type_double.id,
+ "pms_board_service_id": board_service.id,
+ "pms_property_id": self.pms_property1.id,
+ }
+ )
+ reservation = self.env["pms.reservation"].create(
+ {
+ "checkin": fields.date.today(),
+ "checkout": fields.date.today() + datetime.timedelta(days=2),
+ "room_type_id": self.room_type_double.id,
+ "partner_id": self.partner1.id,
+ "pms_property_id": self.pms_property1.id,
+ "pricelist_id": self.pricelist1.id,
+ "agency_id": agency.id,
+ "sale_channel_origin_id": sale_channel.id,
+ "board_service_room_id": board_service_room_type.id,
+ "adults": 2,
+ }
+ )
+ return agency, reservation
+
+ def _create_extra_service(self, reservation):
+ return self.env["pms.service"].create(
+ {
+ "reservation_id": reservation.id,
+ "product_id": self.env["product.product"].create({"name": "Bar"}).id,
+ "is_board_service": False,
+ }
+ )
+
+ @freeze_time("2002-03-01")
+ def test_agency_invoiced_extras(self):
+ """
+ An agency that is always invoiced and also the extras is invoiced the
+ extra services added to the reservation.
+ """
+ # ARRANGE
+ agency, reservation = self._create_agency_reservation(
+ invoice_extras_to_agency=True
+ )
+ # ACT
+ extra = self._create_extra_service(reservation)
+ # ASSERT
+ self.assertEqual(
+ extra.default_invoice_to,
+ agency,
+ "The extra service must be invoiced to the agency",
+ )
+
+ @freeze_time("2002-03-01")
+ def test_agency_only_invoiced_the_stay_by_default(self):
+ """
+ An agency that is always invoiced is invoiced by default the nights
+ and the board services, while the extras added to the reservation
+ are left to the guest, also in the folio sale lines.
+ """
+ # ARRANGE
+ agency, reservation = self._create_agency_reservation()
+ # ACT
+ extra = self._create_extra_service(reservation)
+ # ASSERT
+ sale_lines = reservation.folio_id.sale_line_ids.filtered(
+ lambda line: not line.display_type
+ )
+ extra_lines = sale_lines.filtered(lambda line: line.service_id == extra)
+ self.assertTrue(extra_lines)
+ self.assertTrue(sale_lines.filtered("is_board_service"))
+ self.assertFalse(
+ extra_lines.default_invoice_to,
+ "The extra service must be invoiced to the guest",
+ )
+ self.assertEqual(
+ (sale_lines - extra_lines).default_invoice_to,
+ agency,
+ "The nights and the board services must be invoiced to the agency",
+ )
diff --git a/pms/views/res_partner_views.xml b/pms/views/res_partner_views.xml
index 95c67d2614..4ec17b041f 100644
--- a/pms/views/res_partner_views.xml
+++ b/pms/views/res_partner_views.xml
@@ -97,6 +97,10 @@
-->
+