(self.webpackChunktimetrex=self.webpackChunktimetrex||[]).push([["attendance-timesheet-TimeSheetViewController","filebrowser-TImage"],{1469:(__unused_webpack_module,__unused_webpack_exports,__webpack_require__)=>{eval("/* provided dependency */ var jQuery = __webpack_require__(9755);\n( function( $ ) {\n\n\t$.fn.TImage = function( options ) {\n\n\t\tGlobal.addCss( 'global/widgets/filebrowser/TImageBrowser.css' );\n\t\tvar opts = $.extend( {}, $.fn.TImage.defaults, options );\n\n\t\tvar $this = this;\n\t\tvar field;\n\n\t\tthis.clearErrorStyle = function() {\n\n\t\t};\n\n\t\tthis.getField = function() {\n\t\t\treturn field;\n\t\t};\n\n\t\tthis.getValue = function() {\n\t\t\treturn null;\n\t\t};\n\n\t\tthis.setValue = function( val ) {\n\t\t\tif ( !val ) {\n\t\t\t\tthis.attr( 'src', '' );\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tvar d = new Date();\n\t\t\tthis.attr( 'src', val + '&t=' + d.getTime() );\n\n\t\t};\n\n\t\tthis.each( function() {\n\n\t\t\tvar o = $.meta ? $.extend( {}, opts, $( this ).data() ) : opts;\n\n\t\t\tfield = o.field;\n\n\t\t} );\n\n\t\treturn this;\n\n\t};\n\n\t$.fn.TImage.defaults = {};\n\n\t$( document ).on( 'mouseover', '.file-browser img', function( e ) {\n\t\tvar $this_image_widget = $( e.target ).parents( '.file-browser' );\n\n\t\tif ( !$( '.file_browser_overlay' )[0] && $( e.target ).attr( 'enable-delete' ) == 1 ) {\n\t\t\tvar height = $( e.target ).height();\n\t\t\tvar top = ( height - 32 ) / 2;\n\t\t\tvar left = top;\n\n\t\t\tvar file_browser_overlay = $( '
' );\n\t\t\tfile_browser_overlay.css( 'position', 'absolute' );\n\t\t\tfile_browser_overlay.css( 'top', '0px' );\n\t\t\tfile_browser_overlay.css( 'left', '0' );\n\t\t\tfile_browser_overlay.css( 'cursor', 'pointer' );\n\t\t\tfile_browser_overlay.css( 'height', height + 'px' );\n\t\t\tfile_browser_overlay.css( 'width', '100%' );\n\t\t\tfile_browser_overlay.css( 'background', 'rgba(255,255,255,0.85)' );\n\n\t\t\t$( e.target ).parents( '.file-browser' ).append( file_browser_overlay );\n\n\t\t\t$( document ).on( 'click', '.file_browser_overlay', function( e ) {\n\t\t\t\tvar img_src = $( e.target ).parent().find( 'img' ).attr( 'src' );\n\t\t\t\tTAlertManager.showConfirmAlert( $.i18n._( 'This will permanently delete the image. Are you sure?' ), '', function( flag ) {\n\t\t\t\t\tif ( flag ) {\n\t\t\t\t\t\tvar e = { type: 'deleteClick', message: 'Delete image clicked.', time: new Date() };\n\t\t\t\t\t\t$this_image_widget.trigger( e );\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t} );\n\n\t\t\t$( document ).on( 'mouseleave', '.file-browser', function() {\n\t\t\t\t$( document ).off( 'click', '.file_browser_overlay' );\n\t\t\t\tif ( $( '.file_browser_overlay' )[0] ) {\n\t\t\t\t\tvar file_browser_overlay = $( this ).find( '.file_browser_overlay' );\n\t\t\t\t\tfile_browser_overlay.off().remove();\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\t} );\n\n} )( jQuery );//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMTQ2OS5qcyIsIm1hcHBpbmdzIjoiO0FBQUE7O0FBRUE7O0FBRUE7QUFDQSx5QkFBeUI7O0FBRXpCO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQSxnQ0FBZ0M7O0FBRWhDOztBQUVBLElBQUk7O0FBRUo7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSw0SUFBNEksV0FBVyxZQUFZLGtCQUFrQixvQkFBb0I7QUFDek07QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7QUFDaEI7QUFDQTtBQUNBLE1BQU07QUFDTixLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLEdBQUc7O0FBRUgsRUFBRSxHQUFHLE1BQU0iLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9pbnRlcmZhY2UvaHRtbDUvZ2xvYmFsL3dpZGdldHMvZmlsZWJyb3dzZXIvVEltYWdlLmpzPzllOTIiXSwic291cmNlc0NvbnRlbnQiOlsiKCBmdW5jdGlvbiggJCApIHtcblxuXHQkLmZuLlRJbWFnZSA9IGZ1bmN0aW9uKCBvcHRpb25zICkge1xuXG5cdFx0R2xvYmFsLmFkZENzcyggJ2dsb2JhbC93aWRnZXRzL2ZpbGVicm93c2VyL1RJbWFnZUJyb3dzZXIuY3NzJyApO1xuXHRcdHZhciBvcHRzID0gJC5leHRlbmQoIHt9LCAkLmZuLlRJbWFnZS5kZWZhdWx0cywgb3B0aW9ucyApO1xuXG5cdFx0dmFyICR0aGlzID0gdGhpcztcblx0XHR2YXIgZmllbGQ7XG5cblx0XHR0aGlzLmNsZWFyRXJyb3JTdHlsZSA9IGZ1bmN0aW9uKCkge1xuXG5cdFx0fTtcblxuXHRcdHRoaXMuZ2V0RmllbGQgPSBmdW5jdGlvbigpIHtcblx0XHRcdHJldHVybiBmaWVsZDtcblx0XHR9O1xuXG5cdFx0dGhpcy5nZXRWYWx1ZSA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0cmV0dXJuIG51bGw7XG5cdFx0fTtcblxuXHRcdHRoaXMuc2V0VmFsdWUgPSBmdW5jdGlvbiggdmFsICkge1xuXHRcdFx0aWYgKCAhdmFsICkge1xuXHRcdFx0XHR0aGlzLmF0dHIoICdzcmMnLCAnJyApO1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cdFx0XHR2YXIgZCA9IG5ldyBEYXRlKCk7XG5cdFx0XHR0aGlzLmF0dHIoICdzcmMnLCB2YWwgKyAnJnQ9JyArIGQuZ2V0VGltZSgpICk7XG5cblx0XHR9O1xuXG5cdFx0dGhpcy5lYWNoKCBmdW5jdGlvbigpIHtcblxuXHRcdFx0dmFyIG8gPSAkLm1ldGEgPyAkLmV4dGVuZCgge30sIG9wdHMsICQoIHRoaXMgKS5kYXRhKCkgKSA6IG9wdHM7XG5cblx0XHRcdGZpZWxkID0gby5maWVsZDtcblxuXHRcdH0gKTtcblxuXHRcdHJldHVybiB0aGlzO1xuXG5cdH07XG5cblx0JC5mbi5USW1hZ2UuZGVmYXVsdHMgPSB7fTtcblxuXHQkKCBkb2N1bWVudCApLm9uKCAnbW91c2VvdmVyJywgJy5maWxlLWJyb3dzZXIgaW1nJywgZnVuY3Rpb24oIGUgKSB7XG5cdFx0dmFyICR0aGlzX2ltYWdlX3dpZGdldCA9ICQoIGUudGFyZ2V0ICkucGFyZW50cyggJy5maWxlLWJyb3dzZXInICk7XG5cblx0XHRpZiAoICEkKCAnLmZpbGVfYnJvd3Nlcl9vdmVybGF5JyApWzBdICYmICQoIGUudGFyZ2V0ICkuYXR0ciggJ2VuYWJsZS1kZWxldGUnICkgPT0gMSApIHtcblx0XHRcdHZhciBoZWlnaHQgPSAkKCBlLnRhcmdldCApLmhlaWdodCgpO1xuXHRcdFx0dmFyIHRvcCA9ICggaGVpZ2h0IC0gMzIgKSAvIDI7XG5cdFx0XHR2YXIgbGVmdCA9IHRvcDtcblxuXHRcdFx0dmFyIGZpbGVfYnJvd3Nlcl9vdmVybGF5ID0gJCggJzxkaXYgY2xhc3M9XCJmaWxlX2Jyb3dzZXJfb3ZlcmxheVwiPjxpbWcgc3JjPVwidGhlbWUvZGVmYXVsdC9pbWFnZXMvZGVsZXRlLTUxMi5wbmdcIiBzdHlsZT1cInBvc2l0aW9uOmFic29sdXRlO3dpZHRoOjMycHg7aGVpZ2h0OjMycHg7dG9wOicgKyB0b3AgKyAncHg7bGVmdDonICsgbGVmdCArICdweDtcIj48L2Rpdj4nICk7XG5cdFx0XHRmaWxlX2Jyb3dzZXJfb3ZlcmxheS5jc3MoICdwb3NpdGlvbicsICdhYnNvbHV0ZScgKTtcblx0XHRcdGZpbGVfYnJvd3Nlcl9vdmVybGF5LmNzcyggJ3RvcCcsICcwcHgnICk7XG5cdFx0XHRmaWxlX2Jyb3dzZXJfb3ZlcmxheS5jc3MoICdsZWZ0JywgJzAnICk7XG5cdFx0XHRmaWxlX2Jyb3dzZXJfb3ZlcmxheS5jc3MoICdjdXJzb3InLCAncG9pbnRlcicgKTtcblx0XHRcdGZpbGVfYnJvd3Nlcl9vdmVybGF5LmNzcyggJ2hlaWdodCcsIGhlaWdodCArICdweCcgKTtcblx0XHRcdGZpbGVfYnJvd3Nlcl9vdmVybGF5LmNzcyggJ3dpZHRoJywgJzEwMCUnICk7XG5cdFx0XHRmaWxlX2Jyb3dzZXJfb3ZlcmxheS5jc3MoICdiYWNrZ3JvdW5kJywgJ3JnYmEoMjU1LDI1NSwyNTUsMC44NSknICk7XG5cblx0XHRcdCQoIGUudGFyZ2V0ICkucGFyZW50cyggJy5maWxlLWJyb3dzZXInICkuYXBwZW5kKCBmaWxlX2Jyb3dzZXJfb3ZlcmxheSApO1xuXG5cdFx0XHQkKCBkb2N1bWVudCApLm9uKCAnY2xpY2snLCAnLmZpbGVfYnJvd3Nlcl9vdmVybGF5JywgZnVuY3Rpb24oIGUgKSB7XG5cdFx0XHRcdHZhciBpbWdfc3JjID0gJCggZS50YXJnZXQgKS5wYXJlbnQoKS5maW5kKCAnaW1nJyApLmF0dHIoICdzcmMnICk7XG5cdFx0XHRcdFRBbGVydE1hbmFnZXIuc2hvd0NvbmZpcm1BbGVydCggJC5pMThuLl8oICdUaGlzIHdpbGwgcGVybWFuZW50bHkgZGVsZXRlIHRoZSBpbWFnZS4gQXJlIHlvdSBzdXJlPycgKSwgJycsIGZ1bmN0aW9uKCBmbGFnICkge1xuXHRcdFx0XHRcdGlmICggZmxhZyApIHtcblx0XHRcdFx0XHRcdHZhciBlID0geyB0eXBlOiAnZGVsZXRlQ2xpY2snLCBtZXNzYWdlOiAnRGVsZXRlIGltYWdlIGNsaWNrZWQuJywgdGltZTogbmV3IERhdGUoKSB9O1xuXHRcdFx0XHRcdFx0JHRoaXNfaW1hZ2Vfd2lkZ2V0LnRyaWdnZXIoIGUgKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0gKTtcblx0XHRcdH0gKTtcblxuXHRcdFx0JCggZG9jdW1lbnQgKS5vbiggJ21vdXNlbGVhdmUnLCAnLmZpbGUtYnJvd3NlcicsIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHQkKCBkb2N1bWVudCApLm9mZiggJ2NsaWNrJywgJy5maWxlX2Jyb3dzZXJfb3ZlcmxheScgKTtcblx0XHRcdFx0aWYgKCAkKCAnLmZpbGVfYnJvd3Nlcl9vdmVybGF5JyApWzBdICkge1xuXHRcdFx0XHRcdHZhciBmaWxlX2Jyb3dzZXJfb3ZlcmxheSA9ICQoIHRoaXMgKS5maW5kKCAnLmZpbGVfYnJvd3Nlcl9vdmVybGF5JyApO1xuXHRcdFx0XHRcdGZpbGVfYnJvd3Nlcl9vdmVybGF5Lm9mZigpLnJlbW92ZSgpO1xuXHRcdFx0XHR9XG5cdFx0XHR9ICk7XG5cdFx0fVxuXHR9ICk7XG5cbn0gKSggalF1ZXJ5ICk7Il0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///1469\n")},2693:(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{"use strict";eval("// ESM COMPAT FLAG\n__webpack_require__.r(__webpack_exports__);\n\n// EXPORTS\n__webpack_require__.d(__webpack_exports__, {\n \"TimeSheetViewController\": () => (/* binding */ TimeSheetViewController)\n});\n\n// EXTERNAL MODULE: ./interface/html5/global/widgets/filebrowser/TImage.js\nvar TImage = __webpack_require__(1469);\n// EXTERNAL MODULE: ./interface/html5/services/TTVueUtils.js\nvar TTVueUtils = __webpack_require__(4966);\n// EXTERNAL MODULE: ./node_modules/vue/dist/vue.esm-bundler.js + 6 modules\nvar vue_esm_bundler = __webpack_require__(5166);\n;// CONCATENATED MODULE: ./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[1]!./node_modules/vue-loader/dist/index.js??ruleSet[1].rules[6].use[0]!./interface/html5/components/timesheet/TimeSheetControlBar.vue?vue&type=template&id=71fa0b53&scoped=true\n\n\nconst _withScopeId = n => (_pushScopeId(\"data-v-71fa0b53\"),n=n(),_popScopeId(),n)\nconst _hoisted_1 = { class: \"tt-horizontal-vue-bar\" }\nconst _hoisted_2 = /*#__PURE__*/(0,vue_esm_bundler/* createStaticVNode */.uE)(\"\", 2)\nconst _hoisted_4 = { class: \"bar-column right\" }\nconst _hoisted_5 = { class: \"bar-column punch-manual\" }\nconst _hoisted_6 = { class: \"bar-column menu-item\" }\n\nfunction render(_ctx, _cache, $props, $setup, $data, $options) {\n const _component_SelectButton = (0,vue_esm_bundler/* resolveComponent */.up)(\"SelectButton\")\n const _component_TTContextButton = (0,vue_esm_bundler/* resolveComponent */.up)(\"TTContextButton\")\n\n return ((0,vue_esm_bundler/* openBlock */.wg)(), (0,vue_esm_bundler/* createElementBlock */.iD)(\"div\", _hoisted_1, [\n _hoisted_2,\n (0,vue_esm_bundler/* createElementVNode */._)(\"div\", _hoisted_4, [\n (0,vue_esm_bundler/* createElementVNode */._)(\"div\", _hoisted_5, [\n (0,vue_esm_bundler/* createVNode */.Wm)(_component_SelectButton, {\n modelValue: $data.punch_mode_selected,\n \"onUpdate:modelValue\": _cache[0] || (_cache[0] = $event => (($data.punch_mode_selected) = $event)),\n options: $data.punch_modes,\n optionLabel: \"label\",\n optionValue: \"value\",\n onClick: _cache[1] || (_cache[1] = $event => {this.onPunchModeChange();})\n }, null, 8 /* PROPS */, [\"modelValue\", \"options\"])\n ]),\n (0,vue_esm_bundler/* createElementVNode */._)(\"div\", _hoisted_6, [\n (0,vue_esm_bundler/* createVNode */.Wm)(_component_TTContextButton, {\n class: (0,vue_esm_bundler/* normalizeClass */.C_)(['no-wrap']),\n items: $data.timesheet_settings_options\n }, null, 8 /* PROPS */, [\"items\"])\n ])\n ])\n ]))\n}\n;// CONCATENATED MODULE: ./interface/html5/components/timesheet/TimeSheetControlBar.vue?vue&type=template&id=71fa0b53&scoped=true\n\n// EXTERNAL MODULE: ./node_modules/primevue/selectbutton/selectbutton.esm.js\nvar selectbutton_esm = __webpack_require__(1109);\n// EXTERNAL MODULE: ./interface/html5/components/context_menu/TTContextButton.vue + 24 modules\nvar TTContextButton = __webpack_require__(777);\n;// CONCATENATED MODULE: ./node_modules/vue-loader/dist/index.js??ruleSet[1].rules[6].use[0]!./interface/html5/components/timesheet/TimeSheetControlBar.vue?vue&type=script&lang=js\n/* provided dependency */ var $ = __webpack_require__(9755);\n\n\n\n\n/* harmony default export */ const TimeSheetControlBarvue_type_script_lang_js = ({\n name: \"TimeSheetControlBar\",\n props: {\n component_id: { // passed in via root props from TimeSheetViewController\n type: String,\n default: null\n },\n onPunchModeChange: { // passed in via root props from TimeSheetViewController\n type: Function,\n default: null\n },\n onShowWageClick: { // passed in via root props from TimeSheetViewController\n type: Function,\n default: null\n },\n onTimezoneClick: { // passed in via root props from TimeSheetViewController\n type: Function,\n default: null\n }\n },\n data() {\n return {\n punch_mode_selected: 'punch',\n punch_modes: [\n { label: $.i18n._( 'Punch' ), value: 'punch' },\n { label: $.i18n._( 'Manual' ), value: 'manual' },\n ],\n timesheet_settings_options: [\n {\n label: $.i18n._( 'Show Wages' ),\n id: 'show_wages',\n no_group_label: true,\n vue_icon: 'tticon tticon-settings_black_24dp',\n action_group: 'timesheet_settings',\n multi_select_group: 1,\n visible: PermissionManager.checkTopLevelPermission( 'Wage' ),\n command: () => {\n if( this.onShowWageClick && typeof this.onShowWageClick === 'function' ) {\n this.onShowWageClick( this.timesheet_settings_options[0].active );\n }\n }\n },\n {\n label: $.i18n._( 'Use Employee Timezone' ),\n id: 'use_employee_timezone',\n no_group_label: true,\n vue_icon: 'tticon tticon-settings_black_24dp',\n action_group: 'timesheet_settings',\n multi_select_group: 2,\n visible: ( PermissionManager.validate( 'punch', 'view' ) || PermissionManager.validate( 'punch', 'view_child' ) ),\n command: () => {\n if( this.onTimezoneClick && typeof this.onTimezoneClick === 'function' ) {\n this.onTimezoneClick( this.timesheet_settings_options[1].active );\n }\n }\n },\n ]\n }\n },\n // watch: {\n // punch_mode_selected: function ( val ) {\n // if( this.onPunchModeChange && typeof this.onPunchModeChange === 'function' ) {\n // this.onPunchModeChange( val, false );\n // }\n // },\n // },\n computed: {\n getPunchMode() { // This way the value is cached if it doesnt change.\n return this.punch_mode_selected;\n }\n },\n methods: {\n setPunchMode( new_value ) {\n if ( new_value === 'punch' || new_value === 'manual' ) { // validate the input potentially coming from outside Vue.\n this.punch_mode_selected = new_value;\n return true;\n } else {\n Debug.Error( 'Invalid parameters passed to function: ', 'TimeSheetControlBar.vue', 'TimeSheetControlBar', 'setPunchMode', 1 );\n return false;\n }\n },\n getTimesheetSettingsState( item_id ) {\n var item = this.timesheet_settings_options.find( element => element.id === item_id );\n if( item ) {\n return item.active;\n } else {\n Debug.Error( 'Item not found ('+ item_id +'). Check supplied id.', 'TimeSheetControlBar.vue', 'TimeSheetControlBar', 'getTimesheetSettingsState', 1 );\n return undefined;\n }\n },\n setTimesheetSettingsState( item_id, value ) {\n var item = this.timesheet_settings_options.find( element => element.id === item_id );\n if( item ) {\n item.active = value;\n } else {\n Debug.Error( 'Item not found ('+ item_id +'). Check supplied id.', 'TimeSheetControlBar.vue', 'TimeSheetControlBar', 'setTimesheetSettingsState', 1 );\n }\n }\n },\n components: {\n SelectButton: selectbutton_esm/* default */.Z,\n TTContextButton: TTContextButton/* default */.Z\n }\n});\n\n;// CONCATENATED MODULE: ./interface/html5/components/timesheet/TimeSheetControlBar.vue?vue&type=script&lang=js\n \n// EXTERNAL MODULE: ./node_modules/vue-loader/dist/exportHelper.js\nvar exportHelper = __webpack_require__(3744);\n;// CONCATENATED MODULE: ./interface/html5/components/timesheet/TimeSheetControlBar.vue\n\n\n\n\n;\n\n\nconst __exports__ = /*#__PURE__*/(0,exportHelper/* default */.Z)(TimeSheetControlBarvue_type_script_lang_js, [['render',render],['__scopeId',\"data-v-71fa0b53\"]])\n\n/* harmony default export */ const TimeSheetControlBar = (__exports__);\n// EXTERNAL MODULE: ./interface/html5/global/TTUUID.js\nvar TTUUID = __webpack_require__(4936);\n// EXTERNAL MODULE: ./interface/html5/global/Global.js\nvar Global = __webpack_require__(9490);\n;// CONCATENATED MODULE: ./interface/html5/views/attendance/timesheet/TimeSheetViewController.js\n/* provided dependency */ var _ = __webpack_require__(9050);\n/* provided dependency */ var TimeSheetViewController_$ = __webpack_require__(9755);\n\n\n\n\n\n\nclass TimeSheetViewController extends BaseViewController {\n\tconstructor( options = {} ) {\n\t\t_.defaults( options, {\n\t\t\tel: '#timesheet_view_container', //Must set el here and can only set string, so events can work\n\t\t\t// _required_files: {\n\t\t\t// \t10: ['TImage'],\n\t\t\t// \t15: ['leaflet-timetrex']\n\t\t\t// },\n\t\t\tstatus_array: null,\n\t\t\ttype_array: null,\n\t\t\temployee_nav: null,\n\t\t\tstart_date_picker: null,\n\t\t\tfull_timesheet_data: null, //full timesheet data\n\t\t\tfull_format: 'ddd-MMM-DD-YYYY',\n\t\t\tweekly_format: 'ddd, MMM DD',\n\t\t\tday_format: 'ddd',\n\t\t\tdate_format: 'MMM DD',\n\t\t\tstart_date: null,\n\t\t\tend_date: null,\n\t\t\tselect_cells_Array: [], //Timesheet grid\n\t\t\tselect_punches_array: [], //Timesheet grid.\n\t\t\tabsence_select_cells_Array: [], //Absence grid\n\t\t\taccumulated_time_cells_array: [],\n\t\t\tpremium_cells_array: [],\n\t\t\ttimesheet_data_source: null,\n\t\t\taccumulated_time_source: null,\n\t\t\taccumulated_time_grid: null,\n\t\t\taccumulated_time_source_map: null,\n\t\t\tbranch_grid: null,\n\t\t\tbranch_source_map: null,\n\t\t\tbranch_source: null,\n\t\t\tdepartment_grid: null,\n\t\t\tdepartment_source_map: null,\n\t\t\tdepartment_source: null,\n\t\t\tjob_grid: null,\n\t\t\tjob_source_map: null,\n\t\t\tjob_source: null,\n\t\t\tjob_item_grid: null,\n\t\t\tjob_item_source_map: null,\n\t\t\tjob_item_source: null,\n\t\t\tpunch_tag_source_map: null,\n\t\t\tpunch_tag_source: null,\n\t\t\tpremium_grid: null,\n\t\t\tpremium_source_map: null,\n\t\t\tpremium_source: null,\n\t\t\tabsence_grid: null,\n\t\t\tabsence_source: null,\n\t\t\tabsence_original_source: null,\n\t\t\taccumulated_total_grid: null,\n\t\t\taccumulated_total_grid_source_map: null,\n\t\t\taccumulated_total_grid_source: null,\n\t\t\tpunch_note_grid: null,\n\t\t\tpunch_note_grid_source: null,\n\t\t\tverification_grid: null,\n\t\t\tverification_grid_source: null,\n\t\t\tgrid_dic: null,\n\t\t\tpay_period_map: null,\n\t\t\tpay_period_data: null,\n\t\t\ttimesheet_verify_data: null,\n\t\t\tapi_timesheet: null,\n\t\t\tapi_user_date_total: null,\n\t\t\tapi_date: null,\n\t\t\tapi_station: null,\n\t\t\tapi_punch: null,\n\t\t\tabsence_model: false,\n\t\t\tselect_drag_menu_id: '', //Do drag move or copy\n\t\t\tis_mass_adding: false,\n\t\t\tdepartment_cell_count: 0,\n\t\t\tbranch_cell_count: 0,\n\t\t\tpremium_cell_count: 0,\n\t\t\tjob_cell_count: 0,\n\t\t\ttask_cell_count: 0,\n\t\t\tpunch_tag_cell_count: 0,\n\t\t\tabsence_cell_count: 0,\n\t\t\tpunch_note_account: 0,\n\t\t\tshow_navigation_box: true,\n\t\t\tstation: null,\n\t\t\tscroll_position: 0,\n\t\t\tjob_api: null,\n\t\t\tjob_item_api: null,\n\t\t\tuser_group_id: null,\n\t\t\tpunch_tag_api: null,\n\t\t\tuser_api: null,\n\t\t\tdepartment_api: null,\n\t\t\tdefault_punch_tag: [],\n\t\t\tprevious_punch_tag_selection: [],\n\t\t\tapi_absence_policy: null,\n\t\t\tpre_total_time: null,\n\t\t\tabsence_available_balance_dataList: {},\n\t\t\tavailable_balance_info: null,\n\t\t\tshow_job_ui: false,\n\t\t\tshow_job_item_ui: false,\n\t\t\tshow_punch_tag_ui: false,\n\t\t\tshow_branch_ui: false,\n\t\t\tshow_department_ui: false,\n\t\t\tshow_good_quantity_ui: false,\n\t\t\tshow_bad_quantity_ui: false,\n\t\t\tshow_note_ui: false,\n\t\t\tshow_station_ui: false,\n\t\t\tshow_absence_job_ui: false,\n\t\t\tshow_absence_job_item_ui: false,\n\t\t\tshow_absence_punch_tag_ui: false,\n\t\t\tshow_absence_branch_ui: false,\n\t\t\tshow_absence_department_ui: false,\n\t\t\tholiday_data_dic: {},\n\t\t\tgrid_div: null,\n\t\t\tactual_time_label: null,\n\t\t\tcolumn_maps: null,\n\t\t\taccmulated_order_map: {},\n\t\t\turl_args_before_set_date_url: {},\n\t\t\tallow_auto_switch: true,\n\t\t\tvue_control_bar_id: '',\n\t\t\tprevious_absence_policy_id: false,\n\t\t\tevents: {},\n\t\t\t//Issue #3286 - Users without permission to display \"Current View\" dropdown still need to load select layout from user generic data\n\t\t\t//This is to ensure the API attempts to update the current layout and not create a new one causing a validation error.\n\t\t\tforce_get_select_layout: true\n\t\t} );\n\n\t\tsuper( options );\n\t}\n\n\tinit( options ) {\n\t\t////this._super('initialize', options );\n\t\tthis.permission_id = 'punch';\n\t\tthis.viewId = 'TimeSheet';\n\t\tthis.script_name = 'TimeSheetView';\n\t\tthis.context_menu_name = TimeSheetViewController_$.i18n._( 'TimeSheet' );\n\t\tthis.navigation_label = TimeSheetViewController_$.i18n._( 'TimeSheet' );\n\t\tthis.api = TTAPI.APIPunch;\n\t\tthis.api_timesheet = TTAPI.APITimeSheet;\n\t\tthis.api_user_date_total = TTAPI.APIUserDateTotal;\n\t\tthis.api_date = TTAPI.APITTDate;\n\t\tthis.api_station = TTAPI.APIStation;\n\t\tthis.api_punch = TTAPI.APIPunch;\n\t\tif ( ( Global/* Global.getProductEdition */.x.getProductEdition() >= 20 ) ) {\n\t\t\tthis.job_api = TTAPI.APIJob;\n\t\t\tthis.job_item_api = TTAPI.APIJobItem;\n\t\t\tthis.punch_tag_api = TTAPI.APIPunchTag;\n\t\t\tthis.department_api = TTAPI.APIDepartment;\n\t\t}\n\t\tthis.api_absence_policy = TTAPI.APIAbsencePolicy;\n\t\tthis.scroll_position = 0;\n\t\tthis.grid_dic = {};\n\t\t// this.event_bus = new TTEventBus({ view_id: this.viewId }); // TimeSheet does not use TTEventBus yet, its currently using direct access to the Vue component by reference, as a proof of concept. Best to use TTEventBus for future work though.\n\n\t\tthis.initPermission();\n\t\tthis.render();\n\t\tthis.buildContextMenu();\n\t\tthis.initData();\n\t}\n\n\tinitEditView() {\n\t\tTTPromise.resolve( 'TimeSheetViewController', 'addclick' );\n\t\tsuper.initEditView();\n\t}\n\n\tonSubViewRemoved( is_cancel ) {\n\t\tif ( !is_cancel ) {\n\t\t\tthis.search();\n\t\t}\n\n\t\tif ( !this.edit_view ) {\n\t\t\tthis.setDefaultMenu();\n\t\t} else {\n\t\t\tthis.setEditMenu();\n\t\t}\n\t}\n\n\tsetScrollPosition() {\n\t\tif ( this.scroll_position > 0 ) {\n\t\t\tthis.grid_div.scrollTop( this.scroll_position );\n\t\t}\n\t}\n\n\tpunchModeValidate( p_id ) {\n\t\tif ( !p_id ) {\n\t\t\tp_id = 'punch';\n\t\t}\n\n\t\tif ( PermissionManager.validate( p_id, 'punch_timesheet' ) &&\n\t\t\tPermissionManager.validate( p_id, 'manual_timesheet' ) ) {\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\tgetPunchPermissionType() {\n\t\treturn this.absence_model ? 'absence' : 'punch';\n\t}\n\n\tjobUIValidate( p_id ) {\n\n\t\tif ( !p_id ) {\n\t\t\tp_id = 'punch';\n\t\t}\n\n\t\tif (Global/* Global.getProductEdition */.x.getProductEdition() >= 20 && PermissionManager.validate( 'job', 'enabled' ) &&\n\t\t\tPermissionManager.validate( p_id, 'edit_job' ) ) {\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\tjobItemUIValidate( p_id ) {\n\n\t\tif ( !p_id ) {\n\t\t\tp_id = 'punch';\n\t\t}\n\n\t\tif (Global/* Global.getProductEdition */.x.getProductEdition() >= 20 && PermissionManager.validate( p_id, 'edit_job_item' ) ) {\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\tpunchTagUIValidate( p_id ) {\n\n\t\tif ( !p_id ) {\n\t\t\tp_id = 'punch';\n\t\t}\n\n\t\tif (Global/* Global.getProductEdition */.x.getProductEdition() >= 20 && PermissionManager.validate( p_id, 'edit_punch_tag' ) ) {\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\t//Refresh to clear warnning messages after saving from employee edit view\n\tupdateSelectUserAndRefresh( new_item ) {\n\n\t\tthis.employee_nav.updateSelectItem( new_item );\n\n\t\tthis.search();\n\t}\n\n\tbranchUIValidate( p_id ) {\n\n\t\tif ( !p_id ) {\n\t\t\tp_id = 'punch';\n\t\t}\n\n\t\tif ( PermissionManager.validate( p_id, 'edit_branch' ) ) {\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\tdepartmentUIValidate( p_id ) {\n\n\t\tif ( !p_id ) {\n\t\t\tp_id = 'punch';\n\t\t}\n\n\t\tif ( PermissionManager.validate( p_id, 'edit_department' ) ) {\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\tgoodQuantityUIValidate( p_id ) {\n\n\t\tif ( !p_id ) {\n\t\t\tp_id = 'punch';\n\t\t}\n\n\t\tif ( PermissionManager.validate( p_id, 'edit_quantity' ) ) {\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\tbadQuantityUIValidate( p_id ) {\n\n\t\tif ( !p_id ) {\n\t\t\tp_id = 'punch';\n\t\t}\n\n\t\tif ( PermissionManager.validate( p_id, 'edit_quantity' ) &&\n\t\t\tPermissionManager.validate( p_id, 'edit_bad_quantity' ) ) {\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\tlocationUIValidate( p_id ) {\n\n\t\tif ( !p_id ) {\n\t\t\tp_id = 'punch';\n\t\t}\n\n\t\tif ( PermissionManager.validate( p_id, 'edit_location' ) ) {\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\tnoteUIValidate( p_id ) {\n\n\t\tif ( !p_id ) {\n\t\t\tp_id = 'punch';\n\t\t}\n\n\t\tif ( PermissionManager.validate( p_id, 'edit_note' ) ) {\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\tstationValidate() {\n\t\tif ( PermissionManager.validate( 'station', 'enabled' ) ) {\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/* jshint ignore:start */\n\n\t//Special permission check for views, need override\n\tinitPermission() {\n\t\tsuper.initPermission();\n\n\t\tif ( !PermissionManager.validate( 'punch', 'view' ) && !PermissionManager.validate( 'punch', 'view_child' ) ) {\n\t\t\tthis.show_navigation_box = false;\n\t\t\tthis.show_search_tab = false;\n\t\t} else {\n\t\t\tthis.show_navigation_box = true;\n\t\t\tthis.show_search_tab = true;\n\t\t}\n\n\t\tif ( this.punchModeValidate() ) {\n\t\t\tthis.show_punch_mode_ui = true;\n\t\t} else {\n\t\t\tthis.show_punch_mode_ui = false;\n\t\t}\n\n\t\tthis.allow_auto_switch && this.show_punch_mode_ui && ( this.is_auto_switch = true );\n\n\t\tif ( this.jobUIValidate() ) {\n\t\t\tthis.show_job_ui = true;\n\t\t} else {\n\t\t\tthis.show_job_ui = false;\n\t\t}\n\n\t\tif ( this.jobItemUIValidate() ) {\n\t\t\tthis.show_job_item_ui = true;\n\t\t} else {\n\t\t\tthis.show_job_item_ui = false;\n\t\t}\n\n\n\t\tif ( this.punchTagUIValidate() ) {\n\t\t\tthis.show_punch_tag_ui = true;\n\t\t} else {\n\t\t\tthis.show_punch_tag_ui = false;\n\t\t}\n\n\t\tif ( this.branchUIValidate() ) {\n\t\t\tthis.show_branch_ui = true;\n\t\t} else {\n\t\t\tthis.show_branch_ui = false;\n\t\t}\n\n\t\tif ( this.departmentUIValidate() ) {\n\t\t\tthis.show_department_ui = true;\n\t\t} else {\n\t\t\tthis.show_department_ui = false;\n\t\t}\n\n\t\tif ( this.goodQuantityUIValidate() ) {\n\t\t\tthis.show_good_quantity_ui = true;\n\t\t} else {\n\t\t\tthis.show_good_quantity_ui = false;\n\t\t}\n\n\t\tif ( this.badQuantityUIValidate() ) {\n\t\t\tthis.show_bad_quantity_ui = true;\n\t\t} else {\n\t\t\tthis.show_bad_quantity_ui = false;\n\t\t}\n\n\t\tif ( this.noteUIValidate() ) {\n\t\t\tthis.show_note_ui = true;\n\t\t} else {\n\t\t\tthis.show_note_ui = false;\n\t\t}\n\n\t\tif ( this.locationUIValidate() ) {\n\t\t\tthis.show_location_ui = true;\n\t\t} else {\n\t\t\tthis.show_location_ui = false;\n\t\t}\n\n\t\tif ( this.stationValidate() ) {\n\t\t\tthis.show_station_ui = true;\n\t\t} else {\n\t\t\tthis.show_station_ui = false;\n\t\t}\n\n\t\tif ( this.jobUIValidate( 'absence' ) ) {\n\t\t\tthis.show_absence_job_ui = true;\n\t\t} else {\n\t\t\tthis.show_absence_job_ui = false;\n\t\t}\n\n\t\tif ( this.jobItemUIValidate( 'absence' ) ) {\n\t\t\tthis.show_absence_job_item_ui = true;\n\t\t} else {\n\t\t\tthis.show_absence_job_item_ui = false;\n\t\t}\n\n\t\tif ( this.punchTagUIValidate( 'absence' ) ) {\n\t\t\tthis.show_absence_punch_tag_ui = true;\n\t\t} else {\n\t\t\tthis.show_absence_punch_tag_ui = false;\n\t\t}\n\n\t\tif ( this.branchUIValidate( 'absence' ) ) {\n\t\t\tthis.show_absence_branch_ui = true;\n\t\t} else {\n\t\t\tthis.show_absence_branch_ui = false;\n\t\t}\n\n\t\tif ( this.departmentUIValidate( 'absence' ) ) {\n\t\t\tthis.show_absence_department_ui = true;\n\t\t} else {\n\t\t\tthis.show_absence_department_ui = false;\n\t\t}\n\t}\n\n\t/* jshint ignore:end */\n\n\townerOrChildPermissionValidate( p_id, permission_name, selected_item ) {\n\t\tvar field;\n\t\tif ( permission_name && permission_name.indexOf( 'child' ) > -1 ) {\n\t\t\tfield = 'is_child';\n\t\t} else {\n\t\t\tfield = 'is_owner';\n\t\t}\n\n\t\tvar user = this.getSelectEmployee( true );\n\n\t\tif ( PermissionManager.validate( p_id, permission_name ) && ( !user || !Global/* Global.isSet */.x.isSet( user[field] ) || ( user && user[field] ) ) ) {\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\tinitOptions() {\n\t\tvar options = [\n\t\t\t{ option_name: 'type', api: this.api },\n\t\t\t{ option_name: 'status', api: this.api },\n\t\t];\n\n\t\tthis.initDropDownOptions( options);\n\t}\n\tgetCustomContextMenuModel() {\n\t\tvar context_menu_model = {\n\t\t\tgroups: {\n\t\t\t\tdrag_and_drop: {\n\t\t\t\t\tlabel: TimeSheetViewController_$.i18n._( 'Drag & Drop' ),\n\t\t\t\t\tid: this.viewId + 'drag_and_drop'\n\t\t\t\t}\n\t\t\t},\n\t\t\texclude: [\n\t\t\t\t'export_excel',\n\t\t\t\t'add',\n\t\t\t\t'copy',\n\t\t\t\t'copy_as_new'\n\t\t\t],\n\t\t\tinclude: [\n\t\t\t\t{\n\t\t\t\t\tlabel: TimeSheetViewController_$.i18n._( 'New Punch' ),\n\t\t\t\t\tid: 'add_punch',\n\t\t\t\t\taction_group: 'new',\n\t\t\t\t\tgroup: 'editor',\n\t\t\t\t\tvue_icon: 'tticon tticon-add_black_24dp',\n\t\t\t\t\tshow_on_right_click: true,\n\t\t\t\t\tsort_order: 910\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tlabel: TimeSheetViewController_$.i18n._( 'New Absence' ),\n\t\t\t\t\tid: 'add_absence',\n\t\t\t\t\taction_group: 'new',\n\t\t\t\t\tgroup: 'editor',\n\t\t\t\t\tvue_icon: 'tticon tticon-add_black_24dp',\n\t\t\t\t\tshow_on_right_click: true,\n\t\t\t\t\tsort_order: 920\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tlabel: TimeSheetViewController_$.i18n._( 'In/Out' ),\n\t\t\t\t\tid: 'in_out',\n\t\t\t\t\taction_group: 'in_out',\n\t\t\t\t\tgroup: 'editor',\n\t\t\t\t\tvue_icon: 'tticon tticon-timer_black_24dp',\n\t\t\t\t\tshow_on_right_click: true,\n\t\t\t\t\tsort_order: 1050\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tlabel: TimeSheetViewController_$.i18n._( 'Drag & Drop: Move' ),\n\t\t\t\t\tid: 'move',\n\t\t\t\t\tmenu_align: 'right',\n\t\t\t\t\taction_group: 'move_copy',\n\t\t\t\t\tmulti_select_group: 1\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tlabel: TimeSheetViewController_$.i18n._( 'Drag & Drop: Copy' ),\n\t\t\t\t\tid: 'drag_copy',\n\t\t\t\t\tmenu_align: 'right',\n\t\t\t\t\taction_group: 'move_copy',\n\t\t\t\t\tmulti_select_group: 1\n\t\t\t\t},\n\t\t\t]\n\t\t};\n\n\t\tif ( PermissionManager.validate( 'request', 'add' ) ) {\n\t\t\tcontext_menu_model.include.push( {\n\t\t\t\tlabel: TimeSheetViewController_$.i18n._( 'Add Request' ),\n\t\t\t\tid: 'AddRequest',\n\t\t\t\tvue_icon: 'tticon tticon-post_add_black_24dp',\n\t\t\t\tmenu_align: 'right',\n\t\t\t\tpermission_result: true,\n\t\t\t\tpermission: true,\n\t\t\t\tshow_on_right_click: true,\n\t\t\t\tsort_order: 1000\n\t\t\t} );\n\t\t}\n\n\t\tif ( ( Global/* Global.getProductEdition */.x.getProductEdition() >= 15 ) ) {\n\t\t\tcontext_menu_model.include.push(\n\t\t\t\t{\n\t\t\t\t\tlabel: TimeSheetViewController_$.i18n._( 'Map' ),\n\t\t\t\t\tid: 'map',\n\t\t\t\t\tmenu_align: 'right',\n\t\t\t\t\tvue_icon: 'tticon tticon-map_black_24dp',\n\t\t\t\t\tshow_on_right_click: true,\n\t\t\t\t\tsort_order: 2000,\n\t\t\t\t}\n\t\t\t);\n\t\t}\n\n\t\tcontext_menu_model.include.push(\n\t\t\t{\n\t\t\t\tlabel: TimeSheetViewController_$.i18n._( 'Print' ),\n\t\t\t\tid: 'print',\n\t\t\t\taction_group_header: true,\n\t\t\t\taction_group: 'print_menu',\n\t\t\t\tsort_order: 7000,\n\t\t\t\tmenu_align: 'right',\n\t\t\t\ttype: 2,\n\t\t\t\tpermission_result: true,\n\t\t\t\tpermission: true\n\t\t\t},\n\t\t\t{\n\t\t\t\tlabel: TimeSheetViewController_$.i18n._( 'Summary' ),\n\t\t\t\tid: 'print_summary',\n\t\t\t\taction_group: 'print_menu',\n\t\t\t\tsort_order: 7000,\n\t\t\t\tmenu_align: 'right'\n\t\t\t},\n\t\t\t{\n\t\t\t\tlabel: TimeSheetViewController_$.i18n._( 'Detailed' ),\n\t\t\t\tid: 'print_detailed',\n\t\t\t\taction_group: 'print_menu',\n\t\t\t\tsort_order: 7000,\n\t\t\t\tmenu_align: 'right'\n\t\t\t},\n\t\t\t{\n\t\t\t\tlabel: TimeSheetViewController_$.i18n._( 'Jump To' ),\n\t\t\t\tid: 'jump_to_header',\n\t\t\t\tmenu_align: 'right',\n\t\t\t\taction_group: 'jump_to',\n\t\t\t\tsort_order: 8000,\n\t\t\t\taction_group_header: true,\n\t\t\t\tpermission_result: false // to hide it in legacy context menu and avoid errors in legacy parsers.\n\t\t\t},\n\t\t\t{\n\t\t\t\tlabel: TimeSheetViewController_$.i18n._( 'Schedules' ),\n\t\t\t\tid: 'schedule',\n\t\t\t\tmenu_align: 'right',\n\t\t\t\taction_group: 'jump_to',\n\t\t\t\tsort_order: 8000\n\t\t\t\t},\n\t\t\t{\n\t\t\t\tlabel: TimeSheetViewController_$.i18n._( 'Pay Stubs' ),\n\t\t\t\tid: 'pay_stub',\n\t\t\t\tmenu_align: 'right',\n\t\t\t\taction_group: 'jump_to',\n\t\t\t\tsort_order: 8000\n\t\t\t\t},\n\t\t\t{\n\t\t\t\tlabel: TimeSheetViewController_$.i18n._( 'Edit Employee' ),\n\t\t\t\tid: 'edit_employee',\n\t\t\t\tmenu_align: 'right',\n\t\t\t\taction_group: 'jump_to',\n\t\t\t\tsort_order: 8000\n\t\t\t\t},\n\t\t\t{\n\t\t\t\tlabel: TimeSheetViewController_$.i18n._( 'Edit Pay Period' ),\n\t\t\t\tid: 'edit_pay_period',\n\t\t\t\tmenu_align: 'right',\n\t\t\t\taction_group: 'jump_to',\n\t\t\t\tsort_order: 8000\n\t\t\t\t},\n\t\t\t{\n\t\t\t\tlabel: TimeSheetViewController_$.i18n._( 'Accumulated Time' ),\n\t\t\t\tid: 'accumulated_time',\n\t\t\t\tmenu_align: 'right',\n\t\t\t\taction_group: 'jump_to',\n\t\t\t\tsort_order: 8000\n\t\t\t\t},\n\t\t\t{\n\t\t\t\tlabel: '', //Empty label. vue_icon is displayed instead of text.\n\t\t\t\tid: 'other_header',\n\t\t\t\tmenu_align: 'right',\n\t\t\t\taction_group: 'other',\n\t\t\t\taction_group_header: true,\n\t\t\t\tvue_icon: 'tticon tticon-more_vert_black_24dp',\n\t\t\t},\n\t\t\t{\n\t\t\t\tlabel: TimeSheetViewController_$.i18n._( 'ReCalculate TimeSheet' ),\n\t\t\t\tid: 're_calculate_timesheet',\n\t\t\t\tmenu_align: 'right',\n\t\t\t\taction_group: 'other',\n\t\t\t\t},\n\t\t\t{\n\t\t\t\tlabel: TimeSheetViewController_$.i18n._( 'Generate Pay Stub' ),\n\t\t\t\tid: 'generate_pay_stub',\n\t\t\t\tmenu_align: 'right',\n\t\t\t\taction_group: 'other',\n\t\t\t\t},\n\t\t);\n\n\t\treturn context_menu_model;\n\t}\n\n\tparseCustomContextModelForEditViews( context_menu_model ) {\n\n\t\tcontext_menu_model = super.parseCustomContextModelForEditViews( context_menu_model );\n\n\t\tif( this.determineContextMenuMountAttributes().menu_type === 'editview_contextmenu' ) {\n\t\t\tcontext_menu_model.exclude.push(\n\t\t\t\t'move',\n\t\t\t\t'drag_copy',\n\t\t\t\t're_calculate_timesheet',\n\t\t\t\t'generate_pay_stub',\n\t\t\t\t'print',\n\t\t\t\t'print_detailed',\n\t\t\t\t'print_summary',\n\t\t\t)\n\t\t}\n\n\t\treturn context_menu_model;\n\t}\n\n\topenEditView() {\n\t\t//#2295 - Re-initialize previous_absence_policy_id to ensure that previously saved values are passed correctly into the estimation of projected available balance.\n\t\tthis.previous_absence_policy_id = false;\n\n\t\tGlobal/* Global.setUINotready */.x.setUINotready();\n\t\tTTPromise.add( 'init', 'init' );\n\t\tTTPromise.wait();\n\t\tif ( !this.edit_view ) {\n\t\t\tthis.is_edit = true;\n\t\t\tthis.initEditViewUI( 'TimeSheet', 'TimeSheetEditView.html' );\n\t\t}\n\t}\n\n\t/* jshint ignore:start */\n\n\t//set widget disablebility if view mode or edit mode\n\tsetEditViewWidgetsMode() {\n\t\tvar did_clean = false;\n\t\tfor ( var key in this.edit_view_ui_dic ) {\n\t\t\tif ( !this.edit_view_ui_dic.hasOwnProperty( key ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tvar widget = this.edit_view_ui_dic[key];\n\t\t\tvar widgetContainer = this.edit_view_form_item_dic[key];\n\t\t\tvar column = widget.parent().parent().parent();\n\t\t\tif ( !column.hasClass( 'v-box' ) ) {\n\t\t\t\tif ( !did_clean ) {\n\t\t\t\t\tdid_clean = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ( this.absence_model ) {\n\t\t\t\tswitch ( key ) {\n\t\t\t\t\tcase 'punch_date':\n\t\t\t\t\tcase 'punch_time':\n\t\t\t\t\tcase 'status_id':\n\t\t\t\t\tcase 'type_id':\n\t\t\t\t\tcase 'quantity':\n\t\t\t\t\tcase 'station_id':\n\t\t\t\t\tcase 'has_image':\n\t\t\t\t\tcase 'latitude':\n\t\t\t\t\tcase 'split_punch_control':\n\t\t\t\t\t\tthis.detachElement( key );\n\t\t\t\t\t\twidget.css( 'opacity', 0 );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'punch_dates':\n\t\t\t\t\t\tif ( this.is_mass_adding ) {\n\t\t\t\t\t\t\tthis.attachElement( key );\n\t\t\t\t\t\t\twidget.css( 'opacity', 1 );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tthis.detachElement( key );\n\t\t\t\t\t\t\twidget.css( 'opacity', 0 );\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'date_stamp':\n\t\t\t\t\t\tif ( this.is_mass_adding ) {\n\t\t\t\t\t\t\tthis.detachElement( key );\n\t\t\t\t\t\t\twidget.css( 'opacity', 0 );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tthis.attachElement( key );\n\t\t\t\t\t\t\twidget.css( 'opacity', 1 );\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'total_time':\n\t\t\t\t\tcase 'src_object_id':\n\t\t\t\t\tcase 'override':\n\t\t\t\t\t\tthis.attachElement( key );\n\t\t\t\t\t\twidget.css( 'opacity', 1 );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'available_balance':\n\t\t\t\t\t\tthis.detachElement( key );\n\t\t\t\t\t\twidget.css( 'opacity', 1 );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\twidget.css( 'opacity', 1 );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\t\t\t\tswitch ( key ) {\n\t\t\t\t\tcase 'punch_dates':\n\t\t\t\t\t\tif ( this.is_mass_adding ) {\n\t\t\t\t\t\t\tthis.attachElement( key );\n\t\t\t\t\t\t\twidget.css( 'opacity', 1 );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tthis.detachElement( key );\n\t\t\t\t\t\t\twidget.css( 'opacity', 0 );\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'punch_date':\n\t\t\t\t\t\tif ( this.is_mass_adding ) {\n\t\t\t\t\t\t\tthis.detachElement( key );\n\t\t\t\t\t\t\twidget.css( 'opacity', 0 );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tthis.attachElement( key );\n\t\t\t\t\t\t\twidget.css( 'opacity', 1 );\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'quantity':\n\t\t\t\t\t\tif ( this.show_good_quantity_ui && this.show_bad_quantity_ui ) {\n\t\t\t\t\t\t\tthis.attachElement( key );\n\t\t\t\t\t\t\twidget.css( 'opacity', 1 );\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'station':\n\t\t\t\t\t\tthis.attachElement( key );\n\t\t\t\t\t\twidget.css( 'opacity', 1 );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'punch_time':\n\t\t\t\t\tcase 'status_id':\n\t\t\t\t\tcase 'type_id':\n\t\t\t\t\tcase 'has_image':\n\t\t\t\t\tcase 'latitude':\n\t\t\t\t\t\tthis.attachElement( key );\n\t\t\t\t\t\twidget.css( 'opacity', 1 );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'date_stamp':\n\t\t\t\t\tcase 'total_time':\n\t\t\t\t\tcase 'src_object_id':\n\t\t\t\t\tcase 'override':\n\t\t\t\t\t\tthis.detachElement( key );\n\t\t\t\t\t\twidget.css( 'opacity', 0 );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\twidget.css( 'opacity', 1 );\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ( this.is_viewing ) {\n\t\t\t\tif ( Global/* Global.isSet */.x.isSet( widget.setEnabled ) ) {\n\t\t\t\t\twidget.setEnabled( false );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif ( Global/* Global.isSet */.x.isSet( widget.setEnabled ) ) {\n\t\t\t\t\twidget.setEnabled( true );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tgetCustomFieldReferenceField() {\n\t\treturn 'note';\n\t}\n\n\tsetCustomFields() {\n\t\t//Custom fields are only shown on punch types and not on absence types.\n\t\tif ( this.getPunchPermissionType() === 'punch' ) {\n\t\t\tsuper.setCustomFields();\n\t\t}\n\t}\n\n\tbuildEditViewUI() {\n\t\tsuper.buildEditViewUI();\n\n\t\tvar $this = this;\n\n\t\tvar tab_model = {\n\t\t\t'tab_punch': {\n\t\t\t\t'label': this.absence_model ? TimeSheetViewController_$.i18n._( 'Absence' ) : TimeSheetViewController_$.i18n._( 'Punch' )\n\t\t\t},\n\t\t\t'tab_audit': true,\n\t\t};\n\t\tthis.setTabModel( tab_model );\n\n\t\tvar form_item_input;\n\t\tvar widgetContainer;\n\n\t\t//Tab 0 start\n\n\t\tvar tab_punch = this.edit_view_tab.find( '#tab_punch' );\n\n\t\tvar tab_punch_column1 = tab_punch.find( '.first-column' );\n\n\t\t//Employee\n\n\t\tform_item_input = Global/* Global.loadWidgetByName */.x.loadWidgetByName( FormItemType.TEXT );\n\t\tform_item_input.TText( { field: 'first_last_name' } );\n\t\tthis.addEditFieldToColumn( TimeSheetViewController_$.i18n._( 'Employee' ), form_item_input, tab_punch_column1, '' );\n\n\t\t//Time\n\t\tform_item_input = Global/* Global.loadWidgetByName */.x.loadWidgetByName( FormItemType.TIME_PICKER );\n\t\tform_item_input.TTimePicker( { field: 'punch_time', validation_field: 'time_stamp' } );\n\t\twidgetContainer = TimeSheetViewController_$( '' );\n\t\tthis.actual_time_label = TimeSheetViewController_$( '' );\n\t\twidgetContainer.append( form_item_input );\n\t\twidgetContainer.append( this.actual_time_label );\n\t\tthis.addEditFieldToColumn( TimeSheetViewController_$.i18n._( 'Time' ), form_item_input, tab_punch_column1, '', widgetContainer, true );\n\n\t\t//Absence Model\n\t\t//Absence Policy Type\n\t\tform_item_input = Global/* Global.loadWidgetByName */.x.loadWidgetByName( FormItemType.AWESOME_BOX );\n\n\t\tform_item_input.AComboBox( {\n\t\t\tapi_class: TTAPI.APIAbsencePolicy,\n\t\t\tallow_multiple_selection: false,\n\t\t\tlayout_name: 'global_absences',\n\t\t\tshow_search_inputs: true,\n\t\t\tset_empty: true,\n\t\t\tfield: 'src_object_id',\n\t\t\tvalidation_field: 'absence_policy_id'\n\t\t} );\n\n\t\tform_item_input.customSearchFilter = function( filter ) {\n\t\t\treturn $this.setAbsencePolicyFilter( filter );\n\t\t};\n\n\t\tthis.addEditFieldToColumn( TimeSheetViewController_$.i18n._( 'Absence Policy' ), form_item_input, tab_punch_column1, '', null, true );\n\n\t\t//Available Balance\n\t\tform_item_input = Global/* Global.loadWidgetByName */.x.loadWidgetByName( FormItemType.TEXT );\n\t\tform_item_input.TText( { field: 'available_balance' } );\n\n\t\twidgetContainer = TimeSheetViewController_$( '' );\n\t\tthis.available_balance_info = TimeSheetViewController_$( '' );\n\n\t\twidgetContainer.append( form_item_input );\n\t\twidgetContainer.append( this.available_balance_info );\n\n\t\tthis.addEditFieldToColumn( TimeSheetViewController_$.i18n._( 'Available Balance' ), [form_item_input], tab_punch_column1, '', widgetContainer, true );\n\n\t\t//Date\n\t\tform_item_input = Global/* Global.loadWidgetByName */.x.loadWidgetByName( FormItemType.DATE_PICKER );\n\t\tform_item_input.TDatePicker( { field: 'punch_date', validation_field: 'date_stamp' } );\n\n\t\tthis.addEditFieldToColumn( TimeSheetViewController_$.i18n._( 'Date' ), form_item_input, tab_punch_column1, '', null, true );\n\n\t\t//Mass Add Date\n\t\tform_item_input = Global/* Global.loadWidgetByName */.x.loadWidgetByName( FormItemType.DATE_PICKER );\n\n\t\tform_item_input.TRangePicker( { field: 'punch_dates', validation_field: 'date_stamp' } );\n\n\t\tthis.addEditFieldToColumn( TimeSheetViewController_$.i18n._( 'Date' ), form_item_input, tab_punch_column1, '', null, true );\n\n\t\t//Absence Model\n\t\t//Date\n\t\tform_item_input = Global/* Global.loadWidgetByName */.x.loadWidgetByName( FormItemType.DATE_PICKER );\n\t\tform_item_input.TDatePicker( { field: 'date_stamp' } );\n\n\t\tthis.addEditFieldToColumn( TimeSheetViewController_$.i18n._( 'Date' ), form_item_input, tab_punch_column1, '', null, true );\n\n\t\t//Absence Model\n\t\t//Time\n\t\tform_item_input = Global/* Global.loadWidgetByName */.x.loadWidgetByName( FormItemType.TEXT_INPUT );\n\t\tform_item_input.TTextInput( { field: 'total_time', mode: 'time_unit' } );\n\n\t\tvar widgetContainer = TimeSheetViewController_$( '' );\n\t\tvar release_balance_button = TimeSheetViewController_$( '' );\n\t\trelease_balance_button.css( 'display', 'none' );\n\n\t\trelease_balance_button.click( function() {\n\t\t\t$this.getAvailableBalance( true );\n\t\t} );\n\n\t\twidgetContainer.append( form_item_input );\n\t\twidgetContainer.append( release_balance_button );\n\t\tthis.addEditFieldToColumn( TimeSheetViewController_$.i18n._( 'Time' ), form_item_input, tab_punch_column1, '', widgetContainer, true );\n\n\t\t//Punch Type\n\n\t\tform_item_input = Global/* Global.loadWidgetByName */.x.loadWidgetByName( FormItemType.COMBO_BOX );\n\t\tform_item_input.TComboBox( { field: 'type_id' } );\n\t\tform_item_input.setSourceData( $this.type_array );\n\n\t\twidgetContainer = TimeSheetViewController_$( '' );\n\n\t\tvar check_box = Global/* Global.loadWidgetByName */.x.loadWidgetByName( FormItemType.CHECKBOX );\n\t\tcheck_box.TCheckbox( { field: 'disable_rounding' } );\n\n\t\tvar label = TimeSheetViewController_$( '' + TimeSheetViewController_$.i18n._( 'Disable Rounding' ) + '' );\n\n\t\twidgetContainer.append( form_item_input );\n\n\t\t// Check if view only mode. To prevent option appearing but disabled, as disabled checkboxes are not very clear - same in PunchViewController\n\t\tif ( this.is_viewing ) {\n\t\t\t// dev-note: not sure if we need to pass widgetContainer here, or if we can omit if its only one element now (due to the if is_viewing).\n\t\t\t// to be safe, will continue to use widgetContainer for this case. We only want to affect viewing mode (hide rounding checkbox), less risk of regression to keep widget container in.\n\t\t\tthis.addEditFieldToColumn( TimeSheetViewController_$.i18n._( 'Punch Type' ), form_item_input, tab_punch_column1, '', widgetContainer, true );\n\t\t} else {\n\t\t\twidgetContainer.append( label );\n\t\t\twidgetContainer.append( check_box );\n\t\t\tthis.addEditFieldToColumn( TimeSheetViewController_$.i18n._( 'Punch Type' ), [form_item_input, check_box], tab_punch_column1, '', widgetContainer, true );\n\t\t}\n\n\t\t//In Out (Status)\n\t\tform_item_input = Global/* Global.loadWidgetByName */.x.loadWidgetByName( FormItemType.COMBO_BOX );\n\n\t\tform_item_input.TComboBox( { field: 'status_id' } );\n\t\tform_item_input.setSourceData( $this.status_array );\n\t\tthis.addEditFieldToColumn( TimeSheetViewController_$.i18n._( 'In/Out' ), form_item_input, tab_punch_column1, '', null, true );\n\n\t\t//Default Branch\n\t\tform_item_input = Global/* Global.loadWidgetByName */.x.loadWidgetByName( FormItemType.AWESOME_BOX );\n\n\t\tform_item_input.AComboBox( {\n\t\t\tapi_class: TTAPI.APIBranch,\n\t\t\tallow_multiple_selection: false,\n\t\t\tlayout_name: 'global_branch',\n\t\t\tshow_search_inputs: true,\n\t\t\tset_empty: true,\n\t\t\tfield: 'branch_id'\n\t\t} );\n\t\tthis.addEditFieldToColumn( TimeSheetViewController_$.i18n._( 'Branch' ), form_item_input, tab_punch_column1, '', null, true );\n\n\t\tif ( !this.absence_model ) {\n\t\t\tif ( !this.show_branch_ui ) {\n\t\t\t\tthis.detachElement( 'branch_id' );\n\t\t\t}\n\t\t} else {\n\t\t\tif ( !this.show_absence_branch_ui ) {\n\t\t\t\tthis.detachElement( 'branch_id' );\n\t\t\t}\n\t\t}\n\n\t\t//Department\n\t\tform_item_input = Global/* Global.loadWidgetByName */.x.loadWidgetByName( FormItemType.AWESOME_BOX );\n\n\t\tform_item_input.AComboBox( {\n\t\t\tapi_class: TTAPI.APIDepartment,\n\t\t\tallow_multiple_selection: false,\n\t\t\tlayout_name: 'global_department',\n\t\t\tshow_search_inputs: true,\n\t\t\tset_empty: true,\n\t\t\tfield: 'department_id'\n\t\t} );\n\t\tthis.addEditFieldToColumn( TimeSheetViewController_$.i18n._( 'Department' ), form_item_input, tab_punch_column1, '', null, true );\n\n\t\tif ( !this.absence_model ) {\n\t\t\tif ( !this.show_department_ui ) {\n\t\t\t\tthis.detachElement( 'department_id' );\n\t\t\t}\n\t\t} else {\n\t\t\tif ( !this.show_absence_department_ui ) {\n\t\t\t\tthis.detachElement( 'department_id' );\n\t\t\t}\n\t\t}\n\n\t\tif ( ( Global/* Global.getProductEdition */.x.getProductEdition() >= 20 ) ) {\n\n\t\t\t//Job\n\t\t\tform_item_input = Global/* Global.loadWidgetByName */.x.loadWidgetByName( FormItemType.AWESOME_BOX );\n\n\t\t\tform_item_input.AComboBox( {\n\t\t\t\tapi_class: TTAPI.APIJob,\n\t\t\t\tallow_multiple_selection: false,\n\t\t\t\tlayout_name: 'global_job',\n\t\t\t\tshow_search_inputs: true,\n\t\t\t\tset_empty: true,\n\t\t\t\tsetRealValueCallBack: ( function( val ) {\n\n\t\t\t\t\tif ( val ) {\n\t\t\t\t\t\tjob_coder.setValue( val.manual_id );\n\t\t\t\t\t}\n\t\t\t\t} ),\n\t\t\t\tfield: 'job_id'\n\t\t\t} );\n\n\t\t\twidgetContainer = TimeSheetViewController_$( '' );\n\n\t\t\tvar job_coder = Global/* Global.loadWidgetByName */.x.loadWidgetByName( FormItemType.TEXT_INPUT );\n\t\t\tjob_coder.TTextInput( { field: 'job_quick_search', disable_keyup_event: true } );\n\t\t\tjob_coder.addClass( 'job-coder' );\n\n\t\t\twidgetContainer.append( job_coder );\n\t\t\twidgetContainer.append( form_item_input );\n\t\t\tthis.addEditFieldToColumn( TimeSheetViewController_$.i18n._( 'Job' ), [form_item_input, job_coder], tab_punch_column1, '', widgetContainer, true );\n\n\t\t\tif ( !this.absence_model ) {\n\t\t\t\tif ( !this.show_job_ui ) {\n\t\t\t\t\tthis.detachElement( 'job_id' );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif ( !this.show_absence_job_ui ) {\n\t\t\t\t\tthis.detachElement( 'job_id' );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t//Job Item\n\t\t\tform_item_input = Global/* Global.loadWidgetByName */.x.loadWidgetByName( FormItemType.AWESOME_BOX );\n\n\t\t\tform_item_input.AComboBox( {\n\t\t\t\tapi_class: TTAPI.APIJobItem,\n\t\t\t\tallow_multiple_selection: false,\n\t\t\t\tlayout_name: 'global_job_item',\n\t\t\t\tshow_search_inputs: true,\n\t\t\t\tset_empty: true,\n\t\t\t\tsetRealValueCallBack: ( function( val ) {\n\n\t\t\t\t\tif ( val ) {\n\t\t\t\t\t\tjob_item_coder.setValue( val.manual_id );\n\t\t\t\t\t}\n\t\t\t\t} ),\n\t\t\t\tfield: 'job_item_id'\n\t\t\t} );\n\n\t\t\twidgetContainer = TimeSheetViewController_$( '' );\n\n\t\t\tvar job_item_coder = Global/* Global.loadWidgetByName */.x.loadWidgetByName( FormItemType.TEXT_INPUT );\n\t\t\tjob_item_coder.TTextInput( { field: 'job_item_quick_search', disable_keyup_event: true } );\n\t\t\tjob_item_coder.addClass( 'job-coder' );\n\n\t\t\twidgetContainer.append( job_item_coder );\n\t\t\twidgetContainer.append( form_item_input );\n\t\t\tthis.addEditFieldToColumn( TimeSheetViewController_$.i18n._( 'Task' ), [form_item_input, job_item_coder], tab_punch_column1, '', widgetContainer, true );\n\n\t\t\tif ( !this.absence_model ) {\n\t\t\t\tif ( !this.show_job_item_ui ) {\n\t\t\t\t\tthis.detachElement( 'job_item_id' );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif ( !this.show_absence_job_item_ui ) {\n\t\t\t\t\tthis.detachElement( 'job_item_id' );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t//Punch Tag\n\n\t\t\tform_item_input = Global/* Global.loadWidgetByName */.x.loadWidgetByName( FormItemType.AWESOME_BOX );\n\n\t\t\tform_item_input.AComboBox( {\n\t\t\t\tapi_class: TTAPI.APIPunchTag,\n\t\t\t\tallow_multiple_selection: true,\n\t\t\t\tlayout_name: 'global_punch_tag',\n\t\t\t\tshow_search_inputs: true,\n\t\t\t\tset_empty: true,\n\t\t\t\tget_real_data_on_multi: true,\n\t\t\t\tsetRealValueCallBack: ( ( punch_tags, get_real_data ) => {\n\t\t\t\t\tif ( punch_tags ) {\n\t\t\t\t\t\tthis.setPunchTagQuickSearchManualIds( punch_tags, get_real_data );\n\t\t\t\t\t}\n\t\t\t\t} ),\n\t\t\t\tfield: 'punch_tag_id'\n\t\t\t} );\n\n\t\t\twidgetContainer = TimeSheetViewController_$( '' );\n\n\t\t\tvar punch_tag_coder = Global/* Global.loadWidgetByName */.x.loadWidgetByName( FormItemType.TEXT_INPUT );\n\t\t\tpunch_tag_coder.TTextInput( { field: 'punch_tag_quick_search', disable_keyup_event: true } );\n\t\t\tpunch_tag_coder.addClass( 'job-coder' );\n\n\t\t\twidgetContainer.append( punch_tag_coder );\n\t\t\twidgetContainer.append( form_item_input );\n\t\t\tthis.addEditFieldToColumn( TimeSheetViewController_$.i18n._( 'Tags' ), [form_item_input, punch_tag_coder], tab_punch_column1, '', widgetContainer, true );\n\n\t\t\tif ( !this.absence_model ) {\n\t\t\t\tif ( !this.show_punch_tag_ui ) {\n\t\t\t\t\tthis.detachElement( 'punch_tag_id' );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif ( !this.show_absence_punch_tag_ui ) {\n\t\t\t\t\tthis.detachElement( 'punch_tag_id' );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( ( Global/* Global.getProductEdition */.x.getProductEdition() >= 20 ) ) {\n\n\t\t\t//Quanitity\n\n\t\t\tvar good = Global/* Global.loadWidgetByName */.x.loadWidgetByName( FormItemType.TEXT_INPUT );\n\t\t\tgood.TTextInput( { field: 'quantity' } );\n\t\t\tgood.addClass( 'quantity-input' );\n\n\t\t\tvar good_label = TimeSheetViewController_$( '' + TimeSheetViewController_$.i18n._( 'Good' ) + ': ' );\n\n\t\t\tvar bad = Global/* Global.loadWidgetByName */.x.loadWidgetByName( FormItemType.TEXT_INPUT );\n\t\t\tbad.TTextInput( { field: 'bad_quantity' } );\n\t\t\tbad.addClass( 'quantity-input' );\n\n\t\t\tvar bad_label = TimeSheetViewController_$( '/ ' + TimeSheetViewController_$.i18n._( 'Bad' ) + ': ' );\n\n\t\t\twidgetContainer = TimeSheetViewController_$( '' );\n\n\t\t\twidgetContainer.append( good_label );\n\t\t\twidgetContainer.append( good );\n\t\t\twidgetContainer.append( bad_label );\n\t\t\twidgetContainer.append( bad );\n\n\t\t\tthis.addEditFieldToColumn( TimeSheetViewController_$.i18n._( 'Quantity' ), [good, bad], tab_punch_column1, '', widgetContainer, true );\n\n\t\t\tif ( !this.show_bad_quantity_ui && !this.show_good_quantity_ui ) {\n\t\t\t\tthis.detachElement( 'quantity' );\n\t\t\t} else {\n\t\t\t\tif ( !this.show_bad_quantity_ui ) {\n\t\t\t\t\tbad_label.hide();\n\t\t\t\t\tbad.hide();\n\t\t\t\t}\n\n\t\t\t\tif ( !this.show_good_quantity_ui ) {\n\t\t\t\t\tgood_label.hide();\n\t\t\t\t\tgood.hide();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t//Note\n\t\tform_item_input = Global/* Global.loadWidgetByName */.x.loadWidgetByName( FormItemType.TEXT_AREA );\n\t\tform_item_input.TTextArea( { field: 'note', width: '100%' } );\n\t\tthis.addEditFieldToColumn( TimeSheetViewController_$.i18n._( 'Note' ), form_item_input, tab_punch_column1, '', null, true, true );\n\t\tform_item_input.parent().width( '45%' );\n\n\t\tif ( !this.show_note_ui ) {\n\t\t\tthis.detachElement( 'note' );\n\t\t}\n\n\t\t//Absence Mode\n\t\t//Override\n\t\tform_item_input = Global/* Global.loadWidgetByName */.x.loadWidgetByName( FormItemType.CHECKBOX );\n\t\tform_item_input.TCheckbox( { field: 'override' } );\n\t\tthis.addEditFieldToColumn( TimeSheetViewController_$.i18n._( 'Override' ), form_item_input, tab_punch_column1, '', null, true, true );\n\n\t\t//Location\n\t\tif ( Global/* Global.getProductEdition */.x.getProductEdition() >= 15 ) {\n\n\t\t\tvar latitude = Global/* Global.loadWidgetByName */.x.loadWidgetByName( FormItemType.TEXT );\n\t\t\tlatitude.TText( { field: 'latitude' } );\n\t\t\tvar longitude = Global/* Global.loadWidgetByName */.x.loadWidgetByName( FormItemType.TEXT );\n\t\t\tlongitude.TText( { field: 'longitude' } );\n\t\t\twidgetContainer = TimeSheetViewController_$( '' );\n\t\t\tvar accuracy = Global/* Global.loadWidgetByName */.x.loadWidgetByName( FormItemType.TEXT );\n\t\t\taccuracy.TText( { field: 'position_accuracy' } );\n\t\t\tlabel = TimeSheetViewController_$( '' + TimeSheetViewController_$.i18n._( 'Accuracy' ) + ':' );\n\n\t\t\tvar map_icon = TimeSheetViewController_$( '' );\n\n\t\t\tthis.location_wrapper = TimeSheetViewController_$( '' );\n\t\t\twidgetContainer.append( map_icon );\n\t\t\twidgetContainer.append( this.location_wrapper );\n\t\t\tthis.location_wrapper.append( latitude );\n\t\t\tthis.location_wrapper.append( TimeSheetViewController_$( ', ' ) );\n\t\t\tthis.location_wrapper.append( longitude );\n\t\t\tthis.location_wrapper.append( label );\n\t\t\tthis.location_wrapper.append( accuracy );\n\t\t\tthis.location_wrapper.append( TimeSheetViewController_$( 'm' ) );\n\t\t\tthis.addEditFieldToColumn( TimeSheetViewController_$.i18n._( 'Location' ), [latitude, longitude, accuracy], tab_punch_column1, '', widgetContainer, true );\n\t\t\twidgetContainer.click( function() {\n\t\t\t\t$this.onMapClick();\n\t\t\t} );\n\n\t\t\t// #2117 - Manual location only supported in edit because we need a punch record to append the data to.\n\t\t\tif ( ( !this.is_edit && !this.is_viewing ) || !this.show_location_ui ) {\n\t\t\t\twidgetContainer.parents( '.edit-view-form-item-div' ).hide();\n\t\t\t}\n\t\t}\n\n\t\t//Station\n\t\tform_item_input = Global/* Global.loadWidgetByName */.x.loadWidgetByName( FormItemType.TEXT );\n\t\tform_item_input.TText( { field: 'station_id' } );\n\n\t\tthis.addEditFieldToColumn( TimeSheetViewController_$.i18n._( 'Station' ), form_item_input, tab_punch_column1, '', null, true, true );\n\n\t\tform_item_input.click( function() {\n\t\t\tif ( $this.current_edit_record.station_id && $this.show_station_ui ) {\n\t\t\t\tIndexViewController.openEditView( $this, 'Station', $this.current_edit_record.station_id );\n\t\t\t}\n\n\t\t} );\n\n\t\t//Split Punch Control\n\t\tform_item_input = Global/* Global.loadWidgetByName */.x.loadWidgetByName( FormItemType.CHECKBOX );\n\t\tform_item_input.TCheckbox( { field: 'split_punch_control' } );\n\t\tthis.addEditFieldToColumn( TimeSheetViewController_$.i18n._( 'Split Existing Punches' ), form_item_input, tab_punch_column1, '', null, true, true );\n\t\tif ( this.is_mass_adding == false ) {\n\t\t\tthis.detachElement( 'split_punch_control' );\n\t\t}\n\n\t\t//Punch Image\n\t\tform_item_input = Global/* Global.loadWidgetByName */.x.loadWidgetByName( FormItemType.IMAGE );\n\t\tform_item_input.TImage( { field: 'punch_image' } );\n\t\tthis.addEditFieldToColumn( TimeSheetViewController_$.i18n._( 'Image' ), form_item_input, tab_punch_column1, '', null, true, true );\n\t}\n\n\t/* jshint ignore:end */\n\n\tonEditStationDone() {\n\t\tthis.setStation();\n\t}\n\n\tsetAbsencePolicyFilter( filter ) {\n\t\tif ( !filter.filter_data ) {\n\t\t\tfilter.filter_data = {};\n\t\t}\n\n\t\tfilter.filter_data.user_id = this.current_edit_record.user_id;\n\n\t\tif ( filter.filter_columns ) {\n\t\t\tfilter.filter_columns.absence_policy = true;\n\t\t}\n\n\t\treturn filter;\n\t}\n\n\tonSetSearchFilterFinished() {\n\t}\n\n\tonBuildBasicUIFinished() {\n\t}\n\n\tonBuildAdvUIFinished() {\n\t}\n\n\tparserDatesRange( date ) {\n\t\tvar dates = date.split( ' - ' );\n\t\tvar resultArray = [];\n\t\tvar beginDate = Global/* Global.strToDate */.x.strToDate( dates[0] );\n\t\tvar endDate = Global/* Global.strToDate */.x.strToDate( dates[1] );\n\n\t\tvar nextDate = beginDate;\n\n\t\twhile ( nextDate.getTime() < endDate.getTime() ) {\n\t\t\tresultArray.push( nextDate.format() );\n\t\t\tnextDate = new Date( new Date( nextDate.getTime() ).setDate( nextDate.getDate() + 1 ) );\n\t\t}\n\n\t\tresultArray.push( dates[1] );\n\n\t\treturn resultArray;\n\t}\n\n\tvalidate() {\n\t\tvar $this = this;\n\t\tvar record = this.current_edit_record;\n\t\tvar i;\n\t\tif ( this.is_mass_editing ) {\n\t\t\trecord = [];\n\t\t\tvar len = this.mass_edit_record_ids.length;\n\t\t\tfor ( var i = 0; i < len; i++ ) {\n\t\t\t\tvar temp_item = Global/* Global.clone */.x.clone( this.current_edit_record );\n\t\t\t\ttemp_item.id = this.mass_edit_record_ids[i];\n\t\t\t\trecord.push( temp_item );\n\t\t\t}\n\t\t}\n\n\t\tif ( this.is_mass_adding ) {\n\n\t\t\trecord = [];\n\t\t\tvar dates_array = this.current_edit_record.punch_dates;\n\n\t\t\tif ( dates_array && dates_array.indexOf( ' - ' ) > 0 ) {\n\t\t\t\tdates_array = this.parserDatesRange( dates_array );\n\t\t\t}\n\n\t\t\tfor ( var i = 0; i < dates_array.length; i++ ) {\n\t\t\t\tvar common_record = Global/* Global.clone */.x.clone( this.current_edit_record );\n\t\t\t\tdelete common_record.punch_dates;\n\t\t\t\tif ( this.absence_model ) {\n\t\t\t\t\tcommon_record.date_stamp = dates_array[i];\n\t\t\t\t} else {\n\t\t\t\t\tcommon_record.punch_date = dates_array[i];\n\t\t\t\t}\n\n\t\t\t\trecord.push( common_record );\n\t\t\t}\n\t\t}\n\n\t\tif ( !this.absence_model ) {\n\n\t\t\tthis.api['validate' + this.api.key_name]( record, {\n\t\t\t\tonResult: function( result ) {\n\t\t\t\t\t$this.validateResult( result );\n\t\t\t\t}\n\t\t\t} );\n\n\t\t} else {\n\n\t\t\tthis.api_user_date_total['validate' + this.api_user_date_total.key_name]( record, {\n\t\t\t\tonResult: function( result ) {\n\t\t\t\t\t$this.clearErrorTips(); //Always clear error\n\n\t\t\t\t\tif ( result.isValid() ) {\n\t\t\t\t\t\t$this.setEditMenu();\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$this.setErrorMenu();\n\t\t\t\t\t\t$this.setErrorTips( result );\n\t\t\t\t\t}\n\n\t\t\t\t}\n\t\t\t} );\n\n\t\t}\n\t}\n\n\t/* jshint ignore:start */\n\tonFormItemChange( target, doNotValidate ) {\n\t\tvar $this = this;\n\t\tthis.setIsChanged( target );\n\t\tthis.setMassEditingFieldsWhenFormChange( target );\n\t\tvar key = target.getField();\n\t\tvar c_value = target.getValue();\n\t\t// Error: TypeError: this.current_edit_record is null in interface/html5/framework/jquery.min.js?v=9.0.5-20151222-094938 line 2 > eval line 1409\n\t\tif ( !this.current_edit_record ) {\n\t\t\treturn;\n\t\t}\n\t\tthis.current_edit_record[key] = c_value;\n\t\tswitch ( key ) {\n\t\t\tcase 'job_id':\n\t\t\t\tif ( ( Global/* Global.getProductEdition */.x.getProductEdition() >= 20 ) ) {\n\t\t\t\t\tthis.edit_view_ui_dic['job_quick_search'].setValue( target.getValue( true ) ? ( target.getValue( true ).manual_id ? target.getValue( true ).manual_id : '' ) : '' );\n\t\t\t\t\tthis.setJobItemValueWhenJobChanged( target.getValue( true ), 'job_item_id', {\n\t\t\t\t\t\tstatus_id: 10,\n\t\t\t\t\t\tjob_id: this.current_edit_record.job_id\n\t\t\t\t\t} );\n\t\t\t\t\tthis.edit_view_ui_dic['job_quick_search'].setCheckBox( true );\n\t\t\t\t\tthis.setPunchTagValuesWhenCriteriaChanged( this.getPunchTagFilterData(), 'punch_tag_id' );\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t\tcase 'job_item_id':\n\t\t\t\tif ( ( Global/* Global.getProductEdition */.x.getProductEdition() >= 20 ) ) {\n\t\t\t\t\tthis.edit_view_ui_dic['job_item_quick_search'].setValue( target.getValue( true ) ? ( target.getValue( true ).manual_id ? target.getValue( true ).manual_id : '' ) : '' );\n\t\t\t\t\tthis.edit_view_ui_dic['job_item_quick_search'].setCheckBox( true );\n\t\t\t\t\tthis.setPunchTagValuesWhenCriteriaChanged( this.getPunchTagFilterData(), 'punch_tag_id' );\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'punch_tag_id':\n\t\t\t\tif ( ( Global/* Global.getProductEdition */.x.getProductEdition() >= 20 ) ) {\n\t\t\t\t\tif ( c_value !== TTUUID/* TTUUID.zero_id */.d.zero_id && c_value !== false && c_value.length > 0 ) {\n\t\t\t\t\t\tthis.setPunchTagQuickSearchManualIds( target.getSelectItems() );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.edit_view_ui_dic['punch_tag_quick_search'].setValue( '' );\n\t\t\t\t\t}\n\t\t\t\t\t$this.previous_punch_tag_selection = c_value;\n\t\t\t\t\t//Reset source data to make sure correct punch tags are always shown.\n\t\t\t\t\tthis.edit_view_ui_dic['punch_tag_id'].setSourceData( null );\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'branch_id':\n\t\t\t\tif ( ( Global/* Global.getProductEdition */.x.getProductEdition() >= 20 ) ) {\n\t\t\t\t\tthis.setPunchTagValuesWhenCriteriaChanged( this.getPunchTagFilterData(), 'punch_tag_id' );\n\t\t\t\t\tthis.setJobValueWhenCriteriaChanged( 'job_id', {\n\t\t\t\t\t\tstatus_id: 10,\n\t\t\t\t\t\tuser_id: this.current_edit_record.user_id,\n\t\t\t\t\t\tpunch_branch_id: this.current_edit_record.branch_id,\n\t\t\t\t\t\tpunch_department_id: this.current_edit_record.department_id\n\t\t\t\t\t} );\n\t\t\t\t\tthis.setDepartmentValueWhenBranchChanged( target.getValue( true ), 'department_id', {\n\t\t\t\t\t\tbranch_id: this.current_edit_record.branch_id,\n\t\t\t\t\t\tuser_id: this.current_edit_record.user_id\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'user_id':\n\t\t\tcase 'department_id':\n\t\t\t\tif ( ( Global/* Global.getProductEdition */.x.getProductEdition() >= 20 ) ) {\n\t\t\t\t\tthis.setPunchTagValuesWhenCriteriaChanged( this.getPunchTagFilterData(), 'punch_tag_id' );\n\t\t\t\t\tthis.setJobValueWhenCriteriaChanged( 'job_id', {\n\t\t\t\t\t\tstatus_id: 10,\n\t\t\t\t\t\tuser_id: this.current_edit_record.user_id,\n\t\t\t\t\t\tpunch_branch_id: this.current_edit_record.branch_id,\n\t\t\t\t\t\tpunch_department_id: this.current_edit_record.department_id\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'job_quick_search':\n\t\t\tcase 'job_item_quick_search':\n\t\t\t\tif ( ( Global/* Global.getProductEdition */.x.getProductEdition() >= 20 ) ) {\n\t\t\t\t\tthis.onJobQuickSearch( key, c_value );\n\t\t\t\t\tTTPromise.wait( 'BaseViewController', 'onJobQuickSearch', function() {\n\t\t\t\t\t\t$this.setPunchTagValuesWhenCriteriaChanged( $this.getPunchTagFilterData(), 'punch_tag_id' );\n\t\t\t\t\t} );\n\t\t\t\t\t//Don't validate immediately as onJobQuickSearch is doing async API calls, and it would cause a guaranteed validation failure.\n\t\t\t\t\tdoNotValidate = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'punch_tag_quick_search':\n\t\t\t\tif ( ( Global/* Global.getProductEdition */.x.getProductEdition() >= 20 ) ) {\n\t\t\t\t\tthis.onPunchTagQuickSearch( c_value, this.getPunchTagFilterData(), 'punch_tag_id' );\n\n\t\t\t\t\t//Don't validate immediately as onJobQuickSearch is doing async API calls, and it would cause a guaranteed validation failure.\n\t\t\t\t\tdoNotValidate = true;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'punch_dates':\n\t\t\t\tthis.setEditMenu();\n\t\t\t\tbreak;\n\n\t\t}\n\n\t\tif ( this.absence_model ) {\n\t\t\tif ( key === 'total_time' ) {\n\n\t\t\t\tif ( this.current_edit_record ) {\n\t\t\t\t\tthis.current_edit_record[key] = Global/* Global.parseTimeUnit */.x.parseTimeUnit( c_value );\n\t\t\t\t\t// parsed_total_time_obj = this.api_date.parseTimeUnit( c_value, { async: false } );\n\t\t\t\t\t// if ( parsed_total_time_obj ) {\n\t\t\t\t\t// \tthis.current_edit_record[key] = parsed_total_time_obj.getResult();\n\t\t\t\t\t// }\n\n\t\t\t\t\t//When handling absences, always remove the start/end time stamps otherwise they may be incorrect and trigger a validation error, as the user doesn't see them anyways.\n\t\t\t\t\t// The API will automatically calculated these on save anyways.\n\t\t\t\t\tthis.current_edit_record['start_time_stamp'] = false;\n\t\t\t\t\tthis.current_edit_record['end_time_stamp'] = false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( key !== 'override' && this.edit_view_ui_dic['override'] ) {\n\t\t\t\tthis.edit_view_ui_dic['override'].setValue( true );\n\t\t\t\tthis.current_edit_record['override'] = true;\n\t\t\t}\n\t\t} else {\n\t\t\tthis.current_edit_record[key] = c_value;\n\t\t}\n\n\t\tif ( !doNotValidate ) {\n\t\t\tif ( this.absence_model ) {\n\t\t\t\tif ( key === 'total_time' ||\n\t\t\t\t\tkey === 'date_stamp' ||\n\t\t\t\t\tkey === 'punch_dates' ||\n\t\t\t\t\tkey === 'src_object_id' ) {\n\t\t\t\t\tthis.onAvailableBalanceChange();\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.validate();\n\t\t}\n\t}\n\n\t/* jshint ignore:end */\n\n\tbuildSearchAndLayoutUI() {\n\t\tvar layout_div = this.search_panel.find( 'div #saved_layout_content_div' );\n\n\t\tvar form_item = TimeSheetViewController_$( TimeSheetViewController_$.fn.SearchPanel.html.form_item );\n\t\tvar form_item_label = form_item.find( '.form-item-label' );\n\t\tvar form_item_input_div = form_item.find( '.form-item-input-div' );\n\n\t\tform_item_label.text( TimeSheetViewController_$.i18n._( 'Save Search As' ) );\n\n\t\tthis.save_search_as_input = Global/* Global.loadWidgetByName */.x.loadWidgetByName( FormItemType.TEXT_INPUT );\n\t\tthis.save_search_as_input.TTextInput();\n\n\t\tvar save_btn = TimeSheetViewController_$( '' );\n\n\t\tform_item_input_div.append( this.save_search_as_input );\n\t\tform_item_input_div.append( save_btn );\n\n\t\tvar $this = this;\n\t\tsave_btn.click( function() {\n\t\t\t$this.onSaveNewLayout();\n\t\t} );\n\n\t\t//Previous Saved Layout\n\n\t\tthis.previous_saved_layout_div = TimeSheetViewController_$( '' );\n\n\t\tform_item_input_div.append( this.previous_saved_layout_div );\n\n\t\tform_item_label = TimeSheetViewController_$( '' + TimeSheetViewController_$.i18n._( 'Previous Saved Searches' ) + ':' );\n\t\tthis.previous_saved_layout_div.append( form_item_label );\n\n\t\tthis.previous_saved_layout_selector = TimeSheetViewController_$( '