合并企业版代码(未测试,先提交到测试分支)

This commit is contained in:
qihao.gong@jikimo.com
2023-04-14 17:42:23 +08:00
parent 7a7b3d7126
commit d28525526a
1300 changed files with 513579 additions and 5426 deletions

View File

@@ -0,0 +1,125 @@
odoo.define('web_grid.grid_mobile_tests', function (require) {
"use strict";
let GridView = require('web_grid.GridView');
let testUtils = require('web.test_utils');
let createView = testUtils.createView;
QUnit.module('LegacyViews', {
beforeEach: function () {
this.data = {
'analytic.line': {
fields: {
project_id: {string: "Project", type: "many2one", relation: "project"},
task_id: {string: "Task", type: "many2one", relation: "task"},
date: {string: "Date", type: "date"},
unit_amount: {string: "Unit Amount", type: "float"},
},
records: [
{id: 1, project_id: 31, date: "2017-01-24", unit_amount: 2.5},
{id: 2, project_id: 31, task_id: 1, date: "2017-01-25", unit_amount: 2},
{id: 3, project_id: 31, task_id: 1, date: "2017-01-25", unit_amount: 5.5},
{id: 4, project_id: 31, task_id: 1, date: "2017-01-30", unit_amount: 10},
{id: 5, project_id: 142, task_id: 12, date: "2017-01-31", unit_amount: 3.5},
]
},
project: {
fields: {
name: {string: "Project Name", type: "char"}
},
records: [
{id: 31, display_name: "P1"},
{id: 142, display_name: "Webocalypse Now"},
]
},
task: {
fields: {
name: {string: "Task Name", type: "char"},
project_id: {string: "Project", type: "many2one", relation: "project"},
},
records: [
{id: 1, display_name: "BS task", project_id: 31},
{id: 12, display_name: "Another BS task", project_id: 142},
{id: 54, display_name: "yet another task", project_id: 142},
]
},
};
this.arch = `
<grid string="Timesheet" adjustment="object" adjust_name="adjust_grid">
<field name="project_id" type="row"/>
<field name="task_id" type="row"/>
<field name="date" type="col">
<range name="week" string="Week" span="week" step="day"/>
</field>
<field name="unit_amount" type="measure" widget="float_time"/>
</grid>
`;
}
}, function () {
QUnit.module('GridView (legacy) - Mobile');
QUnit.test('basic grid view, range button in mobile', async function (assert) {
assert.expect(5);
let countCallRPC = 0;
let grid = await createView({
View: GridView,
model: 'analytic.line',
data: this.data,
arch: this.arch,
currentDate: "2017-01-25",
mockRPC: function (route, args) {
if (args.method === 'read_grid') {
if (countCallRPC === 0) {
assert.equal(args.kwargs.range.span, 'day', "range should be day");
} else if (countCallRPC === 1) {
assert.equal(args.kwargs.range.span, 'week', "range should be month");
}
}
countCallRPC++;
return this._super.apply(this, arguments);
},
});
await testUtils.nextTick();
assert.equal(grid.$('table').length, 1, "should have rendered one table");
let btnCal = grid.$buttons.find('.btn-group.o_grid_range > button.btn.fa-calendar');
assert.equal(btnCal.length, 1, "should have a calendar button for range");
await testUtils.dom.click(btnCal);
// Day range should be automatically added.
let btnRange = grid.$buttons.find('.btn-group.o_grid_range button.grid_arrow_range');
assert.equal(btnRange.length, 2, "should have two range buttons (Day and Week)");
await testUtils.dom.click(grid.$buttons.find('button[data-name=week]'));
grid.destroy();
});
QUnit.test('grid view should open in day range for mobile', async function (assert) {
assert.expect(1);
const grid = await createView({
View: GridView,
model: 'analytic.line',
data: this.data,
arch: `<grid string="Timesheet" adjustment="object" adjust_name="adjust_grid">
<field name="project_id" type="row"/>
<field name="task_id" type="row"/>
<field name="date" type="col">
<range name="week" string="Week" span="week" step="day"/>
<range name="day" string="Day" span="day" step="day"/>
</field>
<field name="unit_amount" type="measure" widget="float_time"/>
</grid>`,
currentDate: "2017-01-25",
});
const btnRangeDay = grid.$buttons[0].querySelector('button[data-name=day]');
assert.hasClass(btnRangeDay, "active", "Grid view should be open in day range for mobile");
grid.destroy();
});
});
});

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,223 @@
odoo.define('web_grid.MockServer', function (require) {
"use strict";
var MockServer = require('web.MockServer');
MockServer.include({
/**
* @override
*/
_performRpc: function (route, args) {
if (args.method === 'read_grid') {
return this._mockReadGrid(args.model, args.kwargs);
} else if (args.method === 'read_grid_grouped') {
return this._mockReadGridGrouped(args.model, args.kwargs);
} else if (args.method === 'adjust_grid') {
var domain = args.args[1];
var columnField = args.args[2];
var columnValue = args.args[3];
var cellField = args.args[4];
var change = args.args[5];
var lines = this._mockSearchReadController({
model: args.model,
domain: domain,
fields: [],
});
var newID = this._mockCopy(args.model, lines.records[0].id);
var newRecord = _.findWhere(this.data[args.model].records, {id: newID});
newRecord[cellField] = change;
newRecord[columnField] = columnValue.split('/')[0];
return Promise.resolve({});
} else {
return this._super(route, args);
}
},
/**
* @private
* @param {string} model
* @param {Object} kwargs
* @returns {Promise}
*/
_mockReadGrid: function (model, kwargs) {
var self = this;
// various useful dates
var gridAnchor = moment(kwargs.context.grid_anchor || this.currentDate);
const currentDate = kwargs.context.grid_anchor ? moment(this.currentDate) : gridAnchor;
var today = moment();
var span = kwargs.range.span;
var start = gridAnchor.clone().startOf(span === 'day' ? 'day' : span === 'week' ? 'isoWeek' : 'month');
var end = gridAnchor.clone().endOf(span === 'day' ? 'day' : span === 'week' ? 'isoWeek' : 'month');
var nextAnchor = gridAnchor.clone().add(1, span === 'day' ? 'day' : span === 'week' ? 'weeks' : 'month').format('YYYY-MM-DD');
var prevAnchor = gridAnchor.clone().subtract(1, span === 'day' ? 'day' : span === 'week' ? 'weeks' : 'month').format('YYYY-MM-DD');
// compute columns
var columns = [];
var current = start.clone().subtract(1, 'days');
var unavailable = end.clone().subtract(2, 'days');
while (!current.isSame(end, 'days')) {
current.add(1, 'days');
var dayStr = current.format('YYYY-MM-DD');
var nextDayStr = current.clone().add(1, 'days').format('YYYY-MM-DD');
columns.push({
is_current: current.isSame(today),
is_unavailable: unavailable.isSame(current, 'day'),
domain: ["&", ["date", ">=", dayStr], ["date", "<", nextDayStr]],
values: {date: [dayStr + '/' + nextDayStr, current.format('ddd,\nMMM\u00a0DD')]}
});
}
// compute rows
var rows = [];
var domain = [
'&',
[kwargs.col_field, '>=', start.format('YYYY-MM-DD')],
[kwargs.col_field, '<=', end.format('YYYY-MM-DD')]
].concat(kwargs.domain);
var groups = this._mockReadGroup(model, {
domain: domain,
fields: [kwargs.cell_field],
groupby: [kwargs.row_fields[0]],
});
_.each(groups, function (group) {
var groupValue = {};
groupValue[kwargs.row_fields[0]] = group[kwargs.row_fields[0]];
var groupDomain = ['&'].concat(domain).concat(group.__domain);
if (kwargs.row_fields[1]) {
var subGroups = self._mockReadGroup(model, {
domain: groupDomain,
fields: [kwargs.cell_field],
groupby: [kwargs.row_fields[1]],
});
_.each(subGroups, function (subGroup) {
var subGroupDomain = ['&'].concat(groupDomain, subGroup.__domain);
var values = _.extend({}, groupValue);
values[kwargs.row_fields[1]] = subGroup[kwargs.row_fields[1]] || false;
rows.unshift({
domain: subGroupDomain,
values: values,
});
});
} else {
rows.unshift({
domain: groupDomain,
values: groupValue,
});
}
});
// generate cells
var grid = [];
_.each(rows, function (row) {
var cells = [];
_.each(columns, function (col) {
var cellDomain = ['&'].concat(row.domain).concat(col.domain);
var read_fields = kwargs.readonly_field ? [kwargs.cell_field, kwargs.readonly_field] : [kwargs.cell_field];
var records = self._mockSearchReadController({
model: model,
domain: cellDomain,
fields: read_fields,
});
var value = 0;
_.each(records.records, function (rec) {
value += rec[kwargs.cell_field];
});
var readonly_dict = {};
readonly_dict[kwargs.readonly_field] = true;
cells.push({
size: records.length,
value: value,
is_current: col.is_current,
is_unavailable: col.is_unavailable,
readonly: _.isMatch(records.records[0], readonly_dict),
domain: cellDomain,
});
});
grid.push(cells);
});
return Promise.resolve({
cols: columns,
rows: rows,
grid: grid,
prev: {
default_date: prevAnchor,
grid_anchor: prevAnchor,
},
next: {
default_date: nextAnchor,
grid_anchor: nextAnchor,
},
initial: {
default_date: currentDate.format('YYYY-MM-DD'),
grid_anchor: currentDate.format('YYYY-MM-DD'),
},
});
},
_mockReadGridGrouped(model, kwargs) {
const self = this;
return this._mockReadGridDomain(model, kwargs).then(function (gridDomain) {
gridDomain = gridDomain.concat(kwargs.domain || []);
const groups = self._mockReadGroup(model, {
domain: gridDomain,
fields: [kwargs.section_field],
groupby: [kwargs.section_field],
});
if (!groups.length) {
return Promise.all([self._mockReadGrid(model, {
row_fields: kwargs.row_fields,
col_field: kwargs.col_field,
cell_field: kwargs.cell_field,
domain: kwargs.domain,
range: kwargs.current_range,
readonly_field: kwargs.readonly_field,
context: kwargs.context,
})]);
} else {
return Promise.all((groups || []).map((group) => {
return self._mockReadGrid(model, {
row_fields: kwargs.row_fields,
col_field: kwargs.col_field,
cell_field: kwargs.cell_field,
domain: group.__domain,
range: kwargs.current_range,
readonly_field: kwargs.readonly_field,
context: kwargs.context,
}).then(function (result) {
result.__label = group[kwargs.section_field];
return result;
});
}));
}
});
},
/**
* @TODO: this is not very generic but it works for the tests
* @private
* @returns {Promise}
*/
_mockReadGridDomain: function (model, kwargs) {
if (kwargs.context && kwargs.context.grid_anchor && kwargs.current_range && kwargs.current_range.span) {
var gridAnchor = moment(kwargs.context.grid_anchor || this.currentDate);
var span = kwargs.current_range.span;
var start = gridAnchor.clone().startOf(span === 'day' ? 'day' : span === 'week' ? 'isoWeek' : 'month');
var end = gridAnchor.clone().endOf(span === 'day' ? 'day' : span === 'week' ? 'isoWeek' : 'month');
return Promise.resolve([
'&',
['date', '>=', start.format('YYYY-MM-DD')],
['date', '<=', end.format('YYYY-MM-DD')],
]);
}
return Promise.resolve([
'&',
['date', '>=', '2017-01-01'],
['date', '<=', '2017-01-31'],
]);
},
});
});