From 84fe6955152a2e2a7409c266f6d82f12600f02e4 Mon Sep 17 00:00:00 2001
From: odoo
Date: Tue, 21 Apr 2026 16:53:13 +0200
Subject: [PATCH 01/19] [ADD] module: Estate app created
---
estate/__init__.py | 0
estate/__manifest__.py | 6 ++++++
2 files changed, 6 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..9a44246f6c6
--- /dev/null
+++ b/estate/__manifest__.py
@@ -0,0 +1,6 @@
+{
+ 'name': 'estate',
+ 'depends':['base'],
+ 'application': True
+
+}
\ No newline at end of file
From 77632cf988b164956132fced11777e554f5bdc2a Mon Sep 17 00:00:00 2001
From: yoelf
Date: Wed, 22 Apr 2026 09:54:46 +0200
Subject: [PATCH 02/19] [FIX] module: fix the estate module manifest
---
estate/__manifest__.py | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/estate/__manifest__.py b/estate/__manifest__.py
index 9a44246f6c6..b1847d06917 100644
--- a/estate/__manifest__.py
+++ b/estate/__manifest__.py
@@ -1,6 +1,7 @@
{
'name': 'estate',
- 'depends':['base'],
- 'application': True
-
-}
\ No newline at end of file
+ 'depends': ['base'],
+ 'application': True,
+ 'author': 'Yoelf',
+ 'license': 'LGPL-3'
+}
From 88e8f537ae3191e660124d8ed37e6970618f6e80 Mon Sep 17 00:00:00 2001
From: yoelf
Date: Wed, 22 Apr 2026 14:14:57 +0200
Subject: [PATCH 03/19] [ADD] model : create the estate_property model
---
estate/__init__.py | 1 +
estate/models/__init__.py | 1 +
estate/models/estate_property.py | 27 +++++++++++++++++++++++++++
3 files changed, 29 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..9a7e03eded3 100644
--- a/estate/__init__.py
+++ b/estate/__init__.py
@@ -0,0 +1 @@
+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..f4c8fd6db6d
--- /dev/null
+++ b/estate/models/__init__.py
@@ -0,0 +1 @@
+from . import estate_property
\ No newline at end of file
diff --git a/estate/models/estate_property.py b/estate/models/estate_property.py
new file mode 100644
index 00000000000..abd4d15d304
--- /dev/null
+++ b/estate/models/estate_property.py
@@ -0,0 +1,27 @@
+from odoo import fields, models
+
+
+class EstateProperty(models.Model):
+ _name = "estate.property"
+ _description = "properties managed by us"
+ name = fields.Char(required=True)
+ description = fields.Text()
+ postcode = fields.Char()
+ date_availability = fields.Date()
+ expected_price = fields.Integer(required=True)
+ selling_price = fields.Integer()
+ bedrooms = fields.Integer()
+ living_area = fields.Integer()
+ facades = fields.Integer()
+ garage = fields.Boolean()
+ garden = fields.Boolean()
+ garden_area = fields.Integer()
+ garden_orientation = fields.Selection(
+ string="orientation",
+ selection=[
+ ("north", "North"),
+ ("south", "South"),
+ ("east", "East"),
+ ("west", "West"),
+ ],
+ )
From f5b54a263d5e392f4328b101f2080aeaaad33601 Mon Sep 17 00:00:00 2001
From: yoelf
Date: Wed, 22 Apr 2026 15:09:45 +0200
Subject: [PATCH 04/19] [FIX] model : add access rights to estate_property
---
estate/__init__.py | 2 +-
estate/__manifest__.py | 11 ++++++-----
estate/models/__init__.py | 2 +-
estate/security/ir.model.access.csv | 2 ++
4 files changed, 10 insertions(+), 7 deletions(-)
create mode 100644 estate/security/ir.model.access.csv
diff --git a/estate/__init__.py b/estate/__init__.py
index 9a7e03eded3..0650744f6bc 100644
--- a/estate/__init__.py
+++ b/estate/__init__.py
@@ -1 +1 @@
-from . import models
\ No newline at end of file
+from . import models
diff --git a/estate/__manifest__.py b/estate/__manifest__.py
index b1847d06917..cede66f7418 100644
--- a/estate/__manifest__.py
+++ b/estate/__manifest__.py
@@ -1,7 +1,8 @@
{
- 'name': 'estate',
- 'depends': ['base'],
- 'application': True,
- 'author': 'Yoelf',
- 'license': 'LGPL-3'
+ "name": "estate",
+ "depends": ["base"],
+ "application": True,
+ "author": "Yoelf",
+ "license": "LGPL-3",
+ "data": ["security/ir.model.access.csv"],
}
diff --git a/estate/models/__init__.py b/estate/models/__init__.py
index f4c8fd6db6d..5e1963c9d2f 100644
--- a/estate/models/__init__.py
+++ b/estate/models/__init__.py
@@ -1 +1 @@
-from . import estate_property
\ No newline at end of file
+from . import estate_property
diff --git a/estate/security/ir.model.access.csv b/estate/security/ir.model.access.csv
new file mode 100644
index 00000000000..ab63520e22b
--- /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
+estate.access_estate_property,access_estate_property,estate.model_estate_property,base.group_user,1,1,1,1
\ No newline at end of file
From b0f3765a3ec7c67f3c57fa1d53e44bbb079f0d76 Mon Sep 17 00:00:00 2001
From: yoelf
Date: Wed, 22 Apr 2026 16:41:24 +0200
Subject: [PATCH 05/19] [ADD] views : add property view and action
---
estate/__manifest__.py | 6 +++++-
estate/models/estate_property.py | 19 ++++++++++++++++---
estate/views/estate_menus.xml | 8 ++++++++
estate/views/estate_property_views.xml | 8 ++++++++
4 files changed, 37 insertions(+), 4 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 cede66f7418..476184c7dac 100644
--- a/estate/__manifest__.py
+++ b/estate/__manifest__.py
@@ -4,5 +4,9 @@
"application": True,
"author": "Yoelf",
"license": "LGPL-3",
- "data": ["security/ir.model.access.csv"],
+ "data": [
+ "security/ir.model.access.csv",
+ "views/estate_property_views.xml",
+ "views/estate_menus.xml",
+ ],
}
diff --git a/estate/models/estate_property.py b/estate/models/estate_property.py
index abd4d15d304..6c9c8b3545c 100644
--- a/estate/models/estate_property.py
+++ b/estate/models/estate_property.py
@@ -7,10 +7,12 @@ class EstateProperty(models.Model):
name = fields.Char(required=True)
description = fields.Text()
postcode = fields.Char()
- date_availability = fields.Date()
+ date_availability = fields.Date(
+ copy=False, default=fields.Date.add(fields.Date.today(), months=3)
+ )
expected_price = fields.Integer(required=True)
- selling_price = fields.Integer()
- bedrooms = fields.Integer()
+ selling_price = fields.Integer(readonly=True, copy=False)
+ bedrooms = fields.Integer(default=2)
living_area = fields.Integer()
facades = fields.Integer()
garage = fields.Boolean()
@@ -25,3 +27,14 @@ class EstateProperty(models.Model):
("west", "West"),
],
)
+ active = fields.Boolean(default=True)
+ state = fields.Selection(
+ string="State",
+ selection=[
+ ("new", "New"),
+ ("offer_received", "Offer Received"),
+ ("offer_accepted", "Offer Accepted"),
+ ("sold", "Sold"),
+ ("cancelled", "Cancelled"),
+ ],
+ )
diff --git a/estate/views/estate_menus.xml b/estate/views/estate_menus.xml
new file mode 100644
index 00000000000..f569f16151a
--- /dev/null
+++ b/estate/views/estate_menus.xml
@@ -0,0 +1,8 @@
+
+
+
+
\ No newline at end of file
diff --git a/estate/views/estate_property_views.xml b/estate/views/estate_property_views.xml
new file mode 100644
index 00000000000..fcfc13e2d4b
--- /dev/null
+++ b/estate/views/estate_property_views.xml
@@ -0,0 +1,8 @@
+
+
+
+ Properties
+ estate.property
+ list
+
+
\ No newline at end of file
From 0dc462d4e2c064a0e8506404acc2575b9797aa2e Mon Sep 17 00:00:00 2001
From: yoelfatihi
Date: Thu, 23 Apr 2026 09:21:17 +0200
Subject: [PATCH 06/19] [FIX] module : apply the comments from PR review
Co-authored-by: Mathilde
---
estate/models/estate_property.py | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/estate/models/estate_property.py b/estate/models/estate_property.py
index 6c9c8b3545c..ca915396a72 100644
--- a/estate/models/estate_property.py
+++ b/estate/models/estate_property.py
@@ -3,7 +3,8 @@
class EstateProperty(models.Model):
_name = "estate.property"
- _description = "properties managed by us"
+ _description = "Estate Property"
+
name = fields.Char(required=True)
description = fields.Text()
postcode = fields.Char()
From 2538c7d27bbebbb5d4d6d53906a5748e3ad5f8a3 Mon Sep 17 00:00:00 2001
From: yoelf
Date: Thu, 23 Apr 2026 10:31:38 +0200
Subject: [PATCH 07/19] [FIX] module : apply the comments from PR review
---
estate/__manifest__.py | 5 ++++-
estate/models/estate_property.py | 6 ++++--
estate/security/ir.model.access.csv | 2 +-
estate/views/estate_menus.xml | 2 +-
estate/views/estate_property_views.xml | 6 +++---
5 files changed, 13 insertions(+), 8 deletions(-)
diff --git a/estate/__manifest__.py b/estate/__manifest__.py
index 476184c7dac..39ea37ecce5 100644
--- a/estate/__manifest__.py
+++ b/estate/__manifest__.py
@@ -1,9 +1,12 @@
{
"name": "estate",
- "depends": ["base"],
+ "depends": [
+ "base",
+ ],
"application": True,
"author": "Yoelf",
"license": "LGPL-3",
+ "version": "19.0.0.1.0",
"data": [
"security/ir.model.access.csv",
"views/estate_property_views.xml",
diff --git a/estate/models/estate_property.py b/estate/models/estate_property.py
index ca915396a72..3745a4f0ebd 100644
--- a/estate/models/estate_property.py
+++ b/estate/models/estate_property.py
@@ -4,12 +4,12 @@
class EstateProperty(models.Model):
_name = "estate.property"
_description = "Estate Property"
-
+
name = fields.Char(required=True)
description = fields.Text()
postcode = fields.Char()
date_availability = fields.Date(
- copy=False, default=fields.Date.add(fields.Date.today(), months=3)
+ copy=False, default=lambda self: fields.Date.add(fields.Date.today(), months=3)
)
expected_price = fields.Integer(required=True)
selling_price = fields.Integer(readonly=True, copy=False)
@@ -38,4 +38,6 @@ class EstateProperty(models.Model):
("sold", "Sold"),
("cancelled", "Cancelled"),
],
+ required=True,
+ default="new",
)
diff --git a/estate/security/ir.model.access.csv b/estate/security/ir.model.access.csv
index ab63520e22b..e358a621c01 100644
--- a/estate/security/ir.model.access.csv
+++ b/estate/security/ir.model.access.csv
@@ -1,2 +1,2 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
-estate.access_estate_property,access_estate_property,estate.model_estate_property,base.group_user,1,1,1,1
\ No newline at end of file
+estate_property_access_user,estate.property.user,model_estate_property,base.group_user,1,1,1,1
diff --git a/estate/views/estate_menus.xml b/estate/views/estate_menus.xml
index f569f16151a..a2818644c6b 100644
--- a/estate/views/estate_menus.xml
+++ b/estate/views/estate_menus.xml
@@ -5,4 +5,4 @@
-
\ No newline at end of file
+
diff --git a/estate/views/estate_property_views.xml b/estate/views/estate_property_views.xml
index fcfc13e2d4b..1d2a3aaa4cd 100644
--- a/estate/views/estate_property_views.xml
+++ b/estate/views/estate_property_views.xml
@@ -1,8 +1,8 @@
- Properties
+ Properties
estate.property
- list
+ list,form
-
\ No newline at end of file
+
From 22ff6eeb8be9afb661469822a67c9465330ac46f Mon Sep 17 00:00:00 2001
From: yoelf
Date: Thu, 23 Apr 2026 13:48:29 +0200
Subject: [PATCH 08/19] [ADD] views : add more views and filters
---
estate/views/estate_property_views.xml | 76 ++++++++++++++++++++++++++
1 file changed, 76 insertions(+)
diff --git a/estate/views/estate_property_views.xml b/estate/views/estate_property_views.xml
index 1d2a3aaa4cd..73e49d95675 100644
--- a/estate/views/estate_property_views.xml
+++ b/estate/views/estate_property_views.xml
@@ -5,4 +5,80 @@
estate.property
list,form
+
+
+ estate.property.view.list
+ estate.property
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ estate.property.view.form
+ estate.property
+
+
+
+
+
+
+ estate.property.search
+ estate.property
+
+
+
+
+
+
+
+
+
+
+
+
+
+
From 895799ec83ff1879f7cbd7f70597bc4bc0e239f5 Mon Sep 17 00:00:00 2001
From: yoelf
Date: Thu, 23 Apr 2026 16:16:26 +0200
Subject: [PATCH 09/19] [ADD] estate : add offers,tags, and types
---
estate/__manifest__.py | 2 ++
estate/models/__init__.py | 3 ++
estate/models/estate_property.py | 9 ++++++
estate/models/estate_property_offer.py | 15 +++++++++
estate/models/estate_property_tag.py | 8 +++++
estate/models/estate_property_type.py | 8 +++++
estate/security/ir.model.access.csv | 3 ++
estate/views/estate_menus.xml | 8 +++--
estate/views/estate_property_offer_views.xml | 14 ++++++++
estate/views/estate_property_tag_views.xml | 33 +++++++++++++++++++
estate/views/estate_property_type_views.xml | 34 ++++++++++++++++++++
estate/views/estate_property_views.xml | 22 ++++++++++++-
12 files changed, 156 insertions(+), 3 deletions(-)
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/estate/__manifest__.py b/estate/__manifest__.py
index 39ea37ecce5..476de3d244b 100644
--- a/estate/__manifest__.py
+++ b/estate/__manifest__.py
@@ -10,6 +10,8 @@
"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_menus.xml",
],
}
diff --git a/estate/models/__init__.py b/estate/models/__init__.py
index 5e1963c9d2f..09b2099fe84 100644
--- a/estate/models/__init__.py
+++ b/estate/models/__init__.py
@@ -1 +1,4 @@
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 3745a4f0ebd..5f41b89b234 100644
--- a/estate/models/estate_property.py
+++ b/estate/models/estate_property.py
@@ -41,3 +41,12 @@ class EstateProperty(models.Model):
required=True,
default="new",
)
+ estate_property_type_id = fields.Many2one(
+ "estate.property.type", string="Property Type"
+ )
+ buyer_id = fields.Many2one("res.partner", string="Buyer", copy=False)
+ salesperson_id = fields.Many2one(
+ "res.users", string="Salesman", default=lambda self: self.env.user
+ )
+ estate_property_tag_ids = fields.Many2many("estate.property.tag", string="Tags")
+ estate_property_offer_ids = fields.One2many("estate.property.offer", "property_id")
diff --git a/estate/models/estate_property_offer.py b/estate/models/estate_property_offer.py
new file mode 100644
index 00000000000..e707552f5a7
--- /dev/null
+++ b/estate/models/estate_property_offer.py
@@ -0,0 +1,15 @@
+from odoo import fields, models
+
+
+class EstatePropertyOffer(models.Model):
+ _name = "estate.property.offer"
+ _description = "Offer for property"
+
+ price = fields.Float()
+ status = fields.Selection(
+ string="Status",
+ selection=[("accepted", "Accepted"), ("refused", "Refused")],
+ copy=False,
+ )
+ partner_id = fields.Many2one("res.partner", required=True)
+ property_id = fields.Many2one("estate.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..9e477ca23b7
--- /dev/null
+++ b/estate/models/estate_property_tag.py
@@ -0,0 +1,8 @@
+from odoo import fields, models
+
+
+class EstatePropertyTag(models.Model):
+ _name = "estate.property.tag"
+ _description = "Property Tag"
+
+ 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..ea6d79c3a10
--- /dev/null
+++ b/estate/models/estate_property_type.py
@@ -0,0 +1,8 @@
+from odoo import fields, models
+
+
+class EstatePropertyType(models.Model):
+ _name = "estate.property.type"
+ _description = "Property Type"
+
+ name = fields.Char(required=True)
diff --git a/estate/security/ir.model.access.csv b/estate/security/ir.model.access.csv
index e358a621c01..b2f2cb31b05 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
estate_property_access_user,estate.property.user,model_estate_property,base.group_user,1,1,1,1
+estate_property_type_access_user,estate.property.type.user,model_estate_property_type,base.group_user,1,1,1,1
+estate_property_tag_access_user,estate.property.tag.user,model_estate_property_tag,base.group_user,1,1,1,1
+estate_property_offer_access_user,estate.property.offer.user,model_estate_property_offer,base.group_user,1,1,1,1
diff --git a/estate/views/estate_menus.xml b/estate/views/estate_menus.xml
index a2818644c6b..edf16e45f45 100644
--- a/estate/views/estate_menus.xml
+++ b/estate/views/estate_menus.xml
@@ -1,8 +1,12 @@
diff --git a/estate/views/estate_property_offer_views.xml b/estate/views/estate_property_offer_views.xml
new file mode 100644
index 00000000000..13c1f561b20
--- /dev/null
+++ b/estate/views/estate_property_offer_views.xml
@@ -0,0 +1,14 @@
+
+
+
+ estate.property.offer.view.list
+ estate.property.offer
+
+
+
+
+
+
+
+
+
diff --git a/estate/views/estate_property_tag_views.xml b/estate/views/estate_property_tag_views.xml
new file mode 100644
index 00000000000..418104b7234
--- /dev/null
+++ b/estate/views/estate_property_tag_views.xml
@@ -0,0 +1,33 @@
+
+
+
+ Property tags
+ estate.property.tag
+ list,form
+
+
+ estate.property.tag.view.list
+ estate.property.tag
+
+
+
+
+
+
+
+
+ estate.property.tag.view.form
+ estate.property.tag
+
+
+
+
+
diff --git a/estate/views/estate_property_type_views.xml b/estate/views/estate_property_type_views.xml
new file mode 100644
index 00000000000..8d16ccabe81
--- /dev/null
+++ b/estate/views/estate_property_type_views.xml
@@ -0,0 +1,34 @@
+
+
+
+ Property types
+ estate.property.type
+ list,form
+
+
+ estate.property.type.view.list
+ estate.property.type
+
+
+
+
+
+
+
+
+ estate.property.type.view.form
+ estate.property.type
+
+
+
+
+
+
diff --git a/estate/views/estate_property_views.xml b/estate/views/estate_property_views.xml
index 73e49d95675..f1248cade69 100644
--- a/estate/views/estate_property_views.xml
+++ b/estate/views/estate_property_views.xml
@@ -12,7 +12,9 @@
+
+
@@ -34,7 +36,9 @@
+
+
@@ -44,7 +48,7 @@
-
+
@@ -58,6 +62,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -70,6 +89,7 @@
+
From a80712fd98fd26c459526e1c811e575a851b65fd Mon Sep 17 00:00:00 2001
From: yoelf
Date: Thu, 23 Apr 2026 16:59:10 +0200
Subject: [PATCH 10/19] [FIX] typo
---
estate/models/__init__.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/estate/models/__init__.py b/estate/models/__init__.py
index 09b2099fe84..2f1821a39c1 100644
--- a/estate/models/__init__.py
+++ b/estate/models/__init__.py
@@ -1,4 +1,4 @@
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
From 74913fe79fd20ccf6153c7642d34406e6beed5af Mon Sep 17 00:00:00 2001
From: yoelf
Date: Fri, 24 Apr 2026 11:21:19 +0200
Subject: [PATCH 11/19] [ADD] add computed fields and onchanges
---
estate/models/estate_property.py | 30 ++++++++++++++++++--
estate/models/estate_property_offer.py | 27 +++++++++++++++++-
estate/views/estate_property_offer_views.xml | 20 +++++++++++++
estate/views/estate_property_views.xml | 4 +++
4 files changed, 77 insertions(+), 4 deletions(-)
diff --git a/estate/models/estate_property.py b/estate/models/estate_property.py
index 5f41b89b234..e8415a8ee49 100644
--- a/estate/models/estate_property.py
+++ b/estate/models/estate_property.py
@@ -1,4 +1,4 @@
-from odoo import fields, models
+from odoo import api, fields, models
class EstateProperty(models.Model):
@@ -14,11 +14,11 @@ class EstateProperty(models.Model):
expected_price = fields.Integer(required=True)
selling_price = fields.Integer(readonly=True, copy=False)
bedrooms = fields.Integer(default=2)
- living_area = fields.Integer()
+ living_area = fields.Integer(default=0)
facades = fields.Integer()
garage = fields.Boolean()
garden = fields.Boolean()
- garden_area = fields.Integer()
+ garden_area = fields.Integer(default=0)
garden_orientation = fields.Selection(
string="orientation",
selection=[
@@ -50,3 +50,27 @@ class EstateProperty(models.Model):
)
estate_property_tag_ids = fields.Many2many("estate.property.tag", string="Tags")
estate_property_offer_ids = fields.One2many("estate.property.offer", "property_id")
+ total_area = fields.Integer(compute="_compute_total_area")
+ best_price = fields.Float(compute="_compute_best_price")
+
+ @api.depends("living_area", "garden_area", "garden")
+ def _compute_total_area(self):
+ for property in self:
+ property.total_area = (
+ property.living_area + property.garden_area
+ if property.garden
+ else property.living_area
+ )
+
+ @api.depends("estate_property_offer_ids.price")
+ def _compute_best_price(self):
+ for property in self:
+ property.best_price = (
+ max(property.estate_property_offer_ids.mapped("price")) if property.estate_property_offer_ids else None
+ )
+
+ @api.onchange("garden")
+ def _onchange_has_garden(self):
+ if self.garden:
+ self.garden_area = 10
+ self.garden_orientation = "north"
diff --git a/estate/models/estate_property_offer.py b/estate/models/estate_property_offer.py
index e707552f5a7..1be548c4c8a 100644
--- a/estate/models/estate_property_offer.py
+++ b/estate/models/estate_property_offer.py
@@ -1,4 +1,4 @@
-from odoo import fields, models
+from odoo import api, fields, models
class EstatePropertyOffer(models.Model):
@@ -13,3 +13,28 @@ class EstatePropertyOffer(models.Model):
)
partner_id = fields.Many2one("res.partner", required=True)
property_id = fields.Many2one("estate.property", required=True)
+
+ validity = fields.Integer(default=7)
+ date_deadline = fields.Date(
+ compute="_compute_date_deadline", inverse="_inverse_date_deadline"
+ )
+
+ @api.depends("validity")
+ def _compute_date_deadline(self):
+ for offer in self:
+ if offer.create_date:
+ offer.date_deadline = fields.Date.add(
+ offer.create_date,
+ days=offer.validity,
+ )
+ else:
+ offer.date_deadline = fields.Date.add(
+ fields.Date.today(), days=offer.validity
+ )
+
+ def _inverse_date_deadline(self):
+ for offer in self:
+ if offer.create_date:
+ offer.validity = (offer.date_deadline - offer.create_date.date()).days
+ else:
+ offer.validity = (offer.date_deadline - fields.Date.today()).days
diff --git a/estate/views/estate_property_offer_views.xml b/estate/views/estate_property_offer_views.xml
index 13c1f561b20..a03c09fad52 100644
--- a/estate/views/estate_property_offer_views.xml
+++ b/estate/views/estate_property_offer_views.xml
@@ -8,7 +8,27 @@
+
+
+
+
+ estate.property.offer.form
+ estate.property.offer
+
+
+
+
diff --git a/estate/views/estate_property_views.xml b/estate/views/estate_property_views.xml
index f1248cade69..b94c9bc40bb 100644
--- a/estate/views/estate_property_views.xml
+++ b/estate/views/estate_property_views.xml
@@ -44,6 +44,7 @@
+
@@ -60,6 +61,7 @@
+
@@ -67,6 +69,8 @@
+
+
From 10f341c7e95f368f113bd41da416441bb685d086 Mon Sep 17 00:00:00 2001
From: yoelf
Date: Fri, 24 Apr 2026 14:10:57 +0200
Subject: [PATCH 12/19] [ADD] actions !!!
---
estate/models/estate_property.py | 24 ++++++++++++++++++++++--
estate/models/estate_property_offer.py | 19 +++++++++++++++++++
estate/views/estate_property_views.xml | 7 +++++++
3 files changed, 48 insertions(+), 2 deletions(-)
diff --git a/estate/models/estate_property.py b/estate/models/estate_property.py
index e8415a8ee49..0eb21321b50 100644
--- a/estate/models/estate_property.py
+++ b/estate/models/estate_property.py
@@ -1,3 +1,5 @@
+from odoo.exceptions import UserError
+
from odoo import api, fields, models
@@ -44,7 +46,7 @@ class EstateProperty(models.Model):
estate_property_type_id = fields.Many2one(
"estate.property.type", string="Property Type"
)
- buyer_id = fields.Many2one("res.partner", string="Buyer", copy=False)
+ buyer_id = fields.Many2one("res.partner", string="Buyer", copy=False, readonly=True)
salesperson_id = fields.Many2one(
"res.users", string="Salesman", default=lambda self: self.env.user
)
@@ -66,7 +68,9 @@ def _compute_total_area(self):
def _compute_best_price(self):
for property in self:
property.best_price = (
- max(property.estate_property_offer_ids.mapped("price")) if property.estate_property_offer_ids else None
+ max(property.estate_property_offer_ids.mapped("price"))
+ if property.estate_property_offer_ids
+ else None
)
@api.onchange("garden")
@@ -74,3 +78,19 @@ def _onchange_has_garden(self):
if self.garden:
self.garden_area = 10
self.garden_orientation = "north"
+
+ def action_sell(self):
+ for property in self:
+ if property.state == "cancelled":
+ raise UserError("You can't sell a a cancelled property :)")
+
+ property.state = "sold"
+ return True
+
+ def action_cancel(self):
+ for property in self:
+ if property.state == "sold":
+ raise UserError("you can't cancel a sold property :)")
+
+ property.state = "cancelled"
+ return True
\ No newline at end of file
diff --git a/estate/models/estate_property_offer.py b/estate/models/estate_property_offer.py
index 1be548c4c8a..0ab57bebf59 100644
--- a/estate/models/estate_property_offer.py
+++ b/estate/models/estate_property_offer.py
@@ -1,3 +1,5 @@
+from odoo.exceptions import UserError
+
from odoo import api, fields, models
@@ -38,3 +40,20 @@ def _inverse_date_deadline(self):
offer.validity = (offer.date_deadline - offer.create_date.date()).days
else:
offer.validity = (offer.date_deadline - fields.Date.today()).days
+
+ def action_accept_offer(self):
+ for offer in self:
+ if offer.property_id.buyer_id:
+ raise UserError(
+ "a buyer is already assigned , therefore another offer has been accepted"
+ )
+ offer.status = "accepted"
+ offer.property_id.selling_price = self.price
+ offer.property_id.buyer_id = self.partner_id
+
+ return True
+
+ def action_refuse_offer(self):
+ for offer in self:
+ offer.status = "refused"
+ return True
diff --git a/estate/views/estate_property_views.xml b/estate/views/estate_property_views.xml
index b94c9bc40bb..87c7d30f463 100644
--- a/estate/views/estate_property_views.xml
+++ b/estate/views/estate_property_views.xml
@@ -30,6 +30,10 @@