暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Odoo | 如何实现在日历视图中批量添加多个日程?

338





Odoo

神州数码云基地

在 Odoo 上的尝试、调研与分享




 本期内容 

 日历视图改造 


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哪些好用的功能?欢迎在后台留言给我们哦~





        本期内容就到这里啦

        有更好的办法或疑问请

        ⬇欢迎加入社群一起讨论哦⬇

        本期作者 

         数据开发工程师 查晶晶 



        更多精彩内容 





        了解云基地,就现在!


        IT技术哪家

        神州数码最在行

        行业新星后起之秀

        历史虽不长,但实 力 强




        文章转载自神州数码云基地,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

        评论