diff --git a/pms/models/pms_board_service.py b/pms/models/pms_board_service.py
index b90a57a76f..7632e2d1b3 100644
--- a/pms/models/pms_board_service.py
+++ b/pms/models/pms_board_service.py
@@ -58,6 +58,23 @@ class PmsBoardService(models.Model):
show_detail_report = fields.Boolean(
help="True if you want that board service detail to be shown on the report",
)
+ active = fields.Boolean(
+ default=True,
+ help="If unchecked, this board service will be archived and hidden from "
+ "selections without affecting historical records that reference it.",
+ )
+
+ def write(self, vals):
+ res = super().write(vals)
+ if "active" in vals:
+ new_state = vals["active"]
+ self.with_context(active_test=False).mapped("board_service_line_ids").write(
+ {"active": new_state}
+ )
+ self.with_context(active_test=False).mapped(
+ "pms_board_service_room_type_ids"
+ ).write({"active": new_state})
+ return res
@api.depends("board_service_line_ids.amount")
def _compute_board_amount(self):
diff --git a/pms/models/pms_board_service_line.py b/pms/models/pms_board_service_line.py
index 7e314c68a4..93bf46bc16 100644
--- a/pms/models/pms_board_service_line.py
+++ b/pms/models/pms_board_service_line.py
@@ -50,6 +50,10 @@ class PmsBoardServiceLine(models.Model):
help="Apply service to children",
default=False,
)
+ active = fields.Boolean(
+ default=True,
+ help="Lines of an archived board service are archived as well.",
+ )
def _get_default_price(self):
if self.product_id:
diff --git a/pms/models/pms_board_service_room_type.py b/pms/models/pms_board_service_room_type.py
index 8556c3e692..1e2d4a088f 100644
--- a/pms/models/pms_board_service_room_type.py
+++ b/pms/models/pms_board_service_room_type.py
@@ -64,6 +64,24 @@ class PmsBoardServiceRoomType(models.Model):
help="Pricelists where this Board Service is available",
comodel_name="product.pricelist",
)
+ active = fields.Boolean(
+ default=True,
+ help="If unchecked, this board service room type assignment will be "
+ "archived and hidden from selections without affecting historical "
+ "reservations that reference it.",
+ )
+
+ def write(self, vals):
+ if "pms_board_service_id" in vals and "board_service_line_ids" not in vals:
+ vals.update(
+ self.prepare_board_service_reservation_ids(vals["pms_board_service_id"])
+ )
+ res = super().write(vals)
+ if "active" in vals:
+ self.with_context(active_test=False).mapped("board_service_line_ids").write(
+ {"active": vals["active"]}
+ )
+ return res
@api.depends("board_service_line_ids.amount")
def _compute_board_amount(self):
@@ -136,13 +154,6 @@ def create(self, vals_list):
)
return super().create(vals_list)
- def write(self, vals):
- if "pms_board_service_id" in vals and "board_service_line_ids" not in vals:
- vals.update(
- self.prepare_board_service_reservation_ids(vals["pms_board_service_id"])
- )
- return super().write(vals)
-
@api.model
def prepare_board_service_reservation_ids(self, board_service_id):
"""
diff --git a/pms/models/pms_board_service_room_type_line.py b/pms/models/pms_board_service_room_type_line.py
index 28b4a3818b..c203db5c47 100644
--- a/pms/models/pms_board_service_room_type_line.py
+++ b/pms/models/pms_board_service_room_type_line.py
@@ -48,6 +48,10 @@ class PmsBoardServiceRoomTypeLine(models.Model):
help="Apply service to children",
default=False,
)
+ active = fields.Boolean(
+ default=True,
+ help="Lines of an archived board service room type are archived as well.",
+ )
def _default_amount(self):
return self.product_id.list_price
diff --git a/pms/tests/test_pms_board_service.py b/pms/tests/test_pms_board_service.py
index 43cf24839c..7e85814781 100644
--- a/pms/tests/test_pms_board_service.py
+++ b/pms/tests/test_pms_board_service.py
@@ -409,3 +409,77 @@ def test_search_bs_code_no_properties(self):
board_service2.id,
"Expected board service not found",
)
+
+ def test_archive_board_service_propagates_to_children(self):
+ """
+ Archiving a board service must cascade ``active=False`` to its
+ lines and to its room-type assignments (and their lines), so that
+ the archived regime fully disappears from operative selections
+ while historical references remain in place.
+
+ PRE: - board_service bs1 is active
+ - bs1 has one line (bsl)
+ - bs1 has one room-type assignment (bsrt) with one line (bsrtl)
+ ACT: - bs1.active = False
+ POST: - bsl.active == False
+ - bsrt.active == False
+ - bsrtl.active == False
+ - reactivating bs1 propagates back to all descendants
+ """
+ # ARRANGE
+ product = self.env["product.product"].create(
+ {"name": "Bs Product", "is_pms_available": True}
+ )
+ room_type = self.env["pms.room.type"].create(
+ {
+ "pms_property_ids": [(6, 0, [self.pms_property1.id])],
+ "name": "Room Type Archive Test",
+ "default_code": "RTAT",
+ "class_id": self.room_type_class1.id,
+ "list_price": 30.0,
+ }
+ )
+ board_service = self.env["pms.board.service"].create(
+ {
+ "name": "Bs Archive Test",
+ "default_code": "BSAT",
+ "pms_property_ids": [(6, 0, [self.pms_property1.id])],
+ "board_service_line_ids": [
+ (0, 0, {"product_id": product.id, "adults": True}),
+ ],
+ }
+ )
+ bsrt = self.env["pms.board.service.room.type"].create(
+ {
+ "pms_board_service_id": board_service.id,
+ "pms_room_type_id": room_type.id,
+ "pms_property_id": self.pms_property1.id,
+ }
+ )
+
+ # ACT — archive
+ board_service.active = False
+
+ # ASSERT — propagation downwards
+ bs_line = board_service.with_context(active_test=False).board_service_line_ids
+ bsrt_line = bsrt.with_context(active_test=False).board_service_line_ids
+ self.assertFalse(bs_line.active, "Board service line was not archived")
+ self.assertFalse(
+ bsrt.with_context(active_test=False).active,
+ "Board service room type was not archived",
+ )
+ self.assertFalse(
+ bsrt_line.active,
+ "Board service room type line was not archived",
+ )
+
+ # ACT — reactivate
+ board_service.with_context(active_test=False).active = True
+
+ # ASSERT — propagation back
+ self.assertTrue(bs_line.active, "Board service line was not reactivated")
+ self.assertTrue(bsrt.active, "Board service room type was not reactivated")
+ self.assertTrue(
+ bsrt_line.active,
+ "Board service room type line was not reactivated",
+ )
diff --git a/pms/views/pms_board_service_room_type_views.xml b/pms/views/pms_board_service_room_type_views.xml
index 741ccf691a..745efc1552 100644
--- a/pms/views/pms_board_service_room_type_views.xml
+++ b/pms/views/pms_board_service_room_type_views.xml
@@ -5,23 +5,32 @@
pms.board.service.room.type
diff --git a/pms/views/pms_board_service_views.xml b/pms/views/pms_board_service_views.xml
index 3447c420a0..82754734fe 100644
--- a/pms/views/pms_board_service_views.xml
+++ b/pms/views/pms_board_service_views.xml
@@ -5,26 +5,35 @@
pms.board.service
@@ -41,10 +50,26 @@
+
+ pms.board.service.search
+ pms.board.service
+
+
+
+
+
+
+
+
Board Services
pms.board.service
tree,form
+