From ea3e3196802b01b8418e14468f5f967b507bfb55 Mon Sep 17 00:00:00 2001 From: "Aditya Maurya (adrma)" Date: Mon, 3 Aug 2026 16:41:54 +0530 Subject: [PATCH 01/11] [ADD] estate: add initial module structure and estate.property model --- estate/__init__.py | 1 + estate/__manifest__.py | 5 +++++ estate/models/__init__.py | 1 + estate/models/estate_property.py | 7 +++++++ 4 files changed, 14 insertions(+) create mode 100644 estate/__init__.py create mode 100644 estate/__manifest__.py 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 new file mode 100644 index 00000000000..9a7e03eded3 --- /dev/null +++ b/estate/__init__.py @@ -0,0 +1 @@ +from . import models \ No newline at end of file diff --git a/estate/__manifest__.py b/estate/__manifest__.py new file mode 100644 index 00000000000..9fe357b4efd --- /dev/null +++ b/estate/__manifest__.py @@ -0,0 +1,5 @@ +{ + 'name' :"Real Estate", + 'depends':['base'], + 'application': True, +} 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..47ceab95ec5 --- /dev/null +++ b/estate/models/estate_property.py @@ -0,0 +1,7 @@ +from odoo import fields , models + +class EstateProperty(models.Model): + _name = "estate.property" + _description = "Estate Property" + + name = fields.Char('Property name ' , required = True , translate = True) From a1872517ee34fbd9733ee10afb9b37d69744579c Mon Sep 17 00:00:00 2001 From: "Aditya Maurya (adrma)" Date: Mon, 3 Aug 2026 18:47:41 +0530 Subject: [PATCH 02/11] [ADD] estate: add more fields in models --- estate/__init__.py | 2 +- estate/__manifest__.py | 6 +----- estate/models/__init__.py | 2 +- estate/models/estate_property.py | 25 +++++++++++++++++++++++-- 4 files changed, 26 insertions(+), 9 deletions(-) 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 9fe357b4efd..dc536bc662c 100644 --- a/estate/__manifest__.py +++ b/estate/__manifest__.py @@ -1,5 +1 @@ -{ - 'name' :"Real Estate", - 'depends':['base'], - 'application': True, -} +{"name": "Real Estate", "depends": ["base"], "application": True} diff --git a/estate/models/__init__.py b/estate/models/__init__.py index 5e1963c9d2f..9d5e62fe812 100644 --- a/estate/models/__init__.py +++ b/estate/models/__init__.py @@ -1 +1 @@ -from . import estate_property +from . import estate_property # noqa: F401 diff --git a/estate/models/estate_property.py b/estate/models/estate_property.py index 47ceab95ec5..251d7372cd7 100644 --- a/estate/models/estate_property.py +++ b/estate/models/estate_property.py @@ -1,7 +1,28 @@ -from odoo import fields , models +from odoo import fields, models + class EstateProperty(models.Model): _name = "estate.property" _description = "Estate Property" - name = fields.Char('Property name ' , required = True , translate = True) + name = fields.Char("Property name ", required=True, translate=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 51216483d26d6c650ff49f1252787748bf2f1b72 Mon Sep 17 00:00:00 2001 From: "Aditya Maurya (adrma)" Date: Mon, 3 Aug 2026 19:00:27 +0530 Subject: [PATCH 03/11] [IMP] estate: add field attributes and constraints --- estate/models/estate_property.py | 1 - 1 file changed, 1 deletion(-) diff --git a/estate/models/estate_property.py b/estate/models/estate_property.py index 251d7372cd7..53b42f2cfe3 100644 --- a/estate/models/estate_property.py +++ b/estate/models/estate_property.py @@ -6,7 +6,6 @@ class EstateProperty(models.Model): _description = "Estate Property" name = fields.Char("Property name ", required=True, translate=True) - _description = fields.Text() postcode = fields.Char() date_availability = fields.Date() expected_price = fields.Float(required=True) From 0333ce1736547f428fd10ffe7986b993e425e917 Mon Sep 17 00:00:00 2001 From: "Aditya Maurya (adrma)" Date: Tue, 4 Aug 2026 10:37:28 +0530 Subject: [PATCH 04/11] [FIX] estate : Add Author and License --- estate/__init__.py | 2 +- estate/__manifest__.py | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/estate/__init__.py b/estate/__init__.py index 0650744f6bc..ce9807d14fd 100644 --- a/estate/__init__.py +++ b/estate/__init__.py @@ -1 +1 @@ -from . import models +from . import models # noqa: F401 diff --git a/estate/__manifest__.py b/estate/__manifest__.py index dc536bc662c..fb779ed8573 100644 --- a/estate/__manifest__.py +++ b/estate/__manifest__.py @@ -1 +1,8 @@ -{"name": "Real Estate", "depends": ["base"], "application": True} +{ + "name": "Real Estate", + "depends": ["base"], + "application": True, + "author": "Aditya Maurya", + "license": "LGPL-3", + "category": "Real Estate", +} From a99f51b8643fe5ccd20a75b88de28847b397f556 Mon Sep 17 00:00:00 2001 From: "Aditya Maurya (adrma)" Date: Tue, 4 Aug 2026 14:50:31 +0530 Subject: [PATCH 05/11] [ADD] estate: add access rights for estate.property model --- estate/__manifest__.py | 1 + estate/security/ir.model.access.csv | 2 ++ 2 files changed, 3 insertions(+) create mode 100644 estate/security/ir.model.access.csv diff --git a/estate/__manifest__.py b/estate/__manifest__.py index fb779ed8573..13c1ebfc5fc 100644 --- a/estate/__manifest__.py +++ b/estate/__manifest__.py @@ -5,4 +5,5 @@ "author": "Aditya Maurya", "license": "LGPL-3", "category": "Real Estate", + "data": ['security/ir.model.access.csv'] } diff --git a/estate/security/ir.model.access.csv b/estate/security/ir.model.access.csv new file mode 100644 index 00000000000..775f77c8384 --- /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,0,0,0 From f86df35cfa31b6cc69ec8855d05086b54be4dac2 Mon Sep 17 00:00:00 2001 From: "Aditya Maurya (adrma)" Date: Wed, 5 Aug 2026 18:12:12 +0530 Subject: [PATCH 06/11] [ADD] estate: Added Some Basic UI to Create Record --- estate/__manifest__.py | 7 ++++- estate/models/estate_property.py | 43 ++++++++++++++++++++------ estate/security/ir.model.access.csv | 2 +- estate/views/estate_menu.xml | 17 ++++++++++ estate/views/estate_property_views.xml | 10 ++++++ 5 files changed, 68 insertions(+), 11 deletions(-) create mode 100644 estate/views/estate_menu.xml create mode 100644 estate/views/estate_property_views.xml diff --git a/estate/__manifest__.py b/estate/__manifest__.py index 13c1ebfc5fc..ba5e754812c 100644 --- a/estate/__manifest__.py +++ b/estate/__manifest__.py @@ -2,8 +2,13 @@ "name": "Real Estate", "depends": ["base"], "application": True, + "installable": True, "author": "Aditya Maurya", "license": "LGPL-3", "category": "Real Estate", - "data": ['security/ir.model.access.csv'] + "data": [ + "security/ir.model.access.csv", + "views/estate_property_views.xml", + "views/estate_menu.xml", + ], } diff --git a/estate/models/estate_property.py b/estate/models/estate_property.py index 53b42f2cfe3..33b3178bfef 100644 --- a/estate/models/estate_property.py +++ b/estate/models/estate_property.py @@ -3,25 +3,50 @@ class EstateProperty(models.Model): _name = "estate.property" - _description = "Estate Property" + _description = "Real Estate Property" - name = fields.Char("Property name ", required=True, translate=True) - postcode = fields.Char() - date_availability = fields.Date() - expected_price = fields.Float(required=True) - selling_price = fields.Float() - bedrooms = fields.Integer() + name = fields.Char("Title", required=True) + + description = fields.Text("Description") + postcode = fields.Char("Postcode") + date_availability = fields.Date( + "Available From", + copy=False, + ) + expected_price = fields.Float("Expected Price", required=True) + + selling_price = fields.Float( + "Selling Price", + readonly=True, + copy=False, + ) + + active = fields.Boolean(string="Active", default=True) + bedrooms = fields.Integer("Bedrooms", default=2) 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"), + ] + ) + + state = fields.Selection( + selection=[ + ("new", "New"), + ("offer_received", "Offer Received"), + ("offer_accepted", "Offer Accepted"), + ("sold", "Sold"), + ("cancelled", "Cancelled"), ], - string="Garden Orientation", + string="Status", + required=True, + copy=False, + default="new", ) diff --git a/estate/security/ir.model.access.csv b/estate/security/ir.model.access.csv index 775f77c8384..98f4671fb0d 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,0,0,0 +estate.access_estate_property,access_estate_property,estate.model_estate_property,base.group_user,1,1,1,1 diff --git a/estate/views/estate_menu.xml b/estate/views/estate_menu.xml new file mode 100644 index 00000000000..0b27bd9e24c --- /dev/null +++ b/estate/views/estate_menu.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + \ 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..15f25d3134e --- /dev/null +++ b/estate/views/estate_property_views.xml @@ -0,0 +1,10 @@ + + + + Properties + estate.property + list,form + + + + From 8fe9a0d51fff0f11d3e66313e8ee2139178c1b73 Mon Sep 17 00:00:00 2001 From: "Aditya Maurya (adrma)" Date: Thu, 6 Aug 2026 18:01:11 +0530 Subject: [PATCH 07/11] [ADD] estate: Add menu item , custom list view and icon --- estate/static/description/icon.png | Bin 0 -> 20757 bytes estate/views/estate_menu.xml | 7 ++++-- estate/views/estate_property_views.xml | 30 +++++++++++++++++++++++++ 3 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 estate/static/description/icon.png diff --git a/estate/static/description/icon.png b/estate/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..82e77f8dcfecb866a8385e4691d88b6c50e2aaf0 GIT binary patch literal 20757 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 KuV=q{{qavqlQs+h literal 0 HcmV?d00001 diff --git a/estate/views/estate_menu.xml b/estate/views/estate_menu.xml index 0b27bd9e24c..04bee4781e7 100644 --- a/estate/views/estate_menu.xml +++ b/estate/views/estate_menu.xml @@ -1,6 +1,6 @@ - + - + \ No newline at end of file diff --git a/estate/views/estate_property_views.xml b/estate/views/estate_property_views.xml index 15f25d3134e..9353e9c51c4 100644 --- a/estate/views/estate_property_views.xml +++ b/estate/views/estate_property_views.xml @@ -4,7 +4,37 @@ Properties estate.property list,form + +

+ Create a new properties +

+ Create property advertisements to track availability, expected prices, and manage incoming offers. +

+
+ + + estate property views + estate.property + + + + + + + + + + + + + + + + + + https://odoo.com + From fe3e7980ee85a899f26ba41893e7fc1b4e84d3f8 Mon Sep 17 00:00:00 2001 From: "Aditya Maurya (adrma)" Date: Tue, 18 Aug 2026 10:12:36 +0530 Subject: [PATCH 08/11] [ADD] estate: Added new model for property type --- estate/__manifest__.py | 3 + estate/data/estate_property_demo.xml | 199 +++++++++++++++++++++++++ estate/models/__init__.py | 3 +- estate/models/estate_property.py | 19 +-- estate/models/estate_property_type.py | 8 + estate/security/ir.model.access.csv | 3 +- estate/views/estate_menu.xml | 21 +-- estate/views/estate_property_views.xml | 128 ++++++++++++---- 8 files changed, 328 insertions(+), 56 deletions(-) create mode 100644 estate/data/estate_property_demo.xml create mode 100644 estate/models/estate_property_type.py diff --git a/estate/__manifest__.py b/estate/__manifest__.py index ba5e754812c..bc8ed392e4e 100644 --- a/estate/__manifest__.py +++ b/estate/__manifest__.py @@ -11,4 +11,7 @@ "views/estate_property_views.xml", "views/estate_menu.xml", ], + "demo": [ + "data/estate_property_demo.xml", + ], } diff --git a/estate/data/estate_property_demo.xml b/estate/data/estate_property_demo.xml new file mode 100644 index 00000000000..05d1a85265c --- /dev/null +++ b/estate/data/estate_property_demo.xml @@ -0,0 +1,199 @@ + + + + + + + + + + Cozy Suburban Cottage + A lovely 2-bedroom house with a spacious backyard. + 90210 + 2026-09-01 + 250000 + 0 + 2 + 120 + 2 + True + True + 50 + south + new + + + + + + Modern Downtown Apartment + Luxury high-rise unit in the heart of the city. + 10001 + 2026-10-15 + + 450000 + 0 + 1 + 75 + 1 + False + False + offer_received + + + + + + Spacious Family Villa + Large villa featuring 5 bedrooms, pool, and huge garden. + 33101 + 2026-08-20 + + 850000 + 830000 + 5 + 550 + 4 + True + True + 200 + west + sold + + + + + + Luxury Penthouse Suite + Top-floor penthouse with private rooftop terrace. + 90001 + 2027-01-15 + 1200000 + 0 + + 3 + 280 + 4 + True + True + 100 + west + new + + + + + + Suburban Ranch House + Single-story ranch home with a broad front porch. + 75002 + 2026-09-10 + + 290000 + 285000 + 3 + 160 + 2 + True + True + 80 + east + offer_accepted + + + + + + Minimalist Urban Loft + Open-concept loft with industrial design elements. + 60611 + 2026-10-01 + 380000 + 0 + False + 1 + 95 + 2 + False + False + cancelled + + + + + Beachfront Condo + Stunning ocean views with private balcony access. + 33139 + 2027-03-01 + 600000 + 0 + 2 + 110 + 2 + True + False + new + + + + + + Mountain View Retreat + Peaceful chalet nestled in the mountains. + 80202 + 2026-12-01 + + 510000 + 500000 + 3 + 180 + 3 + True + True + 150 + north + offer_received + + + + + + Historic Townhouse + Classic architecture with modern interior renovations. + 02108 + 2026-08-15 + 720000 + 0 + 3 + 210 + 2 + False + True + 40 + south + new + + + + + + Grand Estate Manor + Massive country estate with extensive living space. + 75001 + 2027-02-15 + 1900000 + 1850000 + 6 + 580 + 4 + True + True + 800 + south + sold + + + + + + diff --git a/estate/models/__init__.py b/estate/models/__init__.py index 9d5e62fe812..40092a2d810 100644 --- a/estate/models/__init__.py +++ b/estate/models/__init__.py @@ -1 +1,2 @@ -from . import estate_property # noqa: F401 +from . import estate_property +from . import estate_property_type diff --git a/estate/models/estate_property.py b/estate/models/estate_property.py index 33b3178bfef..c7880dd1d05 100644 --- a/estate/models/estate_property.py +++ b/estate/models/estate_property.py @@ -1,3 +1,6 @@ +from datetime import datetime + +from dateutil.relativedelta import relativedelta from odoo import fields, models @@ -6,21 +9,20 @@ class EstateProperty(models.Model): _description = "Real Estate Property" name = fields.Char("Title", required=True) - description = fields.Text("Description") postcode = fields.Char("Postcode") - date_availability = fields.Date( - "Available From", - copy=False, - ) - expected_price = fields.Float("Expected Price", required=True) + def _default_Date(self): + return datetime.now() + relativedelta(months=3) + + property_type_id = fields.Many2one("estate.property.type", "Type") + date_availability = fields.Date("Available From", copy=False, default=_default_Date) + expected_price = fields.Float("Expected Price", required=True) selling_price = fields.Float( "Selling Price", readonly=True, copy=False, ) - active = fields.Boolean(string="Active", default=True) bedrooms = fields.Integer("Bedrooms", default=2) living_area = fields.Integer() @@ -36,9 +38,8 @@ class EstateProperty(models.Model): ("west", "West"), ] ) - state = fields.Selection( - selection=[ + [ ("new", "New"), ("offer_received", "Offer Received"), ("offer_accepted", "Offer Accepted"), diff --git a/estate/models/estate_property_type.py b/estate/models/estate_property_type.py new file mode 100644 index 00000000000..09550a5b76b --- /dev/null +++ b/estate/models/estate_property_type.py @@ -0,0 +1,8 @@ +from odoo import fields, models + + +class PropertyType(models.Model): + _name = "estate.property.type" + _description = "Properties Type" + + name = fields.Char("Type", required=True) diff --git a/estate/security/ir.model.access.csv b/estate/security/ir.model.access.csv index 98f4671fb0d..404965c040f 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 -estate.access_estate_property,access_estate_property,estate.model_estate_property,base.group_user,1,1,1,1 +access_estate_property,estate.property,model_estate_property,base.group_system,1,1,1,1 +estate.access_estate_porperty_type,access_estate_porperty_type,estate.model_estate_property_type,base.group_user,1,1,1,1 diff --git a/estate/views/estate_menu.xml b/estate/views/estate_menu.xml index 04bee4781e7..4d7951e0226 100644 --- a/estate/views/estate_menu.xml +++ b/estate/views/estate_menu.xml @@ -1,20 +1,13 @@ - + - + - + - + - \ No newline at end of file + + + diff --git a/estate/views/estate_property_views.xml b/estate/views/estate_property_views.xml index 9353e9c51c4..9820c467234 100644 --- a/estate/views/estate_property_views.xml +++ b/estate/views/estate_property_views.xml @@ -1,40 +1,106 @@ - - Properties - estate.property + + + + Properties + estate.property list,form -

- Create a new properties -

+

+ Create a new properties! +

+

Create property advertisements to track availability, expected prices, and manage incoming offers. -

+

-
- - - estate property views - estate.property - - - - - - - - - - - - - - +
+ + + Properties Type + estate.property.type + list,form + - - - https://odoo.com - + + + estate.property.list + estate.property + + + + + + + + + + + -
+ + estate.property.form + estate.property + +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ + + estate.property.search + estate.property + + + + + + + + + + From f255b732d453f8d99f13bf2554193d6f3ef6b974 Mon Sep 17 00:00:00 2001 From: "Aditya Maurya (adrma)" Date: Tue, 8 Sep 2026 10:34:51 +0530 Subject: [PATCH 09/11] [ADD] estate: property tags and property relationship - Define Many2many relationship with tags in estate.property - Add form and list views for property tags - Add security access rules in ir.model.access.csv --- estate/data/estate_property_demo.xml | 4 ---- estate/models/__init__.py | 1 + estate/models/estate_property.py | 5 +++++ estate/models/estate_property_tag.py | 8 ++++++++ estate/security/ir.model.access.csv | 3 ++- estate/views/estate_menu.xml | 2 ++ estate/views/estate_property_views.xml | 16 +++++++++++++++- 7 files changed, 33 insertions(+), 6 deletions(-) create mode 100644 estate/models/estate_property_tag.py diff --git a/estate/data/estate_property_demo.xml b/estate/data/estate_property_demo.xml index 05d1a85265c..13e36beffb1 100644 --- a/estate/data/estate_property_demo.xml +++ b/estate/data/estate_property_demo.xml @@ -1,10 +1,6 @@ - - - - Cozy Suburban Cottage diff --git a/estate/models/__init__.py b/estate/models/__init__.py index 40092a2d810..c620ac481a3 100644 --- a/estate/models/__init__.py +++ b/estate/models/__init__.py @@ -1,2 +1,3 @@ from . import estate_property from . import estate_property_type +from . import estate_property_tag diff --git a/estate/models/estate_property.py b/estate/models/estate_property.py index c7880dd1d05..fa35efdc48a 100644 --- a/estate/models/estate_property.py +++ b/estate/models/estate_property.py @@ -23,6 +23,11 @@ def _default_Date(self): readonly=True, copy=False, ) + sales_man_id = fields.Many2one( + "res.users", string="Salesperson", default=lambda self: self.env.user + ) + property_tag_ids = fields.Many2many("estate.property.tag", "Tags") + buyer_id = fields.Many2one("res.partner", string="Buyer") active = fields.Boolean(string="Active", default=True) bedrooms = fields.Integer("Bedrooms", default=2) living_area = fields.Integer() diff --git a/estate/models/estate_property_tag.py b/estate/models/estate_property_tag.py new file mode 100644 index 00000000000..ae6c547e650 --- /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 = "Different Tags for Property" + + name = fields.Char("Tag") diff --git a/estate/security/ir.model.access.csv b/estate/security/ir.model.access.csv index 404965c040f..4735194fd1e 100644 --- a/estate/security/ir.model.access.csv +++ b/estate/security/ir.model.access.csv @@ -1,3 +1,4 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink access_estate_property,estate.property,model_estate_property,base.group_system,1,1,1,1 -estate.access_estate_porperty_type,access_estate_porperty_type,estate.model_estate_property_type,base.group_user,1,1,1,1 +estate.access_estate_porperty_type,access_estate_porperty_type,estate.model_estate_property_type,base.group_system,1,1,1,1 +estate.access_estate_porperty_tag,access_estate_porperty_tag,estate.model_estate_property_tag,base.group_system,1,1,1,1 diff --git a/estate/views/estate_menu.xml b/estate/views/estate_menu.xml index 4d7951e0226..4a0530077d7 100644 --- a/estate/views/estate_menu.xml +++ b/estate/views/estate_menu.xml @@ -9,5 +9,7 @@ + + diff --git a/estate/views/estate_property_views.xml b/estate/views/estate_property_views.xml index 9820c467234..1f1eb31c584 100644 --- a/estate/views/estate_property_views.xml +++ b/estate/views/estate_property_views.xml @@ -22,7 +22,12 @@ estate.property.type list,form - + + + Properties Tag + estate.property.tag + list,form + estate.property.list @@ -49,8 +54,11 @@ - + From 1fb607e83745d020619e8fecd0b33ccb6173351a Mon Sep 17 00:00:00 2001 From: "Aditya Maurya (adrma)" Date: Tue, 8 Sep 2026 17:13:15 +0530 Subject: [PATCH 11/11] [ADD] estate: add estate.property.offer model and offer_ids relationship - Create estate.property.offer model with price, status, partner_id, and property_id fields - Add One2many field offer_ids to estate.property - Add list and form views for property offers - Include offers tab in the estate property form view - Add security access rules for estate.property.offer in ir.model.access.csv --- estate/models/__init__.py | 1 + estate/models/estate_property.py | 3 ++- estate/models/estate_property_offer.py | 13 +++++++++++++ estate/security/ir.model.access.csv | 1 + 4 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 estate/models/estate_property_offer.py diff --git a/estate/models/__init__.py b/estate/models/__init__.py index c620ac481a3..2f1821a39c1 100644 --- a/estate/models/__init__.py +++ b/estate/models/__init__.py @@ -1,3 +1,4 @@ from . import estate_property from . import estate_property_type from . import estate_property_tag +from . import estate_property_offer diff --git a/estate/models/estate_property.py b/estate/models/estate_property.py index fa35efdc48a..90d5f490af4 100644 --- a/estate/models/estate_property.py +++ b/estate/models/estate_property.py @@ -26,8 +26,9 @@ def _default_Date(self): sales_man_id = fields.Many2one( "res.users", string="Salesperson", default=lambda self: self.env.user ) - property_tag_ids = fields.Many2many("estate.property.tag", "Tags") buyer_id = fields.Many2one("res.partner", string="Buyer") + property_tag_ids = fields.Many2many("estate.property.tag", string="Tags") + property_offer_id = fields.One2many("estate.property.offer", "property_id", "Offer") active = fields.Boolean(string="Active", default=True) bedrooms = fields.Integer("Bedrooms", default=2) living_area = fields.Integer() diff --git a/estate/models/estate_property_offer.py b/estate/models/estate_property_offer.py new file mode 100644 index 00000000000..0b691ec6c91 --- /dev/null +++ b/estate/models/estate_property_offer.py @@ -0,0 +1,13 @@ +from odoo import fields, models + + +class PropertyOffer(models.Model): + _name = "estate.property.offer" + _description = "Property Offer for Estate Property" + + price = fields.Float("Price", required=True) + status = fields.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/security/ir.model.access.csv b/estate/security/ir.model.access.csv index 4735194fd1e..38c56685bde 100644 --- a/estate/security/ir.model.access.csv +++ b/estate/security/ir.model.access.csv @@ -2,3 +2,4 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink access_estate_property,estate.property,model_estate_property,base.group_system,1,1,1,1 estate.access_estate_porperty_type,access_estate_porperty_type,estate.model_estate_property_type,base.group_system,1,1,1,1 estate.access_estate_porperty_tag,access_estate_porperty_tag,estate.model_estate_property_tag,base.group_system,1,1,1,1 +estate.access_estate_porperty_offer,access_estate_porperty_offer,estate.model_estate_property_offer,base.group_system,1,1,1,1