Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
684e72d
[ADD] estate - Chapter 2 - add estate module
qugeo-odoo Mar 19, 2026
136d6ae
[MOV] estate : fix module init file name
qugeo-odoo Mar 19, 2026
e1b1c09
[IMP] estate: Chapter 3 - add estate property model
qugeo-odoo Mar 19, 2026
4eef21d
[IMP] estate : Chapter 4 - add access rights to esate property model
qugeo-odoo Mar 19, 2026
763d86b
[IMP] estate: add license
qugeo-odoo Mar 20, 2026
cce883f
[IMP] estate: Chapter 5 - add menus and related action
qugeo-odoo Mar 20, 2026
b81747c
[FIX] estate : fix dot notation of module name
qugeo-odoo Mar 20, 2026
31f25f2
[IMP] estate : Chapter 5 - add new fields and attributes to the model
qugeo-odoo Mar 20, 2026
78b121d
[IMP] estate: Chapter 6 - add form and list views for properties
qugeo-odoo Mar 22, 2026
bf131bb
[IMP] estate: Chapter 6 - Add search view for properties with availab…
qugeo-odoo Mar 22, 2026
87dc5e1
[FIX] estate: rename menu items
qugeo-odoo Mar 22, 2026
ed135b9
[IMP] estate: Chapter 7 - Add property types, tags and offers
qugeo-odoo Mar 23, 2026
c5896c9
[CLN] estate: remove extra spaces and fix quote usage
qugeo-odoo Mar 23, 2026
fde75c1
[FIX] estate: set Odoo as author
qugeo-odoo Mar 23, 2026
eceb38a
[FIX] estate: move string attributes from views to models
qugeo-odoo Mar 23, 2026
ad9f755
[FIX] estate: remove redundant module ref in access rules
qugeo-odoo Mar 23, 2026
4ba968b
[IMP] estate: Chapter 8 - Add validty and deadline to offers, add bes…
qugeo-odoo Mar 23, 2026
c9e118f
[IMP] estate: Chapter 9 - Add action button on properties and offers …
qugeo-odoo Mar 24, 2026
25ca60d
[IMP] estate: Chapter 10 - Add constraints on expected price, selling…
qugeo-odoo Mar 24, 2026
8c502aa
[CLN] estate: fix quote usage
qugeo-odoo Mar 24, 2026
e9c1197
[IMP] estate: Chapter 11 - Add in-line list view in property type for…
qugeo-odoo Mar 24, 2026
c725a00
[IMP] estate: remove cancelled state from the status bar in property …
qugeo-odoo Mar 24, 2026
d1ecd37
[IMP] estate: Add default ordering to property, type, tag and offer m…
qugeo-odoo Mar 24, 2026
c92c716
[IMP] estate: Add property type list view with manual ordering
qugeo-odoo Mar 24, 2026
79c8456
[IMP] estate: Add color picker to tags and prevent creation and editi…
qugeo-odoo Mar 24, 2026
8130698
[IMP] estate: use manual ordering in the default ordering of property…
qugeo-odoo Mar 24, 2026
37d08bd
[IMP] estate: Hide property and offer buttons based on state. Hide ga…
qugeo-odoo Mar 24, 2026
c164e22
[IMP] estate: add tag list view and make the offer and tag list views…
qugeo-odoo Mar 24, 2026
690b668
[IMP] estate: Make date availability optional in list view
qugeo-odoo Mar 24, 2026
d907b0e
[IMP] estate: Add list decorations to properties and offers based on …
qugeo-odoo Mar 24, 2026
c5f1ec4
[IMP] estate: add available properties as a default filter on the pro…
qugeo-odoo Mar 24, 2026
2144550
[IMP] estate: Add filter domain for living area in property search
qugeo-odoo Mar 24, 2026
f3b2b89
[IMP] estate: Add related offer smart button in property type list view.
qugeo-odoo Mar 24, 2026
b89b0f1
[IMP] estate: Chapter 12 - prevent offer creation if price is inferio…
qugeo-odoo Mar 25, 2026
05d2281
[IMP] estate: add property type and tags to property list view
qugeo-odoo Mar 25, 2026
448d9a2
[IMP] estate: extend res.user model and view with available properties
qugeo-odoo Mar 25, 2026
068ced1
[ADD] estate_account: Create Estate Account module to enable property…
qugeo-odoo Mar 25, 2026
9783a74
[IMP] estate: Chapter 14 - Add kanban view for properties
qugeo-odoo Mar 25, 2026
7c8adb2
[CLN] estate: Chapter 5 - Merge view files together
qugeo-odoo Mar 25, 2026
de60394
[CLN] estate_account: remove print and unused import
qugeo-odoo Mar 25, 2026
48677c5
[CLN] estate & estate_account: rename actions
qugeo-odoo Mar 25, 2026
f96ac94
[LNT] estate & estate_account
qugeo-odoo Mar 25, 2026
ae038fe
[LINT] estate & estate_account
qugeo-odoo Mar 25, 2026
3f60fc3
[LINT] estate
qugeo-odoo Mar 25, 2026
31a55cc
[LINT] estate_account
qugeo-odoo Mar 25, 2026
4ab872b
[FIX] estate, estate_account: Remove module name from actions. Handle…
qugeo-odoo Mar 26, 2026
f61b33c
[FIX] estate: Name model resUsers
qugeo-odoo Mar 26, 2026
50c914d
[FIX] estate_account: Name model EstateProperty
qugeo-odoo Mar 26, 2026
1adfd0f
[CLN] estate: reorder code blocks, fix quotes
qugeo-odoo Mar 26, 2026
382394e
[CLN] estate, estate_account: fix quotes
qugeo-odoo Mar 26, 2026
e1ead19
[CLN] estate: reorder code blocks
qugeo-odoo Mar 26, 2026
87a9d48
[CLN] estate: delete if parenthesis
qugeo-odoo Mar 26, 2026
cc7e197
[CLN] estate: Import exceptions directly
qugeo-odoo Mar 26, 2026
382fb8a
[CLN] estate: simplify action logic
qugeo-odoo Mar 26, 2026
80a6f15
[IMP] estate: Add error translations
qugeo-odoo Mar 26, 2026
2d95f74
[CLN] estate: use set instead of array in condition
qugeo-odoo Mar 26, 2026
ba2ff87
[CLN] estate_account: Remove redundant base module dependency
qugeo-odoo Mar 26, 2026
3a62dc3
[CLN] estate: Fix quotes in xml
qugeo-odoo Mar 26, 2026
7567d2e
[CLN] estate: add missing trailing comma
qugeo-odoo Mar 26, 2026
6f4d863
[CLN] estate: simplify action logic
qugeo-odoo Mar 26, 2026
8dec08e
[IMP] awewsome_owl: Chapter 1 - Add counter
qugeo-odoo Mar 26, 2026
b06f16e
[IMP] awewsome_owl: Chapter 2
qugeo-odoo Mar 26, 2026
c6df338
[IMP] awewsome_owl: Chapter 3
qugeo-odoo Mar 26, 2026
89b89ed
[IMP] awewsome_owl: Chapter 4
qugeo-odoo Mar 26, 2026
bce1ecf
[IMP] awewsome_owl: Chapter 5
qugeo-odoo Mar 26, 2026
821297f
[IMP] awewsome_owl: Chapter 6
qugeo-odoo Mar 26, 2026
b9385e8
[IMP] awewsome_owl: Chapter 7
qugeo-odoo Mar 26, 2026
2fef72d
[IMP] awewsome_owl: Chapter 8
qugeo-odoo Mar 26, 2026
ee549a5
[IMP] awewsome_owl: Chapter 10
qugeo-odoo Mar 27, 2026
2a175f9
[IMP] awewsome_owl: Chapter 11
qugeo-odoo Mar 27, 2026
06eb246
[IMP] awewsome_owl: Chapter 12
qugeo-odoo Mar 27, 2026
f052144
[IMP] awewsome_owl: Chapter 13
qugeo-odoo Mar 27, 2026
6654b14
[IMP] awewsome_owl: Chapter 14
qugeo-odoo Mar 27, 2026
ffe5ca4
[IMP] awewsome_dashboard: Chapter 4
qugeo-odoo Mar 27, 2026
e898cac
[IMP] awewsome_dashboard: Chapter 5
qugeo-odoo Mar 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
43 changes: 42 additions & 1 deletion awesome_dashboard/static/src/dashboard.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,49 @@
import { Component } from "@odoo/owl";
import { Component, useState, onWillStart } from "@odoo/owl";
import { registry } from "@web/core/registry";
import { Layout } from "@web/search/layout";
import { useService } from "@web/core/utils/hooks";
import { DashboardItem } from "./dashboard_item/dashboard_item";


class AwesomeDashboard extends Component {
static template = "awesome_dashboard.AwesomeDashboard";
static components = { Layout, DashboardItem };

setup(){
this.statisticsService = useService("awesome_dashboard.statistics");
this.action = useService("action");
this.display = useState({
controlPanel: {}
});
this.stats = useState({});
onWillStart(async () => {
const result = await this.statisticsService.loadStatistics();
this.stats = result;
})
}

openCustomers() {
/* this.action.doAction("base.action_partner_form"); */
this.action.doAction({
type: 'ir.actions.act_window',
name: 'Customers',
/* target: 'new', */
res_model: 'res.partner',
views: [[false, 'kanban']],
})
}

openLeads() {
this.action.doAction({
type: 'ir.actions.act_window',
name: 'Leads',
target: 'current',
/* res_id: 'crm_lead_action', */
res_model: 'crm.lead',
views: [[false, 'list'],[false, 'form']],
})
}

}

registry.category("actions").add("awesome_dashboard.dashboard", AwesomeDashboard);
3 changes: 3 additions & 0 deletions awesome_dashboard/static/src/dashboard.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.o_dashboard {
background-color: gray;
}
28 changes: 28 additions & 0 deletions awesome_dashboard/static/src/dashboard.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,34 @@

<t t-name="awesome_dashboard.AwesomeDashboard">
hello dashboard

<Layout display="display" className="'o_dashboard h-100'">
<button t-on-click="openCustomers">Customers</button>
<button t-on-click="openLeads">Leads</button>

<DashboardItem t-if="stats">
Average amount of ... is
<span t-esc="stats.average_quantity"/>
</DashboardItem>
<DashboardItem t-if="stats">
Average time of ... is
<span t-esc="stats.average_time"/>
</DashboardItem>
<DashboardItem t-if="stats">
Number of cancelled orders is
<span t-esc="stats.nb_cancelled_orders"/>
</DashboardItem>
<DashboardItem t-if="stats">
Number of new orders is
<span t-esc="stats.nb_new_orders"/>
</DashboardItem>
<DashboardItem t-if="stats">
The total amount of new orders is
<span t-esc="stats.total_amount"/>
</DashboardItem>
</Layout>


</t>

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

export class DashboardItem extends Component {
static template = "awesome_dashboard.dashboard_item";
static props = {
size:{
type: Number,
optional: true,
default: 1,
}
}

setup(){
this.width = useState({value: this.props.size * 18})
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.card {
display: inline-block;
border: 1px solid grey;
padding: 10px;
}
12 changes: 12 additions & 0 deletions awesome_dashboard/static/src/dashboard_item/dashboard_item.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<templates xml:space="preserve">

<t t-name="awesome_dashboard.dashboard_item">

<span class="card" t-att-style="'width:'+width.value+'rem;'">
<t t-slot="default"/>
</span>

</t>

</templates>
14 changes: 14 additions & 0 deletions awesome_dashboard/static/src/statistics_service.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { registry } from "@web/core/registry";
import { rpc } from "@web/core/network/rpc";
import { memoize } from "@web/core/utils/functions";

const statistics_service = {
async: ["loadStatistics"],
start(env) {
return {
loadStatistics: memoize(() => rpc("/awesome_dashboard/statistics")),
}
}
}

registry.category("services").add("awesome_dashboard.statistics", statistics_service);
24 changes: 24 additions & 0 deletions awesome_owl/static/src/card/card.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { markup, Component, useState } from "@odoo/owl";

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

setup() {
this.state = useState({htmlLink: markup('<a href="/odoo" target="_blank">test</a>')})
this.isMinimized = useState({value: false});
}

toggle() {
this.isMinimized.value = !this.isMinimized.value;
}
}
15 changes: 15 additions & 0 deletions awesome_owl/static/src/card/card.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8" ?>
<templates xml:space="preserve">

<t t-name="awesome_owl.card">
<div class="p-3">
<div class="card d-inline-block m-2" style="width: 18rem;">
<div class="card-body" style="position:relative;">
<h5 class="card-title" t-esc="props.title"/>
<span style="position:absolute;top:10px;right:10px;border:1px solid lightgrey;padding:3px 10px;" t-on-click="toggle">+</span>
<p class="card-text" t-if="!isMinimized.value" t-slot="default"/>
</div>
</div>
</div>
</t>
</templates>
18 changes: 18 additions & 0 deletions awesome_owl/static/src/counter/counter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
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++;
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 class="p-3">
<div>Counter: <span t-esc="state.value"/> </div>
<button t-on-click="increment">Increment</button>
</div>
</t>

</templates>
14 changes: 13 additions & 1 deletion awesome_owl/static/src/playground.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
import { Component } from "@odoo/owl";
import { Component, useState } from "@odoo/owl";
import { Counter } from "./counter/counter";
import { Card } from "./card/card";
import { TodoList } from "./todo_list/todo_list";

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

setup(){
this.sum = useState({value: 0})
}

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

<t t-name="awesome_owl.playground">
<div class="p-3">
hello world
<h1>hello world</h1>
<div>Sum of counters: <span t-esc="sum.value"/></div>
<Card title="'Card 1'">
<p>
Random content 1
</p>
<Counter onChange.bind="incrementSum"/>
</Card>
<Card title="'Card 2'">
<p>
Random content 2
</p>
<Counter onChange.bind="incrementSum"/>
</Card>
</div>
<div>
<TodoList/>
</div>
</t>

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

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

change(){
this.props.toggleState(this.props.todo.id);
}
remove(){
this.props.removeTodo(this.props.todo.id);
}

}
15 changes: 15 additions & 0 deletions awesome_owl/static/src/todo_list/todo_item.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8" ?>
<templates xml:space="preserve">

<t t-name="awesome_owl.todo_item">
<div class="p-3" t-att-class="{'text-muted text-decoration-line-through': props.todo.isCompleted}">
<input type="checkbox" t-on-click="change"/>
[<t t-if="props.todo.isCompleted">X</t>
<t t-else="">_</t>]
<span t-esc="props.todo.id"></span> -
<span t-esc="props.todo.description"></span>
<span class="fa fa-remove" t-on-click="remove"/>
</div>
</t>

</templates>
41 changes: 41 additions & 0 deletions awesome_owl/static/src/todo_list/todo_list.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { Component, useState, useRef, onMounted } from "@odoo/owl";
import { TodoItem } from "./todo_item";

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

setup(){
this.todos = useState([]);
this.todoCount = 1;
this.inputRef = useRef('taskInput');

onMounted(()=>{
this.inputRef.el.focus();
})
}

addTask(e){
if(e.keyCode === 13 && e.target.value !== ""){
this.todos.push({
id: this.todoCount++,
description: e.target.value,
isCompleted: false,
})
e.target.value = "";
}
}

toggleState(id){
let todo = this.todos.find((todo) => todo.id === id);
todo.isCompleted = !todo.isCompleted;
}

removeTodo(id){
const index = this.todos.findIndex((todo) => todo.id === id);
if (index >= 0) {
this.todos.splice(index, 1);
}
}

}
11 changes: 11 additions & 0 deletions awesome_owl/static/src/todo_list/todo_list.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.todo_list">
<div class="p-3">
<input t-att-value="test" t-on-keyup="addTask" t-ref="taskInput" placeholder="Enter a new task"/>
<TodoItem t-foreach="todos" t-as="todo" t-key="todo.id" todo="todo" toggleState.bind="toggleState" removeTodo.bind="removeTodo"/>
</div>
</t>

</templates>
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
21 changes: 21 additions & 0 deletions estate/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
'name': 'estate',
'author': 'Odoo S.A.',
'depends': ['base'],
'application': True,
'license': 'LGPL-3',

'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/estate_menus.xml',

'views/res_users_view_form.xml',

],
}
5 changes: 5 additions & 0 deletions estate/models/__init__.py
Original file line number Diff line number Diff line change
@@ -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
Loading