import '@/global/widgets/filebrowser/TImage';
import TTVueUtils from '@/services/TTVueUtils';
import TimeSheetControlBar from '@/components/timesheet/TimeSheetControlBar';
import { TTUUID } from '@/global/TTUUID';
import { Global } from '@/global/Global';
export class TimeSheetViewController extends BaseViewController {
constructor( options = {} ) {
_.defaults( options, {
el: '#timesheet_view_container', //Must set el here and can only set string, so events can work
// _required_files: {
// 10: ['TImage'],
// 15: ['leaflet-timetrex']
// },
status_array: null,
type_array: null,
employee_nav: null,
start_date_picker: null,
full_timesheet_data: null, //full timesheet data
full_format: 'ddd-MMM-DD-YYYY',
weekly_format: 'ddd, MMM DD',
day_format: 'ddd',
date_format: 'MMM DD',
start_date: null,
end_date: null,
select_cells_Array: [], //Timesheet grid
select_punches_array: [], //Timesheet grid.
absence_select_cells_Array: [], //Absence grid
accumulated_time_cells_array: [],
premium_cells_array: [],
timesheet_data_source: null,
accumulated_time_source: null,
accumulated_time_grid: null,
accumulated_time_source_map: null,
branch_grid: null,
branch_source_map: null,
branch_source: null,
department_grid: null,
department_source_map: null,
department_source: null,
job_grid: null,
job_source_map: null,
job_source: null,
job_item_grid: null,
job_item_source_map: null,
job_item_source: null,
punch_tag_source_map: null,
punch_tag_source: null,
premium_grid: null,
premium_source_map: null,
premium_source: null,
absence_grid: null,
absence_source: null,
absence_original_source: null,
accumulated_total_grid: null,
accumulated_total_grid_source_map: null,
accumulated_total_grid_source: null,
punch_note_grid: null,
punch_note_grid_source: null,
verification_grid: null,
verification_grid_source: null,
grid_dic: null,
pay_period_map: null,
pay_period_data: null,
timesheet_verify_data: null,
api_timesheet: null,
api_user_date_total: null,
api_date: null,
api_station: null,
api_punch: null,
absence_model: false,
select_drag_menu_id: '', //Do drag move or copy
is_mass_adding: false,
department_cell_count: 0,
branch_cell_count: 0,
premium_cell_count: 0,
job_cell_count: 0,
task_cell_count: 0,
punch_tag_cell_count: 0,
absence_cell_count: 0,
punch_note_account: 0,
show_navigation_box: true,
station: null,
scroll_position: 0,
job_api: null,
job_item_api: null,
user_group_id: null,
punch_tag_api: null,
user_api: null,
department_api: null,
default_punch_tag: [],
previous_punch_tag_selection: [],
api_absence_policy: null,
pre_total_time: null,
absence_available_balance_dataList: {},
available_balance_info: null,
show_job_ui: false,
show_job_item_ui: false,
show_punch_tag_ui: false,
show_branch_ui: false,
show_department_ui: false,
show_good_quantity_ui: false,
show_bad_quantity_ui: false,
show_note_ui: false,
show_station_ui: false,
show_absence_job_ui: false,
show_absence_job_item_ui: false,
show_absence_punch_tag_ui: false,
show_absence_branch_ui: false,
show_absence_department_ui: false,
holiday_data_dic: {},
grid_div: null,
actual_time_label: null,
column_maps: null,
accmulated_order_map: {},
url_args_before_set_date_url: {},
allow_auto_switch: true,
vue_control_bar_id: '',
previous_absence_policy_id: false,
events: {},
//Issue #3286 - Users without permission to display "Current View" dropdown still need to load select layout from user generic data
//This is to ensure the API attempts to update the current layout and not create a new one causing a validation error.
force_get_select_layout: true
} );
super( options );
}
init( options ) {
////this._super('initialize', options );
this.permission_id = 'punch';
this.viewId = 'TimeSheet';
this.script_name = 'TimeSheetView';
this.context_menu_name = $.i18n._( 'TimeSheet' );
this.navigation_label = $.i18n._( 'TimeSheet' );
this.api = TTAPI.APIPunch;
this.api_timesheet = TTAPI.APITimeSheet;
this.api_user_date_total = TTAPI.APIUserDateTotal;
this.api_date = TTAPI.APITTDate;
this.api_station = TTAPI.APIStation;
this.api_punch = TTAPI.APIPunch;
if ( ( Global.getProductEdition() >= 20 ) ) {
this.job_api = TTAPI.APIJob;
this.job_item_api = TTAPI.APIJobItem;
this.punch_tag_api = TTAPI.APIPunchTag;
this.department_api = TTAPI.APIDepartment;
}
this.api_absence_policy = TTAPI.APIAbsencePolicy;
this.scroll_position = 0;
this.grid_dic = {};
// 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.
this.initPermission();
this.render();
this.buildContextMenu();
this.initData();
}
initEditView() {
TTPromise.resolve( 'TimeSheetViewController', 'addclick' );
super.initEditView();
}
onSubViewRemoved( is_cancel ) {
if ( !is_cancel ) {
this.search();
}
if ( !this.edit_view ) {
this.setDefaultMenu();
} else {
this.setEditMenu();
}
}
setScrollPosition() {
if ( this.scroll_position > 0 ) {
this.grid_div.scrollTop( this.scroll_position );
}
}
punchModeValidate( p_id ) {
if ( !p_id ) {
p_id = 'punch';
}
if ( PermissionManager.validate( p_id, 'punch_timesheet' ) &&
PermissionManager.validate( p_id, 'manual_timesheet' ) ) {
return true;
}
return false;
}
getPunchPermissionType() {
return this.absence_model ? 'absence' : 'punch';
}
jobUIValidate( p_id ) {
if ( !p_id ) {
p_id = 'punch';
}
if (Global.getProductEdition() >= 20 && PermissionManager.validate( 'job', 'enabled' ) &&
PermissionManager.validate( p_id, 'edit_job' ) ) {
return true;
}
return false;
}
jobItemUIValidate( p_id ) {
if ( !p_id ) {
p_id = 'punch';
}
if (Global.getProductEdition() >= 20 && PermissionManager.validate( p_id, 'edit_job_item' ) ) {
return true;
}
return false;
}
punchTagUIValidate( p_id ) {
if ( !p_id ) {
p_id = 'punch';
}
if (Global.getProductEdition() >= 20 && PermissionManager.validate( p_id, 'edit_punch_tag' ) ) {
return true;
}
return false;
}
//Refresh to clear warnning messages after saving from employee edit view
updateSelectUserAndRefresh( new_item ) {
this.employee_nav.updateSelectItem( new_item );
this.search();
}
branchUIValidate( p_id ) {
if ( !p_id ) {
p_id = 'punch';
}
if ( PermissionManager.validate( p_id, 'edit_branch' ) ) {
return true;
}
return false;
}
departmentUIValidate( p_id ) {
if ( !p_id ) {
p_id = 'punch';
}
if ( PermissionManager.validate( p_id, 'edit_department' ) ) {
return true;
}
return false;
}
goodQuantityUIValidate( p_id ) {
if ( !p_id ) {
p_id = 'punch';
}
if ( PermissionManager.validate( p_id, 'edit_quantity' ) ) {
return true;
}
return false;
}
badQuantityUIValidate( p_id ) {
if ( !p_id ) {
p_id = 'punch';
}
if ( PermissionManager.validate( p_id, 'edit_quantity' ) &&
PermissionManager.validate( p_id, 'edit_bad_quantity' ) ) {
return true;
}
return false;
}
locationUIValidate( p_id ) {
if ( !p_id ) {
p_id = 'punch';
}
if ( PermissionManager.validate( p_id, 'edit_location' ) ) {
return true;
}
return false;
}
noteUIValidate( p_id ) {
if ( !p_id ) {
p_id = 'punch';
}
if ( PermissionManager.validate( p_id, 'edit_note' ) ) {
return true;
}
return false;
}
stationValidate() {
if ( PermissionManager.validate( 'station', 'enabled' ) ) {
return true;
}
return false;
}
/* jshint ignore:start */
//Special permission check for views, need override
initPermission() {
super.initPermission();
if ( !PermissionManager.validate( 'punch', 'view' ) && !PermissionManager.validate( 'punch', 'view_child' ) ) {
this.show_navigation_box = false;
this.show_search_tab = false;
} else {
this.show_navigation_box = true;
this.show_search_tab = true;
}
if ( this.punchModeValidate() ) {
this.show_punch_mode_ui = true;
} else {
this.show_punch_mode_ui = false;
}
this.allow_auto_switch && this.show_punch_mode_ui && ( this.is_auto_switch = true );
if ( this.jobUIValidate() ) {
this.show_job_ui = true;
} else {
this.show_job_ui = false;
}
if ( this.jobItemUIValidate() ) {
this.show_job_item_ui = true;
} else {
this.show_job_item_ui = false;
}
if ( this.punchTagUIValidate() ) {
this.show_punch_tag_ui = true;
} else {
this.show_punch_tag_ui = false;
}
if ( this.branchUIValidate() ) {
this.show_branch_ui = true;
} else {
this.show_branch_ui = false;
}
if ( this.departmentUIValidate() ) {
this.show_department_ui = true;
} else {
this.show_department_ui = false;
}
if ( this.goodQuantityUIValidate() ) {
this.show_good_quantity_ui = true;
} else {
this.show_good_quantity_ui = false;
}
if ( this.badQuantityUIValidate() ) {
this.show_bad_quantity_ui = true;
} else {
this.show_bad_quantity_ui = false;
}
if ( this.noteUIValidate() ) {
this.show_note_ui = true;
} else {
this.show_note_ui = false;
}
if ( this.locationUIValidate() ) {
this.show_location_ui = true;
} else {
this.show_location_ui = false;
}
if ( this.stationValidate() ) {
this.show_station_ui = true;
} else {
this.show_station_ui = false;
}
if ( this.jobUIValidate( 'absence' ) ) {
this.show_absence_job_ui = true;
} else {
this.show_absence_job_ui = false;
}
if ( this.jobItemUIValidate( 'absence' ) ) {
this.show_absence_job_item_ui = true;
} else {
this.show_absence_job_item_ui = false;
}
if ( this.punchTagUIValidate( 'absence' ) ) {
this.show_absence_punch_tag_ui = true;
} else {
this.show_absence_punch_tag_ui = false;
}
if ( this.branchUIValidate( 'absence' ) ) {
this.show_absence_branch_ui = true;
} else {
this.show_absence_branch_ui = false;
}
if ( this.departmentUIValidate( 'absence' ) ) {
this.show_absence_department_ui = true;
} else {
this.show_absence_department_ui = false;
}
}
/* jshint ignore:end */
ownerOrChildPermissionValidate( p_id, permission_name, selected_item ) {
var field;
if ( permission_name && permission_name.indexOf( 'child' ) > -1 ) {
field = 'is_child';
} else {
field = 'is_owner';
}
var user = this.getSelectEmployee( true );
if ( PermissionManager.validate( p_id, permission_name ) && ( !user || !Global.isSet( user[field] ) || ( user && user[field] ) ) ) {
return true;
}
return false;
}
initOptions() {
var options = [
{ option_name: 'type', api: this.api },
{ option_name: 'status', api: this.api },
];
this.initDropDownOptions( options);
}
getCustomContextMenuModel() {
var context_menu_model = {
groups: {
drag_and_drop: {
label: $.i18n._( 'Drag & Drop' ),
id: this.viewId + 'drag_and_drop'
}
},
exclude: [
'export_excel',
'add',
'copy',
'copy_as_new'
],
include: [
{
label: $.i18n._( 'New Punch' ),
id: 'add_punch',
action_group: 'new',
group: 'editor',
vue_icon: 'tticon tticon-add_black_24dp',
show_on_right_click: true,
sort_order: 910
},
{
label: $.i18n._( 'New Absence' ),
id: 'add_absence',
action_group: 'new',
group: 'editor',
vue_icon: 'tticon tticon-add_black_24dp',
show_on_right_click: true,
sort_order: 920
},
{
label: $.i18n._( 'In/Out' ),
id: 'in_out',
action_group: 'in_out',
group: 'editor',
vue_icon: 'tticon tticon-timer_black_24dp',
show_on_right_click: true,
sort_order: 1050
},
{
label: $.i18n._( 'Drag & Drop: Move' ),
id: 'move',
menu_align: 'right',
action_group: 'move_copy',
multi_select_group: 1
},
{
label: $.i18n._( 'Drag & Drop: Copy' ),
id: 'drag_copy',
menu_align: 'right',
action_group: 'move_copy',
multi_select_group: 1
},
]
};
if ( PermissionManager.validate( 'request', 'add' ) ) {
context_menu_model.include.push( {
label: $.i18n._( 'Add Request' ),
id: 'AddRequest',
vue_icon: 'tticon tticon-post_add_black_24dp',
menu_align: 'right',
permission_result: true,
permission: true,
show_on_right_click: true,
sort_order: 1000
} );
}
if ( ( Global.getProductEdition() >= 15 ) ) {
context_menu_model.include.push(
{
label: $.i18n._( 'Map' ),
id: 'map',
menu_align: 'right',
vue_icon: 'tticon tticon-map_black_24dp',
show_on_right_click: true,
sort_order: 2000,
}
);
}
context_menu_model.include.push(
{
label: $.i18n._( 'Print' ),
id: 'print',
action_group_header: true,
action_group: 'print_menu',
sort_order: 7000,
menu_align: 'right',
type: 2,
permission_result: true,
permission: true
},
{
label: $.i18n._( 'Summary' ),
id: 'print_summary',
action_group: 'print_menu',
sort_order: 7000,
menu_align: 'right'
},
{
label: $.i18n._( 'Detailed' ),
id: 'print_detailed',
action_group: 'print_menu',
sort_order: 7000,
menu_align: 'right'
},
{
label: $.i18n._( 'Jump To' ),
id: 'jump_to_header',
menu_align: 'right',
action_group: 'jump_to',
sort_order: 8000,
action_group_header: true,
permission_result: false // to hide it in legacy context menu and avoid errors in legacy parsers.
},
{
label: $.i18n._( 'Schedules' ),
id: 'schedule',
menu_align: 'right',
action_group: 'jump_to',
sort_order: 8000
},
{
label: $.i18n._( 'Pay Stubs' ),
id: 'pay_stub',
menu_align: 'right',
action_group: 'jump_to',
sort_order: 8000
},
{
label: $.i18n._( 'Edit Employee' ),
id: 'edit_employee',
menu_align: 'right',
action_group: 'jump_to',
sort_order: 8000
},
{
label: $.i18n._( 'Edit Pay Period' ),
id: 'edit_pay_period',
menu_align: 'right',
action_group: 'jump_to',
sort_order: 8000
},
{
label: $.i18n._( 'Accumulated Time' ),
id: 'accumulated_time',
menu_align: 'right',
action_group: 'jump_to',
sort_order: 8000
},
{
label: '', //Empty label. vue_icon is displayed instead of text.
id: 'other_header',
menu_align: 'right',
action_group: 'other',
action_group_header: true,
vue_icon: 'tticon tticon-more_vert_black_24dp',
},
{
label: $.i18n._( 'ReCalculate TimeSheet' ),
id: 're_calculate_timesheet',
menu_align: 'right',
action_group: 'other',
},
{
label: $.i18n._( 'Generate Pay Stub' ),
id: 'generate_pay_stub',
menu_align: 'right',
action_group: 'other',
},
);
return context_menu_model;
}
parseCustomContextModelForEditViews( context_menu_model ) {
context_menu_model = super.parseCustomContextModelForEditViews( context_menu_model );
if( this.determineContextMenuMountAttributes().menu_type === 'editview_contextmenu' ) {
context_menu_model.exclude.push(
'move',
'drag_copy',
're_calculate_timesheet',
'generate_pay_stub',
'print',
'print_detailed',
'print_summary',
)
}
return context_menu_model;
}
openEditView() {
//#2295 - Re-initialize previous_absence_policy_id to ensure that previously saved values are passed correctly into the estimation of projected available balance.
this.previous_absence_policy_id = false;
Global.setUINotready();
TTPromise.add( 'init', 'init' );
TTPromise.wait();
if ( !this.edit_view ) {
this.is_edit = true;
this.initEditViewUI( 'TimeSheet', 'TimeSheetEditView.html' );
}
}
/* jshint ignore:start */
//set widget disablebility if view mode or edit mode
setEditViewWidgetsMode() {
var did_clean = false;
for ( var key in this.edit_view_ui_dic ) {
if ( !this.edit_view_ui_dic.hasOwnProperty( key ) ) {
continue;
}
var widget = this.edit_view_ui_dic[key];
var widgetContainer = this.edit_view_form_item_dic[key];
var column = widget.parent().parent().parent();
if ( !column.hasClass( 'v-box' ) ) {
if ( !did_clean ) {
did_clean = true;
}
}
if ( this.absence_model ) {
switch ( key ) {
case 'punch_date':
case 'punch_time':
case 'status_id':
case 'type_id':
case 'quantity':
case 'station_id':
case 'has_image':
case 'latitude':
case 'split_punch_control':
this.detachElement( key );
widget.css( 'opacity', 0 );
break;
case 'punch_dates':
if ( this.is_mass_adding ) {
this.attachElement( key );
widget.css( 'opacity', 1 );
} else {
this.detachElement( key );
widget.css( 'opacity', 0 );
}
break;
case 'date_stamp':
if ( this.is_mass_adding ) {
this.detachElement( key );
widget.css( 'opacity', 0 );
} else {
this.attachElement( key );
widget.css( 'opacity', 1 );
}
break;
case 'total_time':
case 'src_object_id':
case 'override':
this.attachElement( key );
widget.css( 'opacity', 1 );
break;
case 'available_balance':
this.detachElement( key );
widget.css( 'opacity', 1 );
break;
default:
widget.css( 'opacity', 1 );
break;
}
} else {
switch ( key ) {
case 'punch_dates':
if ( this.is_mass_adding ) {
this.attachElement( key );
widget.css( 'opacity', 1 );
} else {
this.detachElement( key );
widget.css( 'opacity', 0 );
}
break;
case 'punch_date':
if ( this.is_mass_adding ) {
this.detachElement( key );
widget.css( 'opacity', 0 );
} else {
this.attachElement( key );
widget.css( 'opacity', 1 );
}
break;
case 'quantity':
if ( this.show_good_quantity_ui && this.show_bad_quantity_ui ) {
this.attachElement( key );
widget.css( 'opacity', 1 );
}
break;
case 'station':
this.attachElement( key );
widget.css( 'opacity', 1 );
break;
case 'punch_time':
case 'status_id':
case 'type_id':
case 'has_image':
case 'latitude':
this.attachElement( key );
widget.css( 'opacity', 1 );
break;
case 'date_stamp':
case 'total_time':
case 'src_object_id':
case 'override':
this.detachElement( key );
widget.css( 'opacity', 0 );
break;
default:
widget.css( 'opacity', 1 );
break;
}
}
if ( this.is_viewing ) {
if ( Global.isSet( widget.setEnabled ) ) {
widget.setEnabled( false );
}
} else {
if ( Global.isSet( widget.setEnabled ) ) {
widget.setEnabled( true );
}
}
}
}
getCustomFieldReferenceField() {
return 'note';
}
setCustomFields() {
//Custom fields are only shown on punch types and not on absence types.
if ( this.getPunchPermissionType() === 'punch' ) {
super.setCustomFields();
}
}
buildEditViewUI() {
super.buildEditViewUI();
var $this = this;
var tab_model = {
'tab_punch': {
'label': this.absence_model ? $.i18n._( 'Absence' ) : $.i18n._( 'Punch' )
},
'tab_audit': true,
};
this.setTabModel( tab_model );
var form_item_input;
var widgetContainer;
//Tab 0 start
var tab_punch = this.edit_view_tab.find( '#tab_punch' );
var tab_punch_column1 = tab_punch.find( '.first-column' );
//Employee
form_item_input = Global.loadWidgetByName( FormItemType.TEXT );
form_item_input.TText( { field: 'first_last_name' } );
this.addEditFieldToColumn( $.i18n._( 'Employee' ), form_item_input, tab_punch_column1, '' );
//Time
form_item_input = Global.loadWidgetByName( FormItemType.TIME_PICKER );
form_item_input.TTimePicker( { field: 'punch_time', validation_field: 'time_stamp' } );
widgetContainer = $( '
' );
this.actual_time_label = $( '' );
widgetContainer.append( form_item_input );
widgetContainer.append( this.actual_time_label );
this.addEditFieldToColumn( $.i18n._( 'Time' ), form_item_input, tab_punch_column1, '', widgetContainer, true );
//Absence Model
//Absence Policy Type
form_item_input = Global.loadWidgetByName( FormItemType.AWESOME_BOX );
form_item_input.AComboBox( {
api_class: TTAPI.APIAbsencePolicy,
allow_multiple_selection: false,
layout_name: 'global_absences',
show_search_inputs: true,
set_empty: true,
field: 'src_object_id',
validation_field: 'absence_policy_id'
} );
form_item_input.customSearchFilter = function( filter ) {
return $this.setAbsencePolicyFilter( filter );
};
this.addEditFieldToColumn( $.i18n._( 'Absence Policy' ), form_item_input, tab_punch_column1, '', null, true );
//Available Balance
form_item_input = Global.loadWidgetByName( FormItemType.TEXT );
form_item_input.TText( { field: 'available_balance' } );
widgetContainer = $( '' );
this.available_balance_info = $( '' );
widgetContainer.append( form_item_input );
widgetContainer.append( this.available_balance_info );
this.addEditFieldToColumn( $.i18n._( 'Available Balance' ), [form_item_input], tab_punch_column1, '', widgetContainer, true );
//Date
form_item_input = Global.loadWidgetByName( FormItemType.DATE_PICKER );
form_item_input.TDatePicker( { field: 'punch_date', validation_field: 'date_stamp' } );
this.addEditFieldToColumn( $.i18n._( 'Date' ), form_item_input, tab_punch_column1, '', null, true );
//Mass Add Date
form_item_input = Global.loadWidgetByName( FormItemType.DATE_PICKER );
form_item_input.TRangePicker( { field: 'punch_dates', validation_field: 'date_stamp' } );
this.addEditFieldToColumn( $.i18n._( 'Date' ), form_item_input, tab_punch_column1, '', null, true );
//Absence Model
//Date
form_item_input = Global.loadWidgetByName( FormItemType.DATE_PICKER );
form_item_input.TDatePicker( { field: 'date_stamp' } );
this.addEditFieldToColumn( $.i18n._( 'Date' ), form_item_input, tab_punch_column1, '', null, true );
//Absence Model
//Time
form_item_input = Global.loadWidgetByName( FormItemType.TEXT_INPUT );
form_item_input.TTextInput( { field: 'total_time', mode: 'time_unit' } );
var widgetContainer = $( '' );
var release_balance_button = $( '' );
release_balance_button.css( 'display', 'none' );
release_balance_button.click( function() {
$this.getAvailableBalance( true );
} );
widgetContainer.append( form_item_input );
widgetContainer.append( release_balance_button );
this.addEditFieldToColumn( $.i18n._( 'Time' ), form_item_input, tab_punch_column1, '', widgetContainer, true );
//Punch Type
form_item_input = Global.loadWidgetByName( FormItemType.COMBO_BOX );
form_item_input.TComboBox( { field: 'type_id' } );
form_item_input.setSourceData( $this.type_array );
widgetContainer = $( '' );
var check_box = Global.loadWidgetByName( FormItemType.CHECKBOX );
check_box.TCheckbox( { field: 'disable_rounding' } );
var label = $( '' + $.i18n._( 'Disable Rounding' ) + '' );
widgetContainer.append( form_item_input );
// Check if view only mode. To prevent option appearing but disabled, as disabled checkboxes are not very clear - same in PunchViewController
if ( this.is_viewing ) {
// 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).
// 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.
this.addEditFieldToColumn( $.i18n._( 'Punch Type' ), form_item_input, tab_punch_column1, '', widgetContainer, true );
} else {
widgetContainer.append( label );
widgetContainer.append( check_box );
this.addEditFieldToColumn( $.i18n._( 'Punch Type' ), [form_item_input, check_box], tab_punch_column1, '', widgetContainer, true );
}
//In Out (Status)
form_item_input = Global.loadWidgetByName( FormItemType.COMBO_BOX );
form_item_input.TComboBox( { field: 'status_id' } );
form_item_input.setSourceData( $this.status_array );
this.addEditFieldToColumn( $.i18n._( 'In/Out' ), form_item_input, tab_punch_column1, '', null, true );
//Default Branch
form_item_input = Global.loadWidgetByName( FormItemType.AWESOME_BOX );
form_item_input.AComboBox( {
api_class: TTAPI.APIBranch,
allow_multiple_selection: false,
layout_name: 'global_branch',
show_search_inputs: true,
set_empty: true,
field: 'branch_id'
} );
this.addEditFieldToColumn( $.i18n._( 'Branch' ), form_item_input, tab_punch_column1, '', null, true );
if ( !this.absence_model ) {
if ( !this.show_branch_ui ) {
this.detachElement( 'branch_id' );
}
} else {
if ( !this.show_absence_branch_ui ) {
this.detachElement( 'branch_id' );
}
}
//Department
form_item_input = Global.loadWidgetByName( FormItemType.AWESOME_BOX );
form_item_input.AComboBox( {
api_class: TTAPI.APIDepartment,
allow_multiple_selection: false,
layout_name: 'global_department',
show_search_inputs: true,
set_empty: true,
field: 'department_id'
} );
this.addEditFieldToColumn( $.i18n._( 'Department' ), form_item_input, tab_punch_column1, '', null, true );
if ( !this.absence_model ) {
if ( !this.show_department_ui ) {
this.detachElement( 'department_id' );
}
} else {
if ( !this.show_absence_department_ui ) {
this.detachElement( 'department_id' );
}
}
if ( ( Global.getProductEdition() >= 20 ) ) {
//Job
form_item_input = Global.loadWidgetByName( FormItemType.AWESOME_BOX );
form_item_input.AComboBox( {
api_class: TTAPI.APIJob,
allow_multiple_selection: false,
layout_name: 'global_job',
show_search_inputs: true,
set_empty: true,
setRealValueCallBack: ( function( val ) {
if ( val ) {
job_coder.setValue( val.manual_id );
}
} ),
field: 'job_id'
} );
widgetContainer = $( '' );
var job_coder = Global.loadWidgetByName( FormItemType.TEXT_INPUT );
job_coder.TTextInput( { field: 'job_quick_search', disable_keyup_event: true } );
job_coder.addClass( 'job-coder' );
widgetContainer.append( job_coder );
widgetContainer.append( form_item_input );
this.addEditFieldToColumn( $.i18n._( 'Job' ), [form_item_input, job_coder], tab_punch_column1, '', widgetContainer, true );
if ( !this.absence_model ) {
if ( !this.show_job_ui ) {
this.detachElement( 'job_id' );
}
} else {
if ( !this.show_absence_job_ui ) {
this.detachElement( 'job_id' );
}
}
//Job Item
form_item_input = Global.loadWidgetByName( FormItemType.AWESOME_BOX );
form_item_input.AComboBox( {
api_class: TTAPI.APIJobItem,
allow_multiple_selection: false,
layout_name: 'global_job_item',
show_search_inputs: true,
set_empty: true,
setRealValueCallBack: ( function( val ) {
if ( val ) {
job_item_coder.setValue( val.manual_id );
}
} ),
field: 'job_item_id'
} );
widgetContainer = $( '' );
var job_item_coder = Global.loadWidgetByName( FormItemType.TEXT_INPUT );
job_item_coder.TTextInput( { field: 'job_item_quick_search', disable_keyup_event: true } );
job_item_coder.addClass( 'job-coder' );
widgetContainer.append( job_item_coder );
widgetContainer.append( form_item_input );
this.addEditFieldToColumn( $.i18n._( 'Task' ), [form_item_input, job_item_coder], tab_punch_column1, '', widgetContainer, true );
if ( !this.absence_model ) {
if ( !this.show_job_item_ui ) {
this.detachElement( 'job_item_id' );
}
} else {
if ( !this.show_absence_job_item_ui ) {
this.detachElement( 'job_item_id' );
}
}
//Punch Tag
form_item_input = Global.loadWidgetByName( FormItemType.AWESOME_BOX );
form_item_input.AComboBox( {
api_class: TTAPI.APIPunchTag,
allow_multiple_selection: true,
layout_name: 'global_punch_tag',
show_search_inputs: true,
set_empty: true,
get_real_data_on_multi: true,
setRealValueCallBack: ( ( punch_tags, get_real_data ) => {
if ( punch_tags ) {
this.setPunchTagQuickSearchManualIds( punch_tags, get_real_data );
}
} ),
field: 'punch_tag_id'
} );
widgetContainer = $( '' );
var punch_tag_coder = Global.loadWidgetByName( FormItemType.TEXT_INPUT );
punch_tag_coder.TTextInput( { field: 'punch_tag_quick_search', disable_keyup_event: true } );
punch_tag_coder.addClass( 'job-coder' );
widgetContainer.append( punch_tag_coder );
widgetContainer.append( form_item_input );
this.addEditFieldToColumn( $.i18n._( 'Tags' ), [form_item_input, punch_tag_coder], tab_punch_column1, '', widgetContainer, true );
if ( !this.absence_model ) {
if ( !this.show_punch_tag_ui ) {
this.detachElement( 'punch_tag_id' );
}
} else {
if ( !this.show_absence_punch_tag_ui ) {
this.detachElement( 'punch_tag_id' );
}
}
}
if ( ( Global.getProductEdition() >= 20 ) ) {
//Quanitity
var good = Global.loadWidgetByName( FormItemType.TEXT_INPUT );
good.TTextInput( { field: 'quantity' } );
good.addClass( 'quantity-input' );
var good_label = $( '' + $.i18n._( 'Good' ) + ': ' );
var bad = Global.loadWidgetByName( FormItemType.TEXT_INPUT );
bad.TTextInput( { field: 'bad_quantity' } );
bad.addClass( 'quantity-input' );
var bad_label = $( '/ ' + $.i18n._( 'Bad' ) + ': ' );
widgetContainer = $( '' );
widgetContainer.append( good_label );
widgetContainer.append( good );
widgetContainer.append( bad_label );
widgetContainer.append( bad );
this.addEditFieldToColumn( $.i18n._( 'Quantity' ), [good, bad], tab_punch_column1, '', widgetContainer, true );
if ( !this.show_bad_quantity_ui && !this.show_good_quantity_ui ) {
this.detachElement( 'quantity' );
} else {
if ( !this.show_bad_quantity_ui ) {
bad_label.hide();
bad.hide();
}
if ( !this.show_good_quantity_ui ) {
good_label.hide();
good.hide();
}
}
}
//Note
form_item_input = Global.loadWidgetByName( FormItemType.TEXT_AREA );
form_item_input.TTextArea( { field: 'note', width: '100%' } );
this.addEditFieldToColumn( $.i18n._( 'Note' ), form_item_input, tab_punch_column1, '', null, true, true );
form_item_input.parent().width( '45%' );
if ( !this.show_note_ui ) {
this.detachElement( 'note' );
}
//Absence Mode
//Override
form_item_input = Global.loadWidgetByName( FormItemType.CHECKBOX );
form_item_input.TCheckbox( { field: 'override' } );
this.addEditFieldToColumn( $.i18n._( 'Override' ), form_item_input, tab_punch_column1, '', null, true, true );
//Location
if ( Global.getProductEdition() >= 15 ) {
var latitude = Global.loadWidgetByName( FormItemType.TEXT );
latitude.TText( { field: 'latitude' } );
var longitude = Global.loadWidgetByName( FormItemType.TEXT );
longitude.TText( { field: 'longitude' } );
widgetContainer = $( '' );
var accuracy = Global.loadWidgetByName( FormItemType.TEXT );
accuracy.TText( { field: 'position_accuracy' } );
label = $( '' + $.i18n._( 'Accuracy' ) + ':' );
var map_icon = $( '' );
this.location_wrapper = $( '' );
widgetContainer.append( map_icon );
widgetContainer.append( this.location_wrapper );
this.location_wrapper.append( latitude );
this.location_wrapper.append( $( ', ' ) );
this.location_wrapper.append( longitude );
this.location_wrapper.append( label );
this.location_wrapper.append( accuracy );
this.location_wrapper.append( $( 'm' ) );
this.addEditFieldToColumn( $.i18n._( 'Location' ), [latitude, longitude, accuracy], tab_punch_column1, '', widgetContainer, true );
widgetContainer.click( function() {
$this.onMapClick();
} );
// #2117 - Manual location only supported in edit because we need a punch record to append the data to.
if ( ( !this.is_edit && !this.is_viewing ) || !this.show_location_ui ) {
widgetContainer.parents( '.edit-view-form-item-div' ).hide();
}
}
//Station
form_item_input = Global.loadWidgetByName( FormItemType.TEXT );
form_item_input.TText( { field: 'station_id' } );
this.addEditFieldToColumn( $.i18n._( 'Station' ), form_item_input, tab_punch_column1, '', null, true, true );
form_item_input.click( function() {
if ( $this.current_edit_record.station_id && $this.show_station_ui ) {
IndexViewController.openEditView( $this, 'Station', $this.current_edit_record.station_id );
}
} );
//Split Punch Control
form_item_input = Global.loadWidgetByName( FormItemType.CHECKBOX );
form_item_input.TCheckbox( { field: 'split_punch_control' } );
this.addEditFieldToColumn( $.i18n._( 'Split Existing Punches' ), form_item_input, tab_punch_column1, '', null, true, true );
if ( this.is_mass_adding == false ) {
this.detachElement( 'split_punch_control' );
}
//Punch Image
form_item_input = Global.loadWidgetByName( FormItemType.IMAGE );
form_item_input.TImage( { field: 'punch_image' } );
this.addEditFieldToColumn( $.i18n._( 'Image' ), form_item_input, tab_punch_column1, '', null, true, true );
}
/* jshint ignore:end */
onEditStationDone() {
this.setStation();
}
setAbsencePolicyFilter( filter ) {
if ( !filter.filter_data ) {
filter.filter_data = {};
}
filter.filter_data.user_id = this.current_edit_record.user_id;
if ( filter.filter_columns ) {
filter.filter_columns.absence_policy = true;
}
return filter;
}
onSetSearchFilterFinished() {
}
onBuildBasicUIFinished() {
}
onBuildAdvUIFinished() {
}
parserDatesRange( date ) {
var dates = date.split( ' - ' );
var resultArray = [];
var beginDate = Global.strToDate( dates[0] );
var endDate = Global.strToDate( dates[1] );
var nextDate = beginDate;
while ( nextDate.getTime() < endDate.getTime() ) {
resultArray.push( nextDate.format() );
nextDate = new Date( new Date( nextDate.getTime() ).setDate( nextDate.getDate() + 1 ) );
}
resultArray.push( dates[1] );
return resultArray;
}
validate() {
var $this = this;
var record = this.current_edit_record;
var i;
if ( this.is_mass_editing ) {
record = [];
var len = this.mass_edit_record_ids.length;
for ( var i = 0; i < len; i++ ) {
var temp_item = Global.clone( this.current_edit_record );
temp_item.id = this.mass_edit_record_ids[i];
record.push( temp_item );
}
}
if ( this.is_mass_adding ) {
record = [];
var dates_array = this.current_edit_record.punch_dates;
if ( dates_array && dates_array.indexOf( ' - ' ) > 0 ) {
dates_array = this.parserDatesRange( dates_array );
}
for ( var i = 0; i < dates_array.length; i++ ) {
var common_record = Global.clone( this.current_edit_record );
delete common_record.punch_dates;
if ( this.absence_model ) {
common_record.date_stamp = dates_array[i];
} else {
common_record.punch_date = dates_array[i];
}
record.push( common_record );
}
}
if ( !this.absence_model ) {
this.api['validate' + this.api.key_name]( record, {
onResult: function( result ) {
$this.validateResult( result );
}
} );
} else {
this.api_user_date_total['validate' + this.api_user_date_total.key_name]( record, {
onResult: function( result ) {
$this.clearErrorTips(); //Always clear error
if ( result.isValid() ) {
$this.setEditMenu();
} else {
$this.setErrorMenu();
$this.setErrorTips( result );
}
}
} );
}
}
/* jshint ignore:start */
onFormItemChange( target, doNotValidate ) {
var $this = this;
this.setIsChanged( target );
this.setMassEditingFieldsWhenFormChange( target );
var key = target.getField();
var c_value = target.getValue();
// 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
if ( !this.current_edit_record ) {
return;
}
this.current_edit_record[key] = c_value;
switch ( key ) {
case 'job_id':
if ( ( Global.getProductEdition() >= 20 ) ) {
this.edit_view_ui_dic['job_quick_search'].setValue( target.getValue( true ) ? ( target.getValue( true ).manual_id ? target.getValue( true ).manual_id : '' ) : '' );
this.setJobItemValueWhenJobChanged( target.getValue( true ), 'job_item_id', {
status_id: 10,
job_id: this.current_edit_record.job_id
} );
this.edit_view_ui_dic['job_quick_search'].setCheckBox( true );
this.setPunchTagValuesWhenCriteriaChanged( this.getPunchTagFilterData(), 'punch_tag_id' );
}
break;
case 'job_item_id':
if ( ( Global.getProductEdition() >= 20 ) ) {
this.edit_view_ui_dic['job_item_quick_search'].setValue( target.getValue( true ) ? ( target.getValue( true ).manual_id ? target.getValue( true ).manual_id : '' ) : '' );
this.edit_view_ui_dic['job_item_quick_search'].setCheckBox( true );
this.setPunchTagValuesWhenCriteriaChanged( this.getPunchTagFilterData(), 'punch_tag_id' );
}
break;
case 'punch_tag_id':
if ( ( Global.getProductEdition() >= 20 ) ) {
if ( c_value !== TTUUID.zero_id && c_value !== false && c_value.length > 0 ) {
this.setPunchTagQuickSearchManualIds( target.getSelectItems() );
} else {
this.edit_view_ui_dic['punch_tag_quick_search'].setValue( '' );
}
$this.previous_punch_tag_selection = c_value;
//Reset source data to make sure correct punch tags are always shown.
this.edit_view_ui_dic['punch_tag_id'].setSourceData( null );
}
break;
case 'branch_id':
if ( ( Global.getProductEdition() >= 20 ) ) {
this.setPunchTagValuesWhenCriteriaChanged( this.getPunchTagFilterData(), 'punch_tag_id' );
this.setJobValueWhenCriteriaChanged( 'job_id', {
status_id: 10,
user_id: this.current_edit_record.user_id,
punch_branch_id: this.current_edit_record.branch_id,
punch_department_id: this.current_edit_record.department_id
} );
this.setDepartmentValueWhenBranchChanged( target.getValue( true ), 'department_id', {
branch_id: this.current_edit_record.branch_id,
user_id: this.current_edit_record.user_id
} );
}
break;
case 'user_id':
case 'department_id':
if ( ( Global.getProductEdition() >= 20 ) ) {
this.setPunchTagValuesWhenCriteriaChanged( this.getPunchTagFilterData(), 'punch_tag_id' );
this.setJobValueWhenCriteriaChanged( 'job_id', {
status_id: 10,
user_id: this.current_edit_record.user_id,
punch_branch_id: this.current_edit_record.branch_id,
punch_department_id: this.current_edit_record.department_id
} );
}
break;
case 'job_quick_search':
case 'job_item_quick_search':
if ( ( Global.getProductEdition() >= 20 ) ) {
this.onJobQuickSearch( key, c_value );
TTPromise.wait( 'BaseViewController', 'onJobQuickSearch', function() {
$this.setPunchTagValuesWhenCriteriaChanged( $this.getPunchTagFilterData(), 'punch_tag_id' );
} );
//Don't validate immediately as onJobQuickSearch is doing async API calls, and it would cause a guaranteed validation failure.
doNotValidate = true;
}
break;
case 'punch_tag_quick_search':
if ( ( Global.getProductEdition() >= 20 ) ) {
this.onPunchTagQuickSearch( c_value, this.getPunchTagFilterData(), 'punch_tag_id' );
//Don't validate immediately as onJobQuickSearch is doing async API calls, and it would cause a guaranteed validation failure.
doNotValidate = true;
}
break;
case 'punch_dates':
this.setEditMenu();
break;
}
if ( this.absence_model ) {
if ( key === 'total_time' ) {
if ( this.current_edit_record ) {
this.current_edit_record[key] = Global.parseTimeUnit( c_value );
// parsed_total_time_obj = this.api_date.parseTimeUnit( c_value, { async: false } );
// if ( parsed_total_time_obj ) {
// this.current_edit_record[key] = parsed_total_time_obj.getResult();
// }
//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.
// The API will automatically calculated these on save anyways.
this.current_edit_record['start_time_stamp'] = false;
this.current_edit_record['end_time_stamp'] = false;
}
}
if ( key !== 'override' && this.edit_view_ui_dic['override'] ) {
this.edit_view_ui_dic['override'].setValue( true );
this.current_edit_record['override'] = true;
}
} else {
this.current_edit_record[key] = c_value;
}
if ( !doNotValidate ) {
if ( this.absence_model ) {
if ( key === 'total_time' ||
key === 'date_stamp' ||
key === 'punch_dates' ||
key === 'src_object_id' ) {
this.onAvailableBalanceChange();
}
}
this.validate();
}
}
/* jshint ignore:end */
buildSearchAndLayoutUI() {
var layout_div = this.search_panel.find( 'div #saved_layout_content_div' );
var form_item = $( $.fn.SearchPanel.html.form_item );
var form_item_label = form_item.find( '.form-item-label' );
var form_item_input_div = form_item.find( '.form-item-input-div' );
form_item_label.text( $.i18n._( 'Save Search As' ) );
this.save_search_as_input = Global.loadWidgetByName( FormItemType.TEXT_INPUT );
this.save_search_as_input.TTextInput();
var save_btn = $( '' );
form_item_input_div.append( this.save_search_as_input );
form_item_input_div.append( save_btn );
var $this = this;
save_btn.click( function() {
$this.onSaveNewLayout();
} );
//Previous Saved Layout
this.previous_saved_layout_div = $( '' );
form_item_input_div.append( this.previous_saved_layout_div );
form_item_label = $( '' + $.i18n._( 'Previous Saved Searches' ) + ':' );
this.previous_saved_layout_div.append( form_item_label );
this.previous_saved_layout_selector = $( '