From b1adea643f9dcf97b7800c2ac8f427fef6f9eba7 Mon Sep 17 00:00:00 2001 From: vrushibh Date: Fri, 5 Jun 2026 15:43:19 +0530 Subject: [PATCH 1/6] [ADD] estate: initialize estate module Add the basic module structure and manifest file for the estate application. --- estate/__init__.py | 0 estate/__manifest__.py | 7 +++++++ 2 files changed, 7 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..473c75d013c --- /dev/null +++ b/estate/__manifest__.py @@ -0,0 +1,7 @@ +{ + "name": "Real Estate", + "depends": ["base"], + "application": True, + "installable": True, + +} \ No newline at end of file From 8594029912f4524a7c6bdeb1c3db8ae6c7356cd8 Mon Sep 17 00:00:00 2001 From: vrushibh Date: Mon, 8 Jun 2026 15:29:21 +0530 Subject: [PATCH 2/6] [ADD] estate: add estate.property model and basic fields Define the 'estate.property' model. - Add basic fields: name, description, postcode, date_availability, expected_price, selling_price, bedrooms, living_area, facades, garage, garden, garden_area, and garden_orientation. - Set 'name' and 'expected_price' as required fields. - Initialize the models package and set up imports. --- estate/__init__.py | 1 + estate/__manifest__.py | 3 +-- estate/models/__init__.py | 1 + estate/models/estate_property.py | 28 ++++++++++++++++++++++++++++ 4 files changed, 31 insertions(+), 2 deletions(-) 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..0650744f6bc 100644 --- a/estate/__init__.py +++ b/estate/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/estate/__manifest__.py b/estate/__manifest__.py index 473c75d013c..bae78a5fc6a 100644 --- a/estate/__manifest__.py +++ b/estate/__manifest__.py @@ -3,5 +3,4 @@ "depends": ["base"], "application": True, "installable": True, - -} \ No newline at end of file +} diff --git a/estate/models/__init__.py b/estate/models/__init__.py new file mode 100644 index 00000000000..5e1963c9d2f --- /dev/null +++ b/estate/models/__init__.py @@ -0,0 +1 @@ +from . import estate_property diff --git a/estate/models/estate_property.py b/estate/models/estate_property.py new file mode 100644 index 00000000000..29cc5e845dd --- /dev/null +++ b/estate/models/estate_property.py @@ -0,0 +1,28 @@ +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(required=True) + 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"), + ], + string="Garden Orientation", + ) From 10c70a56258d77b1d35a386e48534ccd641cc215 Mon Sep 17 00:00:00 2001 From: vrushibh Date: Thu, 11 Jun 2026 18:52:21 +0530 Subject: [PATCH 3/6] [ADD] estate: add security access rules for estate.property - Create ir.model.access.csv in security folder - Grant read, write, create, and unlink permissions to base.group_user - Register security file in __manifest__.py - Fix manifest warnings by adding author and license keys --- estate/__manifest__.py | 5 +++++ estate/security/ir.model.access.csv | 2 ++ 2 files changed, 7 insertions(+) create mode 100644 estate/security/ir.model.access.csv diff --git a/estate/__manifest__.py b/estate/__manifest__.py index bae78a5fc6a..0360c444086 100644 --- a/estate/__manifest__.py +++ b/estate/__manifest__.py @@ -1,6 +1,11 @@ { "name": "Real Estate", + "author": "Odoo S.A.", + "license": "LGPL-3", "depends": ["base"], + "data": [ + "security/ir.model.access.csv", + ], "application": True, "installable": True, } diff --git a/estate/security/ir.model.access.csv b/estate/security/ir.model.access.csv new file mode 100644 index 00000000000..d9d6ba57cc5 --- /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 8fb2322a321cbda5a639335b270984c01c63ec82 Mon Sep 17 00:00:00 2001 From: vrushibh Date: Thu, 18 Jun 2026 12:26:45 +0530 Subject: [PATCH 4/6] [ADD] estate: add basic views, action and menus - Add tree (list), form, and search views for 'estate.property' in views/estate_property_views.xml. - Configure action 'action_estate_property' to load 'list,form,kanban' views and default filter 'available'. - Define advertisements menu structure in views/estate_menus.xml. - Clean up hardcoded field column widths from the list view in views/estate_property_views.xml to use standard auto-sizing layout. --- estate/__manifest__.py | 3 + estate/models/estate_property.py | 27 +++++-- estate/models/estate_property_type.py | 8 ++ estate/security/estate_security.xml | 29 ++++++++ estate/security/ir.model.access.csv | 3 +- estate/static/description/icon.png | Bin 0 -> 8694 bytes estate/views/estate_menus.xml | 9 +++ estate/views/estate_property_views.xml | 97 +++++++++++++++++++++++++ 8 files changed, 170 insertions(+), 6 deletions(-) create mode 100644 estate/models/estate_property_type.py create mode 100644 estate/security/estate_security.xml create mode 100644 estate/static/description/icon.png 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 0360c444086..e2211fb996c 100644 --- a/estate/__manifest__.py +++ b/estate/__manifest__.py @@ -4,7 +4,10 @@ "license": "LGPL-3", "depends": ["base"], "data": [ + "security/estate_security.xml", "security/ir.model.access.csv", + "views/estate_property_views.xml", + "views/estate_menus.xml", ], "application": True, "installable": True, diff --git a/estate/models/estate_property.py b/estate/models/estate_property.py index 29cc5e845dd..d3bb6285923 100644 --- a/estate/models/estate_property.py +++ b/estate/models/estate_property.py @@ -1,17 +1,20 @@ from odoo import fields, models +from dateutil.relativedelta import relativedelta class EstateProperty(models.Model): _name = "estate.property" _description = "Real Estate Property" - name = fields.Char(required=True) + name = fields.Char(required=True, string="Property Name") description = fields.Text() postcode = fields.Char() - date_availability = fields.Date() - expected_price = fields.Float(required=True) - selling_price = fields.Float() - bedrooms = fields.Integer() + date_availability = fields.Date( + default=lambda self: fields.Date.context_today(self) + relativedelta(months=3) + ) + expected_price = fields.Float(required=True, copy=False, default=0.0) + selling_price = fields.Float(readonly=True, copy=False) + bedrooms = fields.Integer(default=2) living_area = fields.Integer() facades = fields.Integer() garage = fields.Boolean() @@ -26,3 +29,17 @@ class EstateProperty(models.Model): ], string="Garden Orientation", ) + active = fields.Boolean(default=True) + state = fields.Selection( + selection=[ + ("new", "New"), + ("offer_received", "Offer Received"), + ("offer_accepted", "Offer Accepted"), + ("sold", "Sold"), + ("cancelled", "Cancelled"), + ], + required=True, + copy=False, + default="new", + string="State", + ) diff --git a/estate/models/estate_property_type.py b/estate/models/estate_property_type.py new file mode 100644 index 00000000000..26c6ce17aa1 --- /dev/null +++ b/estate/models/estate_property_type.py @@ -0,0 +1,8 @@ +from odoo import models, fields + + +class EstatePropertyType(models.Model): + _name = "estate.property.type" + _description = "Real Estate Property Type" + + name = fields.Char(required=True, string="Property Type") diff --git a/estate/security/estate_security.xml b/estate/security/estate_security.xml new file mode 100644 index 00000000000..8ffe601261a --- /dev/null +++ b/estate/security/estate_security.xml @@ -0,0 +1,29 @@ + + + + + + Real Estate + 10 + + + + Access Level + + + + + Agent + + + + + + Manager + + + + + + + diff --git a/estate/security/ir.model.access.csv b/estate/security/ir.model.access.csv index d9d6ba57cc5..55113ee4775 100644 --- a/estate/security/ir.model.access.csv +++ b/estate/security/ir.model.access.csv @@ -1,2 +1,3 @@ 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_agent,access_estate_property_agent,model_estate_property,group_estate_agent,1,1,1,0 +access_estate_property_manager,access_estate_property_manager,model_estate_property,group_estate_manager,1,1,1,1 diff --git a/estate/static/description/icon.png b/estate/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ac5f35cf3404f2ef4c6932737005f02b337c2a52 GIT binary patch literal 8694 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 literal 0 HcmV?d00001 diff --git a/estate/views/estate_menus.xml b/estate/views/estate_menus.xml new file mode 100644 index 00000000000..8a7a69ec9b1 --- /dev/null +++ b/estate/views/estate_menus.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/estate/views/estate_property_views.xml b/estate/views/estate_property_views.xml new file mode 100644 index 00000000000..bd37accd558 --- /dev/null +++ b/estate/views/estate_property_views.xml @@ -0,0 +1,97 @@ + + + + + Properties + estate.property + list,form,kanban + {'search_default_available': 1} + +

+ Create your first real estate property advertisement! +

+

+ Here you can define all the details of the properties you want to sell. +

+
+
+ + estate.property.list + estate.property + + + + + + + + + + + + + + + + estate.property.form + estate.property + +
+ +
+

+ +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ + + estate.property.search + estate.property + + + + + + + + + + + + + + + + +
+
From 67d44d97d21290e2f4c5b232d25cef4fdc3e7fc3 Mon Sep 17 00:00:00 2001 From: vrushibh Date: Mon, 22 Jun 2026 17:58:25 +0530 Subject: [PATCH 5/6] [IMP] estate: add tag and offer models with relations Introduce the property tag (estate.property.tag) and property offer (estate.property.offer) models, establishing relationship fields. - Add estate.property.tag model with basic views. - Add Many2many field tag_ids to estate.property. - Add estate.property.offer model with form and list views. - Add One2many field offer_ids to estate.property. - Add security access rules (ACLs) for both new models task-7 --- estate/__manifest__.py | 5 +++ estate/models/__init__.py | 3 ++ estate/models/estate_property.py | 28 +++++++++----- estate/models/estate_property_offer.py | 18 +++++++++ estate/models/estate_property_tag.py | 10 +++++ estate/security/ir.model.access.csv | 10 ++++- estate/views/estate_property_offer_views.xml | 31 ++++++++++++++++ estate/views/estate_property_tag_views.xml | 39 ++++++++++++++++++++ 8 files changed, 132 insertions(+), 12 deletions(-) create mode 100644 estate/models/estate_property_offer.py create mode 100644 estate/models/estate_property_tag.py create mode 100644 estate/views/estate_property_offer_views.xml create mode 100644 estate/views/estate_property_tag_views.xml diff --git a/estate/__manifest__.py b/estate/__manifest__.py index e2211fb996c..b00f9afce22 100644 --- a/estate/__manifest__.py +++ b/estate/__manifest__.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- { "name": "Real Estate", "author": "Odoo S.A.", @@ -7,7 +8,11 @@ "security/estate_security.xml", "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", + "data/estate_demo.xml", ], "application": True, "installable": True, diff --git a/estate/models/__init__.py b/estate/models/__init__.py index 5e1963c9d2f..4b57c1674fc 100644 --- a/estate/models/__init__.py +++ b/estate/models/__init__.py @@ -1 +1,4 @@ from . import estate_property +from . import estate_property_tag +from . import estate_property_type +from . import estate_property_offer diff --git a/estate/models/estate_property.py b/estate/models/estate_property.py index d3bb6285923..809658aa5c4 100644 --- a/estate/models/estate_property.py +++ b/estate/models/estate_property.py @@ -1,6 +1,7 @@ -from odoo import fields, models from dateutil.relativedelta import relativedelta +from odoo import fields, models + class EstateProperty(models.Model): _name = "estate.property" @@ -22,24 +23,31 @@ class EstateProperty(models.Model): garden_area = fields.Integer() garden_orientation = fields.Selection( selection=[ - ("north", "North"), - ("south", "South"), - ("east", "East"), - ("west", "West"), + ('north', "North"), + ('south', "South"), + ('east', "East"), + ('west', "West"), ], string="Garden Orientation", ) active = fields.Boolean(default=True) 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"), ], required=True, copy=False, default="new", string="State", ) + 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="Salesperson", default=lambda self: self.env.user + ) + tag_ids = fields.Many2many("estate.property.tag", string="Property 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..c9949ed0382 --- /dev/null +++ b/estate/models/estate_property_offer.py @@ -0,0 +1,18 @@ +from odoo import fields, models + + +class EstatePropertyOffer(models.Model): + _name = "estate.property.offer" + _description = "Real Estate Property Offer" + + price = fields.Float(required=True) + status = fields.Selection( + selection=[ + ('accepted', 'Accepted'), + ('rejected', 'Rejected'), + ], + copy=False, + string="Status", + ) + partner_id = fields.Many2one("res.partner", string="Partner",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..c90d1143652 --- /dev/null +++ b/estate/models/estate_property_tag.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- + +from odoo import fields, models + + +class EstatePropertyTag(models.Model): + _name = "estate.property.tag" + _description = "Real Estate Property Tag" + + name = fields.Char(required=True) diff --git a/estate/security/ir.model.access.csv b/estate/security/ir.model.access.csv index 55113ee4775..0ae4ad14d54 100644 --- a/estate/security/ir.model.access.csv +++ b/estate/security/ir.model.access.csv @@ -1,3 +1,9 @@ id,name,model_id/id,group_id/id,perm_read,perm_write,perm_create,perm_unlink -access_estate_property_agent,access_estate_property_agent,model_estate_property,group_estate_agent,1,1,1,0 -access_estate_property_manager,access_estate_property_manager,model_estate_property,group_estate_manager,1,1,1,1 +access_estate_property_agent,access_estate_property_agent,model_estate_property,estate_group_agent,1,1,1,0 +access_estate_property_manager,access_estate_property_manager,model_estate_property,estate_group_manager,1,1,1,1 +access_estate_property_type_agent,access_estate_property_type_agent,model_estate_property_type,estate_group_agent,1,1,1,1 +access_estate_property_type_manager,access_estate_property_type_manager,model_estate_property_type,estate_group_manager,1,1,1,1 +access_estate_property_tag_agent,access_estate_property_tag_agent,model_estate_property_tag,estate_group_agent,1,1,1,1 +access_estate_property_tag_manager,access_estate_property_tag_manager,model_estate_property_tag,estate_group_manager,1,1,1,1 +access_estate_property_offer_agent,access_estate_property_offer_agent,model_estate_property_offer,estate_group_agent,1,1,1,1 +access_estate_property_offer_manager,access_estate_property_offer_manager,model_estate_property_offer,estate_group_manager,1,1,1,1 diff --git a/estate/views/estate_property_offer_views.xml b/estate/views/estate_property_offer_views.xml new file mode 100644 index 00000000000..16d222cef52 --- /dev/null +++ b/estate/views/estate_property_offer_views.xml @@ -0,0 +1,31 @@ + + + + + estate.property.offer.view.list + estate.property.offer + + + + + + + + + + + estate.property.offer.view.form + estate.property.offer + +
+ + + + + + + +
+
+
+
\ No newline at end of file diff --git a/estate/views/estate_property_tag_views.xml b/estate/views/estate_property_tag_views.xml new file mode 100644 index 00000000000..ed016ca6260 --- /dev/null +++ b/estate/views/estate_property_tag_views.xml @@ -0,0 +1,39 @@ + + + + + Property Tags + estate.property.tag + list,form + +

+ Create your first property tag! +

+
+
+ + + estate.property.tag.view.list + estate.property.tag + + + + + + + + + estate.property.tag.view.form + estate.property.tag + +
+ + + + + +
+
+
+ +
From e65e22aab05d929117bb49f10df4b0f97b747fa2 Mon Sep 17 00:00:00 2001 From: vrushibh Date: Mon, 22 Jun 2026 18:02:24 +0530 Subject: [PATCH 6/6] [FIX] estate: address TL review feedback and add demo data Address the code styling, domain filters, and manifest configurations requested in the code review. Additionally, set up demo data for the property, type, and tag models. --- estate/data/estate_demo.xml | 69 +++++++ estate/models/estate_property_type.py | 2 +- estate/security/estate_security.xml | 40 ++-- estate/views/estate_menus.xml | 37 +++- estate/views/estate_property_type_views.xml | 39 ++++ estate/views/estate_property_views.xml | 196 +++++++++++--------- 6 files changed, 269 insertions(+), 114 deletions(-) create mode 100644 estate/data/estate_demo.xml create mode 100644 estate/views/estate_property_type_views.xml diff --git a/estate/data/estate_demo.xml b/estate/data/estate_demo.xml new file mode 100644 index 00000000000..b16fe8169a9 --- /dev/null +++ b/estate/data/estate_demo.xml @@ -0,0 +1,69 @@ + + + + + Residential + + + commercial + + + + Cozy + + + Cool + + + Nice + + + + vrushibh Apartment + 75000.00 + 4 + 250 + 35000 + 2026-09-15 + + + + + + Cozy Apartment + 200000.00 + 2 + 85 + 380001 + + + + + + nice Apartment + 206000.00 + 2 + 85 + 380001 + + + + + cool Apartment + 206000.00 + 2 + 85 + 380001 + + + + + jumbo Apartment + 206000.00 + 2 + 85 + 380001 + + + + \ No newline at end of file diff --git a/estate/models/estate_property_type.py b/estate/models/estate_property_type.py index 26c6ce17aa1..216472e442c 100644 --- a/estate/models/estate_property_type.py +++ b/estate/models/estate_property_type.py @@ -1,4 +1,4 @@ -from odoo import models, fields +from odoo import fields, models class EstatePropertyType(models.Model): diff --git a/estate/security/estate_security.xml b/estate/security/estate_security.xml index 8ffe601261a..b6432bce42b 100644 --- a/estate/security/estate_security.xml +++ b/estate/security/estate_security.xml @@ -1,29 +1,27 @@ - - - Real Estate - 10 - + + Real Estate + 10 + - - Access Level - - + + Access Level + + - - Agent - - - + + Agent + + + - - Manager - - - - + + Manager + + + + - diff --git a/estate/views/estate_menus.xml b/estate/views/estate_menus.xml index 8a7a69ec9b1..3c08d2c78fa 100644 --- a/estate/views/estate_menus.xml +++ b/estate/views/estate_menus.xml @@ -1,9 +1,36 @@ - - - - - + + + + + + + + + + diff --git a/estate/views/estate_property_type_views.xml b/estate/views/estate_property_type_views.xml new file mode 100644 index 00000000000..819000b7da1 --- /dev/null +++ b/estate/views/estate_property_type_views.xml @@ -0,0 +1,39 @@ + + + + + Property Types + estate.property.type + list,form + +

+ Create your first property type! +

+
+
+ + + 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 bd37accd558..58cf28b0496 100644 --- a/estate/views/estate_property_views.xml +++ b/estate/views/estate_property_views.xml @@ -1,97 +1,119 @@ - + - - - Properties - estate.property - list,form,kanban - {'search_default_available': 1} - -

- Create your first real estate property advertisement! -

-

- Here you can define all the details of the properties you want to sell. -

-
-
- - estate.property.list - estate.property - - - - - - - - - - - - + + Properties + estate.property + list,form,kanban + {'search_default_available': 1} + +

+ Create your first real estate property advertisement! +

+

+ Here you can define all the details of the properties you want to sell. +

+
+
- - estate.property.form - estate.property - -
- -
-

- -

-
+ + estate.property.view.list + estate.property + + + + + + + + + + + + + + + + + estate.property.view.form + estate.property + + + +
+

+ +

+ +
+ + + + + + + + + + + + + - - + + + + + + + + + + + + - - + + - - - - - - - - - - - - - - - - - -
- -
-
+ + + + + +
+ +
+
+ + + estate.property.view.search + estate.property + + + + + + + + + + + + + + + + + + + + + + + + - - estate.property.search - estate.property - - - - - - - - - - - - - - - - -