diff --git a/awesome_clicker/__manifest__.py b/awesome_clicker/__manifest__.py
index e57ef4d5bb0..7528d8a1931 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/AwesomeClicker',
-    '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/AwesomeClicker",
+    "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 31406e8addb..17e48f7c1fd 100644
--- a/awesome_dashboard/__manifest__.py
+++ b/awesome_dashboard/__manifest__.py
@@ -1,30 +1,27 @@
 # -*- 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/AwesomeDashboard',
-    '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/AwesomeDashboard",
+    "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/**/*",
+            "awesome_dashboard/static/src/scss/dashboard.scss",
         ],
     },
-    '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 56d4a051287..b5aab01be32 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='json', auth='user')
+    @http.route("/awesome_dashboard/statistics", type="json", 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_dashboard/static/src/dashboard.js b/awesome_dashboard/static/src/dashboard.js
deleted file mode 100644
index 637fa4bb972..00000000000
--- a/awesome_dashboard/static/src/dashboard.js
+++ /dev/null
@@ -1,10 +0,0 @@
-/** @odoo-module **/
-
-import { Component } from "@odoo/owl";
-import { registry } from "@web/core/registry";
-
-class AwesomeDashboard extends Component {
-    static template = "awesome_dashboard.AwesomeDashboard";
-}
-
-registry.category("actions").add("awesome_dashboard.dashboard", AwesomeDashboard);
diff --git a/awesome_dashboard/static/src/dashboard.xml b/awesome_dashboard/static/src/dashboard.xml
deleted file mode 100644
index 1a2ac9a2fed..00000000000
--- a/awesome_dashboard/static/src/dashboard.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<templates xml:space="preserve">
-
-    <t t-name="awesome_dashboard.AwesomeDashboard">
-        hello dashboard
-    </t>
-
-</templates>
diff --git a/awesome_dashboard/static/src/dashboard/dashboard.js b/awesome_dashboard/static/src/dashboard/dashboard.js
new file mode 100644
index 00000000000..683bc4d23c7
--- /dev/null
+++ b/awesome_dashboard/static/src/dashboard/dashboard.js
@@ -0,0 +1,26 @@
+import { useService } from "@web/core/utils/hooks";
+import { Layout } from "@web/search/layout";
+import { DashboardItem } from "../dashboard_items/dashboard_items";
+
+export class AwesomeDashboard extends Component {
+    static template = "awesome_dashboard.AwesomeDashboard";
+    static components = { Layout, DashboardItem };
+
+
+    setup() {
+        this.action = useService("action");
+    }
+
+    openCustomers() {
+        this.action.doAction("base.res_partner_action_kanban");
+    }
+
+    openLeads() {
+        this.action.doAction({
+            name: "Leads",
+            type: "ir.actions.act_window",
+            res_model: "crm.lead",
+            views: [[false, "list"], [false, "form"]],
+        });
+    }
+}
diff --git a/awesome_dashboard/static/src/dashboard/dashboard.scss b/awesome_dashboard/static/src/dashboard/dashboard.scss
new file mode 100644
index 00000000000..32862ec0d82
--- /dev/null
+++ b/awesome_dashboard/static/src/dashboard/dashboard.scss
@@ -0,0 +1,3 @@
+.o_dashboard {
+    background-color: gray;
+}
diff --git a/awesome_dashboard/static/src/dashboard/dashboard.xml b/awesome_dashboard/static/src/dashboard/dashboard.xml
new file mode 100644
index 00000000000..9c48b463423
--- /dev/null
+++ b/awesome_dashboard/static/src/dashboard/dashboard.xml
@@ -0,0 +1,19 @@
+   
+<?xml version="1.0" encoding="UTF-8" ?>
+<templates xml:space="preserve">
+    <t t-name="awesome_dashboard.AwesomeDashboard">
+        <Layout display="{controlPanel: {} }" className="'o_dashboard h-100'">
+            <t t-set-slot="layout-buttons">
+                <div class="o_cp_buttons" role="toolbar" aria-label="Control Panel Buttons" t-ref="buttons">
+                    <button class="btn btn-primary" t-on-click="openCustomers">Customers</button>
+                    <button class="btn btn-primary" style="margin-left: 0.5em" t-on-click="openLeads">Leads</button>
+                </div>
+            </t>
+            <t t-slot="content">
+                <DashboardItem>Item 1</DashboardItem>
+                <DashboardItem size="2">Item 2</DashboardItem>
+            </t>
+        </Layout>
+    </t>
+</templates>
+
diff --git a/awesome_dashboard/static/src/dashboard_items/dahboard_item.xml b/awesome_dashboard/static/src/dashboard_items/dahboard_item.xml
new file mode 100644
index 00000000000..aef49ee9bfa
--- /dev/null
+++ b/awesome_dashboard/static/src/dashboard_items/dahboard_item.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<templates xml:space="preserve">
+    <t t-name="awesome_dashboard.DashboardItem">
+        <div class="o_dashboard_item" t-att-style="'width: ' + (props.size * 18) + 'rem'">
+            <t t-slot="default" />
+        </div>
+    </t>
+</templates>
diff --git a/awesome_dashboard/static/src/dashboard_items/dashboard_item.scss b/awesome_dashboard/static/src/dashboard_items/dashboard_item.scss
new file mode 100644
index 00000000000..0bed5a9b365
--- /dev/null
+++ b/awesome_dashboard/static/src/dashboard_items/dashboard_item.scss
@@ -0,0 +1,7 @@
+.o_dashboard_item {
+    background-color: #f4f4f4;
+    border: 1px solid #ddd;
+    padding: 1rem;
+    margin: 0.5rem;
+    border-radius: 0.5rem;
+}
diff --git a/awesome_dashboard/static/src/dashboard_items/dashboard_items.js b/awesome_dashboard/static/src/dashboard_items/dashboard_items.js
new file mode 100644
index 00000000000..f6063ade108
--- /dev/null
+++ b/awesome_dashboard/static/src/dashboard_items/dashboard_items.js
@@ -0,0 +1,6 @@
+import { Component } from "@odoo/owl";
+
+export class DashboardItem extends Component {
+    static template = "awesome_dashboard.DashboardItem";
+    static props = { size: { type: Number, optional: true, default: 1 } };
+}
diff --git a/awesome_gallery/__manifest__.py b/awesome_gallery/__manifest__.py
index 624766dca89..9410319978e 100644
--- a/awesome_gallery/__manifest__.py
+++ b/awesome_gallery/__manifest__.py
@@ -1,26 +1,24 @@
 # -*- 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/AwesomeGallery',
-    'installable': True,
-    'depends': ['web', 'contacts'],
-    'data': [
-        'views/views.xml',
+    "version": "0.1",
+    "application": True,
+    "category": "Tutorials/AwesomeGallery",
+    "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/**/*",
         ],
     },
-    'license': 'AGPL-3'
+    "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 affef78bb12..e31a4d7189b 100644
--- a/awesome_kanban/__manifest__.py
+++ b/awesome_kanban/__manifest__.py
@@ -1,26 +1,24 @@
 # -*- 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/AwesomeKanban',
-    'installable': True,
-    'depends': ['web', 'crm'],
-    'data': [
-        'views/views.xml',
+    "version": "0.1",
+    "application": True,
+    "category": "Tutorials/AwesomeKanban",
+    "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/**/*",
         ],
     },
-    'license': 'AGPL-3'
+    "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 77abad510ef..a381f2e7ad6 100644
--- a/awesome_owl/__manifest__.py
+++ b/awesome_owl/__manifest__.py
@@ -1,42 +1,37 @@
 # -*- 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/AwesomeOwl',
-    'version': '0.1',
-
+    "category": "Tutorials/AwesomeOwl",
+    "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'),
-            '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"),
+            "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/awesome_owl/static/src/components/TodoItem/todoitem.js b/awesome_owl/static/src/components/TodoItem/todoitem.js
new file mode 100644
index 00000000000..34bccfc468c
--- /dev/null
+++ b/awesome_owl/static/src/components/TodoItem/todoitem.js
@@ -0,0 +1,19 @@
+import { Component} from "@odoo/owl";
+
+export class TodoItem extends Component {
+    static template = "awesome_owl.todoitem";
+    static props = {
+        todo: { type: Object },
+        toggleState: {type: Function},
+        removeTodo: {type: Function}
+    };
+
+    toggleState() {
+        this.props.toggleState(this.props.todo.id);
+    }
+
+    removeTodo() {
+        this.props.removeTodo(this.props.todo.id);
+    }
+
+}
diff --git a/awesome_owl/static/src/components/TodoItem/todoitem.xml b/awesome_owl/static/src/components/TodoItem/todoitem.xml
new file mode 100644
index 00000000000..cc0b04323cb
--- /dev/null
+++ b/awesome_owl/static/src/components/TodoItem/todoitem.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<templates xml:space="preserve">
+    <t t-name="awesome_owl.todoitem">
+        <div t-att-class="{'text-muted text-decoration-line-through': props.todo.isCompleted}">
+            <input type="checkbox" t-att-checked="props.todo.isCompleted" t-on-change="toggleState"/>
+            <t t-esc="props.todo.id"/>.
+            <t t-esc="props.todo.description"/>
+            <span class="fa fa-remove ms-3 text-danger" t-on-click="removeTodo"/>
+        </div>
+    </t>
+</templates>
diff --git a/awesome_owl/static/src/components/TodoList/todolist.js b/awesome_owl/static/src/components/TodoList/todolist.js
new file mode 100644
index 00000000000..f797986f039
--- /dev/null
+++ b/awesome_owl/static/src/components/TodoList/todolist.js
@@ -0,0 +1,43 @@
+import { Component, useState} from "@odoo/owl";
+import { TodoItem } from "../TodoItem/todoitem"; 
+import { useAutofocus } from "../../utils";
+
+
+export class ToDoList extends Component {
+    static template = "awesome_owl.todolist";
+    static components = { TodoItem };
+    setup() {
+        this.todos = useState([]);
+        this.todoItemsNr =0;
+        useAutofocus("todo_input");
+    }
+    addTodo(inp) {
+        if (inp.keyCode === 13) {
+            let content = inp.target.value;
+            if(content){
+                const _newTodo = {
+                    id: ++this.todoItemsNr, 
+                    description: content,
+                    isCompleted: false
+                };
+                this.todos.push(_newTodo);
+
+            }
+            inp.target.value = '';
+            this.render();
+        }
+    }
+
+    toggleState(id) {
+        const index = this.todos.findIndex((item) => item.id === id);
+        this.todos[index].isCompleted = !this.todos[index].isCompleted;
+    }
+
+    removeTodo(id) {
+        const index = this.todos.findIndex((item) => item.id === id);
+        if (index >= 0) {
+            this.todos.splice(index, 1);
+        }
+    }
+
+}
diff --git a/awesome_owl/static/src/components/TodoList/todolist.xml b/awesome_owl/static/src/components/TodoList/todolist.xml
new file mode 100644
index 00000000000..cd82af93974
--- /dev/null
+++ b/awesome_owl/static/src/components/TodoList/todolist.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<templates xml:space="preserve">
+    <t t-name="awesome_owl.todolist">
+        <div class="todo-list">
+            <h3>Todo List</h3>
+            <div class="card shadow-sm mb-4">
+                <input t-ref= "todo_input" placeholder="Enter a new to-do item." t-on-keyup="addTodo"/>
+            </div>            
+            <div t-foreach="this.todos" t-as="todo" t-key="todo.id">
+                <TodoItem t-props="{'todo': todo}" toggleState.bind="toggleState" removeTodo.bind="removeTodo"/>
+            </div>
+        </div>
+    </t>
+</templates>
diff --git a/awesome_owl/static/src/components/card/card.js b/awesome_owl/static/src/components/card/card.js
new file mode 100644
index 00000000000..9ed5c0761c8
--- /dev/null
+++ b/awesome_owl/static/src/components/card/card.js
@@ -0,0 +1,18 @@
+import { Component, useState} from "@odoo/owl";
+
+export class Card extends Component {
+    static template = "awesome_owl.card";
+    static props = {
+        title: {type: String},
+        slots: { type: Object }
+    }
+
+    setup() {
+        this.state = useState({ hidden: false });
+    }
+    
+    toggle() {
+        this.state.hidden = !this.state.hidden;
+    }
+    
+}
diff --git a/awesome_owl/static/src/components/card/card.xml b/awesome_owl/static/src/components/card/card.xml
new file mode 100644
index 00000000000..6d85d12b8a8
--- /dev/null
+++ b/awesome_owl/static/src/components/card/card.xml
@@ -0,0 +1,12 @@
+<templates xml:space="preserve">
+    <t t-name="awesome_owl.card">
+        <div class="card d-inline-block m-2" style="width: 18rem;">
+            <div class="card-body">
+                <h5 class="card-title"> <t t-esc="props.title"/>                    
+                    <button class="btn btn-primary" t-on-click="toggle">Show Counter</button>
+                </h5>
+                <t t-slot="default" t-if="!state.hidden"/>
+            </div>
+        </div>
+    </t>
+</templates>
diff --git a/awesome_owl/static/src/components/counter/counter.js b/awesome_owl/static/src/components/counter/counter.js
new file mode 100644
index 00000000000..aee34b8e3c0
--- /dev/null
+++ b/awesome_owl/static/src/components/counter/counter.js
@@ -0,0 +1,17 @@
+import { Component, useState } from "@odoo/owl";
+
+export class Counter extends Component {
+    static template = "awesome_owl.counter";
+    static props = {
+        onChange : {type: Function, optional: true}
+    }
+    setup() {
+        this.state = useState({
+            count: 1
+        });
+    };
+    increment() {
+        this.state.count++;
+        this.props.onChange?.();
+    }
+}
diff --git a/awesome_owl/static/src/components/counter/counter.xml b/awesome_owl/static/src/components/counter/counter.xml
new file mode 100644
index 00000000000..a36a112e324
--- /dev/null
+++ b/awesome_owl/static/src/components/counter/counter.xml
@@ -0,0 +1,10 @@
+<templates xml:space="preserve">
+    <t t-name="awesome_owl.counter">
+        <div class="counter text-center">
+            <h1 class="display-4 mb-3">Counter: <t t-esc="state.count"/></h1>
+            <div class="d-flex justify-content-center gap-2">
+                <button class="btn btn-success" t-on-click="increment">+</button>
+            </div>
+        </div>
+    </t>
+</templates>
diff --git a/awesome_owl/static/src/playground.js b/awesome_owl/static/src/playground.js
index 657fb8b07bb..f2d641c051f 100644
--- a/awesome_owl/static/src/playground.js
+++ b/awesome_owl/static/src/playground.js
@@ -1,7 +1,23 @@
 /** @odoo-module **/
 
-import { Component } from "@odoo/owl";
+import { Component, markup, useState } from "@odoo/owl";
+import { Counter } from "./components/counter/counter"
+import { Card } from "./components/card/card"
+import { ToDoList } from "./components/TodoList/todolist"
 
 export class Playground extends Component {
     static template = "awesome_owl.playground";
+    static components = { Counter, Card, ToDoList};
+    setup() {
+        this.state = useState({
+            sum: 2
+        });
+    };
+
+    incrementSum(){
+        this.state.sum++;
+    }
+
+    content1= "<div>Card with no markup</div>";
+    content2 = markup("<div>Card with markup content</div>");
 }
diff --git a/awesome_owl/static/src/playground.xml b/awesome_owl/static/src/playground.xml
index 4fb905d59f9..37172310067 100644
--- a/awesome_owl/static/src/playground.xml
+++ b/awesome_owl/static/src/playground.xml
@@ -1,10 +1,45 @@
 <?xml version="1.0" encoding="UTF-8" ?>
 <templates xml:space="preserve">
-
     <t t-name="awesome_owl.playground">
-        <div class="p-3">
-            hello world
+        <div class="container py-5">
+            <div class="card shadow-sm mb-4">
+                <div class="card-body">
+                    <h2 class="card-title">Counters</h2>
+                    <div class="d-flex gap-3">
+                        <div class="col">
+                            <Counter onChange.bind="incrementSum"/>
+                        </div>
+                        <div class="col">
+                            <Counter onChange.bind="incrementSum"/>
+                        </div>
+                    </div>
+                    <div class="mt-3">
+                        <strong>Sum:</strong> <t t-esc="state.sum"/>
+                    </div>
+                </div>
+            </div>
+            <div class="card shadow-sm mb-4">
+                <div class="card-body">
+                    <h1 class="card-title mb-4">Cards</h1>
+                    <div class="row row-cols-1 row-cols-md-2 row-cols-lg-3 g-4">
+                        <div class="col">
+                            <Card title="'Card 1'">
+                                <Counter/>
+                            </Card>
+                        </div>
+                        <div class="col">
+                            <Card title="'Card 2'">
+                                <Counter/>
+                            </Card>
+                        </div>
+                    </div>
+                </div>
+            </div>
+            <div class="card shadow-sm">
+                <div class="card-body">
+                    <ToDoList />
+                </div>
+            </div>
         </div>
     </t>
-
 </templates>
diff --git a/awesome_owl/static/src/utils.js b/awesome_owl/static/src/utils.js
new file mode 100644
index 00000000000..0b0690f0e94
--- /dev/null
+++ b/awesome_owl/static/src/utils.js
@@ -0,0 +1,9 @@
+import { useRef, useEffect } from "@odoo/owl"
+
+export function useAutofocus(itemName) {
+    let ref = useRef(itemName);
+    useEffect(
+        (el) => el?.focus(),
+        () => [ref.el]
+    )
+}
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..32931c038cf
--- /dev/null
+++ b/estate/__manifest__.py
@@ -0,0 +1,21 @@
+{
+    "name": "Real Estate",
+    "version": "1.0",
+    "author": "Abdelrhman Fawzy",
+    "category": "Services/Real Estate",
+    "summary": "Manage real estate properties, offers, and advertisements.",
+    "license": "LGPL-3",
+    "application": True,
+    "installable": True,
+    "auto_install": False,
+    "data": [
+        "security/ir.model.access.csv",
+        "views/estate_property_views.xml",
+        "views/estate_property_type_views.xml",
+        "views/estate_property_tag_views.xml",
+        "views/estate_property_offer_views.xml",
+        'views/res_users_views.xml',
+        "views/estate_menues.xml",
+    ],
+    "description": "This module allows you to manage real estate properties, property types, tags, offers, and advertisements. It also includes tools for organizing and displaying data effectively.",
+}
diff --git a/estate/models/__init__.py b/estate/models/__init__.py
new file mode 100644
index 00000000000..9a2189b6382
--- /dev/null
+++ b/estate/models/__init__.py
@@ -0,0 +1,5 @@
+from . import estate_property
+from . import estate_property_type
+from . import estate_property_tag
+from . import estate_property_offer
+from . import res_users
diff --git a/estate/models/estate_property.py b/estate/models/estate_property.py
new file mode 100644
index 00000000000..5fce905e259
--- /dev/null
+++ b/estate/models/estate_property.py
@@ -0,0 +1,139 @@
+from odoo import api, fields, models
+from odoo.exceptions import UserError, ValidationError
+from odoo.tools.float_utils import float_compare, float_is_zero
+
+
+class EstateProperty(models.Model):
+    _name = "estate.property"
+    _description = "Real Estate Property Options"
+    _order = "id desc"
+
+
+    name = fields.Char(required=True)
+    description = fields.Text()
+    postcode = fields.Char()
+    date_availability = fields.Date(
+        copy=False,
+        default=lambda x: fields.Datetime.add(fields.Datetime.today(), months=3),
+    )
+    expected_price = fields.Float(required=True)
+    selling_price = fields.Float(readonly=True, copy=False)
+    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"),
+        ]
+    )
+    active = fields.Boolean(default=True)
+    state = fields.Selection(
+        required=True,
+        copy=False,
+        default="new",
+        selection=[
+            ("new", "NEW"),
+            ("offer_received", "OFFER RECEIVED"),
+            ("offer_accepted", "OFFER ACCEPTED"),
+            ("sold", "SOLD"),
+            ("cancelled", "CANCELLED"),
+        ],
+    )
+
+    property_type_id = fields.Many2one(comodel_name="estate.property.type")
+    user_id = fields.Many2one(
+        comodel_name="res.users",
+        string="Salesperson",
+        default=lambda self: self.env.user,
+    )
+    partner_id = fields.Many2one(comodel_name="res.partner", string="Buyer", copy=False)
+    property_tag_ids = fields.Many2many(comodel_name="estate.property.tag")
+    property_offer_ids = fields.One2many("estate.property.offer", "property_id")
+
+    total_area = fields.Integer(compute="_compute_total_area")
+    best_price = fields.Float(compute="_compute_best_price")
+
+    _sql_constraints = [
+        (
+            "check_expected_price",
+            "CHECK(expected_price >= 0)",
+            "Property expected price MUST be postive.",
+        ),
+        (
+            "check_selling_price",
+            "CHECK(selling_price >= 0)",
+            "Property selling price MUST be postive.",
+        ),
+    ]
+
+    @api.constrains("expected_price", "selling_price")
+    def _check_selling_price(self):
+        for record in self:
+            if float_is_zero(record.selling_price, precision_digits=2):
+                continue
+            if (
+                float_compare(
+                    value1=record.selling_price,
+                    value2=(0.9 * record.expected_price),
+                    precision_digits=2,
+                )
+                == -1
+            ):
+                raise ValidationError(
+                    "Property selling price  MUST be 90% at least of the expected price."
+                )
+
+    @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("property_offer_ids.price")
+    def _compute_best_price(self):
+        for record in self:
+            record.best_price = max(
+                record.property_offer_ids.mapped("price"), default=0
+            )
+
+    @api.onchange("garden")
+    def _onchange_garden(self):
+        self.garden_area = 10 if self.garden else 0
+        self.garden_orientation = "north" if self.garden else ""
+
+    def action_set_cancelled(self):
+        self.ensure_one()
+        if self.state == "cancelled":
+            raise UserError("Cancelled Items cannot be sold.")
+        self.state = "sold"
+        return True
+
+
+    def action_set_sold(self):
+        for record in self:
+            if record.state == "sold":
+                raise UserError("Sold Items cannot be cancelled.")
+            record.state = "cancelled"
+        return True
+
+
+    def action_process_accept(self, offer):
+        self.ensure_one()
+        if self.state == "offer_accepted":
+            raise UserError("this property has already an accepted offer!!")
+        self.state = "offer_accepted"
+        self.selling_price = offer.price
+        self.partner_id = offer.partner_id
+        return True
+
+
+    @api.ondelete(at_uninstall=False)
+    def _unlink_property(self):
+        for record in self:
+            if record.state not in ('new','cancelled'):
+                raise UserError("Error, It CANNOT be deleted")
diff --git a/estate/models/estate_property_offer.py b/estate/models/estate_property_offer.py
new file mode 100644
index 00000000000..3718bd0086d
--- /dev/null
+++ b/estate/models/estate_property_offer.py
@@ -0,0 +1,69 @@
+from datetime import timedelta
+from odoo import api, fields, models
+from odoo.exceptions import UserError, ValidationError
+
+
+class EstatePropertyType(models.Model):
+    _name = "estate.property.offer"
+    _description = "Offers for real state properties"
+    _order = "price desc"
+
+
+    validity = fields.Integer(string="Validity (Days)", default=7)
+
+    price = fields.Float()
+    status = fields.Selection(
+        selection=[("accepted", "Accepted"), ("refused", "Refused")], copy=False
+    )
+    property_id = fields.Many2one(comodel_name="estate.property")
+    partner_id = fields.Many2one(comodel_name="res.partner", string="Buyer")
+
+    date_deadline = fields.Date(
+        compute="_compute_date_deadline", inverse="_inverse_date_deadline"
+    )
+    property_type_id = fields.Many2one(
+        comodel_name="estate.property.type",
+        related="property_id.property_type_id",
+        store=True,
+    )
+
+    _sql_constraints = [
+        ("check_price", "CHECK(price >= 0)", "Offer prices MUST be postive."),
+    ]
+
+    def action_accept(self):
+        self.ensure_one()
+        self.property_id.action_process_accept(self)
+        self.status = "accepted"
+        return True
+
+
+    def action_refuse(self):
+        self.ensure_one()
+        self.status = "refused"
+        return True
+
+    @api.depends("validity", "create_date")
+    def _compute_date_deadline(self):
+        for record in self:
+            if not record.create_date:
+                record.create_date = fields.Date.today()
+            record.date_deadline = record.create_date + timedelta(days=record.validity)
+
+    def _inverse_date_deadline(self):
+        for record in self:
+            record.validity = (record.date_deadline - record.create_date.date()).days
+
+
+    @api.model_create_multi
+    def create(self, vals):
+        property_record = self.env['estate.property'].browse(vals['property_id'])
+        existing_offers = self.search([
+            ('property_id', '=', vals['property_id'])
+        ])
+        if any(offer.price >= vals['price'] for offer in existing_offers):
+            raise ValidationError(
+                "Error, You CANNOT create an offer with a lower price than an existing one."
+            )
+        property_record.state = 'offer_received'
+        return super().create(vals)
diff --git a/estate/models/estate_property_tag.py b/estate/models/estate_property_tag.py
new file mode 100644
index 00000000000..1cf18028229
--- /dev/null
+++ b/estate/models/estate_property_tag.py
@@ -0,0 +1,15 @@
+from odoo import fields, models
+
+
+class EstatePropertyType(models.Model):
+    _name = "estate.property.tag"
+    _description = "Tags for real state properties"
+    _order = "name"
+
+
+    name = fields.Char(required=True)
+    color = fields.Integer(string='Color', default=0)
+
+    _sql_constraints = [
+        ("check_name", "UNIQUE(name)", "Tag names MUST be unique."),
+    ]
diff --git a/estate/models/estate_property_type.py b/estate/models/estate_property_type.py
new file mode 100644
index 00000000000..278cf102ce4
--- /dev/null
+++ b/estate/models/estate_property_type.py
@@ -0,0 +1,26 @@
+from odoo import api, fields, models
+
+
+class EstatePropertyType(models.Model):
+    _name = "estate.property.type"
+    _description = "Types for real state properties"
+    _order = "sequence, name"
+
+
+    name = fields.Char(required=True)
+    property_ids = fields.One2many('estate.property','property_type_id', string= 'Properties')
+    sequence = fields.Integer('Sequence', default=1, help="Used to order types. Higher is more used.")
+    offer_ids = fields.One2many(
+        comodel_name="estate.property.offer", inverse_name="property_type_id"
+    )
+    offer_count = fields.Integer(compute="_compute_offer_count")
+
+    @api.depends("offer_ids")
+    def _compute_offer_count(self):
+        for record in self:
+            record.offer_count = len(record.offer_ids)
+
+
+    _sql_constraints = [
+        ("check_name", "UNIQUE(name)", "Type Names MUST be unique."),
+    ]
diff --git a/estate/models/res_users.py b/estate/models/res_users.py
new file mode 100644
index 00000000000..676c2d06c88
--- /dev/null
+++ b/estate/models/res_users.py
@@ -0,0 +1,12 @@
+from odoo import fields, models
+
+
+class Users(models.Model):
+    _inherit = "res.users"
+
+    property_ids = fields.One2many(
+        comodel_name="estate.property",
+        inverse_name="user_id",
+        string='Available Properties',
+        domain=["|", ("state", "=", "new"), ("state", "=", "offer_received")],
+    )
diff --git a/estate/security/ir.model.access.csv b/estate/security/ir.model.access.csv
new file mode 100644
index 00000000000..5d6ae781d33
--- /dev/null
+++ b/estate/security/ir.model.access.csv
@@ -0,0 +1,5 @@
+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_type,access_estate_property_type,model_estate_property_type,base.group_user,1,1,1,1
+access_estate_property_tag,access_estate_property_tag,model_estate_property_tag,base.group_user,1,1,1,1
+access_estate_property_offer,access_estate_property_offer,model_estate_property_offer,base.group_user,1,1,1,1
diff --git a/estate/views/estate_menues.xml b/estate/views/estate_menues.xml
new file mode 100644
index 00000000000..855e960b03f
--- /dev/null
+++ b/estate/views/estate_menues.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<odoo>
+    <menuitem id="estate_property_menu_root" name="Real Estate Property">
+        <menuitem id="estate_property_first_level_menu" name="Advertisements">
+            <menuitem id="estate_property_second_level_menu" name="Properties">
+                <menuitem id="estate_property_menu_action" action="estate_property_action"/>
+            </menuitem>
+        </menuitem>
+        <menuitem id="settings_menue" name="Settings">
+                <menuitem id="estate_property_type_menu_action" action="estate_property_type_action"/>
+                <menuitem id="estate_property_tag_menu_action" action="estate_property_tag_action"/>
+        </menuitem>
+    </menuitem>
+
+
+</odoo>
diff --git a/estate/views/estate_property_offer_views.xml b/estate/views/estate_property_offer_views.xml
new file mode 100644
index 00000000000..f7ba3769f61
--- /dev/null
+++ b/estate/views/estate_property_offer_views.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0"?>
+<odoo>
+
+    <record id="estate_property_offer_action" model="ir.actions.act_window">
+        <field name="name">Offers</field>
+        <field name="res_model">estate.property.offer</field>
+        <field name="view_mode">list,form</field>
+        <field name="domain">[('property_type_id', '=', active_id)]</field>
+    </record>
+
+    <record id="estate_property_offer_view_tree" model="ir.ui.view">
+        <field name="name">estate.property.offer.list</field>
+        <field name="model">estate.property.offer</field>
+        <field name="arch" type="xml">
+            <list string="Offers" editable="bottom" decoration-danger="status == 'refused'" decoration-success="status == 'accepted'">
+                <field name="price" string="Price" width="120px"/>
+                <field name="partner_id" string="Partner" width="170px"/>
+                <field name="validity" />
+                <field name="date_deadline" string="Deadline"/>
+                <field name="property_type_id" string="Property Type"/>
+                <button name="action_accept" string="Accept" type="object" icon="fa-check" invisible="status"/>
+                <button name="action_refuse" string="Refuse" type="object" icon="fa-times" invisible="status"/>
+            </list>
+        </field>
+    </record>
+
+    <record id="estate_property_offer_view_form" model="ir.ui.view">
+        <field name="name">estate.property.offer.form</field>
+        <field name="model">estate.property.offer</field>
+        <field name="arch" type="xml">
+            <form string="Create a new Offer">
+                <group>
+                    <field name="price" string="Price" />
+                    <field name="partner_id" string="Partner" />
+                    <field name="validity" />
+                    <field name="date_deadline" string="Deadline"/>
+                </group>
+            </form>
+        </field>
+    </record>
+</odoo>
diff --git a/estate/views/estate_property_tag_views.xml b/estate/views/estate_property_tag_views.xml
new file mode 100644
index 00000000000..5c5f8da7d61
--- /dev/null
+++ b/estate/views/estate_property_tag_views.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0"?>
+<odoo>
+
+    <record id="estate_property_tag_action" model="ir.actions.act_window">
+        <field name="name">Tags</field>
+        <field name="res_model">estate.property.tag</field>
+        <field name="view_mode">list,form</field>
+    </record>
+    <record id="estate_property_tag_view_list" model="ir.ui.view">
+        <field name="name">estate.property.tag.list</field>
+        <field name="model">estate.property.tag</field>
+        <field name="arch" type="xml">
+            <list string="Tags" editable="bottom">
+                <field name="name" string="Tag"/>
+            </list>
+        </field>
+    </record>
+    <record id="estate_property_type_view_form" model="ir.ui.view">
+        <field name="name">estate.property.tag.form</field>
+        <field name="model">estate.property.tag</field>
+        <field name="arch" type="xml">
+            <form string="Tags">
+                <sheet>
+                    <h1>
+                        <field name="name" string="Property Tag" placeholder="Property Tag"/>
+                    </h1>
+                </sheet>
+            </form>
+        </field>
+    </record>
+</odoo>
diff --git a/estate/views/estate_property_type_views.xml b/estate/views/estate_property_type_views.xml
new file mode 100644
index 00000000000..550a9800348
--- /dev/null
+++ b/estate/views/estate_property_type_views.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0"?>
+<odoo>
+
+    <record id="estate_property_type_action" model="ir.actions.act_window">
+        <field name="name">Types</field>
+        <field name="res_model">estate.property.type</field>
+        <field name="view_mode">list,form</field>
+    </record>
+
+    <record id="estate_property_types_view_tree" model="ir.ui.view">
+        <field name="name">estate.property.type.list</field>
+        <field name="model">estate.property.type</field>
+        <field name="arch" type="xml">
+            <list string="Property Types">
+                <field name="name" string="Title" width="120px"/>
+                <field name="sequence" widget="handle"/>
+            </list>
+        </field>
+    </record>
+    
+    <record id="estate_property_types_view_form" model="ir.ui.view">
+        <field name="name">estate.property.type.form</field>
+        <field name="model">estate.property.type</field>
+        <field name="arch" type="xml">
+            <form string="Property Types">
+                <sheet>
+                    <div name="button_box" class="oe_button_box">
+                        <button name="%(estate.estate_property_offer_action)d"
+                            class="oe_stat_button"
+                            icon="fa-money"
+                            type="action">
+                            <field name="offer_count" widget="statinfo" string="Offers"/>
+                        </button>
+                    </div>
+                    <header>
+                        <h1>
+                            <field name="name"/>
+                        </h1>
+                    </header>
+                    <notebook>
+                        <page string="Properties">
+                            <field name="property_ids">
+                                <list>
+                                    <field name="name" string="Title"/>
+                                    <field name="expected_price" string="Expected Price"/>
+                                    <field name="state" string="Status"/>
+                                </list>
+                            </field>
+                        </page>
+                    </notebook>
+                </sheet>
+            </form>
+        </field>
+    </record>
+</odoo>
diff --git a/estate/views/estate_property_views.xml b/estate/views/estate_property_views.xml
new file mode 100644
index 00000000000..920ae6ca5c6
--- /dev/null
+++ b/estate/views/estate_property_views.xml
@@ -0,0 +1,146 @@
+<?xml version="1.0"?>
+<odoo>
+
+    <record id="estate_property_action" model="ir.actions.act_window">
+        <field name="name">Properties</field>
+        <field name="res_model">estate.property</field>
+        <field name="view_mode">list,form,kanban</field>
+        <field name="context">{'search_default_available': True}</field>
+
+    </record>
+
+    <record id="estate_property_view_search" model="ir.ui.view">
+        <field name="name">estate.property.search</field>
+        <field name="model">estate.property</field>
+        <field name="arch" type="xml">
+            <search string="Properties">
+                <field name="name" string="Ttile"/>
+                <field name="postcode" string="Postcode"/>
+                <field name="expected_price" string="Expected Price"/>
+                <field name="bedrooms" string="Bedrooms"/>
+                <field name="living_area" string="Living Area (sqm)" filter_domain="[('living_area', '&gt;=', self)]"/>
+                <field name="selling_price" string="Selling Price"/>
+                <field name="date_availability" string="Availabe From"/>
+                <separator/>
+                <filter string="Available" name="available" domain="[('state', 'in', ('new','offer_received'))]"/>
+                <group expand="1" string="Postcode">
+                    <filter string="Postcode" name="postcode" context="{'group_by':'postcode'}"/>
+                </group>
+            </search>
+        </field>
+    </record>
+    <record id="estate_property_view_tree" model="ir.ui.view">
+        <field name="name">estate.property.list</field>
+        <field name="model">estate.property</field>
+        <field name="arch" type="xml">
+            <list string="Properties" decoration-success="state in ('offer_received', 'offer_accepted')" decoration-bf="state == 'offer_accepted'" decoration-muted="state == 'sold'">
+                <field name="name" string="Title" width="120px"/>
+                <field name="postcode" string="Postcode"/>
+                <field name="property_tag_ids" string="Tags" widget="many2many_tags" options="{'color_field': 'color'}"/>
+                <field name="expected_price" string="Expected Price"/>
+                <field name="bedrooms" string="Bedrooms"/>
+                <field name="living_area" string="Living Area (sqm)"/>
+                <field name="facades" string="Facades"/>
+                <field name="property_type_id" string="Types"/>
+                <field name="date_availability" string="Available From" optional="hide"/>
+            </list>
+        </field>
+    </record>
+    <record id="estate_property_view_kanban" model="ir.ui.view">
+        <field name="name">estate.property.kanban</field>
+        <field name="model">estate.property</field>
+        <field name="arch" type="xml">
+            <kanban default_group_by="property_type_id" records_draggable='false'>
+                <field name="state"/>
+                <templates>
+                    <t t-name="card">
+                        <div>
+                                <main class="ms-2">
+                                    <div class="o_kanban_record_headings mt5">
+                                        <span>
+                                            <field name="name"/>
+                                        </span>
+                                    </div>
+                                    <div>
+                                        <span>Expected Price:</span>
+                                        <field name="expected_price"/>
+                                    </div>
+                                    <div t-if="record.state.raw_value == 'offer_received'">
+                                        <span>Best Offer:</span>
+                                        <field name="best_price"/>
+                                    </div>
+                                    <div t-if="record.state.raw_value == 'offer_accepted'">
+                                        <span>Selling Price:</span>
+                                        <field name="selling_price"/>
+                                    </div>
+                                    <div>
+                                        <field name="property_tag_ids" options="{'color_field': 'color'}"/>
+                                    </div>
+                                </main>
+                        </div>
+                    </t>
+                </templates>
+            </kanban>
+        </field>
+    </record>
+    <record id="estate_property_view_form" model="ir.ui.view">
+        <field name="name">estate.property.form</field>
+        <field name="model">estate.property</field>
+        <field name="arch" type="xml">
+            <form string="Properties">
+                <sheet>
+                    <header>
+                        <button name="action_set_cancelled" string="Cancel" type="object" invisible="state in ('sold', 'cancelled')"/>
+                        <button name="action_set_sold"  string="Sold" class="oe_highlight" type="object" invisible="state in ('sold', 'cancelled')"/>
+                        <field name="state" widget="statusbar" statusbar_visible="new,offer_received,offer_accepted, sold"/>
+                    </header>
+                    <group>
+                        <h1>
+                            <field name="name" string="Title" placeholder="Property Title"/>
+                        </h1>
+                        <field name="property_tag_ids" widget="many2many_tags" options="{'color_field': 'color'}"/>
+                    </group>
+                    <group>
+                        <group>
+                            <field name="property_type_id" string="Property Type" options="{'no_create': true}"/>
+                            <field name="postcode" string="Postcode"/>
+                            <field name="date_availability" string="Availabe From"/>
+                        </group>
+                        <group>
+                            <field name="expected_price" string="Expected Price"/>
+                            <field name="best_price" string="Best Offer"/>
+                            <field name="selling_price" string="Selling Price"/>
+                        </group>
+                    </group>
+                    <notebook>
+                        <page string="Description">
+                            <group>
+                                <field name="bedrooms" string="Bedrooms"/>
+                                <field name="living_area" string="Living Area (sqm)"/>
+                                <field name="facades" string="Facades"/>
+                                <field name="garage" string="Garage"/>
+                                <field name="garden" string="Garden"/>
+                                <field name="garden_area" string="Garden Area" invisible="not garden"/>
+                                <field name="garden_orientation" string="Garden Orientation" invisible="not garden"/>
+                                <field name="total_area" string="Total Area"/>
+                                <field name="description" string="Description"/>
+                            </group>
+                        </page>
+                        <page string="Other Info">
+                            <group>
+                                <field name="partner_id" string="Salesman"/>
+                                <field name="user_id" string="Buyer"/>
+                            </group>
+                        </page>
+                        <page string="Offers">
+                            <field name="property_offer_ids" readonly="state in ('offer_accepted', 'sold', 'cancelled')"/>
+                        </page>
+                    </notebook>
+                </sheet>
+            </form>
+        </field>
+    </record>
+
+
+
+</odoo>
diff --git a/estate/views/res_users_views.xml b/estate/views/res_users_views.xml
new file mode 100644
index 00000000000..7e8857c7e3a
--- /dev/null
+++ b/estate/views/res_users_views.xml
@@ -0,0 +1,15 @@
+<?xml version='1.0' encoding='utf-8'?>
+<odoo>
+    <record id="res_users_inherit_property_view_form" model="ir.ui.view">
+        <field name="name">res.users.view.form.inherit.estate</field>
+        <field name="model">res.users</field>
+        <field name="inherit_id" ref="base.view_users_form"/>
+        <field name="arch" type="xml">
+             <notebook  position="inside">
+                <page string="Properties">
+                    <field name="property_ids" />
+                </page>
+            </notebook>
+        </field>
+    </record>
+</odoo>
diff --git a/estate_account/__init__.py b/estate_account/__init__.py
new file mode 100644
index 00000000000..0650744f6bc
--- /dev/null
+++ b/estate_account/__init__.py
@@ -0,0 +1 @@
+from . import models
diff --git a/estate_account/manifest.py b/estate_account/manifest.py
new file mode 100644
index 00000000000..50dfac7539f
--- /dev/null
+++ b/estate_account/manifest.py
@@ -0,0 +1,9 @@
+{
+    "name": "Sales Accounting",
+    "depends": ["estate", "account"],
+    "installable": True,
+    "license": "LGPL-3",
+    "data": [
+        "security/ir.model.access.csv",
+    ],
+}
diff --git a/estate_account/models/__init_.py b/estate_account/models/__init_.py
new file mode 100644
index 00000000000..5e1963c9d2f
--- /dev/null
+++ b/estate_account/models/__init_.py
@@ -0,0 +1 @@
+from . import estate_property
diff --git a/estate_account/models/estate_property.py b/estate_account/models/estate_property.py
new file mode 100644
index 00000000000..e06211186f9
--- /dev/null
+++ b/estate_account/models/estate_property.py
@@ -0,0 +1,30 @@
+from odoo import models, Command
+
+class EstateProperty(models.Model):
+    _inherit = "estate.property"
+
+    def action_set_sold(self):
+        self.ensure_one()
+        self.env["account.move"].create(
+            {
+                "partner_id": self.buyer_id.id,
+                "move_type": "out_invoice",
+                "invoice_line_ids": [
+                    Command.create(
+                        {
+                            "name": self.name,
+                            "quantity": 1,
+                            "price_unit": 0.06*self.selling_price,
+                        }
+                    ),
+                    Command.create(
+                        {
+                            "name": "Administrative Fees",
+                            "quantity": 1,
+                            "price_unit": 100,
+                        }
+                    ),
+                ],
+            }
+        )
+        return super().action_set_sold()