Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
f28b1ca
[ADD] estate: added the Real Estate Modeule.
kapat-odoo Feb 9, 2026
cf2a062
[IMP] estate: implemented basic fields to property model
kapat-odoo Feb 10, 2026
001d481
[IMP] estate: implemented access rights for the estate module.
kapat-odoo Feb 11, 2026
820bdfe
[IMP] estate: implemented default list and form view for the estate m…
kapat-odoo Feb 13, 2026
a6b6fc1
[IMP] estate: added list and form views for estate along with search.
kapat-odoo Feb 16, 2026
ead4b4f
[IMP] estate: added relational models and fields for estate module.
kapat-odoo Feb 17, 2026
3cb3105
[IMP] estate: added compute fields and onchange to estate property an…
kapat-odoo Feb 19, 2026
e6bdc9e
[IMP] estate: implemented workflow actions with buttons and business …
kapat-odoo Feb 20, 2026
9710e75
[IMP] estate: implemented SQL and Python constraints.
kapat-odoo Feb 25, 2026
23cea2d
[IMP] estate: fixed according to suggestion.
kapat-odoo Feb 26, 2026
fcc3283
[IMP] estate: added demo data, enhanced UX along with business logic.
kapat-odoo Mar 2, 2026
d5a7c52
[IMP] estate: implemented inheritance and improved business logic.
kapat-odoo Mar 9, 2026
80dffb6
[ADD] estate_account: added estate_account for invoice, reports and c…
kapat-odoo Mar 12, 2026
00e6546
[IMP] estate: implemented kanban view for viewing properties.
kapat-odoo Mar 13, 2026
a323586
[IMP] estate: improved menu structure, report actions and enhanced ka…
kapat-odoo Mar 16, 2026
6624b49
[IMP] awesome_owl: implemented counters, card and todo list.
kapat-odoo Mar 25, 2026
ca1cbac
[IMP] awesome_dashboard: implemented a dynamic dashboard for t shirt …
kapat-odoo Mar 31, 2026
dfba049
[IMP] estate: implemented cron, wizard and mail.
kapat-odoo Apr 1, 2026
8e5b2fa
[IMP] estate: implemented cron, wizard and mail.
kapat-odoo Apr 1, 2026
2d066c6
[ADD] estate_auction: estate auction module for auctioning properties.
kapat-odoo Apr 7, 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 awesome_dashboard/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
'web.assets_backend': [
'awesome_dashboard/static/src/**/*',
],
'awesome_dashboard.dashboard': [
'awesome_dashboard/static/src/dashboard/**/*'
]
},
'license': 'AGPL-3'
}
8 changes: 0 additions & 8 deletions awesome_dashboard/static/src/dashboard.js

This file was deleted.

8 changes: 0 additions & 8 deletions awesome_dashboard/static/src/dashboard.xml

This file was deleted.

38 changes: 38 additions & 0 deletions awesome_dashboard/static/src/dashboard/config_dashboard.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { Component, useState } from "@odoo/owl";
import { Dialog } from "@web/core/dialog/dialog";
import { CheckBox } from "@web/core/checkbox/checkbox";
import { browser } from "@web/core/browser/browser";

export class ConfigurationDialog extends Component {
static template = "awesome_dashboard.config_dashboard";
static components = { Dialog, CheckBox };
static props = ["close", "items", "disabledItems", "onUpdateConfiguration"];

setup() {
this.items = useState(this.props.items.map((item) => {
return {
...item,
enabled: !this.props.disabledItems.includes(item.id),
}
}));
}

done() {
this.props.close();
}

onChange(checked, changedItem) {
changedItem.enabled = checked;
const newDisabledItems = Object.values(this.items).filter(
(item) => !item.enabled
).map((item) => item.id)

browser.localStorage.setItem(
"disabledDashboardItems",
newDisabledItems,
);

this.props.onUpdateConfiguration(newDisabledItems);
}

}
17 changes: 17 additions & 0 deletions awesome_dashboard/static/src/dashboard/config_dashboard.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<templates xml:space="preserve">
<t t-name="awesome_dashboard.config_dashboard">
<Dialog title="'Dashboard items configuration'">
Select Items
<t t-foreach="items" t-as="item" t-key="item.id">
<CheckBox value="item.enabled" onChange="(ev) => this.onChange(ev, item)">
<t t-esc="item.description"/>
</CheckBox>
</t>
<t t-set-slot="footer">
<button class="btn btn-primary" t-on-click="done">
Done
</button>
</t>
</Dialog>
</t>
</templates>
57 changes: 57 additions & 0 deletions awesome_dashboard/static/src/dashboard/dashboard.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { Component, useState } from "@odoo/owl";
import { registry } from "@web/core/registry";
import { Layout } from "@web/search/layout";
import { useService } from "@web/core/utils/hooks";
import { browser } from "@web/core/browser/browser";
import { DashboardItem } from "./dashboard_item/dashboard_item";
import { ConfigurationDialog } from "./config_dashboard";


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

setup() {
this.display = {
controlPanel: {},
};
this.action = useService("action");
this.result = useState(useService("awesome_dashboard.statistics"));
this.items = registry.category("awesome_dashboard").getAll();
this.dialog = useService("dialog");
this.state = useState({
disabledItems: browser.localStorage.getItem("disabledDashboardItems")?.split(",") || []
});
}

openConfiguration() {
this.dialog.add(ConfigurationDialog, {
items: this.items,
disabledItems: this.state.disabledItems,
onUpdateConfiguration: this.updateConfiguration.bind(this),
})
}

updateConfiguration(newDisabledItems) {
this.state.disabledItems = newDisabledItems;
}

openCustomer() {
this.action.doAction("base.action_partner_form");
}

openLeads() {
this.action.doAction({
type: "ir.actions.act_window",
name: "All leads",
res_model: "crm.lead",
views: [
[false, "list"],
[false, "form"],
[false, "kanban"],
],
});
}
}

registry.category("lazy_components").add("AwesomeDashboard", AwesomeDashboard);
3 changes: 3 additions & 0 deletions awesome_dashboard/static/src/dashboard/dashboard.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.o_dashboard {
background-color: gray;
}
35 changes: 35 additions & 0 deletions awesome_dashboard/static/src/dashboard/dashboard.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8" ?>
<templates xml:space="preserve">

<t t-name="awesome_dashboard.AwesomeDashboard">
<Layout display="display" className="'o_dashboard h-100'">
<t t-set-slot="layout-buttons">

<button type="button" class="btn btn-primary" t-on-click="openCustomer">
Customers
</button>

<button type="button" class="btn btn-primary" t-on-click="openLeads">
Leads
</button>

</t>
<t t-set-slot="control-panel-additional-actions">
<button t-on-click="openConfiguration" class="btn p-0 ms-1 border-0">
<i class="fa fa-cog"></i>
</button>
</t>

<div class="d-flex flex-wrap" t-if="result.isReady">
<t t-foreach="items" t-as="item" t-key="item.id">
<DashboardItem t-if="!state.disabledItems.includes(item.id)" size="item.size || 1">
<t t-set="itemProp" t-value="item.props ? item.props(result) : {'data': result}"/>
<t t-component="item.Component" t-props="itemProp" />
</DashboardItem>
</t>

</div>
</Layout>
</t>

</templates>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Component } from "@odoo/owl";


export class DashboardItem extends Component {
static template = "awesome_dashboard.DashboardItem";
static components = { Component };
static props = ['*'];

static defaultProps = {
size: 1
};
}
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_dashboard.DashboardItem">
<div class="card" t-attf-style="width: {{18*props.size}}rem;">
<div class="card-body">
<t t-slot="default"/>
</div>
</div>
</t>
</templates>
65 changes: 65 additions & 0 deletions awesome_dashboard/static/src/dashboard/dashboard_item_list.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { NumberCard } from "./number_card/number_card";
import { PieChartCard } from "./pie_chart_card/pie_chart_card";
import { registry } from "@web/core/registry";

const items = [
{
id: "average_quantity",
description: "Average amount of t-shirt",
Component: NumberCard,
props: (data) => ({
title: "Average amount of t-shirt by order this month",
value: data.average_quantity,
})
},
{
id: "average_time",
description: "Average time for an order",
Component: NumberCard,
props: (data) => ({
title: "Average time for an order to go from 'new' to 'sent' or 'cancelled'",
value: data.average_time,
})
},
{
id: "number_new_orders",
description: "New orders this month",
Component: NumberCard,
props: (data) => ({
title: "Number of new orders this month",
value: data.nb_new_orders,
})
},
{
id: "cancelled_orders",
description: "Cancelled orders this month",
Component: NumberCard,
props: (data) => ({
title: "Number of cancelled orders this month",
value: data.nb_cancelled_orders,
})
},
{
id: "amount_new_orders",
description: "amount orders this month",
Component: NumberCard,
props: (data) => ({
title: "Total amount of new orders this month",
value: data.total_amount,
})
},
{
id: "pie_chart",
description: "Shirt orders by size",
Component: PieChartCard,
size: 2,
props: (data) => ({
title: "Shirt orders by size",
values: data.orders_by_size,
})
}
]

for (const item of items) {
registry.category("awesome_dashboard").add(item.id, item);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { Component } from "@odoo/owl";

export class NumberCard extends Component {
static template = "awesome_dashboard.NumberCard";
static props = ['title', 'value'];


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8" ?>
<templates xml:space="preserve">
<t t-name="awesome_dashboard.NumberCard">
<t t-out="props.title"/>
<div class="text-success text-center">
<t t-out="props.value"/>
</div>
</t>
</templates>
38 changes: 38 additions & 0 deletions awesome_dashboard/static/src/dashboard/pie_chart/pie_chart.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { loadJS } from "@web/core/assets";
import { Component, onWillStart, useRef, onMounted, onWillUnmount } from "@odoo/owl";

export class PieChart extends Component {
static template = "awesome_dashboard.PieChart";
static props = {
label: String,
data: Object,
};

setup() {
this.canvasRef = useRef("canvas");
onWillStart(() => loadJS("/web/static/lib/Chart/Chart.js"));
onMounted(() => {
this.renderChart();
});
onWillUnmount(() => {
this.chart.destroy();
});
}

renderChart() {
const labels = Object.keys(this.props.data);
const data = Object.values(this.props.data);
this.chart = new Chart(this.canvasRef.el, {
type: "pie",
data: {
labels: labels,
datasets: [
{
label: this.props.label,
data: data,
},
],
},
});
}
}
10 changes: 10 additions & 0 deletions awesome_dashboard/static/src/dashboard/pie_chart/pie_chart.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<templates xml:space="preserve">
<t t-name="awesome_dashboard.PieChart">
<div t-att-class="'h-100 ' + props.class" t-ref="root">
<div class="h-100 position-relative" t-ref="container">
<canvas t-ref="canvas" />
</div>
</div>
</t>
</templates>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { Component } from "@odoo/owl";
import { PieChart } from "../pie_chart/pie_chart";

export class PieChartCard extends Component {
static template = "awesome_dashboard.PieChartCard";
static components = { PieChart }
static props = ['title', 'values'];

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<templates xml:space="preserve">
<t t-name="awesome_dashboard.PieChartCard">
<t t-out="props.title"/>
<PieChart data="props.values" label="''"/>
</t>
</templates>
25 changes: 25 additions & 0 deletions awesome_dashboard/static/src/dashboard/statistics_service.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { registry } from "@web/core/registry";
import { reactive } from "@odoo/owl";
import { rpc } from "@web/core/network/rpc";


const statisticsService = {

start() {
const result = reactive({ isReady: false });


async function loadData() {
const updates = await rpc("/awesome_dashboard/statistics");
Object.assign(result, updates, { isReady: true });
}

setInterval(loadData, 10*60*1000);
loadData();


return result;
},
};

registry.category("services").add("awesome_dashboard.statistics", statisticsService);
Loading