From 9078a4d272bed42b6442d52c7dab9119049fb515 Mon Sep 17 00:00:00 2001 From: odoo Date: Mon, 15 Dec 2025 10:19:57 +0100 Subject: [PATCH 01/16] [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/16] [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/16] [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/16] [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/16] [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/16] [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/16] [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/16] [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/16] [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/16] [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/16] [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 @@ - + + + + - + + + + + + + + + + + + @@ -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 @@
-

- - + + @@ -82,10 +91,13 @@ - + + + Properties estate.property list,form + {'search_default_filter_available': True} \ No newline at end of file From f073fa7148a2da6b7b661968143f1b01c3d55e93 Mon Sep 17 00:00:00 2001 From: raibr Date: Wed, 17 Dec 2025 09:49:26 +0100 Subject: [PATCH 15/16] [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. --- estate/views/estate_property_offer_views.xml | 38 +++++++++++--------- estate/views/estate_property_views.xml | 2 +- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/estate/views/estate_property_offer_views.xml b/estate/views/estate_property_offer_views.xml index 0aadeb03d9d..65ed8dd67fa 100644 --- a/estate/views/estate_property_offer_views.xml +++ b/estate/views/estate_property_offer_views.xml @@ -5,16 +5,19 @@ estate.property.offer.view.list estate.property.offer - - - - - - - -