{% load i18n static %}
{% load iclock_tags %}
{% load common %}

{% comment %}
 % @Author: Boyce Gao
 % @Date: 2018-08-30 18:24:47
 % @Last Modified by:  Boyce Gao
 % @Last Modified time: 2018-09-04 17:02:28
{% endcomment %}

{% comment %}
 % @Last Modified by:  Damien.Yang
 % @Last Modified time: 2019-06-14
 % @Modified Function: prepare_perm_data()
 % @Description: This refer from Auth Group Edit Form
{% endcomment %}

<style>
    .auth-tree-content { height: 180px; }
</style>

<!--suppress ALL -->
<div id="{{ model_name }}_edit_form">
  <form class="layui-form data-form" style="padding: 10px;">
    {% csrf_token %}
    <div class="layui-form-item">
      {% autoescape off %}
        {% with adminform.form as f %}
          {{ f.salary_amount|layui_item_field }}
          {{ f.salary_formula|layui_item_field }}
          {{ f.effective_date|layui_item_field }}
          {{ f.salary_remark|layui_item_field }}
          {{ f.leaveformula|layui_item_field_ignore:'select' }}
          {{ f.overtimeformula|layui_item_field_ignore:'select' }}
          {{ f.exceptionformula|layui_item_field_ignore:'select' }}
          {{ f.increasementformula|layui_item_field_ignore:'select' }}
          {{ f.deductionformula|layui_item_field_ignore:'select' }}
        {% endwith %}
      {% endautoescape %}
    </div>
  </form>
</div>

<div class="layui-tab layui-tab-brief" lay-filter="auth_tree_tabs">
  <ul class="layui-tab-title"></ul>
  <div class="layui-tab-content" style="height: 203px; overflow-y: hidden;">
  </div>
</div>

<script>
    layui.use(['form', 'laydate', 'element'], function(){
        var form=layui.form, laydate=layui.laydate, element = layui.element;
      $("form.layui-form input.layui-date").each(function () {
        laydate.render({elem: this, type: 'date'});
      });
      $('#id_salary_amount').change(function(){
          var salary = $('#id_salary_amount').val();
          if(salary < 0){
              layer.alert("{% trans 'basic_salary_need_lager_than_zero' %}", {
                        icon: 5, title: gettext("system_exception"),  btn: gettext('btn_confirm')
                    })
          }
      })
    })
  //# sourceURL=payRoll_structure_edit.js
  $(function () {
    /**
     * @author Boyce
     * @summary layui-tab 的动态追加
     * @description
     *   1. 定位 tab 的 DOM
     *   2. 定位 layui 的 tab 下标题域
     *   3. 构造 li 元素
     *   4. 依据 tab-bar 存在与否，来决定 li 的**相对**插入位置
     *   5. 插入 li 对应的 div 内容域到 tab-content 下
     * @param filter -> 过滤器: 用于选取对应的 layui-tab 容器
     * @param options -> 选项: 设定可选值的对象，目前支持的选项如下述示例：
     * ``` javascript
     * tab_add('demo', {
     *   id: '选项卡标题的lay-id属性值',
     *   attr: '选项卡的属性值'
     *   title: '选项卡的标题',
     *   class: '选项卡的 li 元素的 css 类',
     *   content: '选项卡的内容', // 支持传入html
     * });
     * ```
     * @returns {null}
     */
    function tab_add(filter, options) {
      var _title = '.layui-tab-title',
        tabElem = $('.layui-tab[lay-filter=' + filter + ']'),
        titElem = tabElem.children(_title),
        barElem = titElem.children('.layui-tab-bar'),
        contElem = tabElem.children('.layui-tab-content'),
        li_fmt = '<li lay-id="%(id)s"%(class)s%(attr)s>%(title)s</li>',
        li_str = interpolate(li_fmt, {
          'id': (options.id || ''),
          'attr': (options.attr ? ' lay-attr="' + options.attr + '"' : ''),
          'title': (gettext(options.title) || 'unnaming'),
          'class': (options.class ? interject('class="{}"', [options.class]) : '')
        }, true);

      barElem[0] ? barElem.before(li_str) : titElem.append(li_str);
      contElem.append(interpolate(
        '<div id="tabs-%(id)s" data-model-name="%(id)s" class="layui-tab-item%(show)s">%(content)s</div>', {
          'id': options.id,
          'content': (options.content || ''),
          'show': (options.show ? ' layui-show' : '')
        }, true));
    }

    var TAB_FILTER = 'auth_tree_tabs',
      GLOBAL_ACL_MAPPING = {
        enter_system_module: 'system',
        enter_personnel_module: 'overtime',
        enter_terminal_module: 'device',
        enter_attendance_module: 'att'
      },
      $permission = $('select#id_overtimeformula'),
      perm_triple = [],  // 存放权限三元组 (mod, perm, detail)
      perm_dual_dict = {},  // 存放权限三元组 (mod, perm, detail) 字典
      perm_acl_dict = {},
      // var perm_values = [],  // permission value
      perm_value_dict = {}, // permission value
      selected_perm = [],  // 存放已选中的权限条目的 id
      selected_formula = {}
      select_field_perm = {};
      select_field_formula = {}


    var allowed_perm_dict = {
      'overtime': [
        {id: "{% trans 'report_column_overtimeLevel1' %}", name: "{% trans 'report_column_overtimeLevel1' %}"},
        {id: "{% trans 'report_column_overtimeLevel2' %}", name: "{% trans 'report_column_overtimeLevel2' %}"},
        {id: "{% trans 'report_column_overtimeLevel3' %}", name: "{% trans 'report_column_overtimeLevel3' %}"},
        {id: "{% trans 'report_column_normalOvertime' %}", name: "{% trans 'report_column_normalOvertime' %}"},
        {id: "{% trans 'report_column_weekendOvertime' %}", name: "{% trans 'report_column_weekendOvertime' %}"},
        {id: "{% trans 'report_column_holidayOvertime' %}", name: "{% trans 'report_column_holidayOvertime' %}"},
      ], 'exception': [
        {id: "{% trans 'report_column_lateDuration' %}", name: "{% trans 'report_column_lateDuration' %}"},
        {id: "{% trans 'report_column_earlyLeaveDuration' %}", name: "{% trans 'report_column_earlyLeaveDuration' %}"},
        {id: "{% trans 'report_column_absentDuration' %}", name: "{% trans 'report_column_absentDuration' %}"},
      ], 'leave': [
          // 在prepare_perm_data中动态添加leave的allowed_perm_dict
        {id: "{% trans 'leaveCategory_default_sickLeave' %}", name: "{% trans 'leaveCategory_default_sickLeave' %}"},
        {id: "{% trans 'leaveCategory_default_casualLeave' %}", name: "{% trans 'leaveCategory_default_casualLeave' %}"},
        {id: "{% trans 'leaveCategory_default_maternity_leave' %}", name: "{% trans 'leaveCategory_default_maternity_leave' %}"},
        {id: "{% trans 'leaveCategory_default_compassionate_leave' %}", name: "{% trans 'leaveCategory_default_compassionate_leave' %}"},
        {id: "{% trans 'leaveCategory_default_annual_leave' %}", name: "{% trans 'leaveCategory_default_annual_leave' %}"},
        {id: "{% trans 'leaveCategory_default_business_trip' %}", name: "{% trans 'leaveCategory_default_business_trip' %}"},
      ], 'increasement': [
        {id: "{% trans 'payroll_model_increasementFormula' %}", name: "{% trans 'payroll_model_increasementFormula' %}"},
      ], 'deduction': [
        {id: "{% trans 'payroll_model_deductionFormula' %}", name: "{% trans 'payroll_model_deductionFormula' %}"},
      ]
    };

    // init i18n dict
    var i18n_dict = {
      "overtime": "{% trans 'payroll_model_overtimeFormula' %}",
      "exception": "{% trans 'payroll_model_exceptionFormula' %}",
      "leave": "{% trans 'payroll_model_leaveFormula' %}",
      "increasement": "{% trans 'payroll_model_increasementFormula' %}",
      "deduction": "{% trans 'payroll_model_deductionFormula' %}"
    };

    function clear_prop(obj) {
      for (var key in obj) {
        delete obj[key];
      }
    }

    // clear container
    perm_triple.splice(0, perm_triple.length);
    clear_prop(perm_dual_dict);
    // perm_values.splice(0, perm_values.length);
    clear_prop(perm_value_dict);
    selected_perm.splice(0, selected_perm.length);

    var $original_form = $('#{{ model_name }}_edit_form');
    prepare_perm_data($original_form);

    /**
     * @summary 生成权限树的外部包裹容器
     */
    function generate_auth_wrapper(id) {
      var conf_for_general_propose = [{
        name: 'expand_all',
        title: gettext('expand_node'),
        class: '',
        icon: 'fa-chevron-up'
      }, {
        name: 'collapse_all',
        title: gettext('collapse_node'),
        class: '',
        icon: 'fa-chevron-down'
      }], conf_for_multiple_select = [{
        name: 'all',
        title: gettext('select_all'),
        class: '',
        icon: 'fa-check-square-o'
      }];

      var control_panel_for_general_propose = $.fn.get_rendered_panel_html(
        conf_for_general_propose, $.fn.zTreeSelect.const.CONST_CONTROL_PANEL_TPL, 'interject'
      ), control_panel_for_multiple_select = $.fn.get_rendered_panel_html(
        conf_for_multiple_select, $.fn.zTreeSelect.const.CONST_CONTROL_PANEL_TPL, 'interject'
      );

      return [
        '<form class="layui-form">',
        '<div class="layui-form-item">',
        '<div class="auth-tree-control">',
        control_panel_for_multiple_select,
        control_panel_for_general_propose,
        '</div>',
        '<div class="auth-tree-content">',
        interpolate('<ul id="LAY-auth-tree-%s" class="ztree"></ul>', [id]),
        '</div></div>',
        '</form>'].join('');
    }


    /**
     * @summary 自执行函数用于 tab 的动态生成
     */
    (function () {
      $('.layui-layer-content', '.layui-layer').css('overflow-y', 'hidden');

      var _all_tab = ['overtime', 'exception', 'leave', 'increasement', 'deduction'];
      // console.log('## _all_tab', _all_tab);
      _all_tab.forEach(function (_tab_id, index) {
        var title = i18n_dict[_tab_id],
          _options = {
            title: title.substring(0, title.indexOf(' ') !== -1 ? title.indexOf(' ') : title.length),
            id: _tab_id,
            content: generate_auth_wrapper(_tab_id)
          };
        // first tab handle first
        if (index === 0) {
          _options['class'] = 'layui-this';
          _options['show'] = true;
        }
        tab_add(TAB_FILTER, _options);
      });
    })();

    var group_perm_values = [];

    /* 开始结合 layui 作前端的交互 */
    layui.use(['jquery', 'form', 'element'], function () {
      var $ = layui.$,
        authtree = layui.authtree,
        form = layui.form,
        laydate = layui.laydate,
        element = layui.element;  // Tab的切换功能，切换事件监听等，需要依赖element模块

      var tab_dict = {};  // init `index -> tab` mapping
      $('.layui-tab-content', '.layui-tab[lay-filter=' + TAB_FILTER + ']').children('.layui-tab-item').each(function (index, elem) {
        tab_dict[index] = elem.id;
      });

      function add_to_selected(select_id) {
        // 获取当前的树是在哪个tab下，将select_id修改到相对应的tab表单中
        var tab_id = $(interpolate('.layui-tab[lay-filter=%s] > ul > li.layui-this', [TAB_FILTER])).attr('lay-id')
        var formula_type = '#id_' + tab_id + 'formula'
        $(formula_type).get(0).options[select_field_formula[tab_id][select_id]].selected = true;
      }

      function remove_from_selected(select_id) {
        // 获取当前的树是在哪个tab下，将select_id修改到相对应的tab表单中
        var tab_id = $(interpolate('.layui-tab[lay-filter=%s] > ul > li.layui-this', [TAB_FILTER])).attr('lay-id')
        var formula_type = '#id_' + tab_id + 'formula'
        $(formula_type).get(0).options[select_field_formula[tab_id][select_id]].selected = false;
      }


      /**
       * @desc local version of sync to select_field
       */
      function sync_to_select_field(zTree, treeNode) {
        var select_handler = treeNode.checked ? add_to_selected : remove_from_selected;

        if (!treeNode.isParent) {
          select_handler(treeNode.id);
        } else {
          /**
           * @desc 获取当前选中的虚拟结点的下属子结点
           * @param filter -> children_filter search all children node
           * @param isSingle -> false means: search the array of the nodes
           * @param Specific the search range, you can search node from a parent node's child nodes.
           */
          var allChildren = zTree.getNodesByFilter($.tree.all_leaf_nodes_filter_generator(), false, treeNode);
          allChildren.forEach(function (tNode/*, i*/) {
            select_handler(tNode.id);
          });
        }
      }

      function update_entrance_permission(zTree) {
        var all_checked_nodes = zTree.getCheckedNodes(true),
          num_of_checked = all_checked_nodes.length,
          tab_id = $(interpolate('.layui-tab[lay-filter=%s] > ul > li.layui-this', [TAB_FILTER])).attr('lay-id'),
          perm_id = perm_acl_dict[tab_id];

        if (num_of_checked > 0) {
          console.debug(interpolate('[info] insert %s entrance permission', [tab_id]));
          // $permission.get(0).options[select_field_perm[perm_id]].selected = true;
        } else {
          console.debug(interpolate('[info] remove %s entrance permission', [tab_id]));
          // $permission.get(0).options[select_field_perm[perm_id]].selected = false;
        }
      }


      function bind_event_for_panel(event) {
        var that = $(event.target),
          control_panel = $(this);
        if (!that.is('span')) {
          that = that.closest('span[data-name]');
        }

        var unique_id = control_panel.data('tree'),
          name = that.data('name'),
          z_tree_obj = $.fn.zTree.getZTreeObj(unique_id),
          $search_field_str = '#' + unique_id + '_search';


        that.toggleClass('selected');
        // from disable to enable
        if (that.hasClass('selected')) {
          switch (name) {
            case 'all':
              if (z_tree_obj.setting.check.chkStyle === 'checkbox') {
                z_tree_obj.checkAllNodes(true);
                all_children = z_tree_obj.getNodesByFilter($.tree.all_leaf_nodes_filter_generator(), false);
                all_children.forEach(function (tNode/*, i*/) {
                  sync_to_select_field(z_tree_obj, tNode);
                });
              }
              $.tree.fixCheckState(z_tree_obj);
              update_entrance_permission(z_tree_obj);
              break;
            case 'expand_all':
              z_tree_obj.expandAll(true);
              that.toggleClass('selected');
              break;
            case 'collapse_all':
              z_tree_obj.expandAll(false);
              that.toggleClass('selected');
              break;
            case 'search':
              $($search_field_str).fadeIn('slow');
              break;
            default:
              console.log('undefined operation.');
          }
        } else { // from enable to disable
          switch (name) {
            case 'done':
              hide_menu();
              that.toggleClass('selected');
              break;
            case 'all':
              if (z_tree_obj.setting.check.chkStyle === 'checkbox') {
                z_tree_obj.checkAllNodes(false);
                all_children = z_tree_obj.getNodesByFilter($.tree.all_leaf_nodes_filter_generator(), false);
                all_children.forEach(function (tNode/*, i*/) {
                  sync_to_select_field(z_tree_obj, tNode);
                });
              }

              $.tree.fixCheckState(z_tree_obj);
              update_entrance_permission(z_tree_obj);
              break;
            case 'expand_all':
              break;
            case 'collapse_all':
              break;
            case 'search':
              $($search_field_str).val('').trigger('propertychange').fadeOut('fast');
              break;
            default:
              console.log('undefined operation.');
          }
        }
        z_tree_obj.refresh();
      }

      function clickHandler(event, treeId, treeNode) {
        var zTree = $.fn.zTree.getZTreeObj(treeId);
        if (zTree.setting.check.enable == true) {
          // 若当前树结点未选中的话，将其选中；否则取消选中
          // 第三个参数表示联动处理父结点
          zTree.checkNode(treeNode, !treeNode.checked, true);
          sync_to_select_field(zTree, treeNode);
        }
        $.tree.fixCheckState(zTree);
        update_entrance_permission(zTree);
      }

      function checkHandler(event, treeId, treeNode) {
        var zTree = $.fn.zTree.getZTreeObj(treeId);
        console.log(zTree.getCheckedNodes());
        sync_to_select_field(zTree, treeNode);
        $.tree.fixCheckState(zTree);
        // update_entrance_permission(zTree);
      }

      function on_right_click(event, treeId, treeNode) {
        var zTree = $.fn.zTree.getZTreeObj(treeId);
        if (treeNode === null) {
          var _tid = $(event.target).attr('id').replace(new RegExp(treeId + '_(\\d+)(_.+)?'), '$1');
          if (_tid.length === 0 || !/\d+/.test(_tid)) {
            error_prompt('Right click above node or checkbox.');
          }
          treeNode = zTree.getNodeByTId(_tid);
        }
        if (treeNode && treeNode.isParent) {
          zTree.expandNode(treeNode, !treeNode.open, true);
        }
      }


      /**
       * @author boyce
       * @summary 渲染权限树(本质是操作 DOM 和 Event listening & handling)到指定的 tab
       * @param index 指明要渲染内容到 `哪一个` tab
       * @return {null}
       */

      function render_authtree_to_tab(index) {
        var $this_div = $('#' + tab_dict[index]),
          model_name = $this_div.data('modelName'),
          tree_selector = '#LAY-auth-tree-' + model_name,
          $tree = $(tree_selector),
          zTreeSetting = {
            view: {
              showLine: true
            },
            check: {
              enable: true,
              chkStyle: "checkbox",
              chkboxType: {"Y": "ps", "N": "ps"}
            },
            data: {
              simpleData: {
                enable: true, idKey: "id", pIdKey: "pid", rootPId: 0
              }
            },
            callback: {
              onClick: clickHandler,
              onCheck: checkHandler,
              onRightClick: on_right_click
            }
          };
        {#console.log('this_div', $this_div);#}

        // [check]: the auth-tree is initialized or not
        if ($tree.children().length === 0) {
          var auth_tree_content = $tree.closest('.auth-tree-content')
            , auth_tree_control = auth_tree_content.siblings('.auth-tree-control')
            , tree_nodes = get_perm_tree(model_name, i18n_dict[model_name]);
          auth_tree_control.data('tree', $tree.attr('id'));
          auth_tree_control.on('click', bind_event_for_panel);

          // 渲染时传入渲染目标ID，树形结构数据（具体结构看样例，checked表示默认选中），以及input表单的名字
          var zTreeObj = $.fn.zTree.init($tree, zTreeSetting, tree_nodes);
          $.tree.fixCheckState(zTreeObj);
          update_entrance_permission(zTreeObj);

          /*
           authtree.render('#LAY-auth-tree-' + model_name, trees, {
           inputname: 'authids[]',
           layfilter: 'lay-check-auth',
           openall: false,
           });
           */
          {#console.log('auth-tree', interpolate('`%s`', [model_name]), 'inited');#}
        }
      }

      // Firstly, add the ignore class which will dictate layui render engine
      //  not to render and beautify build-in DOM
      $permission.prop('lay-ignore', true);
      form.render();

      $("form.layui-form input.layui-date").each(function () {
        laydate.render({elem: this, type: 'date'});
      });

      $permission.hide();
      $permission.siblings('.layui-form-select').hide();
      $('.field-permissions.layui-form-item').hide();
      // simulate: click the first tab
      render_authtree_to_tab(0);

      /*
       * 监听切换 tab 的动作，经由此来实现 tab 的惰性加载
       */
      element.on('tab(auth_tree_tabs)', function (data) {
        // console.log('### element',this);  // 当前 Tab 标题所在的原始 DOM 元素
        // console.log('### tab', data);  // .index 得到当前 Tab 的所在下标, .elem 得到当前的 Tab 大容器
        if (data.index > 0) {
          render_authtree_to_tab(data.index);
        }
      });

      // 监听自定义lay-filter选中状态，
      // Tips:layui现在不支持多次监听，所以扩展里边只能改变触发逻辑，然后引起了事件冒泡延迟的BUG
      var all_authtree_selector = [],
        all_leaf = [];
      for (var key in tab_dict) {
        all_authtree_selector.push(interject('#LAY-auth-tree-{key}', {'key': tab_dict[key].replace(/tabs-/, '')}));
      }
      {#console.log('all_auth_tree_selector', all_authtree_selector);#}

      form.on('checkbox(lay-check-auth)', function (/*_data*/) {
        // 获取所有节点
        // var all = authtree.getAll('#LAY-auth-tree-personnel');
        // console.log('all', all);
        // 获取所有已选中节点
        // var checked = authtree.getChecked(all_authtree_selector);
        // console.log('checked', checked);
        // 获取所有未选中节点
        // var notchecked = authtree.getNotChecked('#LAY-auth-tree-personnel');
        // console.log('notchecked', notchecked);
        // 注意这里：需要等待事件冒泡完成，不然获取叶子节点不准确。
        /*
         setTimeout(function () {
         // 获取选中的叶子节点
         all_leaf = authtree.getLeaf(all_authtree_selector);
         //console.log('# leaf', all_leaf);
         $('option', $permission).each(function () {
         $(this).removeAttr('selected');
         });
         all_leaf.forEach(function (elem, index) {
         //var perm_opts = $permission.get(0).options;
         $(interject('option[value={}]', [elem]), $permission).prop('selected');
         });
         }, 100);
         */
      });
    });

    /**
     * @summary 为 mod 获取权限树
     */
    function get_perm_tree(mod_name, text) {
      var pseudo_id = -1048576,
        tree = [{
          id: pseudo_id,
          name: text,
          open: true
        }];

      var selected_flag = true

      if (allowed_perm_dict.hasOwnProperty(mod_name)) {
        var _allowed_perm_of_mod = allowed_perm_dict[mod_name];
        _allowed_perm_of_mod.forEach(function (elem, index) {
          var sub_tree = get_subtree_json(elem, index, pseudo_id, false, mod_name);
          // console.log('sub_tree', sub_tree);
          if (sub_tree.length > 1) { // DONE: exclude the pre-defined pseudo node
            tree = $.merge(tree, sub_tree);
            {#tree[0].subtree.push(sub_tree);#}

            if (sub_tree[0].checked == false) {
              selected_flag = false
            }
          }
        });
      }
      // 如果子节点都被选上则将父节点选上
      tree[0].checked = selected_flag
      {#console.log('_tree', mod_name, text, tree);#}
      return tree;
    }

    /**
     * @summary 获取 sub-tree 的 json 表示
     */
    function get_subtree_json(_perm, _index, pid, open_subtree, mod_name) {
      var _open = open_subtree === undefined ? false : Boolean(open_subtree),
        _tree_id = -(_index),
        sub_tree = [{
          id: _tree_id,
          name: _perm.name,
          pid: pid,
          open: _open
        }];

      var selected_flag = true

      var match_record = perm_triple.filter(function (item) {
        // 说明是 _pseudo_node 是非叶子节点, 将 _pseudo === _perm.id 的叶子节点作为 perm 的子结点
        return $.trim(item[1]) === _perm.id;  // _pseudo_node
      });

      match_record.forEach(function (elem/*, index*/) {
        var _db_mod = $.trim(elem[0]),
          _pseudo_node = $.trim(elem[1]),
          _perm_name = $.trim(elem[2]),
          _query_key = [_db_mod, _pseudo_node, _perm_name].join('_'),
          _value = parseInt(perm_value_dict[_query_key]),
          _perm_name = $.trim(elem[2]);
        trans_text = get_trans_text(_pseudo_node, _perm_name);

        if (exist_perm(_value) && trans_text !== "") {
          var _sub_tree = {
            pid: _tree_id,
            id: _value,
            name: _perm_name,
            checked: is_selected(mod_name, _value)
          };
          if (_sub_tree.checked == false) {
            selected_flag = false
          }
          sub_tree.push(_sub_tree);
        }
      });

      // 如果子节点都被选上则将父节点选上
      sub_tree[0].checked = selected_flag

      return sub_tree;
    }

    /**
     * @summary 准备权限数据
     * @param parent_obj
     */
    function prepare_perm_data(parent_obj) {

      // 记录初始化时候被选中的项目
      selected_formula['overtime'] = []
      selected_formula['exception'] = []
      selected_formula['leave'] = []
      selected_formula['increasement'] = []
      selected_formula['deduction'] = []

      // 用于记录index和value的字典, 在点击事件触发的时候查询
      select_field_formula['overtime'] = {}
      select_field_formula['exception'] = {}
      select_field_formula['leave'] = {}
      select_field_formula['increasement'] = {}
      select_field_formula['deduction'] = {}

      var overtime_opts = $("#id_overtimeformula", parent_obj).get(0).options;
      var exception_opts = $("#id_exceptionformula", parent_obj).get(0).options;
      var leave_opts = $("#id_leaveformula", parent_obj).get(0).options;
      var increase_opts = $("#id_increasementformula", parent_obj).get(0).options;
      var deduction_opts = $("#id_deductionformula", parent_obj).get(0).options;
      // overtime节点添加
      for (i = 0; i < overtime_opts.length; i++) {
        select_field_formula['overtime'][overtime_opts[i].value] = i
        var triple = (overtime_opts[i].innerHTML).split("|");
        triple = ['overtime', $.trim(triple[0]), $.trim(triple[1])]
        perm_triple.push(triple);
        perm_value_dict[triple.join('_')] = overtime_opts[i].value;
        if (overtime_opts[i].selected) {
          selected_formula['overtime'].push(parseInt(overtime_opts[i].value));
        }
      }
      // exception节点添加
      for (i = 0; i < exception_opts.length; i++) {
        select_field_formula['exception'][exception_opts[i].value] = i
        var triple = (exception_opts[i].innerHTML).split("|");
        triple = ['exception', $.trim(triple[0]), $.trim(triple[1])]
        perm_triple.push(triple);
        perm_value_dict[triple.join('_')] = exception_opts[i].value;
        if (exception_opts[i].selected) {
          selected_formula['exception'].push(parseInt(exception_opts[i].value));
        }
      }
      // leave节点添加
      // add new custom leave type in allowed_perm_dict
      var leave_nodes = []
      for (var j in allowed_perm_dict["leave"]) {
          leave_nodes.push(allowed_perm_dict["leave"][j]['name']);
      }
      for (i = 0; i < leave_opts.length; i++) {
        select_field_formula['leave'][leave_opts[i].value] = i
        var triple = (leave_opts[i].innerHTML).split("|");
        if (!leave_nodes.includes(triple[0])){
            var new_leave = {id: triple[0], name: triple[0]};
            allowed_perm_dict["leave"].push(new_leave);
        }
        triple = ['leave', $.trim(triple[0]), $.trim(triple[1])]
        perm_triple.push(triple);
        perm_value_dict[triple.join('_')] = leave_opts[i].value;
        if (leave_opts[i].selected) {
          selected_formula['leave'].push(parseInt(leave_opts[i].value));
        }
        // 动态添加leave的allowed_perm_dict
        // allowed_perm_dict['leave'].push({id: triple[1], name: triple[1]})
      }

      // increase节点添加
      for (i = 0; i < increase_opts.length; i++) {
        select_field_formula['increasement'][increase_opts[i].value] = i
        var triple = increase_opts[i].innerHTML;
        triple = ["{% trans 'payroll_model_increasementFormula' %}", "{% trans 'payroll_model_increasementFormula' %}", triple]
        perm_triple.push(triple);
        perm_value_dict[triple.join('_')] = increase_opts[i].value;
        if (increase_opts[i].selected) {
          selected_formula['increasement'].push(parseInt(increase_opts[i].value));
        }
      }

      // deduction节点添加
      for (i = 0; i < deduction_opts.length; i++) {
        select_field_formula['deduction'][deduction_opts[i].value] = i
        var triple = deduction_opts[i].innerHTML;
        triple = ["{% trans 'payroll_model_deductionFormula' %}", "{% trans 'payroll_model_deductionFormula' %}", triple]
        perm_triple.push(triple);
        perm_value_dict[triple.join('_')] = deduction_opts[i].value;
        if (deduction_opts[i].selected) {
          selected_formula['deduction'].push(parseInt(deduction_opts[i].value));
        }
      }

      var allowed_perm_arr = [];
      for (var mod in allowed_perm_dict) {
        allowed_perm_dict[mod].forEach(function (elem/*, index*/) {
          allowed_perm_arr.push(elem.id);
        });
      }

      console.log('allowed_perm_str', allowed_perm_arr);
      console.log('perm_triple', perm_triple);
      console.log('selected_formula', selected_formula);
    }

    function get_trans_text(mod, perm_name) {
      return titleCase(perm_name, '_'); // sentry for perm_name missed
    }

    function is_selected(mod_name, selected_id) {
      return selected_formula[mod_name].includes(selected_id);
    }

    function exist_perm(value) {
      if (group_perm_values.length === 0) {
        return true;
      } else {
        return group_perm_values.includes(value) !== -1;
      }
    }
  });
</script>
