odoo日历模块相信大家都比较熟悉了~直接在相应日期上填写计划就可以简洁直观的看出一天乃至一月的日程安排。
不过如果一天之中想添加多个日程,就要不停点击创建。
那么我们何妨不研究一下如何实现在日历中批量添加日程!
大部分公司都会使用周报系统,我们就以此为例,看看应该如何基于Odoo改造视图,提升效率。
我们先看一下常规的代码:
<record id="weekly_calendar" model="ir.ui.view">
<field name="name">我的周报</field>
<field name="model">dc.weekly.weekday</field>
<field name="arch" type="xml">
<calendar date_start="plan_date" color="task_calendar_id" quick_add="0" event_open_popup="1"
mode="month" js_class='ics_calendar_button'>
<field name="weekday_creator" string="填报人" options="{'no_open': True}"/>
<field name="task_calendar_id" string="重点工作" options="{'no_open': True}"/>
<field name="data_source" string="数据来源" invisible="1"/>
</calendar>
</field>
</record>
不难看出,该视图的侧重点是重点工作,其字段类型是Many2one,这也符合日历视图规范。
Odoo原生效果图如下:
为了达到批量添加的目的,势必要对此视图进行改造。
我们不免想到了odoo的One2many字段,将该类型字段铺到form视图时,会出现“保存并关闭”、“保存并新建”的按钮,如果我们可以借鉴,岂不是皆大欢喜?
经过页面调试可知,在日历视图中点击创建并不是弹出一个Form视图,而是一个Dialog对话框,因此也不能按照寻常方式进行FormController改造。
进一步调试可知,点击创建的时候调用的calendar_controller.js的_onOpenCreate方法,然后去底层的FormViewDialog渲染出按钮。
在FormViewDialog里,odoo通过multi_select来判断按钮样式,而multi_select与options的disable_multiple_selection属性息息相关。
因为前一项!_.isNumber(options.res_id)在创建情况下永远为true。
换言之,只要option的disable_multiple_selection为false,那么页面就会渲染出“保存并新建”按钮。部分源码如下:
var FormViewDialog = ViewDialog.extend({
init: function (parent, options) {
···
var multi_select = !_.isNumber(options.res_id) && !options.disable_multiple_selection;
var readonly = _.isNumber(options.res_id) && options.readonly;
···
if (!readonly) {
options.buttons.unshift({
text: (multi_select ? _t("Save & Close") : _t("Save")),
classes: "btn-primary",
click: function () {
self._save().then(self.close.bind(self));
}
});
if (multi_select) {
options.buttons.splice(1, 0, {
text: _t("Save & New"),
classes: "btn-primary",
click: function () {
self._save()
.then(self.form_view.createRecord.bind(self.form_view, self.parentID))
.then(function () {
if (!self.deletable) {
return;
}
self.deletable = false;
self.buttons = self.buttons.filter(function (button) {
return button.classes.split(' ').indexOf(oBtnRemove) < 0;
});
self.set_buttons(self.buttons);
self.set_title(_t("Create ") + _.str.strRight(self.title, _t("Open: ")));
});
},
});
}
var multi = options.disable_multiple_selection;
if (!multi && this.deletable) {
this._setRemoveButtonOption(options, oBtnRemove);
}
}
}
this._super(parent, options);
},
通过前文的探索,我们发现不能使用常规的方法,同时直接在源码上修改也是不可取的,毕竟一旦修改,全局生效。
所以我们就去calendar_controller.js的_onOpenCreate方法里找找odoo原生是如何给disable_multiple_selection赋值的。
果不其然!原生方法里odoo直接给disable_multiple_selection赋值为true,那么我们就可以另外新建一个js重写_onOpenCreate方法,修改disable_multiple_selection。
代码如下:
odoo.define('ics_calendar_controller', function (require) {
"use strict";
//这些是调⽤需要的模块
var core = require('web.core');
var CalendarView = require('web.CalendarView');
var CalendarController = require('web.CalendarController');
var viewRegistry = require('web.view_registry');
var _t = core._t;
var dialogs = require('web.view_dialogs');
//这块代码是继承CalendarController在原来的基础上进⾏扩展
let BiCalendarController = CalendarController.extend({
_onOpenCreate: function (event) {
···# 与源码一致,故省略
if (this.eventOpenPopup) {
if (this.previousOpen) {
this.previousOpen.close();
}
this.previousOpen = new dialogs.FormViewDialog(self, {
res_model: this.modelName,
context: context,
title: title,
view_id: this.formViewId || false,
disable_multiple_selection: false, //代码修改处
on_saved: function () {
if (event.data.on_save) {
event.data.on_save();
}
self.reload();
},
});
this.previousOpen.open();
} else {
this.do_action({
type: 'ir.actions.act_window',
res_model: this.modelName,
views: [[this.formViewId || false, 'form']],
target: 'current',
context: context,
});
}
},
let BiCalendarView = CalendarView.extend({
config: _.extend({}, CalendarView.prototype.config, {
Controller: BiCalendarController,
}),
});
viewRegistry.add('ics_calendar_button', BiCalendarView);
return BiCalendarView;
});
导入该js后,在日历视图中添加js_class='ics_calendar_button’属性并进行升级后,就可以在日历视图中批量添加日程了。
你还想了解Odoo哪些好用的功能?欢迎留言哦~
版权声明:该内容由神州数码云基地团队编撰,转载请注明出处!
微信公众号后台回复“Odoo”,可加入技术交流群!