1
This commit is contained in:
@@ -1 +1 @@
|
||||
|
||||
from . import models
|
||||
|
||||
@@ -8,7 +8,8 @@
|
||||
'license': 'LGPL-3',
|
||||
'depends': ['base', 'web'],
|
||||
'data': [
|
||||
|
||||
'views/menu.xml',
|
||||
'views/yuthon_report_res_partner.xml'
|
||||
],
|
||||
'installable': True,
|
||||
'application': True,
|
||||
@@ -16,10 +17,12 @@
|
||||
'web.assets_backend': [
|
||||
# 样式
|
||||
'yuthon_report/static/src/lib/ag-grid-c/styles/ag-grid.css',
|
||||
'yuthon_report/static/src/lib/ag-grid-c/styles/ag-theme-alpine.css',
|
||||
# 'yuthon_report/static/src/lib/ag-grid-c/styles/ag-theme-alpine.css',
|
||||
# 'yuthon_report/static/src/lib/ag-grid-c/styles/ag-theme-balham.min.css',
|
||||
'yuthon_report/static/src/lib/ag-grid-c/styles/ag-theme-quartz.min.css',
|
||||
|
||||
# 先引入 community
|
||||
'yuthon_report/static/src/lib/ag-grid-c/dist/ag-grid-community.noStyle.js',
|
||||
'yuthon_report/static/src/lib/ag-grid-c/dist/ag-grid-community.js',
|
||||
# 再引入 enterprise
|
||||
'yuthon_report/static/src/lib/ag-grid-e/dist/ag-grid-enterprise.js',
|
||||
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from . import res_partner
|
||||
@@ -0,0 +1,16 @@
|
||||
from odoo import fields, models, api
|
||||
|
||||
|
||||
class ResPartner(models.Model):
|
||||
_inherit = 'res.partner'
|
||||
|
||||
@api.model
|
||||
def get_report_data(self, params):
|
||||
domain = []
|
||||
if params.get("keyword"):
|
||||
domain.append(("name", "ilike", params["keyword"]))
|
||||
partners = self.search(domain, limit=100)
|
||||
return [
|
||||
{"customer": p.name, "amount": p.credit}
|
||||
for p in partners
|
||||
]
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 7.6 KiB |
@@ -3,12 +3,17 @@
|
||||
|
||||
import { registry } from "@web/core/registry";
|
||||
import { Component, onMounted, useRef, useState } from "@odoo/owl";
|
||||
import { useBus, useService } from "@web/core/utils/hooks";
|
||||
import { standardActionServiceProps } from "@web/webclient/actions/action_service";
|
||||
import { DateTimeInput } from "@web/core/datetime/datetime_input";
|
||||
|
||||
class YouthonReport extends Component {
|
||||
setup() {
|
||||
this.gridRef = useRef("grid");
|
||||
this.dateRangeRef = useRef("date_range_picker");
|
||||
this.keywordRef = useRef("keyword_input");
|
||||
console.log('131231')
|
||||
console.log(this.props.action.context.report_config)
|
||||
|
||||
this.serviceOrm = useService("orm")
|
||||
|
||||
this.state = useState({
|
||||
startDate: null,
|
||||
@@ -16,17 +21,19 @@ class YouthonReport extends Component {
|
||||
keyword: "",
|
||||
});
|
||||
|
||||
this.config = this.props.config || {};
|
||||
this.config = this.props.action.context.report_config || {};
|
||||
|
||||
onMounted(async () => {
|
||||
// 加载 ag-grid
|
||||
//await loadJS("https://cdn.jsdelivr.net/npm/ag-grid-community/dist/ag-grid-community.min.js");
|
||||
this.gridOptions = {
|
||||
theme:agGrid.themeMaterial,
|
||||
columnDefs: this.config.columns || [],
|
||||
rowData: [],
|
||||
sideBar: true,
|
||||
defaultColDef: { resizable: true, sortable: true, filter: true },
|
||||
};
|
||||
this.grid = new agGrid.Grid(this.gridRef.el, this.gridOptions);
|
||||
this.grid = new agGrid.createGrid(this.gridRef.el, this.gridOptions);
|
||||
|
||||
});
|
||||
}
|
||||
@@ -37,15 +44,33 @@ class YouthonReport extends Component {
|
||||
date_end: this.state.endDate,
|
||||
keyword: this.state.keyword,
|
||||
};
|
||||
|
||||
const result = await this.env.services.orm.call(
|
||||
const result = await this.serviceOrm.call(
|
||||
this.config.model,
|
||||
this.config.method,
|
||||
[params]
|
||||
);
|
||||
this.gridOptions.api.setRowData(result);
|
||||
console.log(result)
|
||||
this.grid.setGridOption('rowData',result);
|
||||
}
|
||||
|
||||
onExportExcel() {
|
||||
this.grid.exportDataAsExcel({
|
||||
fileName: 'my-data.xlsx',
|
||||
sheetName: 'Sheet1'
|
||||
});
|
||||
}
|
||||
|
||||
async onChangeStartDate(date){
|
||||
this.state.startDate = date;
|
||||
}
|
||||
async onChangeEndDate(date){
|
||||
this.state.endDate = date;
|
||||
}
|
||||
}
|
||||
YouthonReport.props = {...standardActionServiceProps };
|
||||
YouthonReport.template = "youthon_report.YouthonReport";
|
||||
YouthonReport.components = {
|
||||
DateTimeInput
|
||||
};
|
||||
|
||||
registry.category("actions").add("youthon_report_client", YouthonReport);
|
||||
|
||||
@@ -1,30 +1,55 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<templates id="template" xml:space="preserve">
|
||||
<t t-name="youthon_report.YouthonReport">
|
||||
<div class="container-fluid d-flex flex-column h-100">
|
||||
|
||||
<!-- 搜索区域 -->
|
||||
<div class="row mb-2" t-ref="search_area">
|
||||
<div class="col-auto">
|
||||
<label>日期范围</label>
|
||||
<div t-ref="date_range_picker"></div>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<label>关键字</label>
|
||||
<div t-ref="keyword_input"></div>
|
||||
</div>
|
||||
<div class="col-auto align-self-end">
|
||||
<button class="btn btn-primary" t-on-click="onSearch">搜索</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container-fluid d-flex flex-column h-100 mt-2 pb-3 ">
|
||||
<div class="card mb-2 ">
|
||||
<div class="card-header">
|
||||
销售报表
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<!-- 搜索区域 -->
|
||||
<div class="row mb-2" t-ref="search_area">
|
||||
<div class="col-4">
|
||||
<label>日期范围</label>
|
||||
<DateTimeInput
|
||||
value="state.startDate"
|
||||
type="'date'"
|
||||
placeholder="fromPlaceholder"
|
||||
onChange="(date) => this.onChangeStartDate(date)"
|
||||
/>
|
||||
<i class="oi oi-arrow-right"></i>
|
||||
<DateTimeInput
|
||||
value="state.endDate"
|
||||
type="'date'"
|
||||
placeholder="toPlaceholder"
|
||||
onChange="(date) => this.onChangeEndDate(date)"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<label>关键字</label>
|
||||
<div>
|
||||
<input type="text" class="form-control" t-model="state.keyword" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-4 align-self-end">
|
||||
|
||||
<!-- ag-grid 区域 -->
|
||||
<div class="row flex-grow-1">
|
||||
<button class="btn btn-primary" t-on-click="onSearch">搜索</button>
|
||||
<button class="btn btn-primary" t-on-click="onExportExcel">导出</button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ag-grid 区域 -->
|
||||
<div class="row flex-grow-1">
|
||||
<div class="col-12 h-100">
|
||||
<div class="ag-theme-alpine w-100 h-100" t-ref="grid"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</t>
|
||||
</templates>
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data>
|
||||
|
||||
<menuitem
|
||||
name="报表"
|
||||
id="yuthon_report_root"
|
||||
web_icon="yuthon_report,static/description/icon.png"
|
||||
sequence="125"
|
||||
/>
|
||||
|
||||
</data>
|
||||
</odoo>
|
||||
@@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data>
|
||||
|
||||
<record id="action_youthon_report" model="ir.actions.client">
|
||||
<field name="name">Youthon 报表</field>
|
||||
<field name="tag">youthon_report_client</field>
|
||||
<field name="context">
|
||||
{
|
||||
"sideBar":true,
|
||||
"report_config": {
|
||||
"model": "res.partner",
|
||||
"method": "get_report_data",
|
||||
"search_fields": [
|
||||
{"name": "date_start", "type": "date", "label": "开始日期"},
|
||||
{"name": "date_end", "type": "date", "label": "结束日期"},
|
||||
{"name": "keyword", "type": "char", "label": "关键字"}
|
||||
],
|
||||
"columns": [
|
||||
{"headerName": "客户", "field": "customer", "flex": 1},
|
||||
{"headerName": "销售额", "field": "amount", "flex": 1}
|
||||
]
|
||||
}
|
||||
}
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<menuitem id="menu_youthon_report"
|
||||
name="Youthon 报表"
|
||||
parent="yuthon_report_root"
|
||||
action="action_youthon_report"
|
||||
sequence="160"
|
||||
/>
|
||||
|
||||
</data>
|
||||
</odoo>
|
||||
Reference in New Issue
Block a user