From 9078a4d272bed42b6442d52c7dab9119049fb515 Mon Sep 17 00:00:00 2001
From: odoo
Date: Mon, 15 Dec 2025 10:19:57 +0100
Subject: [PATCH 01/14] [ADD] estate: Initial module setup
---
README-raibr-docs.md | 1 +
1 file changed, 1 insertion(+)
create mode 100644 README-raibr-docs.md
diff --git a/README-raibr-docs.md b/README-raibr-docs.md
new file mode 100644
index 00000000000..cf11e9628c3
--- /dev/null
+++ b/README-raibr-docs.md
@@ -0,0 +1 @@
+My first change on odoo
\ No newline at end of file
From b46dc7d25a36395fa24131310a04638fb24aed4f Mon Sep 17 00:00:00 2001
From: odoo
Date: Mon, 15 Dec 2025 15:53:08 +0100
Subject: [PATCH 02/14] [ADD] estate: Complete Chapter 1 requirements
---
estate/__init__.py | 0
estate/__manifest__.py | 25 +++++++++++++++++++++++++
2 files changed, 25 insertions(+)
create mode 100644 estate/__init__.py
create mode 100644 estate/__manifest__.py
diff --git a/estate/__init__.py b/estate/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/estate/__manifest__.py b/estate/__manifest__.py
new file mode 100644
index 00000000000..a13b1aefdfa
--- /dev/null
+++ b/estate/__manifest__.py
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+{
+ 'name': 'Real Estate Advertisement',
+ 'version': '1.0',
+ 'author': 'Odoo',
+ 'category': 'Sales/Real Estate',
+ 'sequence': 15,
+ 'summary': 'Manage property listings and real estate advertisements',
+ 'description': """
+Real Estate Advertisement Management
+====================================
+This module allows you to manage real estate properties, including:
+ * Property listings with detailed information
+ * Property types and tags
+ * Property offers and negotiations
+ * Sales tracking
+ """,
+ 'depends': ['base'],
+ 'data': [
+ ],
+ 'installable': True,
+ 'application': True,
+ 'license': 'LGPL-3',
+}
From 9d3e35d74ac23af6a9aecd445c98380745843150 Mon Sep 17 00:00:00 2001
From: odoo
Date: Mon, 15 Dec 2025 15:53:52 +0100
Subject: [PATCH 03/14] [ADD] estate: Complete Chapter 2 requirements
---
estate/__init__.py | 4 ++++
estate/models/__init__.py | 4 ++++
estate/models/estate_property.py | 30 ++++++++++++++++++++++++++++++
3 files changed, 38 insertions(+)
create mode 100644 estate/models/__init__.py
create mode 100644 estate/models/estate_property.py
diff --git a/estate/__init__.py b/estate/__init__.py
index e69de29bb2d..e9917144f69 100644
--- a/estate/__init__.py
+++ b/estate/__init__.py
@@ -0,0 +1,4 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from . import models
\ No newline at end of file
diff --git a/estate/models/__init__.py b/estate/models/__init__.py
new file mode 100644
index 00000000000..ddcab4c3593
--- /dev/null
+++ b/estate/models/__init__.py
@@ -0,0 +1,4 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from . import estate_property
diff --git a/estate/models/estate_property.py b/estate/models/estate_property.py
new file mode 100644
index 00000000000..d9ffb28db36
--- /dev/null
+++ b/estate/models/estate_property.py
@@ -0,0 +1,30 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo import fields, models
+
+
+class EstateProperty(models.Model):
+ _name = "estate.property"
+ _description = "Real Estate Property"
+
+ name = fields.Char(required=True)
+ description = fields.Text()
+ postcode = fields.Char()
+ date_availability = fields.Date()
+ expected_price = fields.Float()
+ selling_price = fields.Float()
+ bedrooms = fields.Integer()
+ living_area = fields.Integer()
+ facades = fields.Integer()
+ garage = fields.Boolean()
+ garden = fields.Boolean()
+ garden_area = fields.Integer()
+ garden_orientation = fields.Selection(
+ selection=[
+ ('north', 'North'),
+ ('south', 'South'),
+ ('east', 'East'),
+ ('west', 'West')
+ ]
+ )
From afbf975fa7594ed17c5ee5178e15f579599452bf Mon Sep 17 00:00:00 2001
From: odoo
Date: Mon, 15 Dec 2025 15:56:04 +0100
Subject: [PATCH 04/14] [ADD] estate: Complete Chapter 3 requirements
---
estate/models/estate_property.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/estate/models/estate_property.py b/estate/models/estate_property.py
index d9ffb28db36..b50386b4942 100644
--- a/estate/models/estate_property.py
+++ b/estate/models/estate_property.py
@@ -28,3 +28,4 @@ class EstateProperty(models.Model):
('west', 'West')
]
)
+
From c79e559ec806e7a8cd8286f329d82a3547e79730 Mon Sep 17 00:00:00 2001
From: raibr
Date: Mon, 15 Dec 2025 16:15:37 +0100
Subject: [PATCH 05/14] [ADD] estate: Minimum security configuration (Chapter
4)
---
estate/__manifest__.py | 2 ++
estate/security/ir.model.access.csv | 2 ++
2 files changed, 4 insertions(+)
create mode 100644 estate/security/ir.model.access.csv
diff --git a/estate/__manifest__.py b/estate/__manifest__.py
index a13b1aefdfa..0007d31d1ab 100644
--- a/estate/__manifest__.py
+++ b/estate/__manifest__.py
@@ -18,6 +18,8 @@
""",
'depends': ['base'],
'data': [
+ 'security/ir.model.access.csv',
+
],
'installable': True,
'application': True,
diff --git a/estate/security/ir.model.access.csv b/estate/security/ir.model.access.csv
new file mode 100644
index 00000000000..32389642d4f
--- /dev/null
+++ b/estate/security/ir.model.access.csv
@@ -0,0 +1,2 @@
+id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
+access_estate_property,access_estate_property,model_estate_property,base.group_user,1,1,1,1
From 27d7a398cb88ebccfa84857a7fb516939d8c6ea7 Mon Sep 17 00:00:00 2001
From: raibr
Date: Mon, 15 Dec 2025 16:55:53 +0100
Subject: [PATCH 06/14] [ADD] estate: Property views and menus (Chapter 5)
---
estate/__manifest__.py | 5 +-
estate/views/estate_menus.xml | 15 ++++++
estate/views/estate_property_views.xml | 65 ++++++++++++++++++++++++++
3 files changed, 83 insertions(+), 2 deletions(-)
create mode 100644 estate/views/estate_menus.xml
create mode 100644 estate/views/estate_property_views.xml
diff --git a/estate/__manifest__.py b/estate/__manifest__.py
index 0007d31d1ab..84e35717d96 100644
--- a/estate/__manifest__.py
+++ b/estate/__manifest__.py
@@ -18,8 +18,9 @@
""",
'depends': ['base'],
'data': [
- 'security/ir.model.access.csv',
-
+ 'security/ir.model.access.csv',
+ 'views/estate_property_views.xml',
+ 'views/estate_menus.xml',
],
'installable': True,
'application': True,
diff --git a/estate/views/estate_menus.xml b/estate/views/estate_menus.xml
new file mode 100644
index 00000000000..c6b11f4de01
--- /dev/null
+++ b/estate/views/estate_menus.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/estate/views/estate_property_views.xml b/estate/views/estate_property_views.xml
new file mode 100644
index 00000000000..4b0d79a80a8
--- /dev/null
+++ b/estate/views/estate_property_views.xml
@@ -0,0 +1,65 @@
+
+
+
+
+ estate.property.view.tree
+ estate.property
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ estate.property.view.form
+ estate.property
+
+
+
+
+
+
+
+ Properties
+ estate.property
+ list,form
+
+
From fbb6c5e78c934607d9e5b5f4df2a7fa13753621c Mon Sep 17 00:00:00 2001
From: raibr
Date: Mon, 15 Dec 2025 17:29:12 +0100
Subject: [PATCH 07/14] [ADD] estate: Search filters and grouping options
(Chapter 6)
---
estate/views/estate_property_views.xml | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/estate/views/estate_property_views.xml b/estate/views/estate_property_views.xml
index 4b0d79a80a8..71e75b985f2 100644
--- a/estate/views/estate_property_views.xml
+++ b/estate/views/estate_property_views.xml
@@ -56,6 +56,32 @@
+
+
+ estate.property.view.search
+ estate.property
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Properties
From 06b0b67a94ad2ac898947a415232ac0074838d18 Mon Sep 17 00:00:00 2001
From: raibr
Date: Tue, 16 Dec 2025 13:40:43 +0100
Subject: [PATCH 08/14] [FIX] estate: Chapter 7 fixes
---
.DS_Store | Bin 0 -> 8196 bytes
estate/.DS_Store | Bin 0 -> 6148 bytes
estate/__manifest__.py | 3 ++
estate/models/__init__.py | 3 ++
estate/models/estate_property.py | 4 +-
estate/models/estate_property_offer.py | 13 +++++++
estate/models/estate_property_tag.py | 12 ++++++
estate/models/estate_property_type.py | 12 ++++++
estate/security/ir.model.access.csv | 3 ++
estate/views/estate_menus.xml | 20 ++++++++++
estate/views/estate_property_offer_views.xml | 37 +++++++++++++++++++
estate/views/estate_property_tag_views.xml | 35 ++++++++++++++++++
estate/views/estate_property_type_views.xml | 35 ++++++++++++++++++
estate/views/estate_property_views.xml | 5 +++
14 files changed, 181 insertions(+), 1 deletion(-)
create mode 100644 .DS_Store
create mode 100644 estate/.DS_Store
create mode 100644 estate/models/estate_property_offer.py
create mode 100644 estate/models/estate_property_tag.py
create mode 100644 estate/models/estate_property_type.py
create mode 100644 estate/views/estate_property_offer_views.xml
create mode 100644 estate/views/estate_property_tag_views.xml
create mode 100644 estate/views/estate_property_type_views.xml
diff --git a/.DS_Store b/.DS_Store
new file mode 100644
index 0000000000000000000000000000000000000000..e6dc8b82c3ba14a9d95b63fd3e84b245efe05688
GIT binary patch
literal 8196
zcmeHMv2GJV5S=9!vE&FGi6Z5R4~UdMxFk+Pg=C3_g81yJN8T>>m^*at
zWPI{r{LIE@D8|l?`$yKCOzcowRX`OeD-fZpL8~;RJ(`C3`_lUTqi}4Lbvj9!CFpCK
zZ?B)9AD^$w@xhhjFJ
zr{rf}>6CRGf>nwSR*Oy~x5Y1)u9xr#d2PNdcvZ|3u2+38$!8nE(VfzI?W5-zRtv3U
z)A(6sFSxuZxLi4hU{cdZ@`#y7tHdM2zDgy7*5-W6F!t}KMeK9#8%AAiE#u8O-rIK1
zPZ9N$c4U-~AN)BU#`fc5cJ|rrX>pG*qIotV4)c)XXxq~#!4AdQXV0G=t|l}_&G30D
zVq1Q}zvxPzFy2?mr{8B#4Zqn=y^f#Ybw?Cn<3O8^1B*WlaUH>wePWNfL-e5hl@|f}
M{I}X`b8{8A0KP<&RsaA1
literal 0
HcmV?d00001
diff --git a/estate/.DS_Store b/estate/.DS_Store
new file mode 100644
index 0000000000000000000000000000000000000000..827f8b2ec897d19f03f5f6c0eaac2f788ae72a00
GIT binary patch
literal 6148
zcmeHKJ5B>J5PgP#BGMo#XwZt5DmPf7&?9kx0Go)9vf7C7?N-!WfC7nQ(DS!fN31I>%c64Dw|+shTRC0acL!+@E%Dvc8&y_
zNU(zrTBT@pr~<0MZ&N__ZjHOOg&t11cZd78)!nYICt2F_l&{A}rdhMO)y=jTQGMLI
zS-v}YSotct{f+3}PLYMs#WYf6X!Dfmq93wcxcEF?ik!~hR^WM;;zC|lpD7%XPY1`J)mgeEqrzyB
z%UNyl`QH6*LBvp*(GlVLYod$V-%x-xTdZ1hsJ$wn3aA1D1>}5)*aTybxkGz&u(MYH
zVufyNe6}@+7>R=zd(0iuLo+Uw=u(ZpVi=cBf8^t0kGVsa4r5p5Jbq>4Zz#sDPJd*>
zVPc2cs{*P(sKBIqot65(I{yA2Ch40hpbGpe1x%&6-fZxbd~Gd#oYdNgZG%lr;&O*J
kg`F?Q_CZSVJexI+Me;z5J?0MSq3It1D}#2bz>g~M0sASKHvj+t
literal 0
HcmV?d00001
diff --git a/estate/__manifest__.py b/estate/__manifest__.py
index 84e35717d96..75d7c4cba73 100644
--- a/estate/__manifest__.py
+++ b/estate/__manifest__.py
@@ -20,6 +20,9 @@
'data': [
'security/ir.model.access.csv',
'views/estate_property_views.xml',
+ 'views/estate_property_type_views.xml',
+ 'views/estate_property_tag_views.xml',
+ 'views/estate_property_offer_views.xml',
'views/estate_menus.xml',
],
'installable': True,
diff --git a/estate/models/__init__.py b/estate/models/__init__.py
index ddcab4c3593..18dbe7ac061 100644
--- a/estate/models/__init__.py
+++ b/estate/models/__init__.py
@@ -2,3 +2,6 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import estate_property
+from . import estate_property_type
+from . import estate_property_tag
+from . import estate_property_offer
\ No newline at end of file
diff --git a/estate/models/estate_property.py b/estate/models/estate_property.py
index b50386b4942..ad4114c2091 100644
--- a/estate/models/estate_property.py
+++ b/estate/models/estate_property.py
@@ -28,4 +28,6 @@ class EstateProperty(models.Model):
('west', 'West')
]
)
-
+ property_type_id = fields.Many2one("estate.property.type", string="Property Type")
+ tag_ids = fields.Many2many("estate.property.tag", string="Tags")
+ offer_ids = fields.One2many("estate.property.offer", "property_id", string="Offers")
diff --git a/estate/models/estate_property_offer.py b/estate/models/estate_property_offer.py
new file mode 100644
index 00000000000..4bfee686991
--- /dev/null
+++ b/estate/models/estate_property_offer.py
@@ -0,0 +1,13 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo import fields, models
+
+
+class EstatePropertyOffer(models.Model):
+ _name = "estate.property.offer"
+ _description = "Real Estate Property Offer"
+ _order = "name"
+
+ name = fields.Char(required=True)
+ property_id = fields.Many2one("estate.property", string="Property", required=True)
diff --git a/estate/models/estate_property_tag.py b/estate/models/estate_property_tag.py
new file mode 100644
index 00000000000..9cb7c3e08b1
--- /dev/null
+++ b/estate/models/estate_property_tag.py
@@ -0,0 +1,12 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo import fields, models
+
+
+class EstatePropertyTag(models.Model):
+ _name = "estate.property.tag"
+ _description = "Real Estate Property Tag"
+ _order = "name"
+
+ name = fields.Char(required=True)
diff --git a/estate/models/estate_property_type.py b/estate/models/estate_property_type.py
new file mode 100644
index 00000000000..03ac7946cd9
--- /dev/null
+++ b/estate/models/estate_property_type.py
@@ -0,0 +1,12 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo import fields, models
+
+
+class EstatePropertyType(models.Model):
+ _name = "estate.property.type"
+ _description = "Real Estate Property Type"
+ _order = "name"
+
+ name = fields.Char(required=True)
diff --git a/estate/security/ir.model.access.csv b/estate/security/ir.model.access.csv
index 32389642d4f..05bd9eefba4 100644
--- a/estate/security/ir.model.access.csv
+++ b/estate/security/ir.model.access.csv
@@ -1,2 +1,5 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_estate_property,access_estate_property,model_estate_property,base.group_user,1,1,1,1
+access_estate_property_type,access_estate_property_type,model_estate_property_type,base.group_user,1,1,1,1
+access_estate_property_tag,access_estate_property_tag,model_estate_property_tag,base.group_user,1,1,1,1
+access_estate_property_offer,access_estate_property_offer,model_estate_property_offer,base.group_user,1,1,1,1
\ No newline at end of file
diff --git a/estate/views/estate_menus.xml b/estate/views/estate_menus.xml
index c6b11f4de01..e6c1828cd27 100644
--- a/estate/views/estate_menus.xml
+++ b/estate/views/estate_menus.xml
@@ -12,4 +12,24 @@
name="Properties"
parent="estate_property_menu"
action="estate_property_action"/>
+
+
+
+
+
+
+
+
+
diff --git a/estate/views/estate_property_offer_views.xml b/estate/views/estate_property_offer_views.xml
new file mode 100644
index 00000000000..1d025c3d19c
--- /dev/null
+++ b/estate/views/estate_property_offer_views.xml
@@ -0,0 +1,37 @@
+
+
+
+
+ estate.property.offer.view.tree
+ estate.property.offer
+
+
+
+
+
+
+
+
+
+
+ estate.property.offer.view.form
+ estate.property.offer
+
+
+
+
+
+
+
+ Property Offers
+ estate.property.offer
+ tree,form
+
+
diff --git a/estate/views/estate_property_tag_views.xml b/estate/views/estate_property_tag_views.xml
new file mode 100644
index 00000000000..f253d83cc7b
--- /dev/null
+++ b/estate/views/estate_property_tag_views.xml
@@ -0,0 +1,35 @@
+
+
+
+
+ estate.property.tag.view.tree
+ estate.property.tag
+
+
+
+
+
+
+
+
+
+ estate.property.tag.view.form
+ estate.property.tag
+
+
+
+
+
+
+
+ Property Tags
+ estate.property.tag
+ list,form
+
+
diff --git a/estate/views/estate_property_type_views.xml b/estate/views/estate_property_type_views.xml
new file mode 100644
index 00000000000..0be5c97b813
--- /dev/null
+++ b/estate/views/estate_property_type_views.xml
@@ -0,0 +1,35 @@
+
+
+
+
+ estate.property.type.view.tree
+ estate.property.type
+
+
+
+
+
+
+
+
+
+ estate.property.type.view.form
+ estate.property.type
+
+
+
+
+
+
+
+ Property Types
+ estate.property.type
+ list,form
+
+
diff --git a/estate/views/estate_property_views.xml b/estate/views/estate_property_views.xml
index 71e75b985f2..3ec94fe037e 100644
--- a/estate/views/estate_property_views.xml
+++ b/estate/views/estate_property_views.xml
@@ -7,7 +7,9 @@
+
+
@@ -27,8 +29,10 @@
+
+
@@ -63,6 +67,7 @@
+
From e76dbf5133b3f26d118a1c917a6572b5cd84272e Mon Sep 17 00:00:00 2001
From: raibr
Date: Tue, 16 Dec 2025 14:01:21 +0100
Subject: [PATCH 09/14] [FIX] estate: Chapter 7 corrections
---
.DS_Store | Bin 8196 -> 8196 bytes
estate/views/estate_property_offer_views.xml | 4 ++--
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/.DS_Store b/.DS_Store
index e6dc8b82c3ba14a9d95b63fd3e84b245efe05688..72652f94ff576eb22b364a8bf1b458c6c60adecd 100644
GIT binary patch
delta 111
zcmZp1XmQw}CJ?u00s{jB3xgg*IzuKyNp8N2OHxjL5>Skz{e6_wsfy!{sPZXzX&uOnxJvw0W6896tcGBOdku
delta 111
zcmZp1XmQw}CJ?7o&cMLH!l1{H&XCDalAG`1l9ZF51Qg?7d^fSestate.property.offer.view.tree
estate.property.offer
-
+
-
+
From 23dc9696a79387007940ed2044b769f27fd8c7dc Mon Sep 17 00:00:00 2001
From: raibr
Date: Tue, 16 Dec 2025 16:05:47 +0100
Subject: [PATCH 10/14] [ADD] estate: Implement property offers with computed
fields and onchange
---
.DS_Store | Bin 8196 -> 8196 bytes
estate/.DS_Store | Bin 6148 -> 6148 bytes
estate/models/estate_property.py | 26 ++++++++++++++++++-
estate/models/estate_property_offer.py | 26 ++++++++++++++++---
estate/views/estate_property_offer_views.xml | 14 ++++++----
estate/views/estate_property_views.xml | 5 ++++
6 files changed, 62 insertions(+), 9 deletions(-)
diff --git a/.DS_Store b/.DS_Store
index 72652f94ff576eb22b364a8bf1b458c6c60adecd..a4c34ddcd9b58de9500ff00154e8781bd19a3184 100644
GIT binary patch
delta 143
zcmZp1XmQw}DiH6oA&!B8frUYjA)O(Up(Hoo#U&{xKM5$t;k#8>@l?feM^yO~yz&JZ
zhQZ1CxdlKy47@x743pmoC~aOQ@P(Nv_sQfrB56zs43i5)RW@sg-eO0v?=S%XfkYestate.property.offer.view.tree
estate.property.offer
-
-
+
+
-
+
+
+
@@ -20,8 +22,10 @@
@@ -32,6 +36,6 @@
Property Offers
estate.property.offer
- tree,form
+ list,form
diff --git a/estate/views/estate_property_views.xml b/estate/views/estate_property_views.xml
index 3ec94fe037e..b4ccf317502 100644
--- a/estate/views/estate_property_views.xml
+++ b/estate/views/estate_property_views.xml
@@ -38,6 +38,7 @@
+
@@ -52,8 +53,12 @@
+
+
+
+
From 7d282474c8c6f5986c7fa5d503e7765d54635551 Mon Sep 17 00:00:00 2001
From: raibr
Date: Tue, 16 Dec 2025 16:47:26 +0100
Subject: [PATCH 11/14] [ADD] estate(Chapter 9): Add property state workflow
with sold/cancel actions and offer acceptance
---
.DS_Store | Bin 8196 -> 8196 bytes
estate/.DS_Store | Bin 6148 -> 6148 bytes
estate/models/estate_property.py | 27 ++++++
estate/models/estate_property_offer.py | 25 +++++-
estate/views/estate_property_offer_views.xml | 7 +-
estate/views/estate_property_views.xml | 89 ++++++++++---------
6 files changed, 106 insertions(+), 42 deletions(-)
diff --git a/.DS_Store b/.DS_Store
index a4c34ddcd9b58de9500ff00154e8781bd19a3184..00623c509e777f5ba215bcb8a5ec04ebc4ffd7f0 100644
GIT binary patch
delta 141
zcmZp1XmQw}CJ^_VG^PyOpah(z@%Qg`4=mf5CF=Z3sC?7
delta 33
pcmZoMXffDui-k$6X7U}DG^Pa%lP9o>Opah(z@!qg`4=mf5CF=$3oZZv
diff --git a/estate/models/estate_property.py b/estate/models/estate_property.py
index 5a92c77791c..310e5a5d69d 100644
--- a/estate/models/estate_property.py
+++ b/estate/models/estate_property.py
@@ -2,6 +2,7 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, fields, models
+from odoo.exceptions import UserError
class EstateProperty(models.Model):
@@ -28,6 +29,18 @@ class EstateProperty(models.Model):
('west', 'West')
]
)
+ state = fields.Selection(
+ selection=[
+ ('new', 'New'),
+ ('offer_received', 'Offer Received'),
+ ('offer_accepted', 'Offer Accepted'),
+ ('sold', 'Sold'),
+ ('cancelled', 'Cancelled')
+ ],
+ default='new',
+ required=True
+ )
+ buyer_id = fields.Many2one('res.partner', string='Buyer')
property_type_id = fields.Many2one("estate.property.type", string="Property Type")
tag_ids = fields.Many2many("estate.property.tag", string="Tags")
offer_ids = fields.One2many("estate.property.offer", "property_id", string="Offers")
@@ -55,3 +68,17 @@ def _onchange_garden(self):
else:
self.garden_area = 0
self.garden_orientation = False
+
+ def action_sold(self):
+ for record in self:
+ if record.state == 'cancelled':
+ raise UserError("Cancelled property cannot be sold.")
+ record.state = 'sold'
+ return True
+
+ def action_cancel(self):
+ for record in self:
+ if record.state == 'sold':
+ raise UserError("Sold property cannot be cancelled.")
+ record.state = 'cancelled'
+ return True
diff --git a/estate/models/estate_property_offer.py b/estate/models/estate_property_offer.py
index 10bf4f4723f..f97c3aad750 100644
--- a/estate/models/estate_property_offer.py
+++ b/estate/models/estate_property_offer.py
@@ -3,6 +3,7 @@
from datetime import timedelta
from odoo import api, fields, models
+from odoo.exceptions import UserError
class EstatePropertyOffer(models.Model):
@@ -11,6 +12,14 @@ class EstatePropertyOffer(models.Model):
_order = "price desc"
price = fields.Float(required=True)
+ status = fields.Selection(
+ selection=[
+ ('accepted', 'Accepted'),
+ ('refused', 'Refused')
+ ],
+ copy=False
+ )
+ partner_id = fields.Many2one('res.partner', string='Partner', required=True)
property_id = fields.Many2one("estate.property", string="Property", required=True)
validity = fields.Integer(default=7, string="Validity (days)")
date_deadline = fields.Date(
@@ -30,4 +39,18 @@ def _inverse_date_deadline(self):
for record in self:
if record.date_deadline:
record.validity = (record.date_deadline - fields.Date.today()).days
- print("Inversed deadlines")
\ No newline at end of file
+ print("Inversed deadlines")
+
+ def action_accept(self):
+ for record in self:
+ if record.property_id.offer_ids.filtered(lambda o: o.status == 'accepted' and o.id != record.id):
+ raise UserError("Only one offer can be accepted per property.")
+ record.status = 'accepted'
+ record.property_id.buyer_id = record.partner_id
+ record.property_id.selling_price = record.price
+ return True
+
+ def action_refuse(self):
+ for record in self:
+ record.status = 'refused'
+ return True
\ No newline at end of file
diff --git a/estate/views/estate_property_offer_views.xml b/estate/views/estate_property_offer_views.xml
index 0aeca43e3c7..f03f1497495 100644
--- a/estate/views/estate_property_offer_views.xml
+++ b/estate/views/estate_property_offer_views.xml
@@ -7,9 +7,12 @@
-
+
+
+
+
@@ -23,9 +26,11 @@
+
+
diff --git a/estate/views/estate_property_views.xml b/estate/views/estate_property_views.xml
index b4ccf317502..352a84e96a6 100644
--- a/estate/views/estate_property_views.xml
+++ b/estate/views/estate_property_views.xml
@@ -6,15 +6,15 @@
estate.property
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
@@ -25,39 +25,45 @@
estate.property
+
\ No newline at end of file
From fcbae9f06b611229c7bbaddbc1a269821b32956e Mon Sep 17 00:00:00 2001
From: raibr
Date: Tue, 16 Dec 2025 17:02:44 +0100
Subject: [PATCH 12/14] [IMP] estate: Add .DS_Store to .gitignore
---
.DS_Store | Bin 8196 -> 0 bytes
.gitignore | 1 +
estate/.DS_Store | Bin 6148 -> 0 bytes
3 files changed, 1 insertion(+)
delete mode 100644 .DS_Store
delete mode 100644 estate/.DS_Store
diff --git a/.DS_Store b/.DS_Store
deleted file mode 100644
index 00623c509e777f5ba215bcb8a5ec04ebc4ffd7f0..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 8196
zcmeHMy>8S%5S~p=dtlt__K9w6WTVDI2Kb}B%bJ?(zZ?u>W7Z@p`cLqux(
z3h478K-CyJ%q*It1C2=mfGu>Jg6pon00s_2hnYo;peXAKw64mf7|Ob%KX7)T!_1;}
zC*_h4`t{82X?71^$0{2ZhceG|*PK2vb|}t1bN&o)HK!SBir;e<
z+uA$*MA!QG@qUO;exE@N{0dcX-_&o_4ofKw-OssKos~-
z6;Q3H7i}YWms^);=v+HM?W5|V?J|qT1&v9^fhHXX=KnCnbpTWC6FST+q6g)#d?260HtZKo$6H3dr8AbGNoIz!~@MX#ci)+pEni?+-lX>&cP*JWV^jyu*m-aqnj3
z?)0JYRdn|o(Sw~b3!#fy^pT^>Q>KT5kmXwQ^LUxt(`$a~xdn6d^AV#-F(HpD;Su40
z95NhXAGPye}?sp3!M#_wj2-k0O0kuD(0Bg2bRClPoDxeCe0z(Dle2Ccu6OV;Mdvvg~R{&y-
zZfktDHHa9CgP3?M9MVHGE|us~jlW_Tmrj4|;}VaBLzfO?SLQr^W#exs#;#6(Y{Ov^
zhuW(Gsz9i~w0oVG`oA&x{vRgkn<}6R{3``aEp4Xj{3KsnD<3DdHfC$HiAh}H(5A5S
i<=8$*DPCl=#<5r)h>6F-Aw4wxBVc9FP8Il31wH_k+n5&s
From 90bef7f3c198b749849d787eb16b3c54f27a467a Mon Sep 17 00:00:00 2001
From: raibr
Date: Tue, 16 Dec 2025 17:13:02 +0100
Subject: [PATCH 13/14] [IMP] estate: Fix ruff linting issues
---
estate/__init__.py | 3 +--
estate/__manifest__.py | 1 -
estate/models/__init__.py | 3 +--
estate/models/estate_property.py | 1 -
estate/models/estate_property_offer.py | 5 +----
estate/models/estate_property_tag.py | 1 -
estate/models/estate_property_type.py | 1 -
7 files changed, 3 insertions(+), 12 deletions(-)
diff --git a/estate/__init__.py b/estate/__init__.py
index e9917144f69..d6210b1285d 100644
--- a/estate/__init__.py
+++ b/estate/__init__.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
-from . import models
\ No newline at end of file
+from . import models
diff --git a/estate/__manifest__.py b/estate/__manifest__.py
index 75d7c4cba73..029fc037785 100644
--- a/estate/__manifest__.py
+++ b/estate/__manifest__.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
{
'name': 'Real Estate Advertisement',
diff --git a/estate/models/__init__.py b/estate/models/__init__.py
index 18dbe7ac061..7b28f0f82ad 100644
--- a/estate/models/__init__.py
+++ b/estate/models/__init__.py
@@ -1,7 +1,6 @@
-# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import estate_property
from . import estate_property_type
from . import estate_property_tag
-from . import estate_property_offer
\ No newline at end of file
+from . import estate_property_offer
diff --git a/estate/models/estate_property.py b/estate/models/estate_property.py
index 310e5a5d69d..6dac03e9cc1 100644
--- a/estate/models/estate_property.py
+++ b/estate/models/estate_property.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, fields, models
diff --git a/estate/models/estate_property_offer.py b/estate/models/estate_property_offer.py
index f97c3aad750..ebf857636f2 100644
--- a/estate/models/estate_property_offer.py
+++ b/estate/models/estate_property_offer.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from datetime import timedelta
@@ -33,13 +32,11 @@ class EstatePropertyOffer(models.Model):
def _compute_date_deadline(self):
for record in self:
record.date_deadline = fields.Date.today() + timedelta(days=record.validity)
- print("Computed deadlines2")
def _inverse_date_deadline(self):
for record in self:
if record.date_deadline:
record.validity = (record.date_deadline - fields.Date.today()).days
- print("Inversed deadlines")
def action_accept(self):
for record in self:
@@ -53,4 +50,4 @@ def action_accept(self):
def action_refuse(self):
for record in self:
record.status = 'refused'
- return True
\ No newline at end of file
+ return True
diff --git a/estate/models/estate_property_tag.py b/estate/models/estate_property_tag.py
index 9cb7c3e08b1..101bf583dcd 100644
--- a/estate/models/estate_property_tag.py
+++ b/estate/models/estate_property_tag.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import fields, models
diff --git a/estate/models/estate_property_type.py b/estate/models/estate_property_type.py
index 03ac7946cd9..a5acfbbef67 100644
--- a/estate/models/estate_property_type.py
+++ b/estate/models/estate_property_type.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import fields, models
From 54edce7a151cb99c8ed6e1588b218615df67849c Mon Sep 17 00:00:00 2001
From: raibr
Date: Wed, 17 Dec 2025 09:49:26 +0100
Subject: [PATCH 14/14] [FIX] estate: replace invalid models.Constraint with
_sql_constraints
The models.Constraint syntax does not exist in Odoo's ORM.
SQL constraints must be defined using the _sql_constraints class attribute.
---
.gitignore | 1 -
README-raibr-docs.md | 1 -
estate/__manifest__.py | 34 +++---
estate/models/estate_property.py | 107 +++++++++++--------
estate/models/estate_property_offer.py | 62 ++++++-----
estate/models/estate_property_tag.py | 9 +-
estate/models/estate_property_type.py | 16 ++-
estate/views/estate_property_offer_views.xml | 13 ++-
estate/views/estate_property_tag_views.xml | 6 +-
estate/views/estate_property_type_views.xml | 27 ++++-
estate/views/estate_property_views.xml | 33 ++++--
11 files changed, 185 insertions(+), 124 deletions(-)
delete mode 100644 README-raibr-docs.md
diff --git a/.gitignore b/.gitignore
index 99efc91d956..b6e47617de1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -127,4 +127,3 @@ dmypy.json
# Pyre type checker
.pyre/
-.DS_Store
diff --git a/README-raibr-docs.md b/README-raibr-docs.md
deleted file mode 100644
index cf11e9628c3..00000000000
--- a/README-raibr-docs.md
+++ /dev/null
@@ -1 +0,0 @@
-My first change on odoo
\ No newline at end of file
diff --git a/estate/__manifest__.py b/estate/__manifest__.py
index 029fc037785..3e12b9239d5 100644
--- a/estate/__manifest__.py
+++ b/estate/__manifest__.py
@@ -1,12 +1,11 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
{
- 'name': 'Real Estate Advertisement',
- 'version': '1.0',
- 'author': 'Odoo',
- 'category': 'Sales/Real Estate',
- 'sequence': 15,
- 'summary': 'Manage property listings and real estate advertisements',
- 'description': """
+ "name": "Real Estate Advertisement",
+ "author": "Odoo",
+ "category": "Sales/Real Estate",
+ "sequence": 15,
+ "summary": "Manage property listings and real estate advertisements",
+ "description": """
Real Estate Advertisement Management
====================================
This module allows you to manage real estate properties, including:
@@ -15,16 +14,15 @@
* Property offers and negotiations
* Sales tracking
""",
- 'depends': ['base'],
- 'data': [
- 'security/ir.model.access.csv',
- 'views/estate_property_views.xml',
- 'views/estate_property_type_views.xml',
- 'views/estate_property_tag_views.xml',
- 'views/estate_property_offer_views.xml',
- 'views/estate_menus.xml',
+ "depends": ["base"],
+ "data": [
+ "security/ir.model.access.csv",
+ "views/estate_property_views.xml",
+ "views/estate_property_type_views.xml",
+ "views/estate_property_tag_views.xml",
+ "views/estate_property_offer_views.xml",
+ "views/estate_menus.xml",
],
- 'installable': True,
- 'application': True,
- 'license': 'LGPL-3',
+ "application": True,
+ "license": "LGPL-3",
}
diff --git a/estate/models/estate_property.py b/estate/models/estate_property.py
index 6dac03e9cc1..fd5126a0851 100644
--- a/estate/models/estate_property.py
+++ b/estate/models/estate_property.py
@@ -1,63 +1,73 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, fields, models
-from odoo.exceptions import UserError
+from odoo.exceptions import UserError, ValidationError
+from odoo.tools.float_utils import float_compare, float_is_zero
class EstateProperty(models.Model):
- _name = "estate.property"
+ _name = 'estate.property'
_description = "Real Estate Property"
+ _order = 'id desc'
+ _check_expected_price = models.Constraint('Check(expected_price > 0)', "The expected price must be strictly positive.")
+ _check_selling_price = models.Constraint('Check(selling_price >= 0)', "The selling price must be positive.")
- name = fields.Char(required=True)
- description = fields.Text()
- postcode = fields.Char()
- date_availability = fields.Date()
- expected_price = fields.Float()
- selling_price = fields.Float()
- bedrooms = fields.Integer()
- living_area = fields.Integer()
- facades = fields.Integer()
- garage = fields.Boolean()
- garden = fields.Boolean()
- garden_area = fields.Integer()
+ name = fields.Char(required=True, string="Name")
+ description = fields.Text(string="Description")
+ postcode = fields.Char(string="Postcode")
+ date_availability = fields.Date(string="Available From")
+ expected_price = fields.Float(required=True, string="Expected Price")
+ selling_price = fields.Float(string="Selling Price")
+ bedrooms = fields.Integer(string="Bedrooms")
+ living_area = fields.Integer(string="Living Area (sqm)")
+ facades = fields.Integer(string="Facades")
+ garage = fields.Boolean(string="Garage")
+ garden = fields.Boolean(string="Garden")
+ garden_area = fields.Integer(string="Garden Area (sqm)")
garden_orientation = fields.Selection(
selection=[
- ('north', 'North'),
- ('south', 'South'),
- ('east', 'East'),
- ('west', 'West')
- ]
+ ('north', "North"),
+ ('south', "South"),
+ ('east', "East"),
+ ('west', "West"),
+ ],
+ string="Garden Orientation",
)
state = fields.Selection(
selection=[
- ('new', 'New'),
- ('offer_received', 'Offer Received'),
- ('offer_accepted', 'Offer Accepted'),
- ('sold', 'Sold'),
- ('cancelled', 'Cancelled')
+ ('new', "New"),
+ ('offer_received', "Offer Received"),
+ ('offer_accepted', "Offer Accepted"),
+ ('sold', "Sold"),
+ ('cancelled', "Cancelled"),
],
default='new',
- required=True
+ required=True,
+ string="Status",
+ )
+ buyer_id = fields.Many2one(comodel_name='res.partner', string="Buyer")
+ property_type_id = fields.Many2one(comodel_name='estate.property.type', string="Property Type")
+ tag_ids = fields.Many2many(comodel_name='estate.property.tag', string="Tags")
+ offer_ids = fields.One2many(
+ comodel_name='estate.property.offer',
+ inverse_name='property_id',
+ string="Offers",
)
- buyer_id = fields.Many2one('res.partner', string='Buyer')
- property_type_id = fields.Many2one("estate.property.type", string="Property Type")
- tag_ids = fields.Many2many("estate.property.tag", string="Tags")
- offer_ids = fields.One2many("estate.property.offer", "property_id", string="Offers")
- total_area = fields.Integer(compute="_compute_total_area")
- best_price = fields.Float(compute="_compute_best_price", string="Best Offer Price")
+ total_area = fields.Integer(compute='_compute_total_area', string="Total Area (sqm)")
+ best_price = fields.Float(compute='_compute_best_price', string="Best Offer Price")
@api.depends('living_area', 'garden_area')
def _compute_total_area(self):
- for record in self:
- record.total_area = record.living_area + record.garden_area
+ for property in self:
+ property.total_area = property.living_area + property.garden_area
@api.depends('offer_ids.price')
def _compute_best_price(self):
- for record in self:
- if record.offer_ids:
- record.best_price = max(record.offer_ids.mapped('price'))
+ for property in self:
+ if property.offer_ids:
+ property.best_price = max(property.offer_ids.mapped('price'))
else:
- record.best_price = 0.0
+ property.best_price = 0.0
@api.onchange('garden')
def _onchange_garden(self):
@@ -68,16 +78,23 @@ def _onchange_garden(self):
self.garden_area = 0
self.garden_orientation = False
+ @api.constrains('selling_price', 'expected_price')
+ def _check_selling_price(self):
+ for property in self:
+ if not float_is_zero(property.selling_price, precision_digits=2):
+ if float_compare(property.selling_price, property.expected_price * 0.9, precision_digits=2) < 0:
+ raise ValidationError(self.env._("The selling price cannot be lower than 90% of the expected price."))
+
def action_sold(self):
- for record in self:
- if record.state == 'cancelled':
- raise UserError("Cancelled property cannot be sold.")
- record.state = 'sold'
+ for property in self:
+ if property.state == 'cancelled':
+ raise UserError(self.env._("Cancelled property cannot be sold."))
+ property.state = 'sold'
return True
def action_cancel(self):
- for record in self:
- if record.state == 'sold':
- raise UserError("Sold property cannot be cancelled.")
- record.state = 'cancelled'
+ for property in self:
+ if property.state == 'sold':
+ raise UserError(self.env._("Sold property cannot be cancelled."))
+ property.state = 'cancelled'
return True
diff --git a/estate/models/estate_property_offer.py b/estate/models/estate_property_offer.py
index ebf857636f2..7375f558f28 100644
--- a/estate/models/estate_property_offer.py
+++ b/estate/models/estate_property_offer.py
@@ -6,48 +6,52 @@
class EstatePropertyOffer(models.Model):
- _name = "estate.property.offer"
+ _name = 'estate.property.offer'
_description = "Real Estate Property Offer"
- _order = "price desc"
-
- price = fields.Float(required=True)
- status = fields.Selection(
- selection=[
- ('accepted', 'Accepted'),
- ('refused', 'Refused')
- ],
- copy=False
- )
- partner_id = fields.Many2one('res.partner', string='Partner', required=True)
- property_id = fields.Many2one("estate.property", string="Property", required=True)
+ _order = 'price desc'
+
+ price = fields.Float(required=True, string="Price")
+ _check_price = models.Constraint('Check(price > 0)', "The offer price must be strictly positive.")
+ status = fields.Selection(selection=[('accepted', "Accepted"), ('refused', "Refused")], copy=False, string="Status")
+ partner_id = fields.Many2one(comodel_name='res.partner', string="Partner", required=True)
+ property_id = fields.Many2one(comodel_name='estate.property', string="Property", required=True)
validity = fields.Integer(default=7, string="Validity (days)")
date_deadline = fields.Date(
- compute="_compute_date_deadline",
- inverse="_inverse_date_deadline",
+ compute='_compute_date_deadline',
+ inverse='_inverse_date_deadline',
store=True,
string="Deadline",
)
- @api.depends("validity")
+ # self.property_id.status = 'offer_received' when offer is created
+ @api.model
+ def create(self, vals):
+ offer = super().create(vals)
+ if offer.property_id.state == 'new':
+ offer.property_id.state = 'offer_received'
+ return offer
+
+ @api.depends('validity')
def _compute_date_deadline(self):
- for record in self:
- record.date_deadline = fields.Date.today() + timedelta(days=record.validity)
+ for offer in self:
+ offer.date_deadline = fields.Date.today() + timedelta(days=offer.validity)
def _inverse_date_deadline(self):
- for record in self:
- if record.date_deadline:
- record.validity = (record.date_deadline - fields.Date.today()).days
+ for offer in self:
+ if offer.date_deadline:
+ offer.validity = (offer.date_deadline - fields.Date.today()).days
def action_accept(self):
- for record in self:
- if record.property_id.offer_ids.filtered(lambda o: o.status == 'accepted' and o.id != record.id):
- raise UserError("Only one offer can be accepted per property.")
- record.status = 'accepted'
- record.property_id.buyer_id = record.partner_id
- record.property_id.selling_price = record.price
+ for offer in self:
+ if offer.property_id.offer_ids.filtered(lambda o: o.status == 'accepted' and o.id != offer.id):
+ raise UserError(self.env._("Only one offer can be accepted per property."))
+ offer.status = 'accepted'
+ offer.property_id.buyer_id = offer.partner_id
+ offer.property_id.selling_price = offer.price
+ offer.property_id.state = 'offer_accepted'
return True
def action_refuse(self):
- for record in self:
- record.status = 'refused'
+ for offer in self:
+ offer.status = 'refused'
return True
diff --git a/estate/models/estate_property_tag.py b/estate/models/estate_property_tag.py
index 101bf583dcd..aaa01baad49 100644
--- a/estate/models/estate_property_tag.py
+++ b/estate/models/estate_property_tag.py
@@ -4,8 +4,11 @@
class EstatePropertyTag(models.Model):
- _name = "estate.property.tag"
+ _name = 'estate.property.tag'
_description = "Real Estate Property Tag"
- _order = "name"
+ _order = 'name'
- name = fields.Char(required=True)
+ _check_unique_name = models.Constraint('UNIQUE(name)', "The tag name must be unique.")
+
+ name = fields.Char(required=True, string="Name")
+ color = fields.Integer(string="Color")
diff --git a/estate/models/estate_property_type.py b/estate/models/estate_property_type.py
index a5acfbbef67..97e22125f7b 100644
--- a/estate/models/estate_property_type.py
+++ b/estate/models/estate_property_type.py
@@ -1,11 +1,19 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
-from odoo import fields, models
+from odoo import api, fields, models
class EstatePropertyType(models.Model):
- _name = "estate.property.type"
+ _name = 'estate.property.type'
_description = "Real Estate Property Type"
- _order = "name"
+ _order = 'name'
+ _check_unique_name = models.Constraint('UNIQUE(name)', "The type name must be unique.")
- name = fields.Char(required=True)
+ name = fields.Char(required=True, string="Name")
+ sequence = fields.Integer(default=1, string="Sequence")
+ property_ids = fields.One2many(comodel_name='estate.property', inverse_name='property_type_id', string="Properties")
+ offer_count = fields.Integer(compute='_compute_offer_count', string="Offer Count")
+
+ def _compute_offer_count(self):
+ for property_type in self:
+ property_type.offer_count = sum(property_type.property_ids.mapped(lambda p: len(p.offer_ids)))
diff --git a/estate/views/estate_property_offer_views.xml b/estate/views/estate_property_offer_views.xml
index f03f1497495..0aadeb03d9d 100644
--- a/estate/views/estate_property_offer_views.xml
+++ b/estate/views/estate_property_offer_views.xml
@@ -1,18 +1,20 @@
-
-
- estate.property.offer.view.tree
+
+
+ estate.property.offer.view.list
estate.property.offer
-
+
+
-
+
+
@@ -42,5 +44,6 @@
Property Offers
estate.property.offer
list,form
+ [('property_id.property_type_id', '=', active_id)]
diff --git a/estate/views/estate_property_tag_views.xml b/estate/views/estate_property_tag_views.xml
index f253d83cc7b..b78e6b4be0b 100644
--- a/estate/views/estate_property_tag_views.xml
+++ b/estate/views/estate_property_tag_views.xml
@@ -1,11 +1,11 @@
-
- estate.property.tag.view.tree
+
+ estate.property.tag.view.list
estate.property.tag
-
+
diff --git a/estate/views/estate_property_type_views.xml b/estate/views/estate_property_type_views.xml
index 0be5c97b813..db293eaf395 100644
--- a/estate/views/estate_property_type_views.xml
+++ b/estate/views/estate_property_type_views.xml
@@ -1,12 +1,13 @@
-
- estate.property.type.view.tree
+
+ estate.property.type.view.list
estate.property.type
-
+
+
@@ -18,9 +19,25 @@
@@ -32,4 +49,4 @@
estate.property.type
list,form
-
+
\ No newline at end of file
diff --git a/estate/views/estate_property_views.xml b/estate/views/estate_property_views.xml
index 352a84e96a6..c5770600542 100644
--- a/estate/views/estate_property_views.xml
+++ b/estate/views/estate_property_views.xml
@@ -1,11 +1,13 @@
-
- estate.property.view.tree
+
+ estate.property.view.list
estate.property
-
+
@@ -14,9 +16,11 @@
-
+
+
+
@@ -26,20 +30,25 @@
estate.property
list,form
+ {'search_default_filter_available': True}
\ No newline at end of file