1065 lines
38 KiB
JavaScript
Vendored
1065 lines
38 KiB
JavaScript
Vendored
//This file contains all common functionality for the application
|
|
$(document).on('submit', 'form', function (e) {
|
|
if (!__is_online()) {
|
|
e.preventDefault();
|
|
toastr.error(LANG.not_connected_to_a_network);
|
|
return false;
|
|
}
|
|
|
|
$(this).find('button[type="submit"]').attr('disabled', true);
|
|
});
|
|
$(document).ready(function () {
|
|
window.addEventListener('online', updateOnlineStatus);
|
|
window.addEventListener('offline', updateOnlineStatus);
|
|
|
|
// Setup CSRF token for all Ajax requests
|
|
// Get CSRF token from meta tag
|
|
var csrfToken = $('meta[name="csrf-token"]').attr('content');
|
|
if (!csrfToken) {
|
|
// Try to get it from document head directly
|
|
var metaTag = document.querySelector('meta[name="csrf-token"]');
|
|
if (metaTag) {
|
|
csrfToken = metaTag.getAttribute('content');
|
|
}
|
|
if (!csrfToken) {
|
|
console.warn('CSRF token not found in meta tag. Please ensure the meta tag is present in the HTML head.');
|
|
}
|
|
}
|
|
|
|
// Setup Ajax defaults with CSRF token
|
|
var ajaxSetupConfig = {
|
|
beforeSend: function (jqXHR, settings) {
|
|
if (!__is_online()) {
|
|
toastr.error(LANG.not_connected_to_a_network);
|
|
return false;
|
|
}
|
|
if (settings.url.indexOf('http') === -1) {
|
|
settings.url = base_path + settings.url;
|
|
}
|
|
// Ensure CSRF token is set for each request
|
|
var token = $('meta[name="csrf-token"]').attr('content') || csrfToken;
|
|
if (token && !jqXHR.headers || !jqXHR.headers['X-CSRF-TOKEN']) {
|
|
jqXHR.setRequestHeader('X-CSRF-TOKEN', token);
|
|
}
|
|
},
|
|
};
|
|
|
|
// Only add headers if we have a token
|
|
if (csrfToken) {
|
|
ajaxSetupConfig.headers = {
|
|
'X-CSRF-TOKEN': csrfToken
|
|
};
|
|
}
|
|
|
|
$.ajaxSetup(ajaxSetupConfig);
|
|
|
|
update_font_size();
|
|
if ($('#status_span').length) {
|
|
var status = $('#status_span').attr('data-status');
|
|
if (status === '1') {
|
|
toastr.success($('#status_span').attr('data-msg'));
|
|
} else if (status == '' || status === '0') {
|
|
toastr.error($('#status_span').attr('data-msg'));
|
|
}
|
|
}
|
|
|
|
//Default setting for select2
|
|
$.fn.select2.defaults.set('minimumResultsForSearch', 6);
|
|
if ($('html').attr('dir') == 'rtl') {
|
|
$.fn.select2.defaults.set('dir', 'rtl');
|
|
}
|
|
// Configure datepicker based on language
|
|
if (typeof is_persian_lang !== 'undefined' && is_persian_lang) {
|
|
// Use Persian datepicker for Persian language
|
|
if (typeof $.fn.persianDatepicker !== 'undefined') {
|
|
// Default configuration for Persian Date Picker
|
|
var persianDatepickerConfig = {
|
|
calendarType: 'persian',
|
|
format: typeof datepicker_date_format !== 'undefined' ? datepicker_date_format : 'YYYY/MM/DD',
|
|
autoClose: true,
|
|
initialValue: false,
|
|
observer: true,
|
|
timePicker: {
|
|
enabled: false
|
|
}
|
|
};
|
|
|
|
// Set defaults for Persian Date Picker
|
|
$.fn.persianDatepicker.defaults = persianDatepickerConfig;
|
|
|
|
// Fallback to regular datepicker defaults
|
|
$.fn.datepicker.defaults.todayHighlight = true;
|
|
$.fn.datepicker.defaults.autoclose = true;
|
|
$.fn.datepicker.defaults.format = typeof datepicker_date_format !== 'undefined' ? datepicker_date_format : 'yyyy/mm/dd';
|
|
} else {
|
|
// Fallback to regular datepicker
|
|
$.fn.datepicker.defaults.todayHighlight = true;
|
|
$.fn.datepicker.defaults.autoclose = true;
|
|
$.fn.datepicker.defaults.format = typeof datepicker_date_format !== 'undefined' ? datepicker_date_format : 'yyyy/mm/dd';
|
|
}
|
|
} else {
|
|
$.fn.datepicker.defaults.todayHighlight = true;
|
|
$.fn.datepicker.defaults.autoclose = true;
|
|
$.fn.datepicker.defaults.format = typeof datepicker_date_format !== 'undefined' ? datepicker_date_format : 'yyyy/mm/dd';
|
|
}
|
|
|
|
function mergePersianPickerOptions(defaultOptions, options) {
|
|
var merged = $.extend(true, {}, defaultOptions, options || {});
|
|
if (!options || options.autoClose !== false) {
|
|
merged.autoClose = true;
|
|
}
|
|
if (
|
|
typeof is_persian_lang !== 'undefined' &&
|
|
is_persian_lang &&
|
|
merged.format &&
|
|
/jY|jM|jD/.test(merged.format)
|
|
) {
|
|
var dateFormat = typeof datepicker_date_format !== 'undefined' ? datepicker_date_format : 'YYYY/MM/DD';
|
|
var timeFormat = typeof moment_time_format !== 'undefined' ? moment_time_format : 'HH:mm';
|
|
merged.format = dateFormat + ' ' + timeFormat;
|
|
}
|
|
return merged;
|
|
}
|
|
|
|
function hidePersianPickerInput($input) {
|
|
if (!$input || !$input.length || !$input.data('persianDatepicker')) {
|
|
return;
|
|
}
|
|
try {
|
|
$input.persianDatepicker('hide');
|
|
} catch (e) {}
|
|
$input.blur();
|
|
}
|
|
|
|
function bindPersianPickerAutoClose($input, mergedOptions) {
|
|
if (mergedOptions.autoClose === false) {
|
|
return mergedOptions;
|
|
}
|
|
mergedOptions.autoClose = true;
|
|
var originalOnSelect = mergedOptions.onSelect;
|
|
mergedOptions.onSelect = function(unixDate) {
|
|
if (typeof originalOnSelect === 'function') {
|
|
originalOnSelect(unixDate);
|
|
}
|
|
setTimeout(function() {
|
|
hidePersianPickerInput($input);
|
|
}, 0);
|
|
};
|
|
return mergedOptions;
|
|
}
|
|
|
|
// Helper function to initialize Persian Date Picker with proper configuration
|
|
window.initPersianDatepicker = function(selector, options) {
|
|
if (typeof is_persian_lang !== 'undefined' && is_persian_lang && typeof $.fn.persianDatepicker !== 'undefined') {
|
|
var defaultOptions = {
|
|
calendarType: 'persian',
|
|
format: typeof datepicker_date_format !== 'undefined' ? datepicker_date_format : 'YYYY/MM/DD',
|
|
autoClose: true,
|
|
observer: true,
|
|
timePicker: {
|
|
enabled: false
|
|
}
|
|
};
|
|
|
|
$(selector).each(function() {
|
|
var $input = $(this);
|
|
var mergedOptions = bindPersianPickerAutoClose(
|
|
$input,
|
|
mergePersianPickerOptions(defaultOptions, options)
|
|
);
|
|
if ($input.data('persianDatepicker')) {
|
|
try {
|
|
$input.persianDatepicker('destroy');
|
|
} catch (e) {}
|
|
}
|
|
$input.persianDatepicker(mergedOptions);
|
|
});
|
|
|
|
// Ensure the selected date is displayed in the input field
|
|
$(selector).on('change', function() {
|
|
var selectedDate = $(this).val();
|
|
if (!selectedDate && $(this).data('persianDatepicker')) {
|
|
var pdInstance = $(this).data('persianDatepicker');
|
|
if (pdInstance && pdInstance.getSelectedDate) {
|
|
try {
|
|
var date = pdInstance.getSelectedDate();
|
|
if (date) {
|
|
var formattedDate = pdInstance.viewDate.year + '/' +
|
|
String(pdInstance.viewDate.month + 1).padStart(2, '0') + '/' +
|
|
String(pdInstance.viewDate.day).padStart(2, '0');
|
|
$(this).val(formattedDate);
|
|
}
|
|
} catch(e) {
|
|
console.log('Error getting date from Persian Date Picker:', e);
|
|
}
|
|
}
|
|
}
|
|
});
|
|
} else {
|
|
// Fallback to regular datepicker
|
|
var defaultOptions = {
|
|
autoclose: true,
|
|
format: typeof datepicker_date_format !== 'undefined' ? datepicker_date_format : 'yyyy/mm/dd'
|
|
};
|
|
var mergedOptions = $.extend({}, defaultOptions, options || {});
|
|
$(selector).datepicker(mergedOptions);
|
|
}
|
|
};
|
|
|
|
window.initPersianDatetimepicker = function(selector, options) {
|
|
if (typeof is_persian_lang !== 'undefined' && is_persian_lang && typeof $.fn.persianDatepicker !== 'undefined') {
|
|
var dateFormat = typeof datepicker_date_format !== 'undefined' ? datepicker_date_format : 'YYYY/MM/DD';
|
|
var timeFormat = typeof moment_time_format !== 'undefined' ? moment_time_format : 'HH:mm';
|
|
var defaultOptions = {
|
|
calendarType: 'persian',
|
|
format: dateFormat + ' ' + timeFormat,
|
|
autoClose: true,
|
|
observer: true,
|
|
timePicker: {
|
|
enabled: true
|
|
}
|
|
};
|
|
$(selector).each(function() {
|
|
var $input = $(this);
|
|
var mergedOptions = bindPersianPickerAutoClose(
|
|
$input,
|
|
mergePersianPickerOptions(defaultOptions, options)
|
|
);
|
|
if ($input.data('persianDatepicker')) {
|
|
try {
|
|
$input.persianDatepicker('destroy');
|
|
} catch (e) {}
|
|
}
|
|
$input.persianDatepicker(mergedOptions);
|
|
});
|
|
} else {
|
|
var datetimepicker_config = {
|
|
format: moment_date_format + ' ' + moment_time_format,
|
|
ignoreReadonly: true,
|
|
};
|
|
var mergedOptions = $.extend({}, datetimepicker_config, options || {});
|
|
$(selector).datetimepicker(mergedOptions);
|
|
}
|
|
};
|
|
|
|
window.__init_datetime_field = function(selector, options) {
|
|
if (typeof initPersianDatetimepicker === 'function') {
|
|
initPersianDatetimepicker(selector, options);
|
|
} else {
|
|
var datetimepicker_config = {
|
|
format: moment_date_format + ' ' + moment_time_format,
|
|
ignoreReadonly: true,
|
|
};
|
|
$(selector).datetimepicker($.extend({}, datetimepicker_config, options || {}));
|
|
}
|
|
};
|
|
|
|
window.__init_date_field = function(selector, options) {
|
|
if (typeof initPersianDatepicker === 'function') {
|
|
initPersianDatepicker(selector, options);
|
|
} else {
|
|
var datepicker_config = {
|
|
autoclose: true,
|
|
format: typeof datepicker_date_format !== 'undefined' ? datepicker_date_format : 'yyyy/mm/dd',
|
|
};
|
|
$(selector).datepicker($.extend({}, datepicker_config, options || {}));
|
|
}
|
|
};
|
|
|
|
window.__init_time_field = function(selector, options) {
|
|
var timepicker_config = $.extend({
|
|
format: typeof moment_time_format !== 'undefined' ? moment_time_format : 'HH:mm',
|
|
ignoreReadonly: true,
|
|
}, options || {});
|
|
$(selector).datetimepicker(timepicker_config);
|
|
};
|
|
|
|
window.__destroy_datetime_field = function(selector) {
|
|
$(selector).each(function() {
|
|
var $input = $(this);
|
|
if ($input.data('persianDatepicker')) {
|
|
try {
|
|
$input.persianDatepicker('destroy');
|
|
} catch (e) {}
|
|
}
|
|
if ($input.data('DateTimePicker')) {
|
|
try {
|
|
$input.data('DateTimePicker').destroy();
|
|
} catch (e) {}
|
|
}
|
|
$input.removeData('pp-comm-ready crm-dt-ready mt-shamsi-ready');
|
|
});
|
|
};
|
|
|
|
window.__clear_datetime_field = function(selector) {
|
|
var $input = $(selector);
|
|
if (!$input.length) {
|
|
return;
|
|
}
|
|
$input.val('');
|
|
if ($input.data('DateTimePicker')) {
|
|
$input.data('DateTimePicker').clear();
|
|
}
|
|
if ($input.data('persianDatepicker')) {
|
|
try {
|
|
$input.persianDatepicker('clear');
|
|
} catch (e) {}
|
|
}
|
|
};
|
|
|
|
// Global event handler to ensure datepicker values are set correctly
|
|
$(document).on('pdp:change', function(e) {
|
|
// This event is fired when Persian Date Picker value changes
|
|
var $input = $(e.target);
|
|
if ($input.data('persianDatepicker')) {
|
|
var pdInstance = $input.data('persianDatepicker');
|
|
if (pdInstance && pdInstance.getSelectedDate) {
|
|
try {
|
|
var date = pdInstance.getSelectedDate();
|
|
if (date && !$input.val()) {
|
|
var formattedDate = date.year + '/' +
|
|
String(date.month + 1).padStart(2, '0') + '/' +
|
|
String(date.day).padStart(2, '0');
|
|
$input.val(formattedDate);
|
|
}
|
|
} catch(e) {
|
|
// Silently fail
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
//Toastr setting
|
|
toastr.options.preventDuplicates = true;
|
|
toastr.options.timeOut = '3000';
|
|
|
|
//Play notification sound on success, error and warning
|
|
toastr.options.onShown = function () {
|
|
if ($(this).hasClass('toast-success')) {
|
|
var audio = $('#success-audio')[0];
|
|
if (audio !== undefined) {
|
|
audio.play();
|
|
}
|
|
} else if ($(this).hasClass('toast-error')) {
|
|
var audio = $('#error-audio')[0];
|
|
if (audio !== undefined) {
|
|
audio.play();
|
|
}
|
|
} else if ($(this).hasClass('toast-warning')) {
|
|
var audio = $('#warning-audio')[0];
|
|
if (audio !== undefined) {
|
|
audio.play();
|
|
}
|
|
}
|
|
};
|
|
|
|
//Default setting for jQuey validator
|
|
jQuery.validator.setDefaults({
|
|
errorPlacement: function (error, element) {
|
|
if (element.hasClass('select2') && element.parent().hasClass('input-group')) {
|
|
error.insertAfter(element.parent());
|
|
} else if (element.hasClass('select2')) {
|
|
error.insertAfter(element.next('span.select2-container'));
|
|
} else if (element.parent().hasClass('input-group')) {
|
|
error.insertAfter(element.parent());
|
|
} else if (element.parent().hasClass('multi-input')) {
|
|
error.insertAfter(element.closest('.multi-input'));
|
|
} else if (element.parent().hasClass('input_inline')) {
|
|
error.insertAfter(element.parent());
|
|
} else if (element.hasClass('upload-element')) {
|
|
error.insertAfter(element.closest('.input-group'));
|
|
} else {
|
|
error.insertAfter(element);
|
|
}
|
|
},
|
|
|
|
invalidHandler: function () {
|
|
toastr.error(LANG.some_error_in_input_field);
|
|
},
|
|
});
|
|
|
|
jQuery.validator.addMethod(
|
|
'max-value',
|
|
function (value, element, param) {
|
|
var is_draft = false;
|
|
if (
|
|
$(element).hasClass('pos_quantity') &&
|
|
$('select#status').length &&
|
|
$('select#status').val() !== 'final'
|
|
) {
|
|
is_draft = true;
|
|
}
|
|
return is_draft || this.optional(element) || !(param < __number_uf(value));
|
|
},
|
|
function (params, element) {
|
|
return $(element).data('msg-max-value');
|
|
}
|
|
);
|
|
|
|
jQuery.validator.addMethod('abs_digit', function (value, element) {
|
|
return this.optional(element) || Number.isInteger(Math.abs(__number_uf(value)));
|
|
});
|
|
|
|
//Set global currency to be used in the application
|
|
__currency_symbol = $('input#__symbol').val();
|
|
__currency_thousand_separator = $('input#__thousand').val();
|
|
__currency_decimal_separator = $('input#__decimal').val();
|
|
__currency_symbol_placement = $('input#__symbol_placement').val();
|
|
if ($('input#__precision').length > 0) {
|
|
__currency_precision = $('input#__precision').val();
|
|
} else {
|
|
__currency_precision = 2;
|
|
}
|
|
|
|
if ($('input#__quantity_precision').length > 0) {
|
|
__quantity_precision = $('input#__quantity_precision').val();
|
|
} else {
|
|
__quantity_precision = 2;
|
|
}
|
|
|
|
//Set page level currency to be used for some pages. (Purchase page)
|
|
if ($('input#p_symbol').length > 0) {
|
|
__p_currency_symbol = $('input#p_symbol').val();
|
|
__p_currency_thousand_separator = $('input#p_thousand').val();
|
|
__p_currency_decimal_separator = $('input#p_decimal').val();
|
|
}
|
|
|
|
__currency_convert_recursively($(document), $('input#p_symbol').length);
|
|
|
|
// Simple function to remove currency symbol and HTML tags from string
|
|
function __remove_currency_symbol(str) {
|
|
// DataTables can pass numbers, objects, null - convert all to string
|
|
if (typeof str !== 'string') {
|
|
str = String(str);
|
|
}
|
|
|
|
// HTML REMOVAL: Simple regex to remove HTML tags
|
|
str = str.replace(/<[^>]*>/g, '');
|
|
|
|
// Check 1: Variable exists, Check 2: Has value, Check 3: Symbol present in string
|
|
if (typeof __currency_symbol !== 'undefined' && __currency_symbol && str.includes(__currency_symbol)) {
|
|
// SIMPLE REPLACEMENT: Replace all occurrences of currency symbol with empty string
|
|
str = str.split(__currency_symbol).join('');
|
|
}
|
|
|
|
return str.trim();
|
|
}
|
|
|
|
var buttons = [
|
|
// {
|
|
// extend: 'copy',
|
|
// text: '<i class="fa fa-files-o" aria-hidden="true"></i> ' + LANG.copy,
|
|
// className: 'btn-sm',
|
|
// exportOptions: {
|
|
// columns: ':visible',
|
|
// },
|
|
// footer: true,
|
|
// },
|
|
{
|
|
extend: 'csv',
|
|
text: '<i class="fa fa-file-csv" aria-hidden="true"></i> ' + LANG.export_to_csv,
|
|
className: 'tw-dw-btn-xs tw-dw-btn tw-dw-btn-outline tw-my-2',
|
|
exportOptions: {
|
|
columns: ':visible',
|
|
format: {
|
|
body: function(data, row, column, node) {
|
|
// Remove currency symbol from the cell data
|
|
return __remove_currency_symbol(data);
|
|
},
|
|
footer: function(data, row, column, node) {
|
|
// Remove currency symbol from the footer data
|
|
return __remove_currency_symbol(data);
|
|
}
|
|
}
|
|
},
|
|
footer: true,
|
|
},
|
|
{
|
|
extend: 'excel',
|
|
text: '<i class="fa fa-file-excel" aria-hidden="true"></i> ' + LANG.export_to_excel,
|
|
className: 'tw-dw-btn-xs tw-dw-btn tw-dw-btn-outline tw-my-2',
|
|
exportOptions: {
|
|
columns: ':visible',
|
|
format: {
|
|
body: function(data, row, column, node) {
|
|
// Remove currency symbol from the cell data
|
|
return __remove_currency_symbol(data);
|
|
},
|
|
footer: function(data, row, column, node) {
|
|
// Remove currency symbol from the footer data
|
|
return __remove_currency_symbol(data);
|
|
}
|
|
}
|
|
},
|
|
footer: true,
|
|
},
|
|
{
|
|
extend: 'print',
|
|
text: '<i class="fa fa-print" aria-hidden="true"></i> ' + LANG.print,
|
|
className: 'tw-dw-btn-xs tw-dw-btn tw-dw-btn-outline tw-my-2',
|
|
exportOptions: {
|
|
columns: ':visible',
|
|
stripHtml: true,
|
|
},
|
|
footer: true,
|
|
customize: function (win) {
|
|
if ($('.print_table_part').length > 0) {
|
|
$($('.print_table_part').html()).insertBefore(
|
|
$(win.document.body).find('table')
|
|
);
|
|
}
|
|
if ($(win.document.body).find('table.hide-footer').length) {
|
|
$(win.document.body).find('table.hide-footer tfoot').remove();
|
|
}
|
|
__currency_convert_recursively($(win.document.body).find('table'));
|
|
},
|
|
},
|
|
{
|
|
extend: 'colvis',
|
|
text: '<i class="fa fa-columns" aria-hidden="true"></i> ' + LANG.col_vis,
|
|
className: 'tw-dw-btn-xs tw-dw-btn tw-dw-btn-outline tw-my-2',
|
|
},
|
|
];
|
|
|
|
var pdf_btn = {
|
|
extend: 'pdf',
|
|
text: '<i class="fa fa-file-pdf" aria-hidden="true"></i> ' + LANG.export_to_pdf,
|
|
className: 'tw-dw-btn-xs tw-dw-btn tw-dw-btn-outline tw-my-2',
|
|
exportOptions: {
|
|
columns: ':visible',
|
|
},
|
|
footer: true,
|
|
};
|
|
|
|
if (typeof non_utf8_languages === 'undefined' || !Array.isArray(non_utf8_languages)) {
|
|
window.non_utf8_languages = [];
|
|
}
|
|
|
|
if (non_utf8_languages.indexOf(app_locale) == -1) {
|
|
buttons.push(pdf_btn);
|
|
}
|
|
|
|
if ($('#view_export_buttons').length < 1) {
|
|
buttons = [];
|
|
}
|
|
//Datables
|
|
jQuery.extend($.fn.dataTable.defaults, {
|
|
//Uncomment below line to enable save state of datatable.
|
|
//stateSave: true,
|
|
fixedHeader: true,
|
|
dom: '<"row margin-bottom-20 text-center"<"col-sm-1"l><"col-sm-8"B><"col-sm-3"f> r>tip',
|
|
buttons: buttons,
|
|
aLengthMenu: [
|
|
[25, 50, 100, 200, 500, 1000, -1],
|
|
[25, 50, 100, 200, 500, 1000, LANG.all],
|
|
],
|
|
iDisplayLength: __default_datatable_page_entries,
|
|
language: {
|
|
searchPlaceholder: LANG.search + ' ...',
|
|
search: '',
|
|
lengthMenu: LANG.show + ' _MENU_ ' + LANG.entries,
|
|
emptyTable: LANG.table_emptyTable,
|
|
info: LANG.table_info,
|
|
infoEmpty: LANG.table_infoEmpty,
|
|
loadingRecords: LANG.table_loadingRecords,
|
|
processing: LANG.table_processing,
|
|
zeroRecords: LANG.table_zeroRecords,
|
|
paginate: {
|
|
first: LANG.first,
|
|
last: LANG.last,
|
|
next: LANG.next,
|
|
previous: LANG.previous,
|
|
},
|
|
},
|
|
});
|
|
|
|
|
|
|
|
if ($('input#iraqi_selling_price_adjustment').length > 0) {
|
|
iraqi_selling_price_adjustment = true;
|
|
} else {
|
|
iraqi_selling_price_adjustment = false;
|
|
}
|
|
|
|
//Input number
|
|
$(document).on(
|
|
'click',
|
|
'.input-number .quantity-up, .input-number .quantity-down',
|
|
function () {
|
|
var input = $(this).closest('.input-number').find('input');
|
|
var qty = __read_number(input);
|
|
var step = 1;
|
|
if (input.data('step')) {
|
|
step = input.data('step');
|
|
}
|
|
var min = parseFloat(input.data('min'));
|
|
var max = parseFloat(input.data('max'));
|
|
|
|
if ($(this).hasClass('quantity-up')) {
|
|
//if max reached return false
|
|
if (typeof max != 'undefined' && qty + step > max) {
|
|
return false;
|
|
}
|
|
|
|
__write_number(input, qty + step);
|
|
input.change();
|
|
} else if ($(this).hasClass('quantity-down')) {
|
|
//if max reached return false
|
|
if (typeof min != 'undefined' && qty - step < min) {
|
|
return false;
|
|
}
|
|
|
|
__write_number(input, qty - step);
|
|
input.change();
|
|
}
|
|
}
|
|
);
|
|
|
|
$('div.pos-tab-menu>div.list-group>a').click(function (e) {
|
|
e.preventDefault();
|
|
$(this).siblings('a.active').removeClass('active');
|
|
$(this).addClass('active');
|
|
var index = $(this).index();
|
|
$('div.pos-tab>div.pos-tab-content').removeClass('active');
|
|
$('div.pos-tab>div.pos-tab-content').eq(index).addClass('active');
|
|
});
|
|
|
|
$('.scroll-top-bottom').each(function () {
|
|
$(this).topScrollbar();
|
|
});
|
|
|
|
// Configure datetimepicker based on language
|
|
__init_datetime_field('.datetimepicker');
|
|
});
|
|
|
|
//Default settings for daterangePicker
|
|
var ranges = {};
|
|
var isJalaliDateRange = typeof is_persian_lang !== 'undefined' && is_persian_lang && typeof moment().jYear === 'function';
|
|
var monthUnit = isJalaliDateRange ? 'jMonth' : 'month';
|
|
var yearUnit = isJalaliDateRange ? 'jYear' : 'year';
|
|
|
|
function __date_range_moment(date) {
|
|
if (typeof __moment_date === 'function') {
|
|
return __moment_date(date);
|
|
}
|
|
|
|
return moment.isMoment(date) ? date.clone() : moment(date);
|
|
}
|
|
|
|
function __date_range_now() {
|
|
return moment();
|
|
}
|
|
|
|
function __date_range_start_of(unit) {
|
|
return __date_range_now().startOf(unit);
|
|
}
|
|
|
|
function __date_range_end_of(unit) {
|
|
return __date_range_now().endOf(unit);
|
|
}
|
|
|
|
function __date_range_financial_year_boundary(boundary) {
|
|
var date = financial_year && financial_year[boundary] ? financial_year[boundary] : moment();
|
|
|
|
return __date_range_moment(date);
|
|
}
|
|
|
|
ranges[LANG.today] = [__date_range_now(), __date_range_now()];
|
|
ranges[LANG.yesterday] = [__date_range_now().subtract(1, 'days'), __date_range_now().subtract(1, 'days')];
|
|
ranges[LANG.last_7_days] = [__date_range_now().subtract(6, 'days'), __date_range_now()];
|
|
ranges[LANG.last_30_days] = [__date_range_now().subtract(29, 'days'), __date_range_now()];
|
|
ranges[LANG.this_month] = [__date_range_start_of(monthUnit), __date_range_end_of(monthUnit)];
|
|
ranges[LANG.last_month] = [
|
|
__date_range_now().subtract(1, monthUnit).startOf(monthUnit),
|
|
__date_range_now().subtract(1, monthUnit).endOf(monthUnit),
|
|
];
|
|
ranges[LANG.this_month_last_year] = [
|
|
__date_range_now().subtract(1, yearUnit).startOf(monthUnit),
|
|
__date_range_now().subtract(1, yearUnit).endOf(monthUnit),
|
|
];
|
|
ranges[LANG.this_year] = [__date_range_start_of(yearUnit), __date_range_end_of(yearUnit)];
|
|
ranges[LANG.last_year] = [
|
|
__date_range_start_of(yearUnit).subtract(1, yearUnit),
|
|
__date_range_end_of(yearUnit).subtract(1, yearUnit),
|
|
];
|
|
ranges[LANG.this_financial_year] = [
|
|
__date_range_financial_year_boundary('start'),
|
|
__date_range_financial_year_boundary('end'),
|
|
];
|
|
ranges[LANG.last_financial_year] = [
|
|
__date_range_financial_year_boundary('start').subtract(1, yearUnit),
|
|
__date_range_financial_year_boundary('end').subtract(1, yearUnit),
|
|
];
|
|
|
|
var dateRangePickerLocaleFormat =
|
|
typeof daterangepicker_format !== 'undefined' ? daterangepicker_format : moment_date_format;
|
|
|
|
var dateRangeSettings = {
|
|
showDropdowns : true,
|
|
linkedCalendars : false,
|
|
ranges: ranges,
|
|
startDate: __date_range_financial_year_boundary('start'),
|
|
endDate: __date_range_financial_year_boundary('end'),
|
|
locale: {
|
|
cancelLabel: LANG.clear,
|
|
applyLabel: LANG.apply,
|
|
customRangeLabel: LANG.custom_range,
|
|
format: dateRangePickerLocaleFormat,
|
|
toLabel: '~',
|
|
},
|
|
};
|
|
|
|
// Override locale for Persian if needed
|
|
if (typeof is_persian_lang !== 'undefined' && is_persian_lang) {
|
|
dateRangeSettings.locale.firstDay = 6; // Saturday is first day in Persian calendar
|
|
}
|
|
|
|
if (typeof is_persian_lang !== 'undefined' && is_persian_lang) {
|
|
$(document).on('show.daterangepicker', function (ev, picker) {
|
|
__refresh_daterangepicker_jalali_label(picker);
|
|
});
|
|
|
|
$(document).on(
|
|
'click.daterangepicker',
|
|
'.daterangepicker td.available, .daterangepicker .ranges li',
|
|
function () {
|
|
setTimeout(function () {
|
|
$('.daterangepicker:visible').each(function () {
|
|
var $container = $(this);
|
|
|
|
$('input, button').each(function () {
|
|
var picker = $(this).data('daterangepicker');
|
|
|
|
if (picker && picker.container && picker.container[0] === $container[0]) {
|
|
__refresh_daterangepicker_jalali_label(picker);
|
|
}
|
|
});
|
|
});
|
|
}, 0);
|
|
}
|
|
);
|
|
}
|
|
|
|
$(document).on('apply.daterangepicker', 'input', function (ev, picker) {
|
|
if ($(this).data('skipAutoDateRangeLabel')) {
|
|
return;
|
|
}
|
|
|
|
$(this).val(__format_date_range(picker.startDate, picker.endDate));
|
|
});
|
|
|
|
$(document).on('cancel.daterangepicker', 'input', function () {
|
|
if ($(this).data('skipAutoDateRangeLabel')) {
|
|
return;
|
|
}
|
|
|
|
$(this).val('');
|
|
});
|
|
|
|
//Check for number string in input field, if data-decimal is 0 then don't allow decimal symbol and if no_neg then don't allow negative value
|
|
$(document).on('keypress', 'input.input_number', function (event) {
|
|
var is_decimal = $(this).data('decimal');
|
|
|
|
if (is_decimal == 0) {
|
|
if (__currency_decimal_separator == '.') {
|
|
var regex = new RegExp(/^[0-9,-]+$/);
|
|
} else {
|
|
var regex = new RegExp(/^[0-9.-]+$/);
|
|
}
|
|
} else {
|
|
var regex = new RegExp(/^[0-9.,-]+$/);
|
|
}
|
|
|
|
// Check for no negative values
|
|
if(is_decimal == 'no_neg'){
|
|
var regex = new RegExp(/^[0-9.,]+$/);
|
|
}
|
|
|
|
var key = String.fromCharCode(!event.charCode ? event.which : event.charCode);
|
|
if (!regex.test(key)) {
|
|
event.preventDefault();
|
|
return false;
|
|
}
|
|
});
|
|
|
|
//Select all input values on click
|
|
$(document).on('click', 'input', function (event) {
|
|
$(this).select();
|
|
});
|
|
|
|
$(document).on('click', '.toggle-font-size', function (event) {
|
|
localStorage.setItem('upos_font_size', $(this).data('size'));
|
|
update_font_size();
|
|
});
|
|
$(document).on('click', '.sidebar-toggle', function () {
|
|
var sidebar_collapse = localStorage.getItem('upos_sidebar_collapse');
|
|
if ($('body').hasClass('sidebar-collapse')) {
|
|
localStorage.setItem('upos_sidebar_collapse', 'false');
|
|
} else {
|
|
localStorage.setItem('upos_sidebar_collapse', 'true');
|
|
}
|
|
});
|
|
|
|
//Ask for confirmation for links
|
|
$(document).on('click', 'a.link_confirmation', function (e) {
|
|
e.preventDefault();
|
|
swal({
|
|
title: LANG.sure,
|
|
icon: 'warning',
|
|
buttons: true,
|
|
dangerMode: true,
|
|
}).then((confirmed) => {
|
|
if (confirmed) {
|
|
window.location.href = $(this).attr('href');
|
|
}
|
|
});
|
|
});
|
|
|
|
//Change max quantity rule if lot number changes
|
|
$('table#stock_adjustment_product_table tbody').on('change', 'select.lot_number', function () {
|
|
var tr = $(this).closest('tr');
|
|
var qty_element = tr.find('input.product_quantity');
|
|
var qty_available_el = tr.find('.qty_available_text');
|
|
|
|
var multiplier = 1;
|
|
var unit_name = '';
|
|
var sub_unit_length = tr.find('select.sub_unit').length;
|
|
if (sub_unit_length > 0) {
|
|
var select = tr.find('select.sub_unit');
|
|
multiplier = parseFloat(select.find(':selected').data('multiplier'));
|
|
unit_name = select.find(':selected').data('unit_name');
|
|
}
|
|
|
|
if ($(this).val()) {
|
|
var lot_qty = $('option:selected', $(this)).data('qty_available');
|
|
var max_err_msg = $('option:selected', $(this)).data('msg-max');
|
|
|
|
if (sub_unit_length > 0) {
|
|
lot_qty = lot_qty / multiplier;
|
|
var lot_qty_formated = __number_f(lot_qty, false);
|
|
max_err_msg = __translate('lot_max_qty_error', {
|
|
max_val: lot_qty_formated,
|
|
unit_name: unit_name,
|
|
});
|
|
}
|
|
|
|
qty_element.attr('data-rule-max-value', lot_qty);
|
|
qty_element.attr('data-msg-max-value', max_err_msg);
|
|
|
|
qty_element.rules('add', {
|
|
'max-value': lot_qty,
|
|
messages: {
|
|
'max-value': max_err_msg,
|
|
},
|
|
});
|
|
if (qty_available_el.length) {
|
|
qty_available_el.text(__currency_trans_from_en(lot_qty, false));
|
|
}
|
|
} else {
|
|
var default_qty = qty_element.data('qty_available');
|
|
var default_err_msg = qty_element.data('msg_max_default');
|
|
|
|
if (sub_unit_length > 0) {
|
|
default_qty = default_qty / multiplier;
|
|
var lot_qty_formated = __number_f(default_qty, false);
|
|
default_err_msg = __translate('pos_max_qty_error', {
|
|
max_val: lot_qty_formated,
|
|
unit_name: unit_name,
|
|
});
|
|
}
|
|
|
|
qty_element.attr('data-rule-max-value', default_qty);
|
|
qty_element.attr('data-msg-max-value', default_err_msg);
|
|
|
|
qty_element.rules('add', {
|
|
'max-value': default_qty,
|
|
messages: {
|
|
'max-value': default_err_msg,
|
|
},
|
|
});
|
|
|
|
if (qty_available_el.length) {
|
|
qty_available_el.text(__currency_trans_from_en(default_qty, false));
|
|
}
|
|
}
|
|
qty_element.trigger('change');
|
|
});
|
|
$('button#btnCalculator, button#return_sale').hover(function () {
|
|
$(this).tooltip('show');
|
|
});
|
|
$('button#return_sale').click(function () {
|
|
$(this).popover('toggle');
|
|
});
|
|
$('button#service_staff_replacement').click(function () {
|
|
$(this).popover('toggle');
|
|
});
|
|
$(document).on('mouseleave', 'button#btnCalculator, button#return_sale', function (e) {
|
|
$(this).tooltip('hide');
|
|
});
|
|
|
|
jQuery.validator.addMethod(
|
|
'min-value',
|
|
function (value, element, param) {
|
|
return this.optional(element) || !(param > __number_uf(value));
|
|
},
|
|
function (params, element) {
|
|
return $(element).data('min-value');
|
|
}
|
|
);
|
|
|
|
$(document).on('click', '.view_uploaded_document', function (e) {
|
|
e.preventDefault();
|
|
var src = $(this).data('href');
|
|
var html =
|
|
'<div class="modal-dialog" role="document"><div class="modal-content"><div class="modal-header"><button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button></div><div class="modal-body"><img src="' +
|
|
src +
|
|
'" class="img-responsive" alt="Uploaded Document"></div><div class="modal-footer"><button type="button" class="btn btn-default" data-dismiss="modal">Close</button> <a href="' +
|
|
src +
|
|
'" class="btn btn-success" download=""><i class="fa fa-download"></i> Download</a></div></div></div>';
|
|
$('div.view_modal').html(html).modal('show');
|
|
});
|
|
|
|
$(document).on('click', '#accordion .box-header', function (e) {
|
|
if (e.target.tagName == 'A' || e.target.tagName == 'I') {
|
|
return false;
|
|
}
|
|
$(this).find('.box-title a').click();
|
|
});
|
|
|
|
$(document).on('shown.bs.modal', '.contains_select2, .view_modal', function () {
|
|
$(this)
|
|
.find('.select2')
|
|
.each(function () {
|
|
var $p = $(this).parent();
|
|
$(this).select2({ dropdownParent: $p });
|
|
});
|
|
});
|
|
|
|
//common configuration : tinyMCE editor
|
|
|
|
tinymce.overrideDefaults({
|
|
height: 300,
|
|
language: app_locale, // Set language dynamically
|
|
language_url: base_path + '/js/lang/tiny/' + app_locale + '.js', // Dynamic URL
|
|
theme: 'silver',
|
|
plugins: [
|
|
'advlist autolink link image lists charmap print preview hr anchor pagebreak',
|
|
'searchreplace wordcount visualblocks visualchars code fullscreen insertdatetime media nonbreaking',
|
|
'table template paste help',
|
|
],
|
|
toolbar:
|
|
'undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify |' +
|
|
' bullist numlist outdent indent | link image | print preview media fullpage | ' +
|
|
'forecolor backcolor',
|
|
menu: {
|
|
favs: { title: 'My Favorites', items: 'code | searchreplace' },
|
|
},
|
|
menubar: 'favs file edit view insert format tools table help',
|
|
});
|
|
|
|
// Prevent Bootstrap dialog from blocking focusin
|
|
$(document).on('focusin', function (e) {
|
|
if ($(e.target).closest('.tox-tinymce-aux, .moxman-window, .tam-assetmanager-root, .select2-container').length) {
|
|
e.stopImmediatePropagation();
|
|
}
|
|
});
|
|
|
|
//search parameter in url
|
|
function urlSearchParam(param) {
|
|
var results = new RegExp('[?&]' + param + '=([^&#]*)').exec(window.location.href);
|
|
if (results == null) {
|
|
return null;
|
|
} else {
|
|
return results[1];
|
|
}
|
|
}
|
|
|
|
// For dropdown hidden issue
|
|
// (function() {
|
|
// var dropdownMenu;
|
|
// $('table').on('show.bs.dropdown', function(e) {
|
|
// dropdownMenu = $(e.target).find('.dropdown-menu');
|
|
// $('body').append(dropdownMenu.detach());
|
|
// var eOffset = $(e.target).offset();
|
|
// if(dropdownMenu.hasClass('dropdown-menu-right')) {
|
|
// dropdownMenu.css({
|
|
// 'display': 'block',
|
|
// 'top': eOffset.top + $(e.target).outerHeight(),
|
|
// 'left': 'auto',
|
|
// 'right': 0
|
|
// });
|
|
// } else {
|
|
// dropdownMenu.css({
|
|
// 'display': 'block',
|
|
// 'top': eOffset.top + $(e.target).outerHeight(),
|
|
// 'left': eOffset.left
|
|
// });
|
|
// }
|
|
// });
|
|
// $('table').on('hide.bs.dropdown', function(e) {
|
|
// $(e.target).append(dropdownMenu.detach());
|
|
// dropdownMenu.hide();
|
|
// });
|
|
// })();
|
|
|
|
function updateOnlineStatus() {
|
|
if (!__is_online()) {
|
|
$('#online_indicator').removeClass('text-success');
|
|
$('#online_indicator').addClass('text-danger');
|
|
} else {
|
|
$('#online_indicator').removeClass('text-danger');
|
|
$('#online_indicator').addClass('text-success');
|
|
}
|
|
}
|
|
|
|
$(document).on('change', '.cash_denomination', function () {
|
|
var total = 0;
|
|
var table = $(this).closest('table');
|
|
table.find('tbody tr').each(function () {
|
|
var denomination = parseFloat($(this).find('.cash_denomination').attr('data-denomination'));
|
|
var count = $(this).find('.cash_denomination').val()
|
|
? parseInt($(this).find('.cash_denomination').val())
|
|
: 0;
|
|
var subtotal = denomination * count;
|
|
total = total + subtotal;
|
|
$(this).find('span.denomination_subtotal').text(__currency_trans_from_en(subtotal, true));
|
|
});
|
|
|
|
table.find('span.denomination_total').text(__currency_trans_from_en(total, true));
|
|
table.find('input.denomination_total_amount').val(total);
|
|
});
|
|
|
|
//autofocus select2 search input
|
|
let forceFocusFn = function () {
|
|
// Gets the search input of the opened select2
|
|
var searchInput = document.querySelector('.select2-container--open .select2-search__field');
|
|
// If exists
|
|
if (searchInput) searchInput.focus(); // focus
|
|
};
|
|
|
|
// Every time a select2 is opened
|
|
$(document).on('select2:open', () => {
|
|
// We use a timeout because when a select2 is already opened and you open a new one, it has to wait to find the appropiate
|
|
setTimeout(() => forceFocusFn(), 200);
|
|
});
|
|
|
|
function copyToClipboard(element_id) {
|
|
var temp = $('<input>');
|
|
$('body').append(temp);
|
|
temp.val($('#' + element_id).text()).select();
|
|
document.execCommand('copy');
|
|
temp.remove();
|
|
toastr.success(LANG.copied_to_clipboard);
|
|
}
|
|
|
|
// This function escapes HTML characters in a given string to prevent XSS attacks.
|
|
function escapeHtml(str) {
|
|
if (typeof str !== 'string') return '';
|
|
return str
|
|
.replace(/&/g, '&')
|
|
.replace(/</g, '<')
|
|
.replace(/>/g, '>')
|
|
.replace(/"/g, '"')
|
|
.replace(/'/g, ''');
|
|
}
|