Skip to content

Commit a1670fa

Browse files
committed
[IMP] estate: adding sprinkles to the views - Chapter 11
inline property list view to property type statusbar widget for the status of the property manual and model ordering adding attributes and options (color, invisible, readonly), color decorations default availability filter, filter_domain for living_area stat_button for property types that shows offer for a specific property type
1 parent 339b8eb commit a1670fa

9 files changed

+154
-34
lines changed

estate/__manifest__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@
1010
"security/security.xml",
1111
"security/ir.model.access.csv",
1212
"views/estate_property_views.xml",
13-
"views/estate_property_type_views.xml",
1413
"views/estate_property_tag_views.xml",
1514
"views/estate_property_offer_views.xml",
15+
"views/estate_property_type_views.xml",
1616
"views/estate_menus.xml",
1717
],
1818
"assets": {},

estate/models/estate_property.py

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77

88
class EstateProperty(models.Model):
9-
_name = "estate_property"
9+
_name = "estate.property"
1010
_description = "Estate Property"
1111
name = fields.Char("Title", required=True)
1212
description = fields.Text()
@@ -45,14 +45,16 @@ class EstateProperty(models.Model):
4545
default="new",
4646
required=True,
4747
copy=False,
48+
store=True,
49+
compute="_compute_state",
4850
)
49-
type_id = fields.Many2one("estate_property_type", string="Property Type")
51+
type_id = fields.Many2one("estate.property.type", string="Property Type")
5052
salesperson_id = fields.Many2one(
5153
"res.users", string="Salesperson", default=lambda self: self.env.user
5254
)
5355
buyer_id = fields.Many2one("res.partner", string="Buyer", copy=False)
54-
tag_ids = fields.Many2many("estate_property_tag")
55-
offer_ids = fields.One2many("estate_property_offer", "property_id", string="Offers")
56+
tag_ids = fields.Many2many("estate.property.tag")
57+
offer_ids = fields.One2many("estate.property.offer", "property_id", string="Offers")
5658
total_area = fields.Integer("Total Area (sqm)", compute="_compute_total_area")
5759
best_price = fields.Float("Best Price", compute="_compute_best_price")
5860

@@ -63,6 +65,8 @@ class EstateProperty(models.Model):
6365
"CHECK(selling_price > 0)", "The selling price must be positive"
6466
)
6567

68+
_order = "id desc"
69+
6670
@api.depends("living_area", "garden_area")
6771
def _compute_total_area(self):
6872
for record in self:
@@ -73,6 +77,12 @@ def _compute_best_price(self):
7377
for record in self:
7478
record.best_price = max(record.offer_ids.mapped("price") or [0])
7579

80+
@api.depends("offer_ids")
81+
def _compute_state(self):
82+
for record in self:
83+
if len(record.offer_ids) == 1 and record.state == "new":
84+
record.state = "offer_received"
85+
7686
@api.onchange("garden")
7787
def _onchange_garden(self):
7888
if self.garden:
@@ -89,13 +99,17 @@ def action_cancel_property(self):
8999
for record in self:
90100
record.state = "cancelled"
91101

102+
return True
103+
92104
def action_sell_property(self):
93105
if self.state == "cancelled":
94106
raise UserError("Cancelled property cannot be sold!")
95107

96108
for record in self:
97109
record.state = "sold"
98110

111+
return True
112+
99113
@api.constrains("expected_price", "selling_price")
100114
def _check_selling_price(self):
101115
for record in self:

estate/models/estate_property_offer.py

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,22 @@
44

55

66
class EstatePropertyOffer(models.Model):
7-
_name = "estate_property_offer"
7+
_name = "estate.property.offer"
88
_description = "Estate Property Offer"
99
price = fields.Float()
1010
status = fields.Selection(
1111
[("accepted", "Accepted"), ("refused", "Refused")], copy=False
1212
)
1313
partner_id = fields.Many2one("res.partner", required=True)
14-
property_id = fields.Many2one("estate_property", required=True)
14+
property_id = fields.Many2one("estate.property", required=True)
1515
validity = fields.Integer("Validity", default=7)
1616
date_deadline = fields.Date("Deadline", compute="_compute_date_deadline")
17+
hide_offer_buttons = fields.Boolean(compute="_compute_hide_offer_buttons")
18+
property_type_id = fields.Many2one(related="property_id.type_id", store=True)
1719
_check_price = models.Constraint(
1820
"CHECK(price > 0)", "Offer's price must be positive"
1921
)
22+
_order = "price desc"
2023

2124
@api.depends("validity", "create_date")
2225
def _compute_date_deadline(self):
@@ -25,6 +28,20 @@ def _compute_date_deadline(self):
2528
record.create_date or fields.Datetime.now()
2629
) + timedelta(days=record.validity)
2730

31+
@api.depends("property_id.state")
32+
def _compute_hide_offer_buttons(self):
33+
for record in self:
34+
a_state = record.property_id.state
35+
if (
36+
a_state == "offer_accepted"
37+
or a_state == "cancelled"
38+
or a_state == "sold"
39+
or record.status
40+
):
41+
record.hide_offer_buttons = True
42+
else:
43+
record.hide_offer_buttons = False
44+
2845
def action_accept_offer(self):
2946
if self.status:
3047
raise UserError("You cannot change the status!")
@@ -49,6 +66,18 @@ def action_refuse_offer(self):
4966
record.status = "refused"
5067
return True
5168

69+
def is_still_open_to_offers(self):
70+
if (
71+
self.partner_id.state == "offer_accepted"
72+
or self.partner_id.state == "sold"
73+
or self.partner_id.state == "cancelled"
74+
):
75+
print("HELLO!!")
76+
return True
77+
78+
print("FALSE case!!")
79+
return False
80+
5281
# @api.depends("create_date", "date_deadline") Not working right now!!!
5382
# def _inverse_date_deadline(self):
5483
# print("Hello!")

estate/models/estate_property_tag.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33

44
class EstatePropertyTag(models.Model):
5-
_name = "estate_property_tag"
5+
_name = "estate.property.tag"
66
_description = "Estate Property Tag"
77
name = fields.Char("Name", required=True)
8+
color = fields.Integer("Color")
89
_name_unique = models.Constraint("unique(name)", "Tag name must be unique")
10+
_order = "name"
Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,22 @@
1-
from odoo import fields, models
1+
from odoo import fields, models, api
22

33

44
class EstatePropertyType(models.Model):
5-
_name = "estate_property_type"
5+
_name = "estate.property.type"
66
_description = "Estate Property Type"
77
name = fields.Char(required=True)
88
_name_unique = models.Constraint("unique(name)", "Type must be unique")
9+
property_ids = fields.One2many("estate.property", "type_id", string="Properties")
10+
_order = "sequence, name"
11+
sequence = fields.Integer(
12+
"Sequence", default=1, help="Used to order property types"
13+
)
14+
offer_ids = fields.One2many(
15+
"estate.property.offer", "property_type_id", string="Offers"
16+
)
17+
offer_count = fields.Integer("Offer Count", compute="_compute_offer_count")
18+
19+
@api.depends("offer_ids")
20+
def _compute_offer_count(self):
21+
for record in self:
22+
record.offer_count = len(record.offer_ids)

estate/views/estate_property_offer_views.xml

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
11
<odoo>
22
<record id="estate_property_offer_view_list" model="ir.ui.view">
33
<field name="name">estate_property_offer.list</field>
4-
<field name="model">estate_property_offer</field>
4+
<field name="model">estate.property.offer</field>
55
<field name="arch" type="xml">
6-
<list>
6+
<list editable="bottom" decoration-success="status == 'accepted'"
7+
decoration-danger="status == 'refused'">
78
<field name="price" />
89
<field name="partner_id" />
9-
<field name="status" />
1010
<field name="validity" />
1111
<field name="date_deadline" />
12-
<field name="status" />
12+
<field name="property_type_id" />
1313
<button name="action_accept_offer" type="object" string="" icon="fa-check"
14-
title="accept" />
14+
title="accept" invisible="hide_offer_buttons" />
1515
<button name="action_refuse_offer" type="object" string="" icon="fa-times"
16-
title="refuse" />
16+
title="refuse" invisible="hide_offer_buttons" />
1717
</list>
1818
</field>
1919
</record>
2020
<record id="estate_property_offer_view_form" model="ir.ui.view">
2121
<field name="name">estate_property_offer.form</field>
22-
<field name="model">estate_property_offer</field>
22+
<field name="model">estate.property.offer</field>
2323
<field name="arch" type="xml">
2424
<form>
2525
<sheet>
@@ -36,4 +36,10 @@
3636
</form>
3737
</field>
3838
</record>
39+
<record id="estate_property_offer_action" model="ir.actions.act_window">
40+
<field name="name">Property Offers</field>
41+
<field name="res_model">estate.property.offer</field>
42+
<field name="view_mode">list,form</field>
43+
<field name="domain">[('property_type_id', '=', active_id)]</field>
44+
</record>
3945
</odoo>
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<odoo>
22
<record id="estate_property_tag_action" model="ir.actions.act_window">
33
<field name="name">Property Tags</field>
4-
<field name="res_model">estate_property_tag</field>
4+
<field name="res_model">estate.property.tag</field>
55
<field name="view_mode">list,form</field>
66
</record>
77
</odoo>
Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,53 @@
11
<odoo>
2+
<record id="estate_property_type_view_form" model="ir.ui.view">
3+
<field name="name">estate_property_type.form</field>
4+
<field name="model">estate.property.type</field>
5+
<field name="arch" type="xml">
6+
<form>
7+
<sheet>
8+
<div name="button_box" class="oe_button_box">
9+
<button class="oe_stat_button" name="%(estate_property_offer_action)d"
10+
type="action" icon="fa-money">
11+
<div class="o_stat_info">
12+
<span class="o_stat_value">
13+
<field name="offer_count" widget="statinfo" />
14+
</span>
15+
</div>
16+
</button>
17+
</div>
18+
<h1>
19+
<field name="name" />
20+
</h1>
21+
<notebook>
22+
<page name="Properties">
23+
<field name="property_ids">
24+
<list>
25+
<field name="name" />
26+
<field name="expected_price" />
27+
<field name="state" />
28+
</list>
29+
</field>
30+
</page>
31+
</notebook>
32+
</sheet>
33+
</form>
34+
</field>
35+
</record>
36+
<record id="estate_property_type_view_list" model="ir.ui.view">
37+
<field name="name">estate_property_type.list</field>
38+
<field name="model">estate.property.type</field>
39+
<field name="arch" type="xml">
40+
<list>
41+
<field name="sequence" widget="handle" />
42+
<field name="name" />
43+
<field name="offer_count" />
44+
<field name="offer_ids" />
45+
</list>
46+
</field>
47+
</record>
248
<record id="estate_property_type_action" model="ir.actions.act_window">
349
<field name="name">Property Types</field>
4-
<field name="res_model">estate_property_type</field>
50+
<field name="res_model">estate.property.type</field>
551
<field name="view_mode">list,form</field>
652
</record>
753
</odoo>

0 commit comments

Comments
 (0)