Skip to content

Commit d4f129f

Browse files
committed
[IMP] estate: Implemented offer acceptance and refusal actions;
Implemented offer acceptance and refusal actions; added state management buttons in property views [FIX] estate: resolve Runbot style and linting errors (Ruff/Semgrep) This commit fixes all Runbot Check Style issues for the estate module. [FIX] estate: Cleaned up code by removing unnecessary blank lines in model files
1 parent e789cd4 commit d4f129f

File tree

8 files changed

+102
-57
lines changed

8 files changed

+102
-57
lines changed

Estate/__init__.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
11
from . import models
2-

Estate/models/__init__.py

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

Estate/models/estate_property.py

Lines changed: 75 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
2-
from odoo import models, fields , api
1+
from odoo import models, fields, api
32
from datetime import timedelta
43

54

@@ -10,7 +9,7 @@ class EstateProperty(models.Model):
109
name = fields.Char(required=True)
1110
description = fields.Text()
1211
postcode = fields.Char()
13-
create_date = fields.Date()
12+
create_date = fields.Datetime()
1413
expected_price = fields.Float(required=True)
1514
selling_price = fields.Float()
1615
bedrooms = fields.Integer()
@@ -20,66 +19,90 @@ class EstateProperty(models.Model):
2019
garden = fields.Boolean()
2120
garden_area = fields.Integer()
2221
garden_orientation = fields.Selection([
23-
('north', 'North'),
24-
('south', 'South'),
25-
('east', 'East'),
26-
('west', 'West'),
22+
("north", "North"),
23+
("south", "South"),
24+
("east", "East"),
25+
("west", "West"),
2726
])
28-
state = fields.Selection(
29-
[
30-
('new', 'New'),
31-
('offer_received', 'Offer Received'),
32-
('offer_accepted', 'Offer Accepted'),
33-
('sold', 'Sold'),
34-
('canceled', 'Canceled'),
35-
],
36-
string="Status",
37-
required=True,
38-
copy=False,
39-
default='new'
40-
)
4127
active = fields.Boolean(default=True)
42-
property_type_id = fields.Many2one("estate.property.type", string="Property Type")
28+
29+
state = fields.Selection([
30+
("new", "New"),
31+
("offer_received", "Offer Received"),
32+
("offer_accepted", "Offer Accepted"),
33+
("sold", "Sold"),
34+
("canceled", "Canceled"),
35+
], string="Status", required=True, copy=False, default="new")
36+
37+
property_type_id = fields.Many2one("estate.property.type", string="Property Type")
4338
buyer_id = fields.Many2one("res.partner", string="Buyer")
4439
salesperson_id = fields.Many2one("res.users", string="Salesperson")
4540
tag_ids = fields.Many2many("estate.property.tag", string="Tags")
4641
offer_ids = fields.One2many("estate.property.offer", "property_id", string="Offers")
42+
4743
total_area = fields.Float(compute="_compute_total_area", string="Total Area", store=True)
4844
best_price = fields.Float(compute="_compute_best_price", string="Best Offer", store=True)
49-
validity_days = fields.Integer(default=7)
50-
deadline_date = fields.Date(compute="_compute_validity_date", string="Validity Date", store=True)
51-
@api.depends('living_area', 'garden_area')
45+
46+
validity = fields.Integer(default=7)
47+
date_deadline = fields.Date(
48+
compute="_compute_date_deadline",
49+
inverse="_inverse_date_deadline",
50+
store=True,
51+
)
52+
53+
@api.depends("living_area", "garden_area")
5254
def _compute_total_area(self):
5355
for record in self:
54-
record.total_area = record.living_area + (record.garden_area or 0)
55-
@api.depends('offer_ids.price')
56+
record.total_area = (record.living_area or 0) + (record.garden_area or 0)
57+
58+
@api.depends("offer_ids.price")
5659
def _compute_best_price(self):
5760
for record in self:
58-
if record.offer_ids:
59-
record.best_price = max(record.offer_ids.mapped('price'))
60-
else:
61-
record.best_price = 0.0
62-
63-
@api.depends('create_date', 'validity_days')
64-
def _compute_validity_date(self):
65-
if self.create_date:
66-
for record in self:
67-
record.deadline_date = record.create_date + timedelta(days=record.validity_days)
68-
else:
69-
for record in self:
70-
record.deadline_date = fields.Date.today() + timedelta(days=record.validity_days)
71-
72-
@api.onchange('garden_area')
73-
def _onchange_garden(self):
61+
record.best_price = max(record.offer_ids.mapped("price")) if record.offer_ids else 0.0
62+
63+
@api.depends("create_date", "validity")
64+
def _compute_date_deadline(self):
7465
for record in self:
75-
if self.garden_area == 10:
76-
self.garden_orientation = 'north'
77-
if self.garden_area == 20:
78-
self.garden_orientation = 'south'
79-
if self.garden_area == 30:
80-
self.garden_orientation = 'east'
81-
if self.garden_area == 40:
82-
self.garden_orientation = 'west'
66+
create_date = record.create_date or fields.Date.today()
67+
if hasattr(create_date, "date"):
68+
create_date = create_date.date()
69+
record.date_deadline = create_date + timedelta(days=record.validity)
70+
71+
def _inverse_date_deadline(self):
72+
for record in self:
73+
create_date = record.create_date or fields.Date.today()
74+
if hasattr(create_date, "date"):
75+
create_date = create_date.date()
76+
delta = (record.date_deadline - create_date).days if record.date_deadline else 0
77+
record.validity = delta
78+
79+
@api.onchange("garden")
80+
def _onchange_garden(self):
81+
for record in self:
82+
if record.garden:
83+
record.garden_area = 10
84+
record.garden_orientation = "north"
8385
else:
84-
self.garden_area = 0
85-
self.garden_orientation = False
86+
record.garden_area = 0
87+
record.garden_orientation = False
88+
89+
def action_set_sold(self):
90+
for record in self:
91+
record.state = "sold"
92+
93+
def action_set_canceled(self):
94+
for record in self:
95+
record.state = "canceled"
96+
97+
def action_set_next_status(self):
98+
for record in self:
99+
if record.state == "new":
100+
record.state = "offer_received"
101+
elif record.state == "offer_received":
102+
record.state = "offer_accepted"
103+
elif record.state == "offer_accepted":
104+
record.state = "sold"
105+
106+
def action_back_to_new(self):
107+
for record in self:
108+
record.state = "new"

Estate/models/estate_property_offer.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from odoo import models, fields
22

3+
34
class EstatePropertyOffer(models.Model):
45
_name = "estate.property.offer"
56
_description = "Real Estate Property Offer"
@@ -11,6 +12,14 @@ class EstatePropertyOffer(models.Model):
1112
('refused', 'Refused'),
1213
],
1314
)
14-
15+
1516
property_id = fields.Many2one("estate.property", string="Property", required=True)
1617
partner_id = fields.Many2one("res.partner", string="Buyer", required=True)
18+
19+
def action_accept_offer(self):
20+
for record in self:
21+
record.status = 'accepted'
22+
23+
def action_refuse_offer(self):
24+
for record in self:
25+
record.status = 'refused'
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
from odoo import models, fields
22

3+
34
class EstatePropertyTag(models.Model):
45
_name = "estate.property.tag"
56
_description = "Real Estate Property Tag"
67

7-
name = fields.Char(required=True)
8+
name = fields.Char(required=True)
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
from odoo import models, fields
22

3+
34
class EstatePropertyType(models.Model):
45
_name = "estate.property.type"
56
_description = "Real Estate Property Type"
67

7-
name = fields.Char(required=True)
8+
name = fields.Char(required=True)

Estate/views/estate_property_offer_views.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
<list>
77
<field name="price" />
88
<field name="partner_id" />
9+
<button name="action_accept_offer" string="Accept" type="object" />
10+
<button name="action_refuse_offer" string="Refuse" type="object" />
911
<field name="status" />
1012
</list>
1113
</field>
@@ -20,6 +22,8 @@
2022
<group>
2123
<field name="price"/>
2224
<field name="partner_id"/>
25+
<button name="action_accept_offer" string="Accept" type="object" />
26+
<button name="action_refuse_offer" string="Refuse" type="object" />
2327
<field name="status"/>
2428
</group>
2529
</sheet>

Estate/views/estate_property_views.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,13 @@
3939
<h1>
4040
<field name="name" placeholder="Property Name"/>
4141
</h1>
42+
<header>
43+
<button name="action_set_next_status" string="Next" type="object"/>
44+
<button name="action_back_to_new" string="Reset to New" type="object"/>
45+
<button name="action_set_sold" string="Mark as Sold" type="object"/>
46+
<button name="action_set_canceled" string="Cancel" type="object"/>
47+
<field name="state" widget="statusbar" statusbar_visible="new,offer_received,offer_accepted,sold,canceled"/>
48+
</header>
4249
<group col="2">
4350
<group string="Property Details">
4451
<field name="postcode"/>
@@ -78,6 +85,8 @@
7885
<list editable="bottom">
7986
<field name="partner_id"/>
8087
<field name="price"/>
88+
<button name="action_accept_offer" string="Accept" type="object" />
89+
<button name="action_refuse_offer" string="Refuse" type="object" />
8190
<field name="status"/>
8291
</list>
8392
</field>

0 commit comments

Comments
 (0)