Skip to content

Commit fe42714

Browse files
committed
[ADD] estate: extend CRUD rules and user form with property management
. Prevent deletion of properties unless state is 'New' or 'Cancelled' . On offer creation: set related property state to 'Offer Received' . Raise an error if an offer is lower than an existing one . Show salesperson's available properties directly on the user form . Add a new tab in user settings to manage linked properties
1 parent 167ed52 commit fe42714

13 files changed

+89
-55
lines changed

estate/__manifest__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
"views/estate_property_type_views.xml",
1111
"views/estate_property_tag_views.xml",
1212
"views/estate_menus.xml",
13+
"views/res_users_views.xml",
1314
],
1415
"license": "LGPL-3",
1516
"application": True,

estate/models/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
from . import estate_property_type
33
from . import estate_property_tag
44
from . import estate_property_offer
5+
from . import res_users

estate/models/estate_property.py

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
from datetime import timedelta
22
from odoo import models, fields, api
3-
from odoo.exceptions import ValidationError
4-
from odoo.exceptions import UserError
3+
from odoo.exceptions import ValidationError, UserError
54
from odoo.tools import float_is_zero, float_compare
65

76

@@ -57,13 +56,11 @@ class EstateProperty(models.Model):
5756
("sold", "Sold"),
5857
("cancelled", "Cancelled"),
5958
],
60-
compute="_compute_state",
61-
store=True,
6259
)
6360
salesman_id = fields.Many2one(
6461
"res.users", string="Salesman", default=lambda self: self.env.user
6562
)
66-
buyer_id = fields.Many2one("res.partner", string="Buyer", copy=False)
63+
buyer_id = fields.Many2one("res.partner", string="Buyer", copy=False, readonly=True)
6764

6865
tag_ids = fields.Many2many(
6966
"estate.property.tag",
@@ -83,6 +80,22 @@ class EstateProperty(models.Model):
8380
compute="_compute_best_price",
8481
)
8582

83+
_sql_constraints = [
84+
(
85+
"check_expected_price",
86+
"CHECK(expected_price > 0)",
87+
"The expected price must be greater than 0.",
88+
),
89+
]
90+
91+
@api.ondelete(at_uninstall=False)
92+
def _unlink_check(self):
93+
for property in self:
94+
if property.state not in ["new", "cancelled"]:
95+
raise UserError(
96+
"You cannot delete a property that is not new or cancelled."
97+
)
98+
8699
@api.depends("living_area", "garden_area", "garden")
87100
def _compute_total_area(self):
88101
for property in self:
@@ -95,14 +108,6 @@ def _compute_best_price(self):
95108
for property in self:
96109
property.best_price = max(property.offer_ids.mapped("price"), default=0.0)
97110

98-
@api.depends("offer_ids")
99-
def _compute_state(self):
100-
for record in self:
101-
if record.offer_ids and record.selling_price == 0.0:
102-
record.state = "offer received"
103-
else:
104-
record.state = "new"
105-
106111
@api.onchange("garden")
107112
def _onchange_garden(self):
108113
for property in self:
@@ -135,14 +140,6 @@ def action_set_cancelled(self):
135140
elif property.state == "sold":
136141
raise UserError("A sold property cannot be cancelled.")
137142

138-
_sql_constraints = [
139-
(
140-
"check_expected_price",
141-
"CHECK(expected_price > 0)",
142-
"The expected price must be greater than 0.",
143-
),
144-
]
145-
146143
@api.constrains("selling_price", "expected_price")
147144
def _check_selling_price(self):
148145
for property in self:

estate/models/estate_property_offer.py

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,23 @@ class EstatePropertyOffer(models.Model):
3636
store=True,
3737
)
3838

39+
_sql_constraints = [
40+
("check_price", "CHECK(price > 0)", "The price must be greater than 0."),
41+
]
42+
43+
@api.model_create_multi
44+
def create(self, vals_list):
45+
for record in vals_list:
46+
property = self.env["estate.property"].browse(record["property_id"])
47+
48+
if record.get("price") < property.best_price:
49+
raise UserError(
50+
"You cannot create an offer lower than an existing one."
51+
)
52+
53+
property.state = "offer received"
54+
return super().create(vals_list)
55+
3956
@api.depends("validity")
4057
def _compute_date_deadline(self):
4158
for offer in self:
@@ -58,22 +75,18 @@ def _inverse_date_deadline(self):
5875
else:
5976
offer.validity = 0
6077

61-
# @api.onchange("date_deadline")
62-
# def _onchange_date_deadline(self):
63-
# for offer in self:
64-
# if offer.date_deadline:
65-
# base_date = fields.Date.to_date(offer.create_date) if offer.create_date else fields.Date.context_today(offer)
66-
# offer.validity = (offer.date_deadline - base_date).days
67-
# else:
68-
# offer.validity = 0
69-
7078
def action_set_accepted(self):
7179
for offer in self:
7280
if offer.property_id.selling_price == 0.0:
73-
offer.status = "accepted"
74-
offer.property_id.state = "offer accepted"
75-
offer.property_id.selling_price = offer.price
76-
offer.property_id.buyer_id = offer.partner_id
81+
offer.write({"status": "accepted"})
82+
83+
offer.property_id.write(
84+
{
85+
"state": "offer accepted",
86+
"selling_price": offer.price,
87+
"buyer_id": offer.partner_id.id,
88+
}
89+
)
7790

7891
other_offers = offer.property_id.offer_ids - offer
7992

@@ -83,16 +96,8 @@ def action_set_accepted(self):
8396

8497
def action_set_refused(self):
8598
for offer in self:
86-
if offer.status is False:
87-
offer.status = "refused"
88-
elif offer.status == "accepted":
89-
offer.status = "refused"
99+
if offer.status == "accepted":
90100
offer.property_id.state = "offer received"
91101
offer.property_id.buyer_id = False
92102
offer.property_id.selling_price = 0.0
93-
else:
94-
raise UserError("This offer is not accepted, so it cannot be refused.")
95-
96-
_sql_constraints = [
97-
("check_price", "CHECK(price > 0)", "The price must be greater than 0."),
98-
]
103+
offer.status = "refused"

estate/models/estate_property_tag.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@
44
class EstatePropertyTag(models.Model):
55
_name = "estate.property.tag"
66
_description = "Estate Property Tag"
7-
_sql_constraints = [
8-
("unique_name", "UNIQUE(name)", "A tag with same name is already exists."),
9-
]
107
_order = "name asc"
118

129
name = fields.Char(string="Tag Name", required=True)
1310
description = fields.Text(string="Description")
1411
color = fields.Integer(string="Color")
12+
13+
_sql_constraints = [
14+
("unique_name", "UNIQUE(name)", "A tag with same name is already exists."),
15+
]

estate/models/estate_property_type.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,6 @@
44
class EstatePropertyType(models.Model):
55
_name = "estate.property.type"
66
_description = "Estate Property Type"
7-
_sql_constraints = [
8-
("unique_name", "UNIQUE(name)", "A type with same name is already exists."),
9-
]
107
_order = "sequence,name"
118

129
name = fields.Char(required=True)
@@ -22,6 +19,10 @@ class EstatePropertyType(models.Model):
2219

2320
offer_count = fields.Integer("Offers", compute="_compute_offer_count")
2421

22+
_sql_constraints = [
23+
("unique_name", "UNIQUE(name)", "A type with same name is already exists."),
24+
]
25+
2526
@api.depends("offer_ids")
2627
def _compute_offer_count(self):
2728
for record in self:

estate/models/res_users.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
from odoo import fields, models
2+
3+
4+
class ResUser(models.Model):
5+
_inherit = "res.users"
6+
7+
property_ids = fields.One2many(
8+
"estate.property",
9+
"salesman_id",
10+
string="Properties",
11+
domain=[("state", "in", ["new", "offer received"])],
12+
)

estate/views/estate_menus.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,5 @@
1010
<menuitem id="estate_property_tag_menu_action" action="estate_property_tag_action"/>
1111
</menuitem>
1212
</menuitem>
13-
</odoo>
13+
</odoo>
14+

estate/views/estate_property_offer_views.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,4 @@
4242
</field>
4343
</record>
4444

45-
</odoo>
45+
</odoo>

estate/views/estate_property_tag_views.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,4 @@
3939
</form>
4040
</field>
4141
</record>
42-
</odoo>
42+
</odoo>

0 commit comments

Comments
 (0)