From b9de52f6ede1bf2f07ffb4eb92eda053f9e87135 Mon Sep 17 00:00:00 2001 From: saver-odoo Date: Fri, 5 Jun 2026 14:47:37 +0530 Subject: [PATCH 1/6] [ADD] estate: Add real estate module structure Estate module for managing real estate advertisements in Odoo. --- estate/__init__.py | 1 + estate/__manifest__.py | 6 ++++++ estate/models/__init__.py | 1 + estate/models/estate_property.py | 10 ++++++++++ 4 files changed, 18 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..0650744f6bc --- /dev/null +++ b/estate/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/estate/__manifest__.py b/estate/__manifest__.py new file mode 100644 index 00000000000..c6c3a4c6d98 --- /dev/null +++ b/estate/__manifest__.py @@ -0,0 +1,6 @@ +{ + + "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..73dceab2d81 --- /dev/null +++ b/estate/models/estate_property.py @@ -0,0 +1,10 @@ +from odoo import fields,models + +class EstateProperty(models.Model): + _name="estate.property" + _description="EState property" + + name = fields.Char(required="true") + description=fields.Text() + + From 04adcabca36a7b33db5cfc3927f7eff3070827bf Mon Sep 17 00:00:00 2001 From: saver-odoo Date: Mon, 8 Jun 2026 15:25:45 +0530 Subject: [PATCH 2/6] [ADD] estate: Add Access Rights to Models This commit adds the required access rights to ensure authorized users can interact with the models according to their role configuration. --- awesome_clicker/__manifest__.py | 35 ++++---- awesome_dashboard/__manifest__.py | 36 ++++---- awesome_dashboard/controllers/__init__.py | 2 +- awesome_dashboard/controllers/controllers.py | 22 ++--- awesome_gallery/__manifest__.py | 32 ++++--- awesome_gallery/models/ir_action.py | 8 +- awesome_gallery/models/ir_ui_view.py | 4 +- awesome_kanban/__manifest__.py | 32 ++++--- awesome_owl/__init__.py | 2 +- awesome_owl/__manifest__.py | 53 ++++++------ awesome_owl/controllers/__init__.py | 2 +- awesome_owl/controllers/controllers.py | 5 +- estate/__manifest__.py | 12 ++- estate/models/estate_property.py | 27 ++++-- estate/security/ir.model.access.csv | 2 + website_airproof/__manifest__.py | 88 +++++++++++--------- 16 files changed, 186 insertions(+), 176 deletions(-) create mode 100644 estate/security/ir.model.access.csv diff --git a/awesome_clicker/__manifest__.py b/awesome_clicker/__manifest__.py index 56dc2f779b9..aa6d3cd7a71 100644 --- a/awesome_clicker/__manifest__.py +++ b/awesome_clicker/__manifest__.py @@ -1,29 +1,24 @@ # -*- coding: utf-8 -*- { - 'name': "Awesome Clicker", - - 'summary': """ + "name": "Awesome Clicker", + "summary": """ Starting module for "Master the Odoo web framework, chapter 1: Build a Clicker game" """, - - 'description': """ + "description": """ Starting module for "Master the Odoo web framework, chapter 1: Build a Clicker game" """, - - 'author': "Odoo", - 'website': "https://www.odoo.com/", - 'category': 'Tutorials', - 'version': '0.1', - 'application': True, - 'installable': True, - 'depends': ['base', 'web'], - - 'data': [], - 'assets': { - 'web.assets_backend': [ - 'awesome_clicker/static/src/**/*', + "author": "Odoo", + "website": "https://www.odoo.com/", + "category": "Tutorials", + "version": "0.1", + "application": True, + "installable": True, + "depends": ["base", "web"], + "data": [], + "assets": { + "web.assets_backend": [ + "awesome_clicker/static/src/**/*", ], - }, - 'license': 'AGPL-3' + "license": "AGPL-3", } diff --git a/awesome_dashboard/__manifest__.py b/awesome_dashboard/__manifest__.py index a1cd72893d7..a86d9bb991e 100644 --- a/awesome_dashboard/__manifest__.py +++ b/awesome_dashboard/__manifest__.py @@ -1,30 +1,26 @@ # -*- coding: utf-8 -*- { - 'name': "Awesome Dashboard", - - 'summary': """ + "name": "Awesome Dashboard", + "summary": """ Starting module for "Discover the JS framework, chapter 2: Build a dashboard" """, - - 'description': """ + "description": """ Starting module for "Discover the JS framework, chapter 2: Build a dashboard" """, - - 'author': "Odoo", - 'website': "https://www.odoo.com/", - 'category': 'Tutorials', - 'version': '0.1', - 'application': True, - 'installable': True, - 'depends': ['base', 'web', 'mail', 'crm'], - - 'data': [ - 'views/views.xml', + "author": "Odoo", + "website": "https://www.odoo.com/", + "category": "Tutorials", + "version": "0.1", + "application": True, + "installable": True, + "depends": ["base", "web", "mail", "crm"], + "data": [ + "views/views.xml", ], - 'assets': { - 'web.assets_backend': [ - 'awesome_dashboard/static/src/**/*', + "assets": { + "web.assets_backend": [ + "awesome_dashboard/static/src/**/*", ], }, - 'license': 'AGPL-3' + "license": "AGPL-3", } diff --git a/awesome_dashboard/controllers/__init__.py b/awesome_dashboard/controllers/__init__.py index 457bae27e11..b0f26a9a602 100644 --- a/awesome_dashboard/controllers/__init__.py +++ b/awesome_dashboard/controllers/__init__.py @@ -1,3 +1,3 @@ # -*- coding: utf-8 -*- -from . import controllers \ No newline at end of file +from . import controllers diff --git a/awesome_dashboard/controllers/controllers.py b/awesome_dashboard/controllers/controllers.py index 05977d3bd7f..2e408affe36 100644 --- a/awesome_dashboard/controllers/controllers.py +++ b/awesome_dashboard/controllers/controllers.py @@ -8,8 +8,9 @@ logger = logging.getLogger(__name__) + class AwesomeDashboard(http.Controller): - @http.route('/awesome_dashboard/statistics', type='jsonrpc', auth='user') + @http.route("/awesome_dashboard/statistics", type="jsonrpc", auth="user") def get_statistics(self): """ Returns a dict of statistics about the orders: @@ -22,15 +23,14 @@ def get_statistics(self): """ return { - 'average_quantity': random.randint(4, 12), - 'average_time': random.randint(4, 123), - 'nb_cancelled_orders': random.randint(0, 50), - 'nb_new_orders': random.randint(10, 200), - 'orders_by_size': { - 'm': random.randint(0, 150), - 's': random.randint(0, 150), - 'xl': random.randint(0, 150), + "average_quantity": random.randint(4, 12), + "average_time": random.randint(4, 123), + "nb_cancelled_orders": random.randint(0, 50), + "nb_new_orders": random.randint(10, 200), + "orders_by_size": { + "m": random.randint(0, 150), + "s": random.randint(0, 150), + "xl": random.randint(0, 150), }, - 'total_amount': random.randint(100, 1000) + "total_amount": random.randint(100, 1000), } - diff --git a/awesome_gallery/__manifest__.py b/awesome_gallery/__manifest__.py index f0fe026a9c6..6eaeaa6f83f 100644 --- a/awesome_gallery/__manifest__.py +++ b/awesome_gallery/__manifest__.py @@ -1,27 +1,25 @@ # -*- coding: utf-8 -*- { - 'name': "Gallery View", - 'summary': """ + "name": "Gallery View", + "summary": """ Starting module for "Master the Odoo web framework, chapter 3: Create a Gallery View" """, - - 'description': """ + "description": """ Starting module for "Master the Odoo web framework, chapter 3: Create a Gallery View" """, - - 'version': '0.1', - 'application': True, - 'category': 'Tutorials', - 'installable': True, - 'depends': ['web', 'contacts'], - 'data': [ - 'views/views.xml', + "version": "0.1", + "application": True, + "category": "Tutorials", + "installable": True, + "depends": ["web", "contacts"], + "data": [ + "views/views.xml", ], - 'assets': { - 'web.assets_backend': [ - 'awesome_gallery/static/src/**/*', + "assets": { + "web.assets_backend": [ + "awesome_gallery/static/src/**/*", ], }, - 'author': 'Odoo S.A.', - 'license': 'AGPL-3' + "author": "Odoo S.A.", + "license": "AGPL-3", } diff --git a/awesome_gallery/models/ir_action.py b/awesome_gallery/models/ir_action.py index eae20acbf5c..45dc4a2bb71 100644 --- a/awesome_gallery/models/ir_action.py +++ b/awesome_gallery/models/ir_action.py @@ -3,8 +3,8 @@ class ActWindowView(models.Model): - _inherit = 'ir.actions.act_window.view' + _inherit = "ir.actions.act_window.view" - view_mode = fields.Selection(selection_add=[ - ('gallery', "Awesome Gallery") - ], ondelete={'gallery': 'cascade'}) + view_mode = fields.Selection( + selection_add=[("gallery", "Awesome Gallery")], ondelete={"gallery": "cascade"} + ) diff --git a/awesome_gallery/models/ir_ui_view.py b/awesome_gallery/models/ir_ui_view.py index 0c11b8298ac..555008c371f 100644 --- a/awesome_gallery/models/ir_ui_view.py +++ b/awesome_gallery/models/ir_ui_view.py @@ -3,6 +3,6 @@ class View(models.Model): - _inherit = 'ir.ui.view' + _inherit = "ir.ui.view" - type = fields.Selection(selection_add=[('gallery', "Awesome Gallery")]) + type = fields.Selection(selection_add=[("gallery", "Awesome Gallery")]) diff --git a/awesome_kanban/__manifest__.py b/awesome_kanban/__manifest__.py index 6f31bc8de0d..1dc8791b97b 100644 --- a/awesome_kanban/__manifest__.py +++ b/awesome_kanban/__manifest__.py @@ -1,27 +1,25 @@ # -*- coding: utf-8 -*- { - 'name': "Awesome Kanban", - 'summary': """ + "name": "Awesome Kanban", + "summary": """ Starting module for "Master the Odoo web framework, chapter 4: Customize a kanban view" """, - - 'description': """ + "description": """ Starting module for "Master the Odoo web framework, chapter 4: Customize a kanban view. """, - - 'version': '0.1', - 'application': True, - 'category': 'Tutorials', - 'installable': True, - 'depends': ['web', 'crm'], - 'data': [ - 'views/views.xml', + "version": "0.1", + "application": True, + "category": "Tutorials", + "installable": True, + "depends": ["web", "crm"], + "data": [ + "views/views.xml", ], - 'assets': { - 'web.assets_backend': [ - 'awesome_kanban/static/src/**/*', + "assets": { + "web.assets_backend": [ + "awesome_kanban/static/src/**/*", ], }, - 'author': 'Odoo S.A.', - 'license': 'AGPL-3' + "author": "Odoo S.A.", + "license": "AGPL-3", } diff --git a/awesome_owl/__init__.py b/awesome_owl/__init__.py index 457bae27e11..b0f26a9a602 100644 --- a/awesome_owl/__init__.py +++ b/awesome_owl/__init__.py @@ -1,3 +1,3 @@ # -*- coding: utf-8 -*- -from . import controllers \ No newline at end of file +from . import controllers diff --git a/awesome_owl/__manifest__.py b/awesome_owl/__manifest__.py index 55002ab81de..197652f6027 100644 --- a/awesome_owl/__manifest__.py +++ b/awesome_owl/__manifest__.py @@ -1,43 +1,38 @@ # -*- coding: utf-8 -*- { - 'name': "Awesome Owl", - - 'summary': """ + "name": "Awesome Owl", + "summary": """ Starting module for "Discover the JS framework, chapter 1: Owl components" """, - - 'description': """ + "description": """ Starting module for "Discover the JS framework, chapter 1: Owl components" """, - - 'author': "Odoo", - 'website': "https://www.odoo.com", - + "author": "Odoo", + "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', - + "category": "Tutorials", + "version": "0.1", # any module necessary for this one to work correctly - 'depends': ['base', 'web'], - 'application': True, - 'installable': True, - 'data': [ - 'views/templates.xml', + "depends": ["base", "web"], + "application": True, + "installable": True, + "data": [ + "views/templates.xml", ], - 'assets': { - 'awesome_owl.assets_playground': [ - ('include', 'web._assets_helpers'), - ('include', 'web._assets_backend_helpers'), - 'web/static/src/scss/pre_variables.scss', - 'web/static/lib/bootstrap/scss/_variables.scss', - 'web/static/lib/bootstrap/scss/_maps.scss', - ('include', 'web._assets_bootstrap'), - ('include', 'web._assets_core'), - 'web/static/src/libs/fontawesome/css/font-awesome.css', - 'awesome_owl/static/src/**/*', + "assets": { + "awesome_owl.assets_playground": [ + ("include", "web._assets_helpers"), + ("include", "web._assets_backend_helpers"), + "web/static/src/scss/pre_variables.scss", + "web/static/lib/bootstrap/scss/_variables.scss", + "web/static/lib/bootstrap/scss/_maps.scss", + ("include", "web._assets_bootstrap"), + ("include", "web._assets_core"), + "web/static/src/libs/fontawesome/css/font-awesome.css", + "awesome_owl/static/src/**/*", ], }, - 'license': 'AGPL-3' + "license": "AGPL-3", } diff --git a/awesome_owl/controllers/__init__.py b/awesome_owl/controllers/__init__.py index 457bae27e11..b0f26a9a602 100644 --- a/awesome_owl/controllers/__init__.py +++ b/awesome_owl/controllers/__init__.py @@ -1,3 +1,3 @@ # -*- coding: utf-8 -*- -from . import controllers \ No newline at end of file +from . import controllers diff --git a/awesome_owl/controllers/controllers.py b/awesome_owl/controllers/controllers.py index bccfd6fe283..4da2f03a9f3 100644 --- a/awesome_owl/controllers/controllers.py +++ b/awesome_owl/controllers/controllers.py @@ -1,10 +1,11 @@ from odoo import http from odoo.http import request, route + class OwlPlayground(http.Controller): - @http.route(['/awesome_owl'], type='http', auth='public') + @http.route(["/awesome_owl"], type="http", auth="public") def show_playground(self): """ Renders the owl playground page """ - return request.render('awesome_owl.playground') + return request.render("awesome_owl.playground") diff --git a/estate/__manifest__.py b/estate/__manifest__.py index c6c3a4c6d98..cb6c54f76ee 100644 --- a/estate/__manifest__.py +++ b/estate/__manifest__.py @@ -1,6 +1,10 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. { - - "name":"Real Estate", - "depends":['base'], - 'application': True, + "name": "Real Estate", + "depends": ["base"], + "application": True, + "data": ["security/ir.model.access.csv"], + "author": "Odoo S.A.", + "license": "LGPL-3", } diff --git a/estate/models/estate_property.py b/estate/models/estate_property.py index 73dceab2d81..cb23c0370f2 100644 --- a/estate/models/estate_property.py +++ b/estate/models/estate_property.py @@ -1,10 +1,21 @@ -from odoo import fields,models - -class EstateProperty(models.Model): - _name="estate.property" - _description="EState property" - - name = fields.Char(required="true") - description=fields.Text() +from odoo import fields, models +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() + 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( + [("North", "North"), ("South", "South"), ("East", "East"), ("West", "West")] + ) diff --git a/estate/security/ir.model.access.csv b/estate/security/ir.model.access.csv new file mode 100644 index 00000000000..98f4671fb0d --- /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 diff --git a/website_airproof/__manifest__.py b/website_airproof/__manifest__.py index 2c2c62d6a18..86294451616 100644 --- a/website_airproof/__manifest__.py +++ b/website_airproof/__manifest__.py @@ -1,59 +1,69 @@ { - 'name': 'Airproof Theme', - 'description': 'Airproof Theme - Drones, modelling, camera', - 'category': 'Website/Theme', + "name": "Airproof Theme", + "description": "Airproof Theme - Drones, modelling, camera", + "category": "Website/Theme", # 'version': '18.0.1.0', - 'author': 'PSBE Designers', - 'license': 'LGPL-3', - 'depends': ['website_sale', 'website_sale_wishlist', 'website_blog', 'website_mass_mailing'], - 'data': [ + "author": "PSBE Designers", + "license": "LGPL-3", + "depends": [ + "website_sale", + "website_sale_wishlist", + "website_blog", + "website_mass_mailing", + ], + "data": [ # Snippets - 'views/snippets/options.xml', - 'views/snippets/s_airproof_carousel.xml', + "views/snippets/options.xml", + "views/snippets/s_airproof_carousel.xml", # Options - 'data/presets.xml', - 'data/website.xml', + "data/presets.xml", + "data/website.xml", # Menu - 'data/menu.xml', + "data/menu.xml", # Gradients - 'data/gradients.xml', + "data/gradients.xml", # Shapes - 'data/shapes.xml', + "data/shapes.xml", # Pages - 'data/pages/home.xml', - 'data/pages/contact.xml', + "data/pages/home.xml", + "data/pages/contact.xml", # Frontend - 'views/new_page_template_templates.xml', - 'views/website_templates.xml', - 'views/website_sale_templates.xml', - 'views/website_sale_wishlist_templates.xml', + "views/new_page_template_templates.xml", + "views/website_templates.xml", + "views/website_sale_templates.xml", + "views/website_sale_wishlist_templates.xml", # Images - 'data/images.xml', + "data/images.xml", ], - 'assets': { - 'web._assets_primary_variables': [ - 'website_airproof/static/src/scss/primary_variables.scss', + "assets": { + "web._assets_primary_variables": [ + "website_airproof/static/src/scss/primary_variables.scss", ], - 'web._assets_frontend_helpers': [ - ('prepend', 'website_airproof/static/src/scss/bootstrap_overridden.scss'), + "web._assets_frontend_helpers": [ + ("prepend", "website_airproof/static/src/scss/bootstrap_overridden.scss"), ], - 'web.assets_frontend': [ + "web.assets_frontend": [ # SCSS - 'website_airproof/static/src/scss/font.scss', - 'website_airproof/static/src/scss/components/mouse_follower.scss', - 'website_airproof/static/src/scss/layout/header.scss', - 'website_airproof/static/src/scss/pages/product_page.scss', - 'website_airproof/static/src/scss/pages/shop.scss', - 'website_airproof/static/src/scss/snippets/caroussel.scss', - 'website_airproof/static/src/scss/snippets/newsletter.scss', - 'website_airproof/static/src/snippets/s_airproof_carousel/000.scss', + "website_airproof/static/src/scss/font.scss", + "website_airproof/static/src/scss/components/mouse_follower.scss", + "website_airproof/static/src/scss/layout/header.scss", + "website_airproof/static/src/scss/pages/product_page.scss", + "website_airproof/static/src/scss/pages/shop.scss", + "website_airproof/static/src/scss/snippets/caroussel.scss", + "website_airproof/static/src/scss/snippets/newsletter.scss", + "website_airproof/static/src/snippets/s_airproof_carousel/000.scss", # JS - 'website_airproof/static/src/js/mouse_follower.js', + "website_airproof/static/src/js/mouse_follower.js", ], }, - 'new_page_templates': { - 'airproof': { - 'services': ['s_parallax', 's_airproof_key_benefits_h2', 's_call_to_action', 's_airproof_carousel'] + "new_page_templates": { + "airproof": { + "services": [ + "s_parallax", + "s_airproof_key_benefits_h2", + "s_call_to_action", + "s_airproof_carousel", + ] } }, } From 6a79ca0f9e4ca6afc6a96ead82ac18a0b3b59ae7 Mon Sep 17 00:00:00 2001 From: saver-odoo Date: Thu, 11 Jun 2026 14:25:31 +0530 Subject: [PATCH 3/6] [ADD] estate: Add window action and hierarchical menus Define 'test_model_action' window action with list and form modes Implement structured root, category, and action menus for Real Estate --- estate/__manifest__.py | 8 ++++-- estate/models/estate_property.py | 32 ++++++++++++++++++--- estate/static/description/icon.png | Bin 0 -> 11519 bytes estate/static/description/icon.svg | 1 + estate/static/description/icon_hi.png | Bin 0 -> 4539 bytes estate/views/estate_menuitem.xml | 37 +++++++++++++++++++++++++ estate/views/estate_property_views.xml | 8 ++++++ 7 files changed, 79 insertions(+), 7 deletions(-) create mode 100644 estate/static/description/icon.png create mode 100644 estate/static/description/icon.svg create mode 100644 estate/static/description/icon_hi.png create mode 100644 estate/views/estate_menuitem.xml create mode 100644 estate/views/estate_property_views.xml diff --git a/estate/__manifest__.py b/estate/__manifest__.py index cb6c54f76ee..302dbcaf296 100644 --- a/estate/__manifest__.py +++ b/estate/__manifest__.py @@ -1,10 +1,12 @@ -# -*- coding: utf-8 -*- -# Part of Odoo. See LICENSE file for full copyright and licensing details. { "name": "Real Estate", "depends": ["base"], "application": True, - "data": ["security/ir.model.access.csv"], + "data": [ + "security/ir.model.access.csv", + "views/estate_property_views.xml", + "views/estate_menuitem.xml", + ], "author": "Odoo S.A.", "license": "LGPL-3", } diff --git a/estate/models/estate_property.py b/estate/models/estate_property.py index cb23c0370f2..85577281e07 100644 --- a/estate/models/estate_property.py +++ b/estate/models/estate_property.py @@ -1,16 +1,27 @@ from odoo import fields, models +from dateutil.relativedelta import relativedelta class EstateProperty(models.Model): _name = "estate.property" - _description = "EState property" + _description = "Estate Property" + + def _default_date_availability(self): + return fields.Date.today() + relativedelta(months=3) + name = fields.Char(required=True) description = fields.Text() postcode = fields.Char() - date_availability = fields.Date() + + date_availability = fields.Date( + copy=False, + default=_default_date_availability, + # default=lambda self: fields.Date.today() + relativedelta(months=3) + ) + expected_price = fields.Float(required=True) - selling_price = fields.Float() - bedrooms = fields.Integer() + selling_price = fields.Float(readonly=True, copy=False, default=3000) + bedrooms = fields.Integer(default=2) living_area = fields.Integer() facades = fields.Integer() garage = fields.Boolean() @@ -19,3 +30,16 @@ class EstateProperty(models.Model): garden_orientation = fields.Selection( [("North", "North"), ("South", "South"), ("East", "East"), ("West", "West")] ) + state = fields.Selection( + [ + ("New", "New"), + ("Offer Recieved", "Offer Received"), + ("Offer Accepted", "Offer Accepted"), + ("Sold", "Sold"), + ("Cancelled", "Cancelled"), + ], + required=True, + copy=False, + default="New", + ) + active = fields.Boolean(default=False) diff --git a/estate/static/description/icon.png b/estate/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..923ab37cce71f31c33f90b122bb768ea1d58bc9f GIT binary patch literal 11519 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 XQ0daSx6Z&D%^;&Irf}kAhsXa1)ue+N literal 0 HcmV?d00001 diff --git a/estate/static/description/icon.svg b/estate/static/description/icon.svg new file mode 100644 index 00000000000..2d73304547b --- /dev/null +++ b/estate/static/description/icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/estate/static/description/icon_hi.png b/estate/static/description/icon_hi.png new file mode 100644 index 0000000000000000000000000000000000000000..910e9c6e039c63f094854dbf62998dee310a6284 GIT binary patch literal 4539 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 + + + + + + + + + + + + + diff --git a/estate/views/estate_property_views.xml b/estate/views/estate_property_views.xml new file mode 100644 index 00000000000..45da99fc546 --- /dev/null +++ b/estate/views/estate_property_views.xml @@ -0,0 +1,8 @@ + + + + Properties + estate.property + list,form,kanban + + From f914d6d3107798578e4010ecfffa2f169bc8d5c6 Mon Sep 17 00:00:00 2001 From: saver-odoo Date: Fri, 12 Jun 2026 11:13:13 +0530 Subject: [PATCH 4/6] [IMP] estate: add basic list, form, and search views. Define explicit list view columns for estate.property. Create a structured form view layout using sheets, groups, and notebooks. Implement a search view with custom fields, an 'Available' filter, and a 'Group By' postcode option. --- awesome_owl/controllers/controllers.py | 4 + awesome_owl/static/src/counter.js | 13 ++++ awesome_owl/static/src/counter.xml | 6 ++ awesome_owl/static/src/main.js | 16 +++- awesome_owl/static/src/playground.js | 2 +- awesome_owl/views/templates.xml | 35 +++++++-- estate/__init__.py | 2 +- estate/__manifest__.py | 1 + estate/models/__init__.py | 2 +- estate/models/estate_property.py | 2 +- estate/views/estate_property_list_views.xml | 18 +++++ estate/views/estate_property_views.xml | 84 +++++++++++++++++++-- 12 files changed, 167 insertions(+), 18 deletions(-) create mode 100644 awesome_owl/static/src/counter.js create mode 100644 awesome_owl/static/src/counter.xml create mode 100644 estate/views/estate_property_list_views.xml diff --git a/awesome_owl/controllers/controllers.py b/awesome_owl/controllers/controllers.py index 4da2f03a9f3..3a6170d51ee 100644 --- a/awesome_owl/controllers/controllers.py +++ b/awesome_owl/controllers/controllers.py @@ -9,3 +9,7 @@ def show_playground(self): Renders the owl playground page """ return request.render("awesome_owl.playground") + + @http.route(["/counter"], type="http", auth="public") + def show_counter(self): + return request.render("awesome_owl.counter_page") diff --git a/awesome_owl/static/src/counter.js b/awesome_owl/static/src/counter.js new file mode 100644 index 00000000000..9de9703ca59 --- /dev/null +++ b/awesome_owl/static/src/counter.js @@ -0,0 +1,13 @@ +import { Component, useState } from "@odoo/owl"; + +export class Counter extends Component { + static template = "awesome_owl.Counter"; + + setup() { + this.state = useState({ value: 0 }); + } + + increment() { + this.state.value++; + } +} diff --git a/awesome_owl/static/src/counter.xml b/awesome_owl/static/src/counter.xml new file mode 100644 index 00000000000..ed2dfb609bb --- /dev/null +++ b/awesome_owl/static/src/counter.xml @@ -0,0 +1,6 @@ + + +

Counter:

+ +
+
diff --git a/awesome_owl/static/src/main.js b/awesome_owl/static/src/main.js index 1aaea902b55..7554a51d9b4 100644 --- a/awesome_owl/static/src/main.js +++ b/awesome_owl/static/src/main.js @@ -1,12 +1,20 @@ import { whenReady } from "@odoo/owl"; import { mountComponent } from "@web/env"; + import { Playground } from "./playground"; +import { Counter } from "./counter"; const config = { - dev: true, - name: "Owl Tutorial" + dev: true, + name: "Owl Tutorial", }; -// Mount the Playground component when the document.body is ready -whenReady(() => mountComponent(Playground, document.body, config)); +whenReady(() => { + const page = document.body.dataset.page; + if (page === "counter") { + mountComponent(Counter, document.body, config); + } else { + mountComponent(Playground, document.body, config); + } +}); diff --git a/awesome_owl/static/src/playground.js b/awesome_owl/static/src/playground.js index 4ac769b0aa5..d7755f4dffd 100644 --- a/awesome_owl/static/src/playground.js +++ b/awesome_owl/static/src/playground.js @@ -1,5 +1,5 @@ import { Component } from "@odoo/owl"; export class Playground extends Component { - static template = "awesome_owl.playground"; + static template = "awesome_owl.playground"; } diff --git a/awesome_owl/views/templates.xml b/awesome_owl/views/templates.xml index aa54c1a7241..891a9068cb1 100644 --- a/awesome_owl/views/templates.xml +++ b/awesome_owl/views/templates.xml @@ -1,15 +1,40 @@ - diff --git a/estate/__init__.py b/estate/__init__.py index 0650744f6bc..253f5724e28 100644 --- a/estate/__init__.py +++ b/estate/__init__.py @@ -1 +1 @@ -from . import models +from . import models as models diff --git a/estate/__manifest__.py b/estate/__manifest__.py index 302dbcaf296..b9a6a039366 100644 --- a/estate/__manifest__.py +++ b/estate/__manifest__.py @@ -5,6 +5,7 @@ "data": [ "security/ir.model.access.csv", "views/estate_property_views.xml", + "views/estate_property_list_views.xml", "views/estate_menuitem.xml", ], "author": "Odoo S.A.", diff --git a/estate/models/__init__.py b/estate/models/__init__.py index 5e1963c9d2f..7fdb8c9c868 100644 --- a/estate/models/__init__.py +++ b/estate/models/__init__.py @@ -1 +1 @@ -from . import estate_property +from . import estate_property as estate_property diff --git a/estate/models/estate_property.py b/estate/models/estate_property.py index 85577281e07..75324d64e36 100644 --- a/estate/models/estate_property.py +++ b/estate/models/estate_property.py @@ -42,4 +42,4 @@ def _default_date_availability(self): copy=False, default="New", ) - active = fields.Boolean(default=False) + active = fields.Boolean(default=True) diff --git a/estate/views/estate_property_list_views.xml b/estate/views/estate_property_list_views.xml new file mode 100644 index 00000000000..73e9c3776ee --- /dev/null +++ b/estate/views/estate_property_list_views.xml @@ -0,0 +1,18 @@ + + + + estate.property.view.list + estate.property + + + + + + + + + + + + + diff --git a/estate/views/estate_property_views.xml b/estate/views/estate_property_views.xml index 45da99fc546..9e95aa0f01d 100644 --- a/estate/views/estate_property_views.xml +++ b/estate/views/estate_property_views.xml @@ -1,8 +1,82 @@ - - Properties - estate.property - list,form,kanban - + + Properties + estate.property + list,form,kanban + + + estate.property.form + estate.property + +
+ +
+

+ +

+
+
+ + + + + + + + + + +
+ + + + + + + + + + + + + + + +
+
+
+
+ + + estate.property.search + estate.property + + + + + + + + + + + + + + + +
From 34c4451275f102acbdf47b8e409d5e7a6f56b556 Mon Sep 17 00:00:00 2001 From: saver-odoo Date: Mon, 22 Jun 2026 12:34:33 +0530 Subject: [PATCH 5/6] [IMP] estate: add property offers and tags models and views This commit introduces dedicated offer and tag models with the necessary views, actions, menus, and access rights. Properties can now be associated with multiple tags and offers --- awesome_owl/controllers/controllers.py | 2 +- awesome_owl/static/src/counter.js | 2 +- awesome_owl/static/src/counter.xml | 2 +- awesome_owl/views/templates.xml | 2 +- estate/__manifest__.py | 3 + estate/models/__init__.py | 3 + estate/models/estate_property.py | 22 +++-- estate/models/estate_property_offer.py | 12 +++ estate/models/estate_property_tag.py | 7 ++ estate/models/estate_property_type.py | 7 ++ estate/security/ir.model.access.csv | 3 + estate/views/estate_menuitem.xml | 39 ++------- estate/views/estate_property_list_views.xml | 30 +++---- estate/views/estate_property_offer_views.xml | 29 +++++++ estate/views/estate_property_tag_views.xml | 9 ++ estate/views/estate_property_type_views.xml | 9 ++ estate/views/estate_property_views.xml | 91 +++++++++++--------- 17 files changed, 168 insertions(+), 104 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/awesome_owl/controllers/controllers.py b/awesome_owl/controllers/controllers.py index 3a6170d51ee..9806887c552 100644 --- a/awesome_owl/controllers/controllers.py +++ b/awesome_owl/controllers/controllers.py @@ -12,4 +12,4 @@ def show_playground(self): @http.route(["/counter"], type="http", auth="public") def show_counter(self): - return request.render("awesome_owl.counter_page") + return request.render("awesome_owl.counter_template") diff --git a/awesome_owl/static/src/counter.js b/awesome_owl/static/src/counter.js index 9de9703ca59..f7b1d77a778 100644 --- a/awesome_owl/static/src/counter.js +++ b/awesome_owl/static/src/counter.js @@ -1,7 +1,7 @@ import { Component, useState } from "@odoo/owl"; export class Counter extends Component { - static template = "awesome_owl.Counter"; + static template = "awesome_owl.Counter_xml"; setup() { this.state = useState({ value: 0 }); diff --git a/awesome_owl/static/src/counter.xml b/awesome_owl/static/src/counter.xml index ed2dfb609bb..09dc3c45358 100644 --- a/awesome_owl/static/src/counter.xml +++ b/awesome_owl/static/src/counter.xml @@ -1,5 +1,5 @@ - +

Counter:

diff --git a/awesome_owl/views/templates.xml b/awesome_owl/views/templates.xml index 891a9068cb1..3add218ba4f 100644 --- a/awesome_owl/views/templates.xml +++ b/awesome_owl/views/templates.xml @@ -19,7 +19,7 @@