diff --git a/pms/models/pms_folio.py b/pms/models/pms_folio.py
index 77c31ef18..4c2e4e45a 100644
--- a/pms/models/pms_folio.py
+++ b/pms/models/pms_folio.py
@@ -114,10 +114,16 @@ class PmsFolio(models.Model):
)
agency_id = fields.Many2one(
"res.partner",
- "Agency",
+ string="Agency",
ondelete="restrict",
domain=[("is_agency", "=", True)],
)
+ channel_type_id = fields.Many2one(
+ "pms.sale.channel",
+ string="Direct Sale Channel",
+ ondelete = "restrict",
+ domain=[("channel_type","=","direct")],
+ )
payment_ids = fields.One2many("account.payment", "folio_id", readonly=True)
# return_ids = fields.One2many("payment.return", "folio_id", readonly=True)
payment_term_id = fields.Many2one(
@@ -163,15 +169,6 @@ class PmsFolio(models.Model):
string="Type",
default=lambda *a: "normal",
)
- channel_type = fields.Selection(
- [
- ("direct", "Direct"),
- ("indirect", "Indirect"),
- ],
- string="Sales Channel",
- compute="_compute_channel_type",
- store=True,
- )
date_order = fields.Datetime(
string="Order Date",
required=True,
@@ -308,14 +305,6 @@ class PmsFolio(models.Model):
addr = folio.partner_id.address_get(["invoice"])
folio.partner_invoice_id = addr["invoice"]
- @api.depends("agency_id")
- def _compute_channel_type(self):
- for folio in self:
- if folio.agency_id:
- folio.channel_type = "indirect"
- else:
- folio.channel_type = "direct"
-
@api.depends("partner_id")
def _compute_payment_term_id(self):
self.payment_term_id = False
@@ -442,17 +431,6 @@ class PmsFolio(models.Model):
"amount_total": amount_untaxed + amount_tax,
}
)
- # Check channel type
- @api.constrains("channel_type")
- def check_channel_type(self):
- for record in self:
- if (record.channel_type == "indirect" and record.partner_id.is_agency != True
- or record.channel_type == "direct" and record.partner_id.is_agency == True):
- raise ValidationError(
- _(
- "Indirect Sale Channel must have an agency associated!"
- )
- )
@api.depends("reservation_ids", "reservation_ids.state")
def _compute_reservations_pending_arrival(self):
diff --git a/pms/models/pms_reservation.py b/pms/models/pms_reservation.py
index bf32504a3..9e9765711 100644
--- a/pms/models/pms_reservation.py
+++ b/pms/models/pms_reservation.py
@@ -147,8 +147,14 @@ class PmsReservation(models.Model):
store=True,
readonly=False,
)
- agency_id = fields.Many2one(related="folio_id.agency_id")
-
+ agency_id = fields.Many2one(
+ related="folio_id.agency_id",
+ readonly=True,
+ )
+ channel_type_id = fields.Many2one(
+ related="folio_id.agency_id",
+ readonly=True,
+ )
partner_invoice_id = fields.Many2one(
"res.partner",
string="Invoice Address",
@@ -343,11 +349,6 @@ class PmsReservation(models.Model):
overbooking = fields.Boolean("Is Overbooking", default=False)
reselling = fields.Boolean("Is Reselling", default=False)
nights = fields.Integer("Nights", compute="_compute_nights", store=True)
- channel_type = fields.Selection(
- related="folio_id.channel_type",
- required = True,
- readonly = True,
- )
origin = fields.Char("Origin", compute="_compute_origin", store=True)
detail_origin = fields.Char(
"Detail Origin", compute="_compute_detail_origin", store=True
diff --git a/pms/models/pms_sale_channel.py b/pms/models/pms_sale_channel.py
new file mode 100644
index 000000000..7f72c7af9
--- /dev/null
+++ b/pms/models/pms_sale_channel.py
@@ -0,0 +1,15 @@
+class PmsSaleChannel(models.Model):
+ _name = "pms.sale.channel"
+ _description = "Sales Channel"
+
+ #Fields declaration
+ name = fields.Text(
+ string="Sale Channel Name"
+ )
+ channel_type = fields.Selection(
+ [
+ ("direct","Direct"),
+ ("indirect","Indirect")
+ ],
+ string = "Sale Channel Type"
+ )
diff --git a/pms/models/res_partner.py b/pms/models/res_partner.py
index 1c135639e..14ce1e831 100644
--- a/pms/models/res_partner.py
+++ b/pms/models/res_partner.py
@@ -21,6 +21,12 @@ class ResPartner(models.Model):
folios_count = fields.Integer("Folios", compute="_compute_folios_count")
unconfirmed = fields.Boolean("Unconfirmed", default=True)
is_agency = fields.Boolean("Is Agency")
+ sale_channel_id = fields.Many2one(
+ "pms.sale.channel",
+ string="Sale Channel",
+ ondelete = "restrict",
+ domain=[("channel_type","=","indirect")],
+ )
# Compute and Search methods
def _compute_reservations_count(self):
@@ -64,3 +70,11 @@ class ResPartner(models.Model):
name, args=args, operator=operator, limit=limit_rest
)
return res
+
+ @api.constrains("is_agency","sale_channel_id")
+ def _check_is_agency(self):
+ for record in self:
+ if record.is_agency and not record.sale_channel_id:
+ raise models.ValidationError(_("Sale Channel must be entered"))
+ if not record.is_agency and record.sale_channel_id:
+ record.sale_channel_id=None
diff --git a/pms/tests/test_pms_sale_channel.py b/pms/tests/test_pms_sale_channel.py
index e54c03b3f..a955ce117 100644
--- a/pms/tests/test_pms_sale_channel.py
+++ b/pms/tests/test_pms_sale_channel.py
@@ -6,7 +6,7 @@ from odoo import fields
@freeze_time("2010-01-01")
class TestPmsSaleChannel(TestHotel):
- def test_reservation_indirect_channel(self):
+ def test_not_agency_as_agency(self):
#ARRANGE
PmsReservation = self.env["pms.reservation"]
not_agency = self.env["res.partner"].create(
@@ -22,34 +22,103 @@ class TestPmsSaleChannel(TestHotel):
{
"checkin": datetime.datetime.now(),
"checkout":datetime.datetime.now() + datetime.timedelta(days=3),
- "channel_type":"indirect",
- "partner_id":not_agency.id,
+ "agency_id":not_agency.id,
}
)
- def test_reservation_direct_channel(self):
+ def test_partner_as_direct_channel(self):
+ #ARRANGE
PmsReservation = self.env["pms.reservation"]
- agency = self.env["res.partner"].create(
- {
- "name":"partner2",
- "is_agency":True,
- }
- )
+ partner = customer = self.env.ref("base.res_partner_12")
#ACT & ASSERT
with self.assertRaises(ValidationError), self.cr.savepoint():
PmsReservation.create(
- {
- "checkin": datetime.datetime.now() +datetime.timedelta(days=5),
- "checkout":datetime.datetime.now() + datetime.timedelta(days=8),
- "channel_type":"direct",
- "partner_id":agency.id,
+ {
+ "checkin": datetime.datetime.now(),
+ "checkout":datetime.datetime.now() + datetime.timedelta(days=3),
+ "channel_type_id":partner.id,
}
)
+ def test_channel_type_id_only_directs(self):
+ #ARRANGE
+ PmsReservation = self.env["pms.reservation"]
+ PmsSaleChannel = self.env["pms.sale.channel"]
+ #ACT
+ saleChannel = PmsSaleChannel.create(
+ {
+ "channel_type":"direct"
+ }
+ )
+ reservation = PmsReservation.create(
+ {
+ "checkin":datetime.datetime.now(),
+ "checkout":datetime.datetime.now()+datetime.datetimedelta(days=3)
+ "channel_type_id": saleChannel.id
+ }
+ )
+ #ASSERT
+ self.assertEqual(
+ self.browse_ref(reservation.channel_type_id).channel_type,
+ "direct",
+ "Sale channel is not direct"
+ )
+ def test_agency_id_is_agency(self):
+ #ARRANGE
+ PmsReservation = self.env["pms.reservation"]
+ #ACT
+ agency = self.env["res.partner"].create(
+ {
+ "name":"partner1",
+ "is_agency":True
+ }
+ )
+ reservation = PmsReservation.create(
+ {
+ "checkin":datetime.datetime.now(),
+ "checkout":datetime.datetime.now()+datetime.datetimedelta(days=3)
+ "agency_id":agency.id
+ }
+ )
+ #ASSERT
+ self.assertEqual(
+ self.browse_ref(reservation.agency_id).is_agency,
+ True,
+ "Agency_id doesn't correspond to an agency"
+ )
+ def test_sale_channel_id_only_indirect(self):
+ #ARRANGE
+ PmsSaleChannel = self.env["pms.sale.channel"]
+ #ACT
+ saleChannel = PmsSaleChannel.create(
+ {
+ "channel_type":"indirect"
+ }
+ )
+ agency = self.env["res.partner"].create(
+ {
+ "name":"example",
+ "is_agency":True,
+ "sale_channel_id":saleChannel.id
+ }
+ )
+ #ASSERT
+ self.assertEqual(
+ self.browse_ref(agency.sale_channel_id).channel_type,
+ "indirect",
+ "An agency should be a indirect channel"
+ )
-
-
-
+ def test_agency_without_sale_channel_id(self):
+ #ARRANGE & ACT & ASSERT
+ with self.assertRaises(ValidationError), self.cr.savepoint():
+ self.env["res.partner"].create(
+ {
+ "name":"example",
+ "is_agency":True,
+ "sale_channel_id":None
+ }
+ )
diff --git a/pms/views/pms_folio_views.xml b/pms/views/pms_folio_views.xml
index ca2e6fb57..31a68bcc2 100644
--- a/pms/views/pms_folio_views.xml
+++ b/pms/views/pms_folio_views.xml
@@ -98,14 +98,16 @@
name="reservation_type"
attrs="{'readonly':[('state','not in',('draft'))]}"
/>
-
+ />-->
+
+
diff --git a/pms/views/pms_reservation_views.xml b/pms/views/pms_reservation_views.xml
index c1bc8593c..ae296b13b 100644
--- a/pms/views/pms_reservation_views.xml
+++ b/pms/views/pms_reservation_views.xml
@@ -255,7 +255,7 @@
'readonly': [('partner_id', '!=', False),
('mobile','!=', False)]}"
/>
-
+ />-->
-
+ />-->
+
+
-
+ />-->
@@ -736,7 +738,7 @@
domain="[('to_assign','=',True)]"
/>
-
+ />-->
-
+
+
+