Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
b68a192
[FIX] website_airproof: fix template loading order issue
omarait-mlouk Sep 24, 2025
b7e18c9
[FIX] awesome_owl: Fix missing css variables
clbr-odoo Nov 21, 2025
781b590
[FIX] awesome_dashboard: Get rid of the deprecated warning
clbr-odoo Nov 21, 2025
bc75b91
[ADD] estate: initialize new application
ahmedamein100 Apr 22, 2026
703b451
[MOV] estate: move module to root
ahmedamein100 Apr 22, 2026
2b46f88
[ADD] estate: add property model and fields
ahmedamein100 Apr 22, 2026
2666fbd
[CLN] estate: fix formatting and typos
ahmedamein100 Apr 22, 2026
a1c6e1e
[ADD] estate: add access rights for property model
ahmedamein100 Apr 22, 2026
1fb914a
[CLN] estate: fix formatting and follow odoo guidelines
ahmedamein100 Apr 22, 2026
afbfbba
[CLN] estate: fix formatting and follow odoo guidelines
ahmedamein100 Apr 22, 2026
80d74ce
[CLN] estate: fix formatting and follow odoo guidelines
ahmedamein100 Apr 22, 2026
37bbff7
[ADD] estate: add basic UI and field business logic
ahmedamein100 Apr 22, 2026
39cd9c6
[FIX] estate: remove unlink permission for base users
vandroogenbd Apr 23, 2026
a930b33
[IMP] estate: add custom views and address PR feedback
ahmedamein100 Apr 23, 2026
b9b84e2
[ADD] estate: add relational models and fields
ahmedamein100 Apr 23, 2026
034623c
[FIX] estate: fix invalid search view definition
ahmedamein100 Apr 24, 2026
688ae48
[IMP] estate: add computed fields and onchange logic
ahmedamein100 Apr 24, 2026
f073812
[FIX] estate: fix python linting and styling issues
ahmedamein100 Apr 24, 2026
a8f5d11
[FIX] estate: fix python linting and styling issues
ahmedamein100 Apr 24, 2026
11467ce
[IMP] estate: add state management and offer actions
ahmedamein100 Apr 24, 2026
29377d5
[IMP] estate: add SQL and Python constraints for data integrity
ahmedamein100 Apr 24, 2026
9713b4c
[FIX] estate: clean up code styling
ahmedamein100 Apr 27, 2026
8e0f36c
[IMP] estate: add UI "sprinkles" and visual improvements
ahmedamein100 Apr 27, 2026
c6546c2
[CLN] estate: cleanup Python code and remove debug prints
ahmedamein100 Apr 27, 2026
4cec624
[CLN] estate: fix trailing whitespace in validation error
ahmedamein100 Apr 27, 2026
7df65a3
[CLN] estate: remove redundant invisible status field from offer list
ahmedamein100 Apr 27, 2026
158a5e3
[IMP] estate: add business logic and user inheritance
ahmedamein100 Apr 28, 2026
aafedb2
[IMP] estate: add basic test cases
vandroogenbd Apr 28, 2026
777efdb
[IMP] estate_account: link estate to account for invoicing
ahmedamein100 Apr 28, 2026
8a51cf8
[FIX] estate: enforce minimum price for south-facing gardens
ahmedamein100 Apr 28, 2026
ed456c8
[REF] estate: fix linting and PEP8 violations
ahmedamein100 Apr 28, 2026
e406286
[IMP] estate: implement advanced kanban view
ahmedamein100 Apr 29, 2026
27dac19
[FIX] estate: address review feedback on code standards
ahmedamein100 Apr 29, 2026
40e8c45
[REF] estate: fix whitespace and PEP8 linting violations
ahmedamein100 Apr 29, 2026
6d7c4d4
[FIX] estate: handle null create_date in offer deadline compute
ahmedamein100 Apr 29, 2026
02b6fb4
[REF] awesome_owl: implement Owl framework tutorial exercises
ahmedamein100 Apr 30, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -127,3 +127,6 @@ dmypy.json

# Pyre type checker
.pyre/

# IDE Settings
.vscode/
56 changes: 56 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
{
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should configure your global .gitignore to make sure such files don't get pushed to your PRs 😉

// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Python Debugger: Current File",
"type": "debugpy",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal"
},

{
"name": "Odoo Server",
"type": "debugpy",
"request": "launch",
"python": "/home/odoo/odoo/venv/bin/python3",
"program": "/home/odoo/odoo/odoo-bin",
"args" : [
"--addons-path", "/home/odoo/odoo/addons/,/home/enterprise/,/home/tutorials",
"-d", "rd_demo",
"--dev", "all",
"--without-demo", "all",
"-p", "8069",
"--limit-time-cpu", "0",
"--limit-time-real", "0",
// "-i", "",
],
"console": "integratedTerminal",
"variablePresentation": {}
},
{
"name": "Test Odoo",
// "preLaunchTask": "drop_test_db",
"type": "debugpy",
"request": "launch",
"program": "/home/odoo/odoo/odoo-bin",
"args" : [
"--addons-path", "/home/odoo/odoo/addons/,/home/enterprise/,/home/tutorials",
"-d", "DB_NAMEtest",
"-p", "8071",
"--limit-time-cpu", "0",
"--limit-time-real", "0",
"--without-demo", "all",
"--stop-after-init",
//"-i", "",
"--test-tags", "",
//"--log-level", "error",
],
"console": "integratedTerminal",
"variablePresentation": {}
}
]
}
59 changes: 59 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
{
"folders": [
{
"path": "/home/odoo/odoo"
},
{
"path": "/home/enterprise"
},
{
"path": "/home/tutorials"
}
],
"settings": {
"launch": {
"version": "0.2.0",
"configurations": [
{
"name": "Odoo Server",
"type": "debugpy",
"request": "launch",
"program": "/home/odoo/odoo/odoo-bin",
"args" : [
"--addons-path", "/home/odoo/odoo/addons/,/home/enterprise/,/home/tutorials",
"-d", "rd_demo",
"--dev", "all",
"--without-demo", "all",
"-p", "8069",
"--limit-time-cpu", "0",
"--limit-time-real", "0",
// "-i", "",
],
"console": "integratedTerminal",
"variablePresentation": {}
},
{
"name": "Test Odoo",
// "preLaunchTask": "drop_test_db",
"type": "debugpy",
"request": "launch",
"program": "/home/odoo/odoo/odoo-bin",
"args" : [
"--addons-path", "/home/odoo/odoo/addons/,/home/enterprise/,/home/tutorials",
"-d", "DB_NAMEtest",
"-p", "8071",
"--limit-time-cpu", "0",
"--limit-time-real", "0",
"--without-demo", "all",
"--stop-after-init",
//"-i", "",
"--test-tags", "",
//"--log-level", "error",
],
"console": "integratedTerminal",
"variablePresentation": {}
}
]
}
}
}
2 changes: 1 addition & 1 deletion awesome_dashboard/controllers/controllers.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
logger = logging.getLogger(__name__)

class AwesomeDashboard(http.Controller):
@http.route('/awesome_dashboard/statistics', type='json', auth='user')
@http.route('/awesome_dashboard/statistics', type='jsonrpc', auth='user')
def get_statistics(self):
"""
Returns a dict of statistics about the orders:
Expand Down
2 changes: 2 additions & 0 deletions awesome_owl/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@
'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',
Expand Down
20 changes: 20 additions & 0 deletions awesome_owl/static/src/card/card.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Component, useState } from "@odoo/owl";

export class Card extends Component {
static template = "awesome_owl.card";
static props = {
title: String,
slots: {
type: Object,
optional: true,
},
};

setup() {
this.state = useState({ isOpen: true });
}

toggle() {
this.state.isOpen = !this.state.isOpen;
}
}
19 changes: 19 additions & 0 deletions awesome_owl/static/src/card/card.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8" ?>
<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">
<div class="d-flex justify-content-between align-items-center mb-2">
<h5 class="card-title mb-0" t-esc="props.title"/>
<button class="btn btn-sm btn-light" t-on-click="toggle">
<i t-att-class="state.isOpen ? 'fa fa-chevron-up' : 'fa fa-chevron-down'"/>
</button>
</div>

<div t-if="state.isOpen" class="card-text">
<t t-slot="default"/>
</div>
</div>
</div>
</t>
</templates>
19 changes: 19 additions & 0 deletions awesome_owl/static/src/counter/counter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
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({ value: 0 });
}

increment() {
this.state.value++;
if (this.props.onChange) {
this.props.onChange();
}
}
}
11 changes: 11 additions & 0 deletions awesome_owl/static/src/counter/counter.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<templates xml:space="preserve">
<t t-name="awesome_owl.counter">
<div>
<p>Counter: <t t-esc="state.value"/></p>
<button class="btn btn-primary" t-on-click="increment">
Increment
</button>
</div>
</t>
</templates>
15 changes: 14 additions & 1 deletion awesome_owl/static/src/playground.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
import { Component } from "@odoo/owl";
import { Component, useState, markup } from "@odoo/owl";
import { Counter } from "./counter/counter";
import { Card } from "./card/card";
import { TodoList } from "./todo/todoList";

export class Playground extends Component {
static template = "awesome_owl.playground";
static components = { Card, Counter, TodoList };

setup() {
this.htmlContent = markup("<em class='text-success'>some content!</em>");
this.state = useState({ sum: 2 });
}

incrementSum = () => {
this.state.sum++;
}
}
9 changes: 7 additions & 2 deletions awesome_owl/static/src/playground.xml
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
<?xml version="1.0" encoding="UTF-8" ?>
<templates xml:space="preserve">

<t t-name="awesome_owl.playground">
<div class="p-3">
hello world
</div>
<Counter onChange='incrementSum.bind'/>
<Counter onChange='incrementSum.bind'/>
<Card title="'card 2'">
<Counter/>
</Card>
<strong>Sum: <t t-esc="state.sum"/></strong>
<TodoList/>
</t>

</templates>
26 changes: 26 additions & 0 deletions awesome_owl/static/src/todo/todoItem.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Component } from "@odoo/owl";

export class TodoItem extends Component {
static template = "awesome_owl.todoItem";
static props = {
todo: {
type: Object,
shape: {
id: Number,
description: String,
isCompleted: Boolean,
},
},
toggleTodo: Function,
removeTodo: Function
};


onToggleState() {
this.props.toggleTodo(this.props.todo.id);
}

onDelete(){
this.props.removeTodo(this.props.todo.id)
}
}
39 changes: 39 additions & 0 deletions awesome_owl/static/src/todo/todoList.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { Component, useState, useRef, onMounted } from "@odoo/owl";
import { TodoItem } from "./todoItem";
import { useAutofocus } from "../utils/useAutofocus";

export class TodoList extends Component {
static template = "awesome_owl.todoList";
static components = { TodoItem };

setup() {
this.nextId = 1
this.todos = useState([]);
this.inputRef = useAutofocus('todo_input');
}

addTodo(ev) {
if (ev.keyCode === 13 && ev.target.value.trim() !== "") {
this.todos.push({
id: this.nextId++,
description: ev.target.value,
isCompleted: false,
});
ev.target.value = "";
}
}

toggleTodo = (todoId) => {
const todo = this.todos.find((t) => t.id === todoId);
if (todo) {
todo.isCompleted = !todo.isCompleted;
}
}

removeTodo = (todoId) => {
const index = this.todos.findIndex((t) => t.id === todoId);
if (index >= 0) {
this.todos.splice(index, 1);
}
}
}
21 changes: 21 additions & 0 deletions awesome_owl/static/src/todo/todo_item.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8" ?>
<templates xml:space="preserve">
<t t-name="awesome_owl.todoItem">
<div class="p-2 border-bottom d-flex align-items-center">
<input type="checkbox"
t-att-id="'todo_' + props.todo.id"
class="form-check-input me-2"
t-att-checked="props.todo.isCompleted"
t-on-change="onToggleState"/>

<label t-att-for="'todo_' + props.todo.id" class="flex-grow-1 mb-0"
t-att-class="props.todo.isCompleted ? 'text-muted text-decoration-line-through' : ''"
>
<t t-esc="props.todo.id"/>. <t t-esc="props.todo.description"/>
</label>
<span class="fa fa-remove text-danger ms-auto"
style="cursor: pointer;"
t-on-click="onDelete"/>
</div>
</t>
</templates>
17 changes: 17 additions & 0 deletions awesome_owl/static/src/todo/todo_list.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8" ?>
<templates xml:space="preserve">
<t t-name="awesome_owl.todoList">
<div class="todo-list shadow-sm p-3 mb-5 bg-white rounded">
<h3>To-do List</h3>
<input type="text"
class="form-control mb-3"
placeholder="Enter a new task..."
t-on-keydown="addTodo"
t-ref="todo_input"
/>
<t t-foreach="todos" t-as="todo" t-key="todo.id">
<TodoItem todo="todo" toggleTodo="toggleTodo" removeTodo="removeTodo"/>
</t>
</div>
</t>
</templates>
12 changes: 12 additions & 0 deletions awesome_owl/static/src/utils/useAutofocus.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { useRef, onMounted } from "@odoo/owl";


export function useAutofocus(name) {
const ref = useRef(name);
onMounted(() => {
if (ref.el) {
ref.el.focus();
}
});
return ref;
}
1 change: 1 addition & 0 deletions estate/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
Loading