odoo-addon-pms 16.0.0.4.0.6__py3-none-any.whl → 16.0.0.15.0.10__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -10625,6 +10625,16 @@ msgstr ""
10625
10625
  msgid "Terms and conditions"
10626
10626
  msgstr ""
10627
10627
 
10628
+ #. module: pms
10629
+ #. odoo-python
10630
+ #: code:addons/pms/models/pms_reservation_line.py:0
10631
+ #, python-format
10632
+ msgid ""
10633
+ "The '%(incompatible_class)s' is not compatible with the reservation type "
10634
+ "class '%(reservation_class)s'. Please select a compatible class room for "
10635
+ "this reservation."
10636
+ msgstr ""
10637
+
10628
10638
  #. module: pms
10629
10639
  #: model:ir.model.fields,help:pms.field_res_partner_id_number__name
10630
10640
  msgid "The ID itself. For example, Driver License number of this person"
@@ -11061,16 +11071,6 @@ msgstr ""
11061
11071
  msgid "The revenue manager in the folio"
11062
11072
  msgstr ""
11063
11073
 
11064
- #. module: pms
11065
- #. odoo-python
11066
- #: code:addons/pms/models/pms_reservation.py:0
11067
- #, python-format
11068
- msgid ""
11069
- "The room %(room)s (type: %(room_type)s) is not\n"
11070
- " compatible with the room type %(record_room_type)s\n"
11071
- " (type: %(record_room_class)s)"
11072
- msgstr ""
11073
-
11074
11074
  #. module: pms
11075
11075
  #. odoo-python
11076
11076
  #: code:addons/pms/wizards/wizard_split_join_swap_reservation.py:0
@@ -285,7 +285,7 @@ class AccountMove(models.Model):
285
285
  lambda line,
286
286
  pay_term_lines=pay_term_lines,
287
287
  move=move: line.account_id == pay_term_lines.account_id
288
- and line.folio_ids in move.folio_ids
288
+ and line.payment_id.folio_ids in move.folio_ids
289
289
  )
290
290
  )
291
291
  to_reconcile = self.match_pays_by_amount(
@@ -89,23 +89,21 @@ class PmsAvailability(models.Model):
89
89
  "reservation_line_ids",
90
90
  "reservation_line_ids.occupies_availability",
91
91
  "room_type_id.total_rooms_count",
92
+ "reservation_line_ids.room_id",
93
+ "reservation_line_ids.date",
92
94
  "parent_avail_id",
93
95
  "parent_avail_id.reservation_line_ids",
94
96
  "parent_avail_id.reservation_line_ids.occupies_availability",
97
+ "parent_avail_id.reservation_line_ids.room_id",
98
+ "parent_avail_id.reservation_line_ids.date",
95
99
  "child_avail_ids",
96
100
  "child_avail_ids.reservation_line_ids",
97
101
  "child_avail_ids.reservation_line_ids.occupies_availability",
102
+ "child_avail_ids.reservation_line_ids.room_id",
103
+ "child_avail_ids.reservation_line_ids.date",
98
104
  )
99
105
  def _compute_real_avail(self):
100
106
  for record in self:
101
- Rooms = self.env["pms.room"]
102
- total_rooms = Rooms.search_count(
103
- [
104
- ("active", "=", True),
105
- ("room_type_id", "=", record.room_type_id.id),
106
- ("pms_property_id", "=", record.pms_property_id.id),
107
- ]
108
- )
109
107
  room_ids = record.room_type_id.room_ids.filtered(
110
108
  lambda r, record=record: r.pms_property_id == record.pms_property_id
111
109
  and r.active
@@ -118,7 +116,7 @@ class PmsAvailability(models.Model):
118
116
  pms_property_id=record.pms_property_id.id,
119
117
  )
120
118
  )
121
- record.real_avail = total_rooms - count_rooms_not_avail
119
+ record.real_avail = len(room_ids) - count_rooms_not_avail
122
120
 
123
121
  @api.depends("reservation_line_ids", "reservation_line_ids.room_id")
124
122
  def _compute_parent_avail_id(self):
@@ -609,6 +609,10 @@ class PmsFolio(models.Model):
609
609
  folio_lines_to_invoice = folio.sale_line_ids.filtered(
610
610
  lambda r: r.id in list(lines_to_invoice.keys())
611
611
  )
612
+ # Avoid create invoices without invoicing lines
613
+ # (display_type is False)
614
+ if not folio_lines_to_invoice.filtered(lambda r: not r.display_type):
615
+ continue
612
616
  groups_invoice_lines = folio._get_groups_invoice_lines(
613
617
  lines_to_invoice=folio_lines_to_invoice,
614
618
  partner_invoice_id=partner_invoice_id,
@@ -2318,10 +2322,18 @@ class PmsFolio(models.Model):
2318
2322
  old_note = reservation.sale_line_ids.filtered(
2319
2323
  lambda x: x.auto_reservation_note
2320
2324
  )
2321
- if old_note:
2322
- sale_reservation_vals.append((2, old_note.id))
2323
2325
  note_vals = self._get_reservation_note_vals(reservation, sequence)
2324
- if note_vals:
2326
+ create_note = True
2327
+ if old_note:
2328
+ if (
2329
+ not note_vals
2330
+ or old_note.name != note_vals[2]["name"]
2331
+ or old_note.reservation_id.id != note_vals[2]["reservation_id"]
2332
+ ):
2333
+ sale_reservation_vals.append((2, old_note.id))
2334
+ else:
2335
+ create_note = False
2336
+ if note_vals and create_note:
2325
2337
  sale_reservation_vals.append(note_vals)
2326
2338
  expected_reservation_lines = self.env["pms.reservation.line"].read_group(
2327
2339
  [
@@ -1088,12 +1088,7 @@ class PmsReservation(models.Model):
1088
1088
  # Reservations can be cancelled
1089
1089
  for record in self:
1090
1090
  record.allowed_cancel = (
1091
- True
1092
- if (
1093
- record.state not in ["done"]
1094
- and fields.Date.today() <= record.checkout
1095
- )
1096
- else False
1091
+ True if (record.state not in ["done", "onboard"]) else False
1097
1092
  )
1098
1093
 
1099
1094
  def _compute_ready_for_checkin(self):
@@ -1295,9 +1290,7 @@ class PmsReservation(models.Model):
1295
1290
  @api.depends("service_ids.price_total", "services_discount")
1296
1291
  def _compute_price_services(self):
1297
1292
  for record in self:
1298
- record.price_services = (
1299
- sum(record.mapped("service_ids.price_total")) - record.services_discount
1300
- )
1293
+ record.price_services = sum(record.mapped("service_ids.price_total"))
1301
1294
 
1302
1295
  @api.depends("price_services", "price_total")
1303
1296
  def _compute_price_room_services_set(self):
@@ -1384,7 +1377,9 @@ class PmsReservation(models.Model):
1384
1377
  if record.partner_id and record.partner_id != record.agency_id:
1385
1378
  record.partner_name = record.partner_id.name
1386
1379
  if (record.folio_id and not record.partner_name) or (
1387
- record.folio_id.partner_name != record.partner_name
1380
+ record.folio_id
1381
+ and record.folio_id.partner_name
1382
+ and record.folio_id.partner_name != record.partner_name
1388
1383
  ):
1389
1384
  record.partner_name = record.folio_id.partner_name
1390
1385
  elif record.agency_id and not record.partner_name:
@@ -1842,10 +1837,9 @@ class PmsReservation(models.Model):
1842
1837
  )
1843
1838
  )
1844
1839
 
1845
- @api.constrains(
1846
- "reservation_line_ids", "reservation_line_ids.room_id", "room_type_id"
1847
- )
1840
+ @api.constrains("reservation_line_ids", "room_type_id")
1848
1841
  def _check_room_class_compatibility(self):
1842
+ incompatible_class = False
1849
1843
  for record in self:
1850
1844
  if (
1851
1845
  record.room_type_id
@@ -1854,20 +1848,24 @@ class PmsReservation(models.Model):
1854
1848
  ):
1855
1849
  for line in record.reservation_line_ids:
1856
1850
  if (
1857
- line.room_id.room_type_id.class_id
1858
- != record.room_type_id.class_id
1851
+ line.room_id.room_type_id.class_id.overnight
1852
+ != record.room_type_id.class_id.overnight
1859
1853
  ):
1860
- raise ValidationError(
1861
- _(
1862
- """The room %(room)s (type: %(room_type)s) is not
1863
- compatible with the room type %(record_room_type)s
1864
- (type: %(record_room_class)s)""",
1865
- room=line.room_id.name,
1866
- room_type=line.room_id.room_type_id.class_id.name,
1867
- record_room_type=record.room_type_id.name,
1868
- record_room_class=record.room_type_id.class_id.name,
1869
- )
1870
- )
1854
+ incompatible_class = line.room_id.room_type_id.class_id.name
1855
+ if incompatible_class:
1856
+ raise ValidationError(
1857
+ _(
1858
+ (
1859
+ "The '%(incompatible_class)s' is not compatible with the "
1860
+ "reservation type class '%(reservation_class)s'. Please select "
1861
+ "a compatible class room for this reservation."
1862
+ ),
1863
+ {
1864
+ "incompatible_class": incompatible_class,
1865
+ "reservation_class": record.room_type_id.class_id.name,
1866
+ },
1867
+ )
1868
+ )
1871
1869
 
1872
1870
  # Action methods
1873
1871
  def open_partner(self):
@@ -2504,17 +2502,29 @@ class PmsReservation(models.Model):
2504
2502
  self.ensure_one()
2505
2503
  if self.reservation_type != "normal":
2506
2504
  return False
2507
- tax_products = self._get_tourist_tax_products()
2505
+ tax_products = self._get_tourist_tax_products(
2506
+ pms_property_id=self.pms_property_id.id
2507
+ )
2508
2508
  if not tax_products:
2509
2509
  return []
2510
2510
 
2511
2511
  nightly_dates = self._get_nightly_dates()
2512
- grouped_lines = self._build_grouped_tax_lines(tax_products, nightly_dates)
2512
+ grouped_lines = self._build_grouped_tax_lines(
2513
+ tax_products,
2514
+ nightly_dates,
2515
+ )
2513
2516
  existing_services = self._get_existing_tourist_tax_services()
2514
2517
  return self._build_service_commands(grouped_lines, existing_services)
2515
2518
 
2516
- def _get_tourist_tax_products(self):
2517
- return self.env["product.product"].search([("is_tourist_tax", "=", True)])
2519
+ def _get_tourist_tax_products(self, pms_property_id):
2520
+ return self.env["product.product"].search(
2521
+ [
2522
+ ("is_tourist_tax", "=", True),
2523
+ "|",
2524
+ ("pms_property_ids", "=", False),
2525
+ ("pms_property_ids", "in", pms_property_id),
2526
+ ]
2527
+ )
2518
2528
 
2519
2529
  def _get_nightly_dates(self):
2520
2530
  return [
@@ -2618,7 +2628,7 @@ class PmsReservation(models.Model):
2618
2628
  "folio_id": self.folio_id.id,
2619
2629
  "product_id": product.id,
2620
2630
  "name": product.name,
2621
- "per_day": True,
2631
+ "per_day": False,
2622
2632
  "service_line_ids": [(0, 0, line) for line in new_lines],
2623
2633
  },
2624
2634
  )
@@ -660,3 +660,29 @@ class PmsReservationLine(models.Model):
660
660
  if record.pms_property_id.block_create_past_reservations:
661
661
  if record.date < fields.Date.today():
662
662
  raise ValidationError(_("You can't create past reservations"))
663
+
664
+ @api.constrains("room_id")
665
+ def _check_room_class_compatibility(self):
666
+ incompatible_class = False
667
+ for record in self:
668
+ if (
669
+ record.room_id
670
+ and record.reservation_id.room_type_id
671
+ and (
672
+ record.room_id.room_type_id.class_id.overnight
673
+ != record.reservation_id.room_type_id.class_id.overnight
674
+ )
675
+ ):
676
+ incompatible_class = True
677
+ if incompatible_class:
678
+ raise ValidationError(
679
+ _(
680
+ "The '%(incompatible_class)s' is not compatible with the "
681
+ "reservation type class '%(reservation_class)s'. Please select "
682
+ "a compatible class room for this reservation."
683
+ )
684
+ % {
685
+ "incompatible_class": incompatible_class,
686
+ "reservation_class": record.room_id.room_type_id.class_id.name,
687
+ }
688
+ )
@@ -372,7 +372,7 @@ ul.auto-toc {
372
372
  !! This file is generated by oca-gen-addon-readme !!
373
373
  !! changes will be overwritten. !!
374
374
  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
375
- !! source digest: sha256:a724bc0473f65c77aa82b77897ea0610ac258b5a83d314f6909b690dfcc45281
375
+ !! source digest: sha256:1932d20cb515244c940884a7573b46a3b589228ee1ebb94ad7f300612769a869
376
376
  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
377
377
  <p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/license-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/pms/tree/16.0/pms"><img alt="OCA/pms" src="https://img.shields.io/badge/github-OCA%2Fpms-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/pms-16-0/pms-16-0-pms"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/pms&amp;target_branch=16.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
378
378
  <p>This module is an all-in-one property management system (PMS) focused on medium-sized properties
@@ -38,6 +38,7 @@ from . import test_pms_wizard_split_join_swap_reservation
38
38
  from . import test_product_template
39
39
  from . import test_pms_multiproperty
40
40
  from . import test_shared_room
41
+ from . import test_pms_reservation_line
41
42
 
42
43
  # from . import test_automated_mails
43
44
  from . import test_pms_service
@@ -45,6 +45,50 @@ class TestPmsReservations(TestPms, AccountTestInvoicingCommon):
45
45
  }
46
46
  )
47
47
 
48
+ # Additional room type class for incompatible test
49
+ cls.room_type_class_day = cls.env["pms.room.type.class"].create(
50
+ {
51
+ "name": "Day Use",
52
+ "overnight": False,
53
+ "default_code": "DAY",
54
+ }
55
+ )
56
+ cls.room_type_class_overnight = cls.env["pms.room.type.class"].create(
57
+ {
58
+ "name": "Overnight",
59
+ "overnight": True,
60
+ "default_code": "OVN",
61
+ }
62
+ )
63
+
64
+ cls.room_type_day = cls.env["pms.room.type"].create(
65
+ {
66
+ "pms_property_ids": [cls.pms_property1.id],
67
+ "name": "Day Room",
68
+ "default_code": "DAY_Test",
69
+ "class_id": cls.room_type_class_day.id,
70
+ }
71
+ )
72
+
73
+ cls.room_type_overnight = cls.env["pms.room.type"].create(
74
+ {
75
+ "pms_property_ids": [cls.pms_property1.id],
76
+ "name": "Overnight Room",
77
+ "default_code": "OVN_Test",
78
+ "class_id": cls.room_type_class_overnight.id,
79
+ }
80
+ )
81
+
82
+ cls.room_day = cls.env["pms.room"].create(
83
+ {
84
+ "pms_property_id": cls.pms_property1.id,
85
+ "name": "Day 201",
86
+ "room_type_id": cls.room_type_day.id,
87
+ "capacity": 1,
88
+ "extra_beds_allowed": 0,
89
+ }
90
+ )
91
+
48
92
  # create rooms
49
93
  cls.room1 = cls.env["pms.room"].create(
50
94
  {
@@ -3399,3 +3443,63 @@ class TestPmsReservations(TestPms, AccountTestInvoicingCommon):
3399
3443
  "Sale_channel_origin_id of folio must be the same as "
3400
3444
  "sale_channel_origin of rservation",
3401
3445
  )
3446
+
3447
+ @freeze_time("2000-12-01")
3448
+ def test_modify_reservation_with_compatible_overnight_classes(self):
3449
+ """
3450
+ Check that when modifying a reservation with compatible overnight
3451
+ classes, the reservation is modified correctly.
3452
+ """
3453
+ # ARRANGE
3454
+ checkin = fields.date.today()
3455
+ checkout = fields.date.today() + datetime.timedelta(days=3)
3456
+ reservation_vals = {
3457
+ "checkin": checkin,
3458
+ "checkout": checkout,
3459
+ "room_type_id": self.room_type_double.id,
3460
+ "partner_id": self.partner1.id,
3461
+ "pms_property_id": self.pms_property1.id,
3462
+ "sale_channel_origin_id": self.sale_channel_direct.id,
3463
+ }
3464
+ reservation = self.env["pms.reservation"].create(reservation_vals)
3465
+
3466
+ # ACT
3467
+ reservation.write(
3468
+ {
3469
+ "room_type_id": self.room_type_overnight.id,
3470
+ }
3471
+ )
3472
+
3473
+ # ASSERT
3474
+ self.assertEqual(
3475
+ reservation.room_type_id.id,
3476
+ self.room_type_overnight.id,
3477
+ "The reservation should be modified with the new room type",
3478
+ )
3479
+
3480
+ @freeze_time("2000-12-01")
3481
+ def test_modify_reservation_with_incompatible_overnight_classes(self):
3482
+ """
3483
+ Check that when modifying a reservation with incompatible overnight
3484
+ classes, the reservation raises an error.
3485
+ """
3486
+ # ARRANGE
3487
+ checkin = fields.date.today()
3488
+ checkout = fields.date.today() + datetime.timedelta(days=3)
3489
+ reservation_vals = {
3490
+ "checkin": checkin,
3491
+ "checkout": checkout,
3492
+ "room_type_id": self.room_type_double.id,
3493
+ "partner_id": self.partner1.id,
3494
+ "pms_property_id": self.pms_property1.id,
3495
+ "sale_channel_origin_id": self.sale_channel_direct.id,
3496
+ }
3497
+ reservation = self.env["pms.reservation"].create(reservation_vals)
3498
+
3499
+ # ACT & ASSERT
3500
+ with self.assertRaises(ValidationError):
3501
+ reservation.write(
3502
+ {
3503
+ "room_type_id": self.room_type_day.id,
3504
+ }
3505
+ )
@@ -0,0 +1,225 @@
1
+ import datetime
2
+
3
+ from freezegun import freeze_time
4
+
5
+ from odoo import fields
6
+ from odoo.exceptions import ValidationError
7
+ from odoo.tests import tagged
8
+
9
+ from .common import TestPms
10
+
11
+
12
+ @tagged("post_install", "-at_install")
13
+ class TestPmsReservationLines(TestPms):
14
+ @classmethod
15
+ def setUpClass(cls):
16
+ super().setUpClass()
17
+ user = cls.env["res.users"].browse(1)
18
+ cls.env = cls.env(user=user)
19
+ # create a room type availability
20
+ cls.room_type_availability = cls.env["pms.availability.plan"].create(
21
+ {
22
+ "name": "Availability plan for TEST",
23
+ "pms_pricelist_ids": [(6, 0, [cls.pricelist1.id])],
24
+ }
25
+ )
26
+
27
+ # create room type
28
+ cls.room_type_double = cls.env["pms.room.type"].create(
29
+ {
30
+ "pms_property_ids": [cls.pms_property1.id],
31
+ "name": "Double Test",
32
+ "default_code": "DBL_Test",
33
+ "class_id": cls.room_type_class1.id,
34
+ }
35
+ )
36
+
37
+ cls.room_type_triple = cls.env["pms.room.type"].create(
38
+ {
39
+ "pms_property_ids": [cls.pms_property1.id],
40
+ "name": "Triple Test",
41
+ "default_code": "TRP_Test",
42
+ "class_id": cls.room_type_class1.id,
43
+ }
44
+ )
45
+
46
+ # Additional room type class for incompatible test
47
+ cls.room_type_class_day = cls.env["pms.room.type.class"].create(
48
+ {
49
+ "name": "Day Use",
50
+ "overnight": False,
51
+ "default_code": "DAY",
52
+ }
53
+ )
54
+ cls.room_type_class_overnight = cls.env["pms.room.type.class"].create(
55
+ {
56
+ "name": "Overnight",
57
+ "overnight": True,
58
+ "default_code": "OVN",
59
+ }
60
+ )
61
+
62
+ cls.room_type_day = cls.env["pms.room.type"].create(
63
+ {
64
+ "pms_property_ids": [cls.pms_property1.id],
65
+ "name": "Day Room",
66
+ "default_code": "DAY_Test",
67
+ "class_id": cls.room_type_class_day.id,
68
+ }
69
+ )
70
+
71
+ cls.room_type_overnight = cls.env["pms.room.type"].create(
72
+ {
73
+ "pms_property_ids": [cls.pms_property1.id],
74
+ "name": "Overnight Room",
75
+ "default_code": "OVN_Test",
76
+ "class_id": cls.room_type_class_overnight.id,
77
+ }
78
+ )
79
+
80
+ cls.room_day = cls.env["pms.room"].create(
81
+ {
82
+ "pms_property_id": cls.pms_property1.id,
83
+ "name": "Day 201",
84
+ "room_type_id": cls.room_type_day.id,
85
+ "capacity": 1,
86
+ "extra_beds_allowed": 0,
87
+ }
88
+ )
89
+ cls.room_overnight = cls.env["pms.room"].create(
90
+ {
91
+ "pms_property_id": cls.pms_property1.id,
92
+ "name": "Overnight 202",
93
+ "room_type_id": cls.room_type_overnight.id,
94
+ "capacity": 1,
95
+ "extra_beds_allowed": 0,
96
+ }
97
+ )
98
+
99
+ # create rooms
100
+ cls.room1 = cls.env["pms.room"].create(
101
+ {
102
+ "pms_property_id": cls.pms_property1.id,
103
+ "name": "Double 101",
104
+ "room_type_id": cls.room_type_double.id,
105
+ "capacity": 2,
106
+ "extra_beds_allowed": 1,
107
+ }
108
+ )
109
+
110
+ cls.room2 = cls.env["pms.room"].create(
111
+ {
112
+ "pms_property_id": cls.pms_property1.id,
113
+ "name": "Double 102",
114
+ "room_type_id": cls.room_type_double.id,
115
+ "capacity": 2,
116
+ "extra_beds_allowed": 1,
117
+ }
118
+ )
119
+
120
+ cls.room3 = cls.env["pms.room"].create(
121
+ {
122
+ "pms_property_id": cls.pms_property1.id,
123
+ "name": "Double 103",
124
+ "room_type_id": cls.room_type_double.id,
125
+ "capacity": 2,
126
+ "extra_beds_allowed": 1,
127
+ }
128
+ )
129
+
130
+ cls.room4 = cls.env["pms.room"].create(
131
+ {
132
+ "pms_property_id": cls.pms_property1.id,
133
+ "name": "Triple 104",
134
+ "room_type_id": cls.room_type_triple.id,
135
+ "capacity": 3,
136
+ "extra_beds_allowed": 1,
137
+ }
138
+ )
139
+ cls.partner1 = cls.env["res.partner"].create(
140
+ {
141
+ "firstname": "Jaime",
142
+ "lastname": "García",
143
+ "email": "jaime@example.com",
144
+ "birthdate_date": "1983-03-01",
145
+ "gender": "male",
146
+ }
147
+ )
148
+ cls.id_category = cls.env["res.partner.id_category"].create(
149
+ {"name": "DNI", "code": "D"}
150
+ )
151
+ cls.sale_channel_direct = cls.env["pms.sale.channel"].create(
152
+ {"name": "sale channel direct", "channel_type": "direct"}
153
+ )
154
+ cls.sale_channel1 = cls.env["pms.sale.channel"].create(
155
+ {"name": "saleChannel1", "channel_type": "indirect"}
156
+ )
157
+ cls.agency1 = cls.env["res.partner"].create(
158
+ {
159
+ "firstname": "partner1",
160
+ "is_agency": True,
161
+ "invoice_to_agency": "always",
162
+ "default_commission": 15,
163
+ "sale_channel_id": cls.sale_channel1.id,
164
+ }
165
+ )
166
+
167
+ @freeze_time("2000-12-01")
168
+ def test_modify_reservation_line_with_compatible_overnight_classes(self):
169
+ """
170
+ Check that when modifying a reservation with compatible overnight
171
+ classes, the reservation is modified correctly.
172
+ """
173
+ # ARRANGE
174
+ checkin = fields.date.today()
175
+ checkout = fields.date.today() + datetime.timedelta(days=3)
176
+ reservation_vals = {
177
+ "checkin": checkin,
178
+ "checkout": checkout,
179
+ "room_type_id": self.room_type_double.id,
180
+ "partner_id": self.partner1.id,
181
+ "pms_property_id": self.pms_property1.id,
182
+ "sale_channel_origin_id": self.sale_channel_direct.id,
183
+ }
184
+ reservation = self.env["pms.reservation"].create(reservation_vals)
185
+
186
+ # ACT
187
+ reservation.reservation_line_ids[0].write(
188
+ {
189
+ "room_id": self.room_overnight.id,
190
+ }
191
+ )
192
+
193
+ # ASSERT
194
+ self.assertEqual(
195
+ reservation.reservation_line_ids[0].room_id.room_type_id.id,
196
+ self.room_type_overnight.id,
197
+ "The reservation should be modified with the new room type",
198
+ )
199
+
200
+ @freeze_time("2000-12-01")
201
+ def test_modify_reservation_with_incompatible_overnight_classes(self):
202
+ """
203
+ Check that when modifying a reservation with incompatible overnight
204
+ classes, the reservation raises an error.
205
+ """
206
+ # ARRANGE
207
+ checkin = fields.date.today()
208
+ checkout = fields.date.today() + datetime.timedelta(days=3)
209
+ reservation_vals = {
210
+ "checkin": checkin,
211
+ "checkout": checkout,
212
+ "room_type_id": self.room_type_double.id,
213
+ "partner_id": self.partner1.id,
214
+ "pms_property_id": self.pms_property1.id,
215
+ "sale_channel_origin_id": self.sale_channel_direct.id,
216
+ }
217
+ reservation = self.env["pms.reservation"].create(reservation_vals)
218
+
219
+ # ACT & ASSERT
220
+ with self.assertRaises(ValidationError):
221
+ reservation.reservation_line_ids[0].write(
222
+ {
223
+ "room_id": self.room_day.id,
224
+ }
225
+ )
@@ -6,6 +6,7 @@
6
6
  <field name="arch" type="xml">
7
7
  <form string="Property Configuration">
8
8
  <sheet>
9
+ <div class="o_button_box" name="button_box" />
9
10
  <label for="name" class="oe_edit_only" />
10
11
  <h1>
11
12
  <field name="name" class="oe_inline" />
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: odoo-addon-pms
3
- Version: 16.0.0.4.0.6
3
+ Version: 16.0.0.15.0.10
4
4
  Summary: A property management system
5
5
  Home-page: https://github.com/OCA/pms
6
6
  Author: Commit [Sun], Odoo Community Association (OCA)
@@ -36,7 +36,7 @@ PMS (Property Management System)
36
36
  !! This file is generated by oca-gen-addon-readme !!
37
37
  !! changes will be overwritten. !!
38
38
  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
39
- !! source digest: sha256:a724bc0473f65c77aa82b77897ea0610ac258b5a83d314f6909b690dfcc45281
39
+ !! source digest: sha256:1932d20cb515244c940884a7573b46a3b589228ee1ebb94ad7f300612769a869
40
40
  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
41
41
 
42
42
  .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png