Skip to content

Commit 7e736d7

Browse files
committed
[IMP] estate: Added Inline Views, Widgets, List Order, Attributes and Buttons
Chapter 11 : Added inline views, widgets, and stat buttons for clear navigation Added list order like model, view and manual for easy to find Added default search filters, editable list views, optional fields
1 parent dfc0ad5 commit 7e736d7

10 files changed

+156
-100
lines changed

estate/__manifest__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
'name': "Real Estate",
3+
'description': """Real estate management tutorial module with properties, offers, types and tags.""",
34
'version': '1.0',
45
'license': 'LGPL-3',
56
'summary': 'Real Estate advertisement tutorial module',
@@ -16,5 +17,4 @@
1617
'category': 'Sales/Real Estate',
1718
'installable': True,
1819
'auto_install': False,
19-
'description': """Real estate management tutorial module with properties, offers, types and tags.""",
2020
}

estate/models/estate_property.py

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,24 @@
11
from dateutil.relativedelta import relativedelta
22
from datetime import date
3+
34
from odoo import models, fields, api
4-
from odoo.exceptions import UserError,ValidationError
5-
from odoo.tools.float_utils import float_compare, float_is_zero
5+
from odoo.exceptions import UserError, ValidationError
6+
from odoo.tools.float_utils import float_compare
67

78

89
class EstateProperty(models.Model):
910
_name = "estate.property"
1011
_description = "Real Estate Property"
12+
_order = "id desc"
1113

1214
name = fields.Char(required=True)
1315
description = fields.Text()
1416
postcode = fields.Char()
1517
date_availability = fields.Date(
16-
default=lambda sself: date.today() + relativedelta(months=3),
18+
default=lambda self: date.today() + relativedelta(months=3),
1719
copy=False
1820
)
19-
expected_price = fields.Float(string="Expected Price", required=True)
21+
expected_price = fields.Float(required=True)
2022
selling_price = fields.Float(
2123
readonly=True,
2224
copy=False
@@ -101,28 +103,27 @@ def _onchange_garden(self):
101103
self.garden_area = 0
102104
self.garden_orientation = None
103105

104-
def action_cancel(self):
105-
for rec in self:
106-
if rec.state == "sold":
107-
raise UserError("Sold properties cannot be cancelled.")
108-
else:
109-
rec.state = "cancelled"
106+
def action_cancel_property(self):
107+
if self.filtered(lambda rec: rec.state == "sold"):
108+
raise exceptions.UserError(_("Sold properties cannot be cancelled."))
109+
self.write({"state": "cancelled"})
110110
return True
111111

112112
def action_set_sold(self):
113113
for rec in self:
114114
if rec.state == "cancelled":
115-
raise UserError("Canceled properties cannot be sold.")
115+
raise exceptions.UserError(_("Canceled properties cannot be sold."))
116116
else:
117117
rec.state = "sold"
118118
return True
119+
119120
@api.constrains("selling_price", "expected_price")
120121
def _check_selling_price(self):
121-
for rec in self:
122+
for rec in self:
122123
if rec.selling_price == 0:
123124
return False
124125
if float_compare(rec.selling_price, rec.expected_price * 0.9, precision_digits=2) < 0:
125-
raise ValidationError(
126+
raise exceptions.ValidationError(_(
126127
"The selling price must be at least 90% of the expected price!\n"
127128
"You must reduce the expected price if you want to accept this offer."
128-
)
129+
))

estate/models/estate_property_offer.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
from dateutil.relativedelta import relativedelta
2+
23
from odoo import models, fields, api
34
from odoo.exceptions import UserError
45

56

67
class EstatePropertyOffer(models.Model):
78
_name = "estate.property.offer"
89
_description = "Real Estate Property Offer"
10+
_order = "price desc"
911

1012
price = fields.Float(string="Price")
1113
status = fields.Selection(
12-
[
14+
selection=[
1315
("accepted", "Accepted"),
1416
("refused", "Refused"),
1517
],
@@ -31,6 +33,13 @@ class EstatePropertyOffer(models.Model):
3133
inverse="_inverse_date_deadline",
3234
store=True,
3335
)
36+
property_type_id = fields.Many2one(
37+
related="property_id.property_type_id", store=True
38+
)
39+
_offer_price = models.Constraint(
40+
'CHECK (price > 0)',
41+
'Offer price must be greater than 0',
42+
)
3443

3544
@api.depends("validity")
3645
def _compute_date_deadline(self):
@@ -50,14 +59,10 @@ def action_accept(self):
5059
offer.status = 'accepted'
5160
offer.property_id.selling_price = offer.price
5261
offer.property_id.buyer_id = offer.partner_id
62+
offer.property_id.state = 'offer_accepted'
5363
return True
5464

5565
def action_refuse(self):
5666
for offer in self:
5767
offer.status = 'refused'
5868
return True
59-
60-
_offer_price = models.Constraint(
61-
'CHECK (price > 0)',
62-
'Offer price must be greater than 0',
63-
)

estate/models/estate_property_tag.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@
44
class EstatePropertyTag(models.Model):
55
_name = "estate.property.tag"
66
_description = "Real Estate Property Tag"
7+
_order = "name"
78

89
name = fields.Char(required=True)
10+
color = fields.Integer()
911

1012
_unique_name = models.Constraint(
1113
'unique(name)',

estate/models/estate_property_type.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,22 @@
44
class EstatePropertyType(models.Model):
55
_name = "estate.property.type"
66
_description = "Real Estate Property Type"
7+
_order = "sequence,name"
78

89
name = fields.Char(required=True)
10+
property_ids = fields.One2many(
11+
"estate.property",
12+
"property_type_id",
13+
)
14+
sequence = fields.Integer(default=1, help="Used to order stages. Lower is better.")
15+
offer_ids = fields.One2many("estate.property.offer", "property_type_id")
16+
offer_count = fields.Integer(compute="_compute_offer_count")
917

1018
_unique_name = models.Constraint(
1119
'unique(name)',
1220
'The property type name must be unique.',
13-
)
21+
)
22+
23+
def _compute_offer_count(self):
24+
for rec in self:
25+
rec.offer_count = len(rec.offer_ids)

estate/views/estate_menus.xml

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
<odoo>
2-
<menuitem id="menu_estate_root" name="Real Estate"/>
3-
<menuitem id="menu_estate_advertisements" name="Advertisements" parent="menu_estate_root" sequence="10"/>
4-
<menuitem id="menu_estate_properties" name="Properties" parent="menu_estate_advertisements" action="action_estate_property" sequence="10"/>
5-
6-
<menuitem id="menu_estate_settings" name="Settings" parent="menu_estate_root" sequence="20"/>
7-
2+
<menuitem id="menu_estate_root" name="Real Estate" />
3+
<menuitem id="menu_estate_advertisements" name="Advertisements" parent="menu_estate_root"
4+
sequence="10" />
5+
<menuitem id="menu_estate_properties" name="Properties" parent="menu_estate_advertisements"
6+
action="action_estate_property" sequence="10" />
7+
<menuitem id="menu_estate_settings" name="Settings" parent="menu_estate_root" sequence="20" />
88
<menuitem id="menu_estate_property_types" name="Property Types"
9-
parent="menu_estate_settings"
10-
action="action_estate_property_type"
11-
sequence="10"/>
12-
9+
parent="menu_estate_settings"
10+
action="action_estate_property_type"
11+
sequence="10" />
1312
<menuitem id="menu_estate_property_tags" name="Property Tags"
14-
parent="menu_estate_settings"
15-
action="action_estate_property_tag"/>
13+
parent="menu_estate_settings"
14+
action="action_estate_property_tag" />
1615
</odoo>
Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,23 @@
11
<odoo>
2+
<record id="action_estate_property_offer" model="ir.actions.act_window">
3+
<field name="name">Property Offers</field>
4+
<field name="res_model">estate.property.offer</field>
5+
<field name="view_mode">list,form</field>
6+
<field name="domain">[('property_type_id', '=', active_id)]</field>
7+
</record>
28
<record id="view_estate_property_offer_list" model="ir.ui.view">
39
<field name="name">estate.property.offer.list</field>
410
<field name="model">estate.property.offer</field>
511
<field name="arch" type="xml">
6-
<list string="Offers">
12+
<list string="Offers" editable="bottom" decoration-danger="status=='refused'" decoration-success="status=='accepted'">
713
<field name="price"/>
814
<field name="partner_id"/>
915
<field name="validity"/>
1016
<field name="date_deadline"/>
11-
<button name="action_accept" string="Accept" type="object" icon="fa-check"/>
12-
<button name="action_refuse" string="Refuse" type="object" icon="fa-close" />
17+
<button name="action_accept" string="Accept" type="object" icon="fa-check" invisible="status"/>
18+
<button name="action_refuse" string="Refuse" type="object" icon="fa-close" invisible="status"/>
1319
<field name="status"/>
1420
</list>
1521
</field>
1622
</record>
17-
18-
<record id="view_estate_property_offer_form" model="ir.ui.view">
19-
<field name="name">estate.property.offer.form</field>
20-
<field name="model">estate.property.offer</field>
21-
<field name="arch" type="xml">
22-
<form string="Offer">
23-
<sheet>
24-
<group>
25-
<field name="price"/>
26-
<field name="partner_id"/>
27-
<field name="validity"/>
28-
<field name="date_deadline"/>
29-
<field name="status"/>
30-
</group>
31-
</sheet>
32-
</form>
33-
</field>
34-
</record>
3523
</odoo>

estate/views/estate_property_tag_views.xml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,14 @@
77
<p>Create and manage tags for your properties.</p>
88
</field>
99
</record>
10+
<record id="view_estate_property_tag_list" model="ir.ui.view">
11+
<field name="name">estate.property.tag.list</field>
12+
<field name="model">estate.property.tag</field>
13+
<field name="arch" type="xml">
14+
<list string="Tag" editable="bottom">
15+
<field name="name"/>
16+
<field name="color"/>
17+
</list>
18+
</field>
19+
</record>
1020
</odoo>

estate/views/estate_property_type_views.xml

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,37 @@
44
<field name="res_model">estate.property.type</field>
55
<field name="view_mode">list,form</field>
66
</record>
7-
</odoo>
7+
<record id="view_estate_property_type_form" model="ir.ui.view">
8+
<field name="name">estate.property.type.form</field>
9+
<field name="model">estate.property.type</field>
10+
<field name="arch" type="xml">
11+
<form string="Property Type">
12+
<sheet>
13+
<button class="oe_stat_button"
14+
type="action"
15+
name="%(estate.action_estate_property_offer)d"
16+
icon="fa-money"
17+
invisible="offer_count == 0">
18+
<field name="offer_count" widget="statinfo" string="Offers" />
19+
</button>
20+
<group>
21+
<field name="name" />
22+
</group>
23+
24+
<notebook>
25+
<page string="Properties">
26+
<field name="property_ids">
27+
<list editable="bottom">
28+
<field name="name" />
29+
<field name="expected_price" />
30+
<field name="state" />
31+
</list>
32+
</field>
33+
</page>
34+
</notebook>
35+
36+
</sheet>
37+
</form>
38+
</field>
39+
</record>
40+
</odoo>

0 commit comments

Comments
 (0)