Skip to content

Commit 354427d

Browse files
committed
[IMP] real_estate: Add access groups,, demo data & chatter
- Created 'Agent' and 'Manager' security groups for the estate module. - Implemented conditional visibility and access rules based on user roles. - Added demo data to support testing, training, and development. - Integrated chatter to enable message tracking and logging. - Ensured field and button visibility/functionality adapts to user role.
1 parent b02961b commit 354427d

11 files changed

+184
-30
lines changed

estate_account/models/estate_property.py

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,7 @@ class Property(models.Model):
88

99
def action_sold(self):
1010
for property in self:
11-
journal = self.env["account.journal"].search(
12-
[("type", "=", "sale")], limit=1
13-
)
14-
11+
property.check_access("write")
1512
commission = property.selling_price * 0.06
1613
discount = property.selling_price * 0.05
1714
invoice_lines = [
@@ -37,14 +34,10 @@ def action_sold(self):
3734
}
3835
),
3936
]
40-
4137
invoice_vals = {
4238
"partner_id": property.buyer_id.id,
4339
"move_type": "out_invoice",
44-
"journal_id": journal.id,
4540
"invoice_line_ids": invoice_lines,
4641
}
47-
48-
self.env["account.move"].create(invoice_vals)
49-
42+
self.env["account.move"].sudo().create(invoice_vals)
5043
return super().action_sold()

real_estate/__manifest__.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,21 @@
33
{
44
"name": "Dream Homes",
55
"version": "1.0",
6-
"depends": ["base"],
6+
"depends": ["base", "mail"],
77
"category": "Real Estate/Brokerage",
88
"data": [
9+
"security/estate_property_security.xml",
910
"security/ir.model.access.csv",
1011
"views/estate_property_views.xml",
1112
"views/estate_property_offer_views.xml",
1213
"views/estate_property_type_views.xml",
1314
"views/estate_property_tag_views.xml",
1415
"views/estate_property_menus.xml",
1516
"views/res_users_views.xml",
17+
"data/estate.property.types.csv",
18+
],
19+
"demo": [
20+
"demo/estate_property_demo.xml",
1621
],
1722
"license": "LGPL-3",
1823
"installable": True,
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
id,name
2+
property_type_1,Residential
3+
property_type_2,Commercial
4+
property_type_3,Industrial
5+
property_type_4,Land
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<odoo>
3+
<data noupdate="1">
4+
<record id="estate_property_big_villa" model="estate.property">
5+
<field name="name">Big Villa</field>
6+
<field name="state">new</field>
7+
<field name="description">A nice and big villa</field>
8+
<field name="postcode">12345</field>
9+
<field name="date_availability">2020-02-02</field>
10+
<field name="expected_price">1600000</field>
11+
<field name="selling_price">1500000</field>
12+
<field name="bedrooms">6</field>
13+
<field name="living_area">100</field>
14+
<field name="facades">4</field>
15+
<field name="garage">True</field>
16+
<field name="garden">True</field>
17+
<field name="garden_area">100000</field>
18+
<field name="garden_orientation">south</field>
19+
<field name="estate_property_type_id" ref="real_estate.property_type_1" />
20+
</record>
21+
22+
<record id="estate_property_trailer_home" model="estate.property">
23+
<field name="name">Trailer home</field>
24+
<field name="state">cancelled</field>
25+
<field name="description">Home in a trailer park</field>
26+
<field name="postcode">54321</field>
27+
<field name="date_availability">1970-01-01</field>
28+
<field name="expected_price">100000</field>
29+
<field name="bedrooms">1</field>
30+
<field name="living_area">10</field>
31+
<field name="facades">4</field>
32+
<field name="garage">False</field>
33+
<field name="garden">False</field>
34+
<field name="estate_property_type_id" ref="real_estate.property_type_1" />
35+
</record>
36+
37+
<record id="offer_1" model="estate.property.offers">
38+
<field name="partner_id" ref="base.res_partner_12" />
39+
<field name="property_id" ref="real_estate.estate_property_big_villa" />
40+
<field name="price">1550000</field>
41+
<field name="validity">14</field>
42+
<field name="offer_deadline" eval="(datetime.now() + relativedelta(days=14)).date()" />
43+
</record>
44+
45+
<record id="offer_2" model="estate.property.offers">
46+
<field name="partner_id" ref="base.res_partner_12" />
47+
<field name="property_id" ref="real_estate.estate_property_big_villa" />
48+
<field name="price">1560000</field>
49+
<field name="validity">14</field>
50+
<field name="offer_deadline" eval="(datetime.now() + relativedelta(days=14)).date()" />
51+
</record>
52+
53+
<record id="offer_3" model="estate.property.offers">
54+
<field name="partner_id" ref="base.res_partner_2" />
55+
<field name="property_id" ref="real_estate.estate_property_big_villa" />
56+
<field name="price">1570001</field>
57+
<field name="validity">14</field>
58+
<field name="offer_deadline" eval="(datetime.now() + relativedelta(days=14)).date()" />
59+
</record>
60+
61+
<function model="estate.property.offers" name="action_accept_offer">
62+
<value eval="[ref('real_estate.offer_1')]" />
63+
</function>
64+
65+
<function model="estate.property.offers" name="action_refuse_offer">
66+
<value eval="[ref('real_estate.offer_2')]" />
67+
</function>
68+
69+
<function model="estate.property.offers" name="action_refuse_offer">
70+
<value eval="[ref('real_estate.offer_3')]" />
71+
</function>
72+
73+
<record id="estate_property_with_inline_offers" model="estate.property">
74+
<field name="name">House with Inline Offers</field>
75+
<field name="state">new</field>
76+
<field name="expected_price">500000</field>
77+
<field name="estate_property_type_id" ref="real_estate.property_type_1" />
78+
<field name="estate_property_offer_ids"
79+
eval="[
80+
Command.create({
81+
'partner_id': ref('base.res_partner_1'),
82+
'price': 480000,
83+
'validity': 10,
84+
'offer_deadline': (datetime.now() + relativedelta(days=10)).date()
85+
}),
86+
Command.create({
87+
'partner_id': ref('base.res_partner_2'),
88+
'price': 510000,
89+
'validity': 7,
90+
'offer_deadline': (datetime.now() + relativedelta(days=7)).date()
91+
})
92+
]" />
93+
</record>
94+
</data>
95+
</odoo>

real_estate/models/estate_property.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@
99
class EstateProperty(models.Model):
1010
_name = "estate.property"
1111
_description = "This is a real estate module"
12+
_inherit = "mail.thread"
1213
_order = "id desc"
1314

14-
name = fields.Char(string="Property Name", required=True)
15+
name = fields.Char(string="Property Name", required=True, tracking=True)
1516
description = fields.Text(string="Description")
1617
postcode = fields.Char(string="Postcode")
1718
expected_price = fields.Float(string="Expected Price", required=True)
@@ -35,17 +36,22 @@ class EstateProperty(models.Model):
3536
comodel_name="estate.property.offers",
3637
inverse_name="property_id",
3738
string="Offers",
39+
tracking=True,
3840
)
3941
seller_id = fields.Many2one(
4042
comodel_name="res.users",
4143
string="SalesPerson",
4244
default=lambda self: self.env.user,
4345
)
4446
estate_property_type_id = fields.Many2one(
45-
comodel_name="estate.property.types", string="Property Type"
47+
comodel_name="estate.property.types",
48+
string="Property Type",
49+
tracking=True,
4650
)
4751
estate_property_tag_ids = fields.Many2many(
48-
comodel_name="estate.property.tags", string="Tags"
52+
comodel_name="estate.property.tags",
53+
string="Tags",
54+
tracking=True,
4955
)
5056
garden_orientation = fields.Selection(
5157
selection=[
@@ -69,6 +75,12 @@ class EstateProperty(models.Model):
6975
default="new",
7076
string="State",
7177
)
78+
company_id = fields.Many2one(
79+
comodel_name="res.company",
80+
string="Company",
81+
required=True,
82+
default=lambda self: self.env.company,
83+
)
7284
_sql_constraints = [
7385
(
7486
"check_expected_price_positive",

real_estate/models/estate_property_offers.py

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,21 @@ class EstatePropertyOffers(models.Model):
1616
property_type_id = fields.Many2one(
1717
related="property_id.estate_property_type_id", store=True
1818
)
19-
2019
offer_deadline = fields.Date(
2120
compute="_compute_date_deadline", inverse="_inverse_date_deadline"
2221
)
2322
status = fields.Selection(
2423
selection=[("accepted", "Accepted"), ("refused", "Refused")]
2524
)
2625

26+
_sql_constraints = [
27+
(
28+
"check_offer_price_positive",
29+
"CHECK(price > 0)",
30+
"Offer price must be strictly positive.",
31+
)
32+
]
33+
2734
@api.depends("create_date", "validity")
2835
def _compute_date_deadline(self):
2936
for record in self:
@@ -62,14 +69,6 @@ def action_refuse_offer(self):
6269
for offer in self:
6370
offer.status = "refused"
6471

65-
_sql_constraints = [
66-
(
67-
"check_offer_price_positive",
68-
"CHECK(price > 0)",
69-
"Offer price must be strictly positive.",
70-
)
71-
]
72-
7372
@api.model_create_multi
7473
def create(self, vals):
7574
for val in vals:
@@ -82,5 +81,4 @@ def create(self, vals):
8281
raise UserError(
8382
f"The offer must be higher than {property_id.best_offer}"
8483
)
85-
8684
return super().create(vals)
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<odoo>
3+
<data>
4+
<record id="estate_group_user" model="res.groups">
5+
<field name="name">Agent</field>
6+
<field name="category_id" ref="base.module_category_real_estate_brokerage" />
7+
</record>
8+
9+
<record id="estate_group_manager" model="res.groups">
10+
<field name="name">Manager</field>
11+
<field name="category_id" ref="base.module_category_real_estate_brokerage" />
12+
<field name="implied_ids" eval="[(4, ref('real_estate.estate_group_user'))]" />
13+
<field name="users" eval="[(4, ref('base.user_admin'))]" />
14+
</record>
15+
16+
<record id="estate_property_rule_agent" model="ir.rule">
17+
<field name="name">
18+
Limit agents to only being able to see or modify properties which have no
19+
salesperson, or
20+
for which they are the salesperson.
21+
</field>
22+
<field name="model_id" ref="model_estate_property" />
23+
<field name="perm_read" eval="True" />
24+
<field name="perm_write" eval="True" />
25+
<field name="groups" eval="[Command.link(ref('real_estate.estate_group_user'))]"></field>
26+
<field name="domain_force">[
27+
'|', ('seller_id', '=', user.id),
28+
('seller_id', '=', False), '|', ('company_id', '=', user.company_id.id),
29+
('company_id', '=', False)]
30+
</field>
31+
</record>
32+
33+
<record id="estate_property_rule_manager" model="ir.rule">
34+
<field name="name">Managers can see all properties</field>
35+
<field name="model_id" ref="model_estate_property" />
36+
<field name="groups" eval="[Command.link(ref('real_estate.estate_group_manager'))]" />
37+
</record>
38+
</data>
39+
</odoo>
Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
2-
real_estate.access_estate_property,access_estate_property,real_estate.model_estate_property,base.group_user,1,1,1,1
3-
real_estate.access_estate_property_types,access_estate_property_types,real_estate.model_estate_property_types,base.group_user,1,1,1,1
4-
real_estate.access_estate_property_tags,access_estate_property_tags,real_estate.model_estate_property_tags,base.group_user,1,1,1,1
5-
real_estate.access_estate_property_offers,access_estate_property_offers,real_estate.model_estate_property_offers,base.group_user,1,1,1,1
2+
real_estate.access_estate_property_manager,access_estate_property,real_estate.model_estate_property,real_estate.estate_group_manager,1,1,1,0
3+
real_estate.access_estate_property_type_manager,access_estate_property_type,real_estate.model_estate_property_types,real_estate.estate_group_manager,1,1,1,1
4+
real_estate.access_estate_property_tag_manager,access_estate_property_tag,real_estate.model_estate_property_tags,real_estate.estate_group_manager,1,1,1,1
5+
real_estate.access_estate_property_offer_manager,access_estate_property_offer,real_estate.model_estate_property_offers,real_estate.estate_group_manager,1,1,1,1
6+
7+
real_estate.access_estate_property_user,access_estate_property,real_estate.model_estate_property,real_estate.estate_group_user,1,1,1,0
8+
real_estate.access_estate_property_type_user,access_estate_property_type,real_estate.model_estate_property_types,real_estate.estate_group_user,1,0,0,0
9+
real_estate.access_estate_property_tag_user,access_estate_property_tag,real_estate.model_estate_property_tags,real_estate.estate_group_user,1,0,0,0
10+
real_estate.access_estate_property_offer_user,access_estate_property_offer,real_estate.model_estate_property_offers,real_estate.estate_group_user,1,1,1,1

real_estate/views/estate_property_menus.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
action="estate_property_main_view_action" />
1010

1111
<menuitem id="estate_property_type_menu_action" parent="estate_menu_settings"
12-
action="estate_property_type_view_action" />
12+
action="estate_property_type_view_action" groups="real_estate.estate_group_manager" />
1313
<menuitem id="estate_property_tag_menu_action" parent="estate_menu_settings"
14-
action="estate_property_tag_view_action" />
14+
action="estate_property_tag_view_action" groups="real_estate.estate_group_manager" />
1515
</odoo>

real_estate/views/estate_property_offer_views.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
<field name="name">estate.property.offer.list</field>
1212
<field name="model">estate.property.offers</field>
1313
<field name="arch" type="xml">
14-
<list editable="bottom" decoration-danger="status == 'refused'" decoration-success="status == 'accepted'">
14+
<list editable="bottom" decoration-danger="status == 'refused'"
15+
decoration-success="status == 'accepted'">
1516
<field name="price" />
1617
<field name="partner_id" />
1718
<field name="status" />

0 commit comments

Comments
 (0)