mirror of
https://github.com/OCA/pms.git
synced 2025-01-29 00:17:45 +02:00
[IMP] add test to check sales channel domain
This commit is contained in:
committed by
Darío Lodeiros
parent
d5de68e120
commit
29fc701c52
@@ -114,10 +114,16 @@ class PmsFolio(models.Model):
|
|||||||
)
|
)
|
||||||
agency_id = fields.Many2one(
|
agency_id = fields.Many2one(
|
||||||
"res.partner",
|
"res.partner",
|
||||||
"Agency",
|
string="Agency",
|
||||||
ondelete="restrict",
|
ondelete="restrict",
|
||||||
domain=[("is_agency", "=", True)],
|
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)
|
payment_ids = fields.One2many("account.payment", "folio_id", readonly=True)
|
||||||
# return_ids = fields.One2many("payment.return", "folio_id", readonly=True)
|
# return_ids = fields.One2many("payment.return", "folio_id", readonly=True)
|
||||||
payment_term_id = fields.Many2one(
|
payment_term_id = fields.Many2one(
|
||||||
@@ -163,15 +169,6 @@ class PmsFolio(models.Model):
|
|||||||
string="Type",
|
string="Type",
|
||||||
default=lambda *a: "normal",
|
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(
|
date_order = fields.Datetime(
|
||||||
string="Order Date",
|
string="Order Date",
|
||||||
required=True,
|
required=True,
|
||||||
@@ -308,14 +305,6 @@ class PmsFolio(models.Model):
|
|||||||
addr = folio.partner_id.address_get(["invoice"])
|
addr = folio.partner_id.address_get(["invoice"])
|
||||||
folio.partner_invoice_id = addr["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")
|
@api.depends("partner_id")
|
||||||
def _compute_payment_term_id(self):
|
def _compute_payment_term_id(self):
|
||||||
self.payment_term_id = False
|
self.payment_term_id = False
|
||||||
@@ -442,17 +431,6 @@ class PmsFolio(models.Model):
|
|||||||
"amount_total": amount_untaxed + amount_tax,
|
"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")
|
@api.depends("reservation_ids", "reservation_ids.state")
|
||||||
def _compute_reservations_pending_arrival(self):
|
def _compute_reservations_pending_arrival(self):
|
||||||
|
|||||||
@@ -147,8 +147,14 @@ class PmsReservation(models.Model):
|
|||||||
store=True,
|
store=True,
|
||||||
readonly=False,
|
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(
|
partner_invoice_id = fields.Many2one(
|
||||||
"res.partner",
|
"res.partner",
|
||||||
string="Invoice Address",
|
string="Invoice Address",
|
||||||
@@ -343,11 +349,6 @@ class PmsReservation(models.Model):
|
|||||||
overbooking = fields.Boolean("Is Overbooking", default=False)
|
overbooking = fields.Boolean("Is Overbooking", default=False)
|
||||||
reselling = fields.Boolean("Is Reselling", default=False)
|
reselling = fields.Boolean("Is Reselling", default=False)
|
||||||
nights = fields.Integer("Nights", compute="_compute_nights", store=True)
|
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)
|
origin = fields.Char("Origin", compute="_compute_origin", store=True)
|
||||||
detail_origin = fields.Char(
|
detail_origin = fields.Char(
|
||||||
"Detail Origin", compute="_compute_detail_origin", store=True
|
"Detail Origin", compute="_compute_detail_origin", store=True
|
||||||
|
|||||||
15
pms/models/pms_sale_channel.py
Normal file
15
pms/models/pms_sale_channel.py
Normal file
@@ -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"
|
||||||
|
)
|
||||||
@@ -21,6 +21,12 @@ class ResPartner(models.Model):
|
|||||||
folios_count = fields.Integer("Folios", compute="_compute_folios_count")
|
folios_count = fields.Integer("Folios", compute="_compute_folios_count")
|
||||||
unconfirmed = fields.Boolean("Unconfirmed", default=True)
|
unconfirmed = fields.Boolean("Unconfirmed", default=True)
|
||||||
is_agency = fields.Boolean("Is Agency")
|
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
|
# Compute and Search methods
|
||||||
def _compute_reservations_count(self):
|
def _compute_reservations_count(self):
|
||||||
@@ -64,3 +70,11 @@ class ResPartner(models.Model):
|
|||||||
name, args=args, operator=operator, limit=limit_rest
|
name, args=args, operator=operator, limit=limit_rest
|
||||||
)
|
)
|
||||||
return res
|
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
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ from odoo import fields
|
|||||||
|
|
||||||
@freeze_time("2010-01-01")
|
@freeze_time("2010-01-01")
|
||||||
class TestPmsSaleChannel(TestHotel):
|
class TestPmsSaleChannel(TestHotel):
|
||||||
def test_reservation_indirect_channel(self):
|
def test_not_agency_as_agency(self):
|
||||||
#ARRANGE
|
#ARRANGE
|
||||||
PmsReservation = self.env["pms.reservation"]
|
PmsReservation = self.env["pms.reservation"]
|
||||||
not_agency = self.env["res.partner"].create(
|
not_agency = self.env["res.partner"].create(
|
||||||
@@ -22,34 +22,103 @@ class TestPmsSaleChannel(TestHotel):
|
|||||||
{
|
{
|
||||||
"checkin": datetime.datetime.now(),
|
"checkin": datetime.datetime.now(),
|
||||||
"checkout":datetime.datetime.now() + datetime.timedelta(days=3),
|
"checkout":datetime.datetime.now() + datetime.timedelta(days=3),
|
||||||
"channel_type":"indirect",
|
"agency_id":not_agency.id,
|
||||||
"partner_id":not_agency.id,
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_reservation_direct_channel(self):
|
def test_partner_as_direct_channel(self):
|
||||||
|
#ARRANGE
|
||||||
PmsReservation = self.env["pms.reservation"]
|
PmsReservation = self.env["pms.reservation"]
|
||||||
agency = self.env["res.partner"].create(
|
partner = customer = self.env.ref("base.res_partner_12")
|
||||||
{
|
|
||||||
"name":"partner2",
|
|
||||||
"is_agency":True,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
#ACT & ASSERT
|
#ACT & ASSERT
|
||||||
with self.assertRaises(ValidationError), self.cr.savepoint():
|
with self.assertRaises(ValidationError), self.cr.savepoint():
|
||||||
PmsReservation.create(
|
PmsReservation.create(
|
||||||
{
|
{
|
||||||
"checkin": datetime.datetime.now() +datetime.timedelta(days=5),
|
"checkin": datetime.datetime.now(),
|
||||||
"checkout":datetime.datetime.now() + datetime.timedelta(days=8),
|
"checkout":datetime.datetime.now() + datetime.timedelta(days=3),
|
||||||
"channel_type":"direct",
|
"channel_type_id":partner.id,
|
||||||
"partner_id":agency.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
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|||||||
@@ -98,14 +98,16 @@
|
|||||||
name="reservation_type"
|
name="reservation_type"
|
||||||
attrs="{'readonly':[('state','not in',('draft'))]}"
|
attrs="{'readonly':[('state','not in',('draft'))]}"
|
||||||
/>
|
/>
|
||||||
<field
|
<!--<field
|
||||||
name="channel_type"
|
name="channel_type"
|
||||||
attrs="{'required':[('reservation_type','=','normal')]}"
|
attrs="{'required':[('reservation_type','=','normal')]}"
|
||||||
/>
|
/>
|
||||||
<field
|
<field
|
||||||
name="agency_id"
|
name="agency_id"
|
||||||
options="{'no_create': True,'no_open': True}"
|
options="{'no_create': True,'no_open': True}"
|
||||||
/>
|
/>-->
|
||||||
|
<field name="agency_id"/>
|
||||||
|
<field name="channel_type_id"/>
|
||||||
</group>
|
</group>
|
||||||
<group>
|
<group>
|
||||||
<field name="partner_internal_comment" />
|
<field name="partner_internal_comment" />
|
||||||
|
|||||||
@@ -255,7 +255,7 @@
|
|||||||
'readonly': [('partner_id', '!=', False),
|
'readonly': [('partner_id', '!=', False),
|
||||||
('mobile','!=', False)]}"
|
('mobile','!=', False)]}"
|
||||||
/>
|
/>
|
||||||
<field
|
<!--<field
|
||||||
name="phone"
|
name="phone"
|
||||||
colspan="2"
|
colspan="2"
|
||||||
nolabel="1"
|
nolabel="1"
|
||||||
@@ -267,7 +267,7 @@
|
|||||||
('mobile','=','')],
|
('mobile','=','')],
|
||||||
'readonly': [('partner_id', '!=', False),
|
'readonly': [('partner_id', '!=', False),
|
||||||
('phone','!=', False)]}"
|
('phone','!=', False)]}"
|
||||||
/>
|
/>-->
|
||||||
<field
|
<field
|
||||||
placeholder="Partner Notes"
|
placeholder="Partner Notes"
|
||||||
colspan="2"
|
colspan="2"
|
||||||
@@ -297,10 +297,12 @@
|
|||||||
name="pricelist_id"
|
name="pricelist_id"
|
||||||
attrs="{'invisible': [('reservation_type','in',('out'))]}"
|
attrs="{'invisible': [('reservation_type','in',('out'))]}"
|
||||||
/>
|
/>
|
||||||
<field
|
<!--<field
|
||||||
name="agency_id"
|
name="agency_id"
|
||||||
options="{'no_create': True,'no_open': True}"
|
options="{'no_create': True,'no_open': True}"
|
||||||
/>
|
/>-->
|
||||||
|
<field name="agency_id"/>
|
||||||
|
<field name="channel_type_id"/>
|
||||||
<field
|
<field
|
||||||
name="cancelled_reason"
|
name="cancelled_reason"
|
||||||
attrs="{'invisible': [('state', 'not in', ('cancelled'))]}"
|
attrs="{'invisible': [('state', 'not in', ('cancelled'))]}"
|
||||||
@@ -527,10 +529,10 @@
|
|||||||
<field name="overbooking" />
|
<field name="overbooking" />
|
||||||
</group>
|
</group>
|
||||||
<group>
|
<group>
|
||||||
<field
|
<!--<field
|
||||||
name="channel_type"
|
name="channel_type"
|
||||||
attrs="{'required':[('reservation_type','not in',('staff','out'))]}"
|
attrs="{'required':[('reservation_type','not in',('staff','out'))]}"
|
||||||
/>
|
/>-->
|
||||||
<field name="reservation_type" />
|
<field name="reservation_type" />
|
||||||
</group>
|
</group>
|
||||||
</page>
|
</page>
|
||||||
@@ -736,7 +738,7 @@
|
|||||||
domain="[('to_assign','=',True)]"
|
domain="[('to_assign','=',True)]"
|
||||||
/>
|
/>
|
||||||
<separator />
|
<separator />
|
||||||
<filter
|
<!--<filter
|
||||||
string="Web"
|
string="Web"
|
||||||
name="web"
|
name="web"
|
||||||
domain="[('channel_type', '=', 'web')]"
|
domain="[('channel_type', '=', 'web')]"
|
||||||
@@ -755,7 +757,7 @@
|
|||||||
string="Phone"
|
string="Phone"
|
||||||
name="phone"
|
name="phone"
|
||||||
domain="[('channel_type', '=', 'phone')]"
|
domain="[('channel_type', '=', 'phone')]"
|
||||||
/>
|
/>-->
|
||||||
<separator />
|
<separator />
|
||||||
<filter
|
<filter
|
||||||
string="Still to be paid"
|
string="Still to be paid"
|
||||||
|
|||||||
@@ -39,14 +39,19 @@
|
|||||||
<field string="Folios" name="folios_count" widget="statinfo" />
|
<field string="Folios" name="folios_count" widget="statinfo" />
|
||||||
</button>
|
</button>
|
||||||
</xpath>
|
</xpath>
|
||||||
<xpath expr="//field[@name='user_id']" position="after">
|
<!--<xpath expr="//field[@name='user_id']" position="after">
|
||||||
<field name="company_type" invisible="1" />
|
<field name="company_type" invisible="1" />
|
||||||
<field
|
<field
|
||||||
name="is_agency"
|
name="is_agency"
|
||||||
attrs="{'invisible': [('company_type','!=','company')]}"
|
attrs="{'invisible': [('company_type','!=','company')]}"
|
||||||
/>
|
/>
|
||||||
</xpath>
|
</xpath>-->
|
||||||
</field>
|
</field>
|
||||||
|
<field name="is_agency"/>
|
||||||
|
<field
|
||||||
|
name="sale_channel_id"
|
||||||
|
attrs="{'invisible':[('is_agency','=','True')]}"
|
||||||
|
/>
|
||||||
</record>
|
</record>
|
||||||
<menuitem
|
<menuitem
|
||||||
name="Customers"
|
name="Customers"
|
||||||
|
|||||||
Reference in New Issue
Block a user