From 36e0588adcabb657c858baac5b6688e7bf134234 Mon Sep 17 00:00:00 2001 From: vikri-odoo Date: Tue, 16 Dec 2025 13:41:17 +0100 Subject: [PATCH 01/12] [ADD] new addon for real estate onboarding project --- real_estate/__init__.py | 1 + real_estate/__manifest__.py | 32 ++++++++++++++++++++++++ real_estate/data/res_estate_data.xml | 5 ++++ real_estate/models/__init__.py | 1 + real_estate/models/estate.py | 25 ++++++++++++++++++ real_estate/security/ir.model.access.csv | 2 ++ real_estate/views/estate_menu.xml | 9 +++++++ real_estate/views/estate_templates.xml | 10 ++++++++ website_airproof/data/presets.xml | 2 +- 9 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 real_estate/__init__.py create mode 100644 real_estate/__manifest__.py create mode 100644 real_estate/data/res_estate_data.xml create mode 100644 real_estate/models/__init__.py create mode 100644 real_estate/models/estate.py create mode 100644 real_estate/security/ir.model.access.csv create mode 100644 real_estate/views/estate_menu.xml create mode 100644 real_estate/views/estate_templates.xml diff --git a/real_estate/__init__.py b/real_estate/__init__.py new file mode 100644 index 00000000000..9a7e03eded3 --- /dev/null +++ b/real_estate/__init__.py @@ -0,0 +1 @@ +from . import models \ No newline at end of file diff --git a/real_estate/__manifest__.py b/real_estate/__manifest__.py new file mode 100644 index 00000000000..7e08b490fde --- /dev/null +++ b/real_estate/__manifest__.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- +{ + 'name': "Real Estate Application", + + 'summary': """ + This is a custom real estate application for understanding Odoo + """, + + 'description': """ + This is a custom real estate application for understanding Odoo + """, + + 'author': "Odoo S.A.", + 'website': "https://www.odoo.com", + + # Categories can be used to filter modules in modules listing + # Check https://github.com/odoo/odoo/blob/15.0/odoo/addons/base/data/ir_module_category_data.xml + # for the full list + 'category': 'Tutorials', + 'version': '0.1', + + 'application': True, + 'installable': True, + 'data': [ + "security/ir.model.access.csv", + "views/estate_templates.xml", + "views/estate_menu.xml", + ], + 'assets': { + }, + 'license': 'AGPL-3' +} diff --git a/real_estate/data/res_estate_data.xml b/real_estate/data/res_estate_data.xml new file mode 100644 index 00000000000..3fc307ed2ba --- /dev/null +++ b/real_estate/data/res_estate_data.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/real_estate/models/__init__.py b/real_estate/models/__init__.py new file mode 100644 index 00000000000..912e8d6a61f --- /dev/null +++ b/real_estate/models/__init__.py @@ -0,0 +1 @@ +from . import estate \ No newline at end of file diff --git a/real_estate/models/estate.py b/real_estate/models/estate.py new file mode 100644 index 00000000000..687e71b7501 --- /dev/null +++ b/real_estate/models/estate.py @@ -0,0 +1,25 @@ +from odoo import fields, models + + +class Estate(models.Model): + _name = 'estate' + _description = 'Real_Estate' + + name = fields.Char(string="Name", required=True) + description = fields.Text(string="Description") + postcode = fields.Char(string="Postcode") + date_availability = fields.Datetime(string="Date Availability") + expected_price = fields.Float(string="Expected Price", required=True) + selling_price = fields.Float(string="Selling Price") + bedrooms = fields.Integer(string="Bedrooms") + living_area = fields.Integer(string="Living Area") + facades = fields.Integer(string="Facades") + garage = fields.Boolean(string="Garage") + garden = fields.Boolean(string="Garden") + garden_area = fields.Integer(string="Garden Area") + garden_orientation = fields.Selection([ + ('north', 'North'), + ('south', 'South'), + ('east', 'East'), + ('west', 'West'), + ]) \ No newline at end of file diff --git a/real_estate/security/ir.model.access.csv b/real_estate/security/ir.model.access.csv new file mode 100644 index 00000000000..40478cb571a --- /dev/null +++ b/real_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,access.estate,model_estate,base.group_user,1,1,1,1 \ No newline at end of file diff --git a/real_estate/views/estate_menu.xml b/real_estate/views/estate_menu.xml new file mode 100644 index 00000000000..f1b0aec6b5d --- /dev/null +++ b/real_estate/views/estate_menu.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/real_estate/views/estate_templates.xml b/real_estate/views/estate_templates.xml new file mode 100644 index 00000000000..85c0b1a029d --- /dev/null +++ b/real_estate/views/estate_templates.xml @@ -0,0 +1,10 @@ + + + + + Real Estate + estate + list,form + + + diff --git a/website_airproof/data/presets.xml b/website_airproof/data/presets.xml index e4b3637a101..3b4445d25b1 100644 --- a/website_airproof/data/presets.xml +++ b/website_airproof/data/presets.xml @@ -49,7 +49,7 @@ - + From 528b3cf6c3e68d9851927685ef6070d84c2617b3 Mon Sep 17 00:00:00 2001 From: vikri-odoo Date: Wed, 17 Dec 2025 13:41:51 +0100 Subject: [PATCH 02/12] [ADD] add the new model for property types Completed till chapter 7 many to one --- real_estate/__manifest__.py | 21 ++--- real_estate/data/res_estate_data.xml | 53 ++++++++++- real_estate/models/__init__.py | 3 +- real_estate/models/estate.py | 25 ------ real_estate/models/estate_property.py | 42 +++++++++ real_estate/models/estate_property_type.py | 8 ++ real_estate/security/ir.model.access.csv | 3 +- real_estate/views/estate_menu.xml | 16 ++-- .../views/estate_property_templates.xml | 89 +++++++++++++++++++ .../views/estate_property_type_templates.xml | 17 ++++ real_estate/views/estate_templates.xml | 10 --- website_airproof/data/presets.xml | 2 +- 12 files changed, 227 insertions(+), 62 deletions(-) delete mode 100644 real_estate/models/estate.py create mode 100644 real_estate/models/estate_property.py create mode 100644 real_estate/models/estate_property_type.py create mode 100644 real_estate/views/estate_property_templates.xml create mode 100644 real_estate/views/estate_property_type_templates.xml delete mode 100644 real_estate/views/estate_templates.xml diff --git a/real_estate/__manifest__.py b/real_estate/__manifest__.py index 7e08b490fde..6db5cf37332 100644 --- a/real_estate/__manifest__.py +++ b/real_estate/__manifest__.py @@ -1,29 +1,18 @@ # -*- coding: utf-8 -*- { 'name': "Real Estate Application", - - 'summary': """ - This is a custom real estate application for understanding Odoo - """, - - 'description': """ - This is a custom real estate application for understanding Odoo - """, - + 'summary': "This is a custom real estate application for understanding Odoo", + 'description': "This is a custom real estate application for understanding Odoo", 'author': "Odoo S.A.", 'website': "https://www.odoo.com", - - # Categories can be used to filter modules in modules listing - # Check https://github.com/odoo/odoo/blob/15.0/odoo/addons/base/data/ir_module_category_data.xml - # for the full list 'category': 'Tutorials', 'version': '0.1', - 'application': True, - 'installable': True, 'data': [ + "data/res_estate_data.xml", "security/ir.model.access.csv", - "views/estate_templates.xml", + "views/estate_property_templates.xml", + "views/estate_property_type_templates.xml", "views/estate_menu.xml", ], 'assets': { diff --git a/real_estate/data/res_estate_data.xml b/real_estate/data/res_estate_data.xml index 3fc307ed2ba..df1226e7339 100644 --- a/real_estate/data/res_estate_data.xml +++ b/real_estate/data/res_estate_data.xml @@ -1,5 +1,56 @@ - + + + Property 1 + Description 1 + 1000 + + 10000 + 9000 + True + 2 + 2 + 2 + True + True + 22 + new + north + + + Property 2 + Description 2 + 2000 + + 10000 + 9000 + True + 2 + 2 + 2 + True + True + 22 + new + north + + + Property 3 + Description 3 + 1040 + + 10000 + 9000 + True + 2 + 2 + 2 + True + True + 22 + new + north + \ No newline at end of file diff --git a/real_estate/models/__init__.py b/real_estate/models/__init__.py index 912e8d6a61f..97aee757823 100644 --- a/real_estate/models/__init__.py +++ b/real_estate/models/__init__.py @@ -1 +1,2 @@ -from . import estate \ No newline at end of file +from . import estate_property +from . import estate_property_type \ No newline at end of file diff --git a/real_estate/models/estate.py b/real_estate/models/estate.py deleted file mode 100644 index 687e71b7501..00000000000 --- a/real_estate/models/estate.py +++ /dev/null @@ -1,25 +0,0 @@ -from odoo import fields, models - - -class Estate(models.Model): - _name = 'estate' - _description = 'Real_Estate' - - name = fields.Char(string="Name", required=True) - description = fields.Text(string="Description") - postcode = fields.Char(string="Postcode") - date_availability = fields.Datetime(string="Date Availability") - expected_price = fields.Float(string="Expected Price", required=True) - selling_price = fields.Float(string="Selling Price") - bedrooms = fields.Integer(string="Bedrooms") - living_area = fields.Integer(string="Living Area") - facades = fields.Integer(string="Facades") - garage = fields.Boolean(string="Garage") - garden = fields.Boolean(string="Garden") - garden_area = fields.Integer(string="Garden Area") - garden_orientation = fields.Selection([ - ('north', 'North'), - ('south', 'South'), - ('east', 'East'), - ('west', 'West'), - ]) \ No newline at end of file diff --git a/real_estate/models/estate_property.py b/real_estate/models/estate_property.py new file mode 100644 index 00000000000..b7e26defc5b --- /dev/null +++ b/real_estate/models/estate_property.py @@ -0,0 +1,42 @@ +from datetime import date + +from dateutil.relativedelta import relativedelta +from odoo import fields, models + + +def _set_default_start_date(): + return date.today() + relativedelta(months=3) + + +class Estate(models.Model): + _name = "estate.property" + _description = "Real_Estate_Property" + + name = fields.Char(string="Name", required=True) + description = fields.Text(string="Description") + postcode = fields.Char(string="Postcode") + date_availability = fields.Datetime(string="Date Availability", default=_set_default_start_date(), copy=False) + expected_price = fields.Float(string="Expected Price", required=True) + selling_price = fields.Float(string="Selling Price", readonly=True, copy=False) + active = fields.Boolean(string="Active", default=True) + bedrooms = fields.Integer(string="Bedrooms", default=2) + living_area = fields.Integer(string="Living Area") + facades = fields.Integer(string="Facades") + garage = fields.Boolean(string="Garage") + garden = fields.Boolean(string="Garden") + garden_area = fields.Integer(string="Garden Area") + state = fields.Selection(string="State", selection=[ + ('new', 'New'), + ('offered', 'Offer Received'), + ('accepted', 'Offer Accepted'), + ('sold', 'Sold'), + ('cancelled', 'Cancelled'), + ], required=True, copy=False) + garden_orientation = fields.Selection([ + ('north', 'North'), + ('south', 'South'), + ('east', 'East'), + ('west', 'West'), + ]) + sales_person = fields.Many2one('res.users', string="Sales Person", copy=False, default=lambda self: self.env.user) + buyer = fields.Many2one('res.partner', string="Buyer") \ No newline at end of file diff --git a/real_estate/models/estate_property_type.py b/real_estate/models/estate_property_type.py new file mode 100644 index 00000000000..f9e11b60955 --- /dev/null +++ b/real_estate/models/estate_property_type.py @@ -0,0 +1,8 @@ +from odoo import fields, models + + +class EstatePropertyType(models.Model): + _name = "estate.property.type" + _description = "Real Estate Property Type" + + name = fields.Char(string="Name", required=True) \ No newline at end of file diff --git a/real_estate/security/ir.model.access.csv b/real_estate/security/ir.model.access.csv index 40478cb571a..0fff7b7f660 100644 --- a/real_estate/security/ir.model.access.csv +++ b/real_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,access.estate,model_estate,base.group_user,1,1,1,1 \ No newline at end of file +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 \ No newline at end of file diff --git a/real_estate/views/estate_menu.xml b/real_estate/views/estate_menu.xml index f1b0aec6b5d..6369ff0f96b 100644 --- a/real_estate/views/estate_menu.xml +++ b/real_estate/views/estate_menu.xml @@ -1,9 +1,11 @@ - - - - - - - + + + + \ No newline at end of file diff --git a/real_estate/views/estate_property_templates.xml b/real_estate/views/estate_property_templates.xml new file mode 100644 index 00000000000..a54f401a485 --- /dev/null +++ b/real_estate/views/estate_property_templates.xml @@ -0,0 +1,89 @@ + + + + + Properties + estate.property + list,form,search + + + + estate.property.list + estate.property + + + + + + + + + + + + estate.property.form + estate.property + +
+ + + +

+ Primary Details +

+ + + + +

+ Property Details +

+ + + + + + + + + + +

+ Availability Details +

+ + + + + + + +
+ + + + + + +
+
+
+
+
+ + estate.property.search + estate.property + + + + + + + + + + + + + +
\ No newline at end of file diff --git a/real_estate/views/estate_property_type_templates.xml b/real_estate/views/estate_property_type_templates.xml new file mode 100644 index 00000000000..f24117bc561 --- /dev/null +++ b/real_estate/views/estate_property_type_templates.xml @@ -0,0 +1,17 @@ + + + + Property Types + estate.property.type + list,form,search + + + estate.property.type.list + estate.property.type + + + + + + + \ No newline at end of file diff --git a/real_estate/views/estate_templates.xml b/real_estate/views/estate_templates.xml deleted file mode 100644 index 85c0b1a029d..00000000000 --- a/real_estate/views/estate_templates.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - Real Estate - estate - list,form - - - diff --git a/website_airproof/data/presets.xml b/website_airproof/data/presets.xml index 3b4445d25b1..e4b3637a101 100644 --- a/website_airproof/data/presets.xml +++ b/website_airproof/data/presets.xml @@ -49,7 +49,7 @@ - + From abc57b5db909026184dcb73b278ec7ab2c9a549d Mon Sep 17 00:00:00 2001 From: vikri-odoo Date: Wed, 17 Dec 2025 21:43:49 +0100 Subject: [PATCH 03/12] [LINT] format the code using ruff Added new tags model to understand many2many --- real_estate/__init__.py | 2 +- real_estate/__manifest__.py | 24 +++++----- real_estate/data/res_estate_data.xml | 6 +-- real_estate/models/__init__.py | 3 +- real_estate/models/estate_property.py | 47 ++++++++++++------- real_estate/models/estate_property_tags.py | 8 ++++ real_estate/models/estate_property_type.py | 2 +- real_estate/security/ir.model.access.csv | 3 +- real_estate/views/estate_menu.xml | 11 +++-- .../views/estate_property_tags_templates.xml | 17 +++++++ .../views/estate_property_templates.xml | 45 +++++++++--------- 11 files changed, 106 insertions(+), 62 deletions(-) create mode 100644 real_estate/models/estate_property_tags.py create mode 100644 real_estate/views/estate_property_tags_templates.xml diff --git a/real_estate/__init__.py b/real_estate/__init__.py index 9a7e03eded3..0650744f6bc 100644 --- a/real_estate/__init__.py +++ b/real_estate/__init__.py @@ -1 +1 @@ -from . import models \ No newline at end of file +from . import models diff --git a/real_estate/__manifest__.py b/real_estate/__manifest__.py index 6db5cf37332..22e37519acc 100644 --- a/real_estate/__manifest__.py +++ b/real_estate/__manifest__.py @@ -1,21 +1,21 @@ # -*- coding: utf-8 -*- { - 'name': "Real Estate Application", - 'summary': "This is a custom real estate application for understanding Odoo", - 'description': "This is a custom real estate application for understanding Odoo", - 'author': "Odoo S.A.", - 'website': "https://www.odoo.com", - 'category': 'Tutorials', - 'version': '0.1', - 'application': True, - 'data': [ + "name": "Real Estate Application", + "summary": "This is a custom real estate application for understanding Odoo", + "description": "This is a custom real estate application for understanding Odoo", + "author": "Odoo S.A.", + "website": "https://www.odoo.com", + "category": "Tutorials", + "version": "0.1", + "application": True, + "data": [ "data/res_estate_data.xml", "security/ir.model.access.csv", "views/estate_property_templates.xml", "views/estate_property_type_templates.xml", + "views/estate_property_tags_templates.xml", "views/estate_menu.xml", ], - 'assets': { - }, - 'license': 'AGPL-3' + "assets": {}, + "license": "AGPL-3", } diff --git a/real_estate/data/res_estate_data.xml b/real_estate/data/res_estate_data.xml index df1226e7339..678cde98b57 100644 --- a/real_estate/data/res_estate_data.xml +++ b/real_estate/data/res_estate_data.xml @@ -5,7 +5,7 @@ Property 1 Description 1 1000 - + 10000 9000 True @@ -22,7 +22,7 @@ Property 2 Description 2 2000 - + 10000 9000 True @@ -39,7 +39,7 @@ Property 3 Description 3 1040 - + 10000 9000 True diff --git a/real_estate/models/__init__.py b/real_estate/models/__init__.py index 97aee757823..337c9c6647d 100644 --- a/real_estate/models/__init__.py +++ b/real_estate/models/__init__.py @@ -1,2 +1,3 @@ from . import estate_property -from . import estate_property_type \ No newline at end of file +from . import estate_property_type +from . import estate_property_tags diff --git a/real_estate/models/estate_property.py b/real_estate/models/estate_property.py index b7e26defc5b..ba344c362aa 100644 --- a/real_estate/models/estate_property.py +++ b/real_estate/models/estate_property.py @@ -15,7 +15,9 @@ class Estate(models.Model): name = fields.Char(string="Name", required=True) description = fields.Text(string="Description") postcode = fields.Char(string="Postcode") - date_availability = fields.Datetime(string="Date Availability", default=_set_default_start_date(), copy=False) + date_availability = fields.Datetime( + string="Date Availability", default=_set_default_start_date(), copy=False + ) expected_price = fields.Float(string="Expected Price", required=True) selling_price = fields.Float(string="Selling Price", readonly=True, copy=False) active = fields.Boolean(string="Active", default=True) @@ -25,18 +27,31 @@ class Estate(models.Model): garage = fields.Boolean(string="Garage") garden = fields.Boolean(string="Garden") garden_area = fields.Integer(string="Garden Area") - state = fields.Selection(string="State", selection=[ - ('new', 'New'), - ('offered', 'Offer Received'), - ('accepted', 'Offer Accepted'), - ('sold', 'Sold'), - ('cancelled', 'Cancelled'), - ], required=True, copy=False) - garden_orientation = fields.Selection([ - ('north', 'North'), - ('south', 'South'), - ('east', 'East'), - ('west', 'West'), - ]) - sales_person = fields.Many2one('res.users', string="Sales Person", copy=False, default=lambda self: self.env.user) - buyer = fields.Many2one('res.partner', string="Buyer") \ No newline at end of file + state = fields.Selection( + string="State", + selection=[ + ("new", "New"), + ("offered", "Offer Received"), + ("accepted", "Offer Accepted"), + ("sold", "Sold"), + ("cancelled", "Cancelled"), + ], + required=True, + copy=False, + ) + garden_orientation = fields.Selection( + [ + ("north", "North"), + ("south", "South"), + ("east", "East"), + ("west", "West"), + ] + ) + sales_person = fields.Many2one( + "res.users", + string="Sales Person", + copy=False, + default=lambda self: self.env.user, + ) + buyer = fields.Many2one("res.partner", string="Buyer") + tags = fields.Many2many("estate.property.tags", string="Tags") diff --git a/real_estate/models/estate_property_tags.py b/real_estate/models/estate_property_tags.py new file mode 100644 index 00000000000..e483cd230fe --- /dev/null +++ b/real_estate/models/estate_property_tags.py @@ -0,0 +1,8 @@ +from odoo import fields, models + + +class EstatePropertyTags(models.Model): + _name = "estate.property.tags" + _description = "Real Estate Property Tags" + + name = fields.Char(string="Name", required=True) diff --git a/real_estate/models/estate_property_type.py b/real_estate/models/estate_property_type.py index f9e11b60955..4df188f53dc 100644 --- a/real_estate/models/estate_property_type.py +++ b/real_estate/models/estate_property_type.py @@ -5,4 +5,4 @@ class EstatePropertyType(models.Model): _name = "estate.property.type" _description = "Real Estate Property Type" - name = fields.Char(string="Name", required=True) \ No newline at end of file + name = fields.Char(string="Name", required=True) diff --git a/real_estate/security/ir.model.access.csv b/real_estate/security/ir.model.access.csv index 0fff7b7f660..9155dae334a 100644 --- a/real_estate/security/ir.model.access.csv +++ b/real_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,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 \ No newline at end of file +access_estate_property_type,access.estate.property.type,model_estate_property_type,base.group_user,1,1,1,1 +access_estate_property_tags,access.estate.property.tags,model_estate_property_tags,base.group_user,1,1,1,1 \ No newline at end of file diff --git a/real_estate/views/estate_menu.xml b/real_estate/views/estate_menu.xml index 6369ff0f96b..ec1f2f01d17 100644 --- a/real_estate/views/estate_menu.xml +++ b/real_estate/views/estate_menu.xml @@ -1,11 +1,12 @@ - - + - - + /> + + + \ No newline at end of file diff --git a/real_estate/views/estate_property_tags_templates.xml b/real_estate/views/estate_property_tags_templates.xml new file mode 100644 index 00000000000..5d5e594738d --- /dev/null +++ b/real_estate/views/estate_property_tags_templates.xml @@ -0,0 +1,17 @@ + + + + Property Tags + estate.property.tags + list,form + + + estate.property.tags.list + estate.property.tags + + + + + + + \ No newline at end of file diff --git a/real_estate/views/estate_property_templates.xml b/real_estate/views/estate_property_templates.xml index a54f401a485..0444cb240a5 100644 --- a/real_estate/views/estate_property_templates.xml +++ b/real_estate/views/estate_property_templates.xml @@ -1,25 +1,25 @@ - + Properties estate.property list,form,search - + estate.property.list estate.property - - - + + + - + estate.property.form estate.property @@ -34,34 +34,35 @@ +

Property Details

- - - - - - - - + + + + + + + +

Availability Details

- - - - - + + + + + - + @@ -76,10 +77,10 @@ - + - + From 247d7ca693b11ab601dfbe9739146586a5bfe237 Mon Sep 17 00:00:00 2001 From: vikri-odoo Date: Thu, 18 Dec 2025 10:00:05 +0100 Subject: [PATCH 04/12] [REF] address the PR comments and resole it Check the style guide and resolve the issues --- real_estate/__manifest__.py | 1 - real_estate/data/res_estate_data.xml | 3 -- real_estate/models/estate_property.py | 32 +++++++++---------- real_estate/security/ir.model.access.csv | 2 +- real_estate/views/estate_menu.xml | 7 +--- .../views/estate_property_templates.xml | 3 -- 6 files changed, 17 insertions(+), 31 deletions(-) diff --git a/real_estate/__manifest__.py b/real_estate/__manifest__.py index 22e37519acc..23b772cb9d0 100644 --- a/real_estate/__manifest__.py +++ b/real_estate/__manifest__.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- { "name": "Real Estate Application", "summary": "This is a custom real estate application for understanding Odoo", diff --git a/real_estate/data/res_estate_data.xml b/real_estate/data/res_estate_data.xml index 678cde98b57..a36472d5ec7 100644 --- a/real_estate/data/res_estate_data.xml +++ b/real_estate/data/res_estate_data.xml @@ -5,7 +5,6 @@ Property 1 Description 1 1000 - 10000 9000 True @@ -22,7 +21,6 @@ Property 2 Description 2 2000 - 10000 9000 True @@ -39,7 +37,6 @@ Property 3 Description 3 1040 - 10000 9000 True diff --git a/real_estate/models/estate_property.py b/real_estate/models/estate_property.py index ba344c362aa..a2502110405 100644 --- a/real_estate/models/estate_property.py +++ b/real_estate/models/estate_property.py @@ -4,10 +4,6 @@ from odoo import fields, models -def _set_default_start_date(): - return date.today() + relativedelta(months=3) - - class Estate(models.Model): _name = "estate.property" _description = "Real_Estate_Property" @@ -16,7 +12,9 @@ class Estate(models.Model): description = fields.Text(string="Description") postcode = fields.Char(string="Postcode") date_availability = fields.Datetime( - string="Date Availability", default=_set_default_start_date(), copy=False + string="Date Availability", + default=lambda: date.today() + relativedelta(months=3), + copy=False, ) expected_price = fields.Float(string="Expected Price", required=True) selling_price = fields.Float(string="Selling Price", readonly=True, copy=False) @@ -30,28 +28,28 @@ class Estate(models.Model): state = fields.Selection( string="State", selection=[ - ("new", "New"), - ("offered", "Offer Received"), - ("accepted", "Offer Accepted"), - ("sold", "Sold"), - ("cancelled", "Cancelled"), + ('new', "New"), + ('offered', "Offer Received"), + ('accepted', "Offer Accepted"), + ('sold', "Sold"), + ('cancelled', "Cancelled"), ], required=True, copy=False, ) garden_orientation = fields.Selection( [ - ("north", "North"), - ("south", "South"), - ("east", "East"), - ("west", "West"), + ('north', "North"), + ('south', "South"), + ('east', "East"), + ('west', "West"), ] ) sales_person = fields.Many2one( - "res.users", + 'res.users', string="Sales Person", copy=False, default=lambda self: self.env.user, ) - buyer = fields.Many2one("res.partner", string="Buyer") - tags = fields.Many2many("estate.property.tags", string="Tags") + buyer = fields.Many2one('res.partner', string="Buyer") + tags = fields.Many2many('estate.property.tags', string="Tags") diff --git a/real_estate/security/ir.model.access.csv b/real_estate/security/ir.model.access.csv index 9155dae334a..a083e598e79 100644 --- a/real_estate/security/ir.model.access.csv +++ b/real_estate/security/ir.model.access.csv @@ -1,4 +1,4 @@ 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_tags,access.estate.property.tags,model_estate_property_tags,base.group_user,1,1,1,1 \ No newline at end of file +access_estate_property_tags,access.estate.property.tags,model_estate_property_tags,base.group_user,1,1,1,1 diff --git a/real_estate/views/estate_menu.xml b/real_estate/views/estate_menu.xml index ec1f2f01d17..f044e6b570a 100644 --- a/real_estate/views/estate_menu.xml +++ b/real_estate/views/estate_menu.xml @@ -1,11 +1,6 @@ - + diff --git a/real_estate/views/estate_property_templates.xml b/real_estate/views/estate_property_templates.xml index 0444cb240a5..eb49af18f8b 100644 --- a/real_estate/views/estate_property_templates.xml +++ b/real_estate/views/estate_property_templates.xml @@ -1,12 +1,10 @@ - Properties estate.property list,form,search - estate.property.list estate.property @@ -19,7 +17,6 @@
- estate.property.form estate.property From 66c0381865cc72c2da66db9ffe37bf6dc0de4111 Mon Sep 17 00:00:00 2001 From: vikri-odoo Date: Thu, 18 Dec 2025 10:17:20 +0100 Subject: [PATCH 05/12] [REF] update the default availability method to lamda --- real_estate/data/res_estate_data.xml | 2 +- real_estate/models/estate_property.py | 2 +- real_estate/views/estate_menu.xml | 2 +- real_estate/views/estate_property_tags_templates.xml | 2 +- real_estate/views/estate_property_templates.xml | 2 +- real_estate/views/estate_property_type_templates.xml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/real_estate/data/res_estate_data.xml b/real_estate/data/res_estate_data.xml index a36472d5ec7..eb829a764c0 100644 --- a/real_estate/data/res_estate_data.xml +++ b/real_estate/data/res_estate_data.xml @@ -50,4 +50,4 @@ north -
\ No newline at end of file + diff --git a/real_estate/models/estate_property.py b/real_estate/models/estate_property.py index a2502110405..b9af96cbe3f 100644 --- a/real_estate/models/estate_property.py +++ b/real_estate/models/estate_property.py @@ -13,7 +13,7 @@ class Estate(models.Model): postcode = fields.Char(string="Postcode") date_availability = fields.Datetime( string="Date Availability", - default=lambda: date.today() + relativedelta(months=3), + default=lambda self: date.today() + relativedelta(months=3), copy=False, ) expected_price = fields.Float(string="Expected Price", required=True) diff --git a/real_estate/views/estate_menu.xml b/real_estate/views/estate_menu.xml index f044e6b570a..925907a4c07 100644 --- a/real_estate/views/estate_menu.xml +++ b/real_estate/views/estate_menu.xml @@ -4,4 +4,4 @@ - \ No newline at end of file + diff --git a/real_estate/views/estate_property_tags_templates.xml b/real_estate/views/estate_property_tags_templates.xml index 5d5e594738d..424f7870fe8 100644 --- a/real_estate/views/estate_property_tags_templates.xml +++ b/real_estate/views/estate_property_tags_templates.xml @@ -14,4 +14,4 @@
- \ No newline at end of file + diff --git a/real_estate/views/estate_property_templates.xml b/real_estate/views/estate_property_templates.xml index eb49af18f8b..86660084222 100644 --- a/real_estate/views/estate_property_templates.xml +++ b/real_estate/views/estate_property_templates.xml @@ -84,4 +84,4 @@
- \ No newline at end of file + diff --git a/real_estate/views/estate_property_type_templates.xml b/real_estate/views/estate_property_type_templates.xml index f24117bc561..df24c1412fc 100644 --- a/real_estate/views/estate_property_type_templates.xml +++ b/real_estate/views/estate_property_type_templates.xml @@ -14,4 +14,4 @@
- \ No newline at end of file + From d00c06f27bd676262f151d1e9e2d5ab24742dfd7 Mon Sep 17 00:00:00 2001 From: vikri-odoo Date: Thu, 18 Dec 2025 12:26:48 +0100 Subject: [PATCH 06/12] [ADD] created new model for estate offers 1.create new model and view for offers 2.complete chapter 7 --- real_estate/data/res_estate_data.xml | 18 ++++++++++++--- real_estate/models/__init__.py | 1 + real_estate/models/estate_property.py | 5 +++++ real_estate/models/estate_property_offers.py | 22 +++++++++++++++++++ real_estate/security/ir.model.access.csv | 1 + .../views/estate_property_offer_templates.xml | 14 ++++++++++++ .../views/estate_property_templates.xml | 6 +++++ 7 files changed, 64 insertions(+), 3 deletions(-) create mode 100644 real_estate/models/estate_property_offers.py create mode 100644 real_estate/views/estate_property_offer_templates.xml diff --git a/real_estate/data/res_estate_data.xml b/real_estate/data/res_estate_data.xml index eb829a764c0..5ec21f95a3e 100644 --- a/real_estate/data/res_estate_data.xml +++ b/real_estate/data/res_estate_data.xml @@ -1,7 +1,10 @@ - + + House + + Property 1 Description 1 1000 @@ -16,8 +19,12 @@ 22 new north + + + + Apartment - + Property 2 Description 2 2000 @@ -32,8 +39,12 @@ 22 new north + + + + Castle - + Property 3 Description 3 1040 @@ -48,6 +59,7 @@ 22 new north + diff --git a/real_estate/models/__init__.py b/real_estate/models/__init__.py index 337c9c6647d..3ed85a6943c 100644 --- a/real_estate/models/__init__.py +++ b/real_estate/models/__init__.py @@ -1,3 +1,4 @@ from . import estate_property from . import estate_property_type from . import estate_property_tags +from . import estate_property_offers diff --git a/real_estate/models/estate_property.py b/real_estate/models/estate_property.py index b9af96cbe3f..f41ce95e61f 100644 --- a/real_estate/models/estate_property.py +++ b/real_estate/models/estate_property.py @@ -52,4 +52,9 @@ class Estate(models.Model): default=lambda self: self.env.user, ) buyer = fields.Many2one('res.partner', string="Buyer") + property_type = fields.Many2one( + comodel_name="estate.property.type", + String="Property Type", + ) tags = fields.Many2many('estate.property.tags', string="Tags") + offer_ids = fields.One2many('estate.property.offers', 'property_id', string="Offers") diff --git a/real_estate/models/estate_property_offers.py b/real_estate/models/estate_property_offers.py new file mode 100644 index 00000000000..4bb7deb930c --- /dev/null +++ b/real_estate/models/estate_property_offers.py @@ -0,0 +1,22 @@ +from odoo import fields, models + + +class EstatePropertyOffers(models.Model): + _name = "estate.property.offers" + _description = "Real Estate Property Offers" + + price = fields.Float(string="Price") + status = fields.Selection( + string="Status", + selection=[('accepted', "Accepted"), ('rejected', "Rejected")], + required=True, + copy=False, + ) + partner_id = fields.Many2one( + comodel_name='res.partner', + required=True, + ) + property_id = fields.Many2one( + comodel_name='estate.property', + required=True, + ) diff --git a/real_estate/security/ir.model.access.csv b/real_estate/security/ir.model.access.csv index a083e598e79..58710e125d0 100644 --- a/real_estate/security/ir.model.access.csv +++ b/real_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,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_tags,access.estate.property.tags,model_estate_property_tags,base.group_user,1,1,1,1 +access_estate_property_offers,access.estate.property.offers,model_estate_property_offers,base.group_user,1,1,1,1 diff --git a/real_estate/views/estate_property_offer_templates.xml b/real_estate/views/estate_property_offer_templates.xml new file mode 100644 index 00000000000..2086c5ef621 --- /dev/null +++ b/real_estate/views/estate_property_offer_templates.xml @@ -0,0 +1,14 @@ + + + + estate.property.offer.list + estate.property.offer + + + + + + + + + diff --git a/real_estate/views/estate_property_templates.xml b/real_estate/views/estate_property_templates.xml index 86660084222..fb9bf746d14 100644 --- a/real_estate/views/estate_property_templates.xml +++ b/real_estate/views/estate_property_templates.xml @@ -37,6 +37,7 @@ Property Details + @@ -63,6 +64,11 @@ + + + + + From 484f590f8c91c5d381a741a2807d27095ac79a15 Mon Sep 17 00:00:00 2001 From: vikri-odoo Date: Fri, 19 Dec 2025 09:10:29 +0100 Subject: [PATCH 07/12] [ADD] chapter 9: action added for buttons 1. Sold and cancel button and actions added 2. Accept and reject button added with actions for offers --- real_estate/__manifest__.py | 1 + real_estate/data/res_estate_data.xml | 54 ++++++++++++++++--- real_estate/models/estate_property.py | 44 ++++++++++++++- real_estate/models/estate_property_offers.py | 35 ++++++++---- .../views/estate_property_offer_templates.xml | 14 ----- .../estate_property_offers_templates.xml | 16 ++++++ .../views/estate_property_templates.xml | 7 +++ 7 files changed, 140 insertions(+), 31 deletions(-) delete mode 100644 real_estate/views/estate_property_offer_templates.xml create mode 100644 real_estate/views/estate_property_offers_templates.xml diff --git a/real_estate/__manifest__.py b/real_estate/__manifest__.py index 23b772cb9d0..6f6773a04f3 100644 --- a/real_estate/__manifest__.py +++ b/real_estate/__manifest__.py @@ -13,6 +13,7 @@ "views/estate_property_templates.xml", "views/estate_property_type_templates.xml", "views/estate_property_tags_templates.xml", + "views/estate_property_offers_templates.xml", "views/estate_menu.xml", ], "assets": {}, diff --git a/real_estate/data/res_estate_data.xml b/real_estate/data/res_estate_data.xml index 5ec21f95a3e..5f72f31c6ed 100644 --- a/real_estate/data/res_estate_data.xml +++ b/real_estate/data/res_estate_data.xml @@ -4,6 +4,12 @@ House + + Apartment + + + Castle + Property 1 Description 1 @@ -20,9 +26,26 @@ new north - - - Apartment + + + + + + + + + + + 20000.00 + accepted + + + + 10000.00 + rejected + + + Property 2 @@ -40,9 +63,23 @@ new north - - - Castle + + + + + + + + 20000.00 + accepted + + + + 10000.00 + rejected + + + Property 3 @@ -60,6 +97,11 @@ new north + + + + + diff --git a/real_estate/models/estate_property.py b/real_estate/models/estate_property.py index f41ce95e61f..4297fe91526 100644 --- a/real_estate/models/estate_property.py +++ b/real_estate/models/estate_property.py @@ -1,7 +1,8 @@ from datetime import date from dateutil.relativedelta import relativedelta -from odoo import fields, models +from odoo import api, fields, models +from odoo.exceptions import UserError class Estate(models.Model): @@ -11,7 +12,7 @@ class Estate(models.Model): name = fields.Char(string="Name", required=True) description = fields.Text(string="Description") postcode = fields.Char(string="Postcode") - date_availability = fields.Datetime( + date_availability = fields.Date( string="Date Availability", default=lambda self: date.today() + relativedelta(months=3), copy=False, @@ -58,3 +59,42 @@ class Estate(models.Model): ) tags = fields.Many2many('estate.property.tags', string="Tags") offer_ids = fields.One2many('estate.property.offers', 'property_id', string="Offers") + total_area = fields.Integer(compute='_compute_total_area') + best_offer = fields.Float(compute='_compute_best_offer') + + @api.depends('living_area', 'garden_area') + def _compute_total_area(self): + for record in self: + record.total_area = record.living_area + record.garden_area + + @api.depends('offer_ids') + def _compute_best_offer(self): + for record in self: + offers = record.offer_ids.mapped('price') + if offers: + record.best_offer = max(offers) + else: + record.best_offer = 0.0 + + @api.onchange('garden') + def _onchange_garden(self): + if self.garden: + self.garden_area = 10 + self.garden_orientation = 'north' + else: + self.garden_area = 0 + self.garden_orientation = 0 + + def action_set_sold(self): + for record in self: + if record.state == 'cancelled': + raise UserError("This property cannot be sold.") + record.state = 'sold' + return True + + def action_set_cancel(self): + for record in self: + if record.state == 'sold': + raise UserError("This property is sold.") + record.state = 'cancelled' + return True diff --git a/real_estate/models/estate_property_offers.py b/real_estate/models/estate_property_offers.py index 4bb7deb930c..d4bb0ad247d 100644 --- a/real_estate/models/estate_property_offers.py +++ b/real_estate/models/estate_property_offers.py @@ -1,4 +1,7 @@ -from odoo import fields, models +from datetime import date + +from dateutil.relativedelta import relativedelta +from odoo import api, fields, models class EstatePropertyOffers(models.Model): @@ -12,11 +15,25 @@ class EstatePropertyOffers(models.Model): required=True, copy=False, ) - partner_id = fields.Many2one( - comodel_name='res.partner', - required=True, - ) - property_id = fields.Many2one( - comodel_name='estate.property', - required=True, - ) + partner_id = fields.Many2one(comodel_name='res.partner',required=True) + property_id = fields.Many2one(comodel_name='estate.property',required=True) + validity = fields.Integer(string="Validity", default=7) + date_deadline = fields.Date(compute='_compute_date_deadline') + + @api.depends('create_date','validity') + def _compute_date_deadline(self): + for record in self: + start_date = record.create_date if record.create_date else date.today() + record.date_deadline = start_date + relativedelta(days=record.validity) + + def action_accept_offer(self): + for record in self: + record.status = 'accepted' + record.property_id.buyer = record.partner_id + record.property_id.selling_price = record.price + return True + + def action_reject_offer(self): + for record in self: + record.status = 'rejected' + return True diff --git a/real_estate/views/estate_property_offer_templates.xml b/real_estate/views/estate_property_offer_templates.xml deleted file mode 100644 index 2086c5ef621..00000000000 --- a/real_estate/views/estate_property_offer_templates.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - estate.property.offer.list - estate.property.offer - - - - - - - - - diff --git a/real_estate/views/estate_property_offers_templates.xml b/real_estate/views/estate_property_offers_templates.xml new file mode 100644 index 00000000000..99aeff87ee1 --- /dev/null +++ b/real_estate/views/estate_property_offers_templates.xml @@ -0,0 +1,16 @@ + + + + estate.property.offers.list + estate.property.offers + + + + +