Skip to content

Commit f32a4ed

Browse files
committed
[IMP] estate: add constraints on some fields
In this commit, I've added api and sql constraints on some of the fields in the property model and the offers model to make sure we don't create a property with an expected_price less than zero and users don't submit an offer with a price less than zero as well, and added business logic to not accept multiple offers on the same property at the same time and not to submit an offer on a property that is already sold.
1 parent bfe3033 commit f32a4ed

7 files changed

+46
-25
lines changed

estate/__manifest__.py

+1-4
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,9 @@
55
"data": [
66
"security/ir.model.access.csv",
77
"views/estate_property_offer_actions.xml",
8-
"views/estate_property_actions.xml",
98
"views/estate_property_type_actions.xml",
109
"views/estate_property_tag_actions.xml",
10+
"views/estate_property_actions.xml",
1111
"views/estate_property_menus.xml",
1212
],
13-
"application": True,
14-
"installable": True,
15-
"auto_install": False,
1613
}

estate/models/estate_property.py

+21-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import datetime
22

33
from odoo import api, fields, models
4-
from odoo.excepetions import UserError
4+
from odoo.excepetions import UserError, ValidationError
5+
from odoo.tools import float_utils
56

67

78
class EstateProperty(models.Model):
@@ -41,6 +42,19 @@ class EstateProperty(models.Model):
4142
offer_ids = fields.One2many("estate.property.offer", "property_id")
4243
best_offer_price = fields.Float(compute="_compute_best_offer_price")
4344

45+
_sql_constraints = [
46+
(
47+
"check_expected_price",
48+
"CHECK(expected_price > 0)",
49+
"The expected price of a property must be strictly positive.",
50+
),
51+
(
52+
"check_selling_price",
53+
"CHECK(selling_price > 0)",
54+
"The selling price of a property must be strictly positive.",
55+
),
56+
]
57+
4458
@api.depends("garden_area", "living_area")
4559
def _compute_total_area(self):
4660
for record in self:
@@ -61,6 +75,12 @@ def _onchange_has_garden(self):
6175
record.garden_orientation = False
6276
record.garden_area = False
6377

78+
@api.constrains("selling_price")
79+
def _check_price(self):
80+
for record in self:
81+
if float_utils.float_compare(record.selling_price, record.expected_price * 0.9) > 0:
82+
raise ValidationError("The selling price cannot be lower than 90%% of the expected price.")
83+
6484
def action_mark_property_as_sold(self):
6585
if "cancelled" in self.mapped("status"):
6686
raise UserError("Cannot sell a property that was canceled.")

estate/models/estate_property_offer.py

+17-2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,14 @@ class EstatePropertyOffer(models.Model):
1414
validity_days = fields.Integer(default=7)
1515
deadline_date = fields.Date(compute="_compute_deadline_date", inverse="_inverse_validity_days")
1616

17+
_sql_constraints = [
18+
(
19+
"check_price",
20+
"CHECK(price > 0)",
21+
"The offer price of a property must be strictly positive.",
22+
),
23+
]
24+
1725
@api.depends("validity_days")
1826
def _compute_deadline_date(self):
1927
for record in self:
@@ -27,11 +35,18 @@ def action_accept_offer(self):
2735
self.ensure_one()
2836

2937
if self.property_id.status == "sold":
30-
raise UserError(f"Property with this id {self.property_id} has already been sold.")
38+
raise UserError(f"Property with id {self.property_id.id} has already been sold.")
39+
40+
has_offer_accepted = self.env["estate.property.offer"].search_count(
41+
[("status", "=", "accepted"), ("property_id", "=", self.property_id.id)]
42+
)
43+
44+
if has_offer_accepted:
45+
raise UserError(f"Property with id {self.property_id.id} has an accepted offer.")
3146

3247
self.status = "accepted"
3348

34-
self.property_id.action_mark_property_as_sold()
49+
# self.property_id.action_mark_property_as_sold()
3550

3651
def action_reject_offer(self):
3752
for record in self:

estate/models/estate_property_tag.py

+2
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,5 @@ class EstatePropertyTag(models.Model):
66
_description = "Estate Property Type"
77

88
name = fields.Char(required=True)
9+
10+
_sql_constraints = [("check_property_tag_name", "unique(name)", "Two property tags cannot have the same name.")]

estate/models/estate_property_type.py

+2
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,5 @@ class EstatePropertyType(models.Model):
66
_description = "Estate Property Type"
77

88
name = fields.Char(required=True)
9+
10+
_sql_constraints = [("check_property_type_name", "unique(name)", "Two property types cannot have the same name.")]

estate/views/estate_property_actions.xml

+1-3
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,7 @@
6767
</page>
6868

6969
<page string="Offers">
70-
<group>
71-
<field name="offer_ids"/>
72-
</group>
70+
<field name="offer_ids"/>
7371
</page>
7472
</notebook>
7573
</sheet>

estate/views/estate_property_offer_actions.xml

+2-15
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,11 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<odoo>
3-
<record id="estate_property_offer_list_view" model="ir.ui.view">
4-
<field name="name">estate.property.offer.list_view</field>
5-
<field name="model">estate.property.offer</field>
6-
<field name="arch" type="xml">
7-
<list string="Offers">
8-
<field name="price"/>
9-
<field name="partner_id"/>
10-
</list>
11-
</field>
12-
</record>
13-
143
<record id="estate_property_offer_form_view" model="ir.ui.view">
154
<field name="name">estate.property.offer.form_view</field>
165
<field name="model">estate.property.offer</field>
176
<field name="arch" type="xml">
187
<form string="Property Offer">
198
<sheet>
20-
<button name="action_accept_offer" class="btn-success" string="Accept" type="object"/>
21-
<button name="action_reject_offer" class="btn-danger" string="Reject" type="object"/>
229
<h1 class="mb32">
2310
<field name="property_id"/>
2411
</h1>
@@ -41,8 +28,8 @@
4128
<field name="partner_id"/>
4229
<field name="deadline_date"/>
4330
<field name="validity_days" string = "Validity"/>
44-
<button name="action_accept_offer" type="object" icon="fa-check"/>
45-
<button name="action_reject_offer" type="object" icon="fa-times"/>
31+
<button name="action_accept_offer" type="object" icon="fa-check" string="accept"/>
32+
<button name="action_reject_offer" type="object" icon="fa-times" string="refuse"/>
4633
<field name="status"/>
4734
</list>
4835
</field>

0 commit comments

Comments
 (0)