fix(e-taxes): reliable dialog/progress close + working Cancel across all forms
Under jey_theme/Bootstrap, soft .hide() / frappe.hide_progress() does NOT
reliably remove a modal — it sticks and the next dialog stacks on top of it
(e.g. the ASAN auth "success" message stayed under the date/org picker).
The loading-spinner Cancel button only changed its label, never closing.
- dialogs.hide(): force modal('hide') + remove() + orphaned-backdrop cleanup
(guarded by .modal:visible); no longer resets cancelLoading there so in-flight
pagination callbacks still see the cancel and bail out
- Cancel button now actually closes the spinner
- add import._closeProgress() and route every frappe.hide_progress() through a
robust force-close: purchase/sales order, sales invoice, journal entry,
employee/AMAS (closeAmasProgress), and the E-Taxes unit list
- E-Taxes list-view loading dialogs (items/customers/suppliers/units) and their
success paths force-close the same way
Applies the fix uniformly across all ETaxes JS modules and list views.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
e67a2d2ec1
commit
f5b7e56577
|
|
@ -92,10 +92,10 @@ ETaxes.dialogs = {
|
||||||
}],
|
}],
|
||||||
primary_action_label: __('Cancel'),
|
primary_action_label: __('Cancel'),
|
||||||
primary_action: function() {
|
primary_action: function() {
|
||||||
|
// Флаг ставим ПЕРЕД закрытием: hide() его больше не сбрасывает,
|
||||||
|
// поэтому in-flight callback'и пагинации увидят отмену и выйдут.
|
||||||
ETaxes.cancelLoading = true;
|
ETaxes.cancelLoading = true;
|
||||||
ETaxes.loadingDialog.$wrapper.find('.primary-action').prop('disabled', true);
|
ETaxes.dialogs.hide();
|
||||||
ETaxes.loadingDialog.$wrapper.find('.primary-action').html(__('Cancelling...'));
|
|
||||||
$('#status_message p').text(__('Cancelling the operation.'));
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -193,15 +193,24 @@ ETaxes.dialogs = {
|
||||||
|
|
||||||
// Скрыть диалог
|
// Скрыть диалог
|
||||||
hide: function() {
|
hide: function() {
|
||||||
|
// Мягкий loadingDialog.hide() в jey_theme/Bootstrap НЕ всегда убирает модал
|
||||||
|
// (он зависает и следующий диалог накладывается сверху). Принудительно:
|
||||||
|
// modal('hide') + remove() + чистка осиротевшего backdrop.
|
||||||
|
// cancelLoading здесь НЕ сбрасываем — иначе отмена потеряется для in-flight
|
||||||
|
// callback'ов; флаг сбрасывается в начале операции / при создании диалога.
|
||||||
if (ETaxes.loadingDialog) {
|
if (ETaxes.loadingDialog) {
|
||||||
try {
|
try {
|
||||||
ETaxes.loadingDialog.hide();
|
ETaxes.loadingDialog.$wrapper.modal('hide');
|
||||||
|
ETaxes.loadingDialog.$wrapper.remove();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("Error hiding loading dialog:", e);
|
console.error("Error hiding loading dialog:", e);
|
||||||
}
|
}
|
||||||
ETaxes.loadingDialog = null;
|
ETaxes.loadingDialog = null;
|
||||||
}
|
}
|
||||||
ETaxes.cancelLoading = false;
|
if ($('.modal:visible').length === 0) {
|
||||||
|
$('.modal-backdrop').remove();
|
||||||
|
$('body').removeClass('modal-open');
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// Получить HTML для диалога загрузки
|
// Получить HTML для диалога загрузки
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,15 @@ $(document).on('page:before-change', function() {
|
||||||
function cleanup_customers_loading_state() {
|
function cleanup_customers_loading_state() {
|
||||||
try {
|
try {
|
||||||
// Скрываем прогресс бар
|
// Скрываем прогресс бар
|
||||||
|
if (frappe.cur_progress) {
|
||||||
|
try {
|
||||||
|
frappe.cur_progress.$wrapper.modal('hide');
|
||||||
|
frappe.cur_progress.$wrapper.remove();
|
||||||
|
} catch (e) {}
|
||||||
|
frappe.cur_progress = null;
|
||||||
|
} else {
|
||||||
frappe.hide_progress();
|
frappe.hide_progress();
|
||||||
|
}
|
||||||
|
|
||||||
// Удаляем event listeners
|
// Удаляем event listeners
|
||||||
$(document).off('progress-cancel.loading_customers');
|
$(document).off('progress-cancel.loading_customers');
|
||||||
|
|
@ -133,14 +141,20 @@ function show_loading_dialog_customers(title, message, submessage) {
|
||||||
|
|
||||||
// ИСПРАВЛЕННАЯ функция для скрытия диалога загрузки
|
// ИСПРАВЛЕННАЯ функция для скрытия диалога загрузки
|
||||||
function hide_loading_dialog_customers() {
|
function hide_loading_dialog_customers() {
|
||||||
|
// Принудительное закрытие: soft .hide() в jey_theme/Bootstrap не всегда
|
||||||
|
// убирает модал (он зависает, и следующий диалог накладывается сверху).
|
||||||
if (loading_dialog_customers) {
|
if (loading_dialog_customers) {
|
||||||
try {
|
try {
|
||||||
loading_dialog_customers.hide();
|
loading_dialog_customers.$wrapper.modal('hide');
|
||||||
loading_dialog_customers = null;
|
loading_dialog_customers.$wrapper.remove();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Error hiding loading dialog customers:', e);
|
console.error('Error hiding loading dialog customers:', e);
|
||||||
|
}
|
||||||
loading_dialog_customers = null;
|
loading_dialog_customers = null;
|
||||||
}
|
}
|
||||||
|
if ($('.modal:visible').length === 0) {
|
||||||
|
$('.modal-backdrop').remove();
|
||||||
|
$('body').removeClass('modal-open');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -181,10 +195,7 @@ function set_loading_success_customers(message, submessage, callback, delay = 20
|
||||||
|
|
||||||
// Автоматически закрываем через указанную задержку
|
// Автоматически закрываем через указанную задержку
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
if (loading_dialog_customers) {
|
hide_loading_dialog_customers();
|
||||||
loading_dialog_customers.hide();
|
|
||||||
loading_dialog_customers = null;
|
|
||||||
}
|
|
||||||
if (callback) callback();
|
if (callback) callback();
|
||||||
}, delay);
|
}, delay);
|
||||||
} else if (callback) {
|
} else if (callback) {
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,15 @@ $(document).on('page:before-change', function() {
|
||||||
function cleanup_items_loading_state() {
|
function cleanup_items_loading_state() {
|
||||||
try {
|
try {
|
||||||
// Скрываем прогресс бар
|
// Скрываем прогресс бар
|
||||||
|
if (frappe.cur_progress) {
|
||||||
|
try {
|
||||||
|
frappe.cur_progress.$wrapper.modal('hide');
|
||||||
|
frappe.cur_progress.$wrapper.remove();
|
||||||
|
} catch (e) {}
|
||||||
|
frappe.cur_progress = null;
|
||||||
|
} else {
|
||||||
frappe.hide_progress();
|
frappe.hide_progress();
|
||||||
|
}
|
||||||
|
|
||||||
// Удаляем event listeners
|
// Удаляем event listeners
|
||||||
$(document).off('progress-cancel.loading_items');
|
$(document).off('progress-cancel.loading_items');
|
||||||
|
|
@ -139,14 +147,20 @@ function show_verification_code_items(code) {
|
||||||
|
|
||||||
// ИСПРАВЛЕННАЯ функция для скрытия диалога загрузки для items
|
// ИСПРАВЛЕННАЯ функция для скрытия диалога загрузки для items
|
||||||
function hide_loading_dialog_items() {
|
function hide_loading_dialog_items() {
|
||||||
|
// Принудительное закрытие: soft .hide() в jey_theme/Bootstrap не всегда
|
||||||
|
// убирает модал (он зависает, и следующий диалог накладывается сверху).
|
||||||
if (loading_dialog_items) {
|
if (loading_dialog_items) {
|
||||||
try {
|
try {
|
||||||
loading_dialog_items.hide();
|
loading_dialog_items.$wrapper.modal('hide');
|
||||||
loading_dialog_items = null;
|
loading_dialog_items.$wrapper.remove();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Error hiding loading dialog:', e);
|
console.error('Error hiding loading dialog:', e);
|
||||||
|
}
|
||||||
loading_dialog_items = null;
|
loading_dialog_items = null;
|
||||||
}
|
}
|
||||||
|
if ($('.modal:visible').length === 0) {
|
||||||
|
$('.modal-backdrop').remove();
|
||||||
|
$('body').removeClass('modal-open');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -187,10 +201,7 @@ function set_loading_success_items(message, submessage, callback, delay = 1500)
|
||||||
|
|
||||||
// Автоматически закрываем через указанную задержку
|
// Автоматически закрываем через указанную задержку
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
if (loading_dialog_items) {
|
hide_loading_dialog_items();
|
||||||
loading_dialog_items.hide();
|
|
||||||
loading_dialog_items = null;
|
|
||||||
}
|
|
||||||
if (callback) callback();
|
if (callback) callback();
|
||||||
}, delay);
|
}, delay);
|
||||||
} else if (callback) {
|
} else if (callback) {
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,15 @@ $(document).on('page:before-change', function() {
|
||||||
function cleanup_suppliers_loading_state() {
|
function cleanup_suppliers_loading_state() {
|
||||||
try {
|
try {
|
||||||
// Скрываем прогресс бар
|
// Скрываем прогресс бар
|
||||||
|
if (frappe.cur_progress) {
|
||||||
|
try {
|
||||||
|
frappe.cur_progress.$wrapper.modal('hide');
|
||||||
|
frappe.cur_progress.$wrapper.remove();
|
||||||
|
} catch (e) {}
|
||||||
|
frappe.cur_progress = null;
|
||||||
|
} else {
|
||||||
frappe.hide_progress();
|
frappe.hide_progress();
|
||||||
|
}
|
||||||
|
|
||||||
// Удаляем event listeners
|
// Удаляем event listeners
|
||||||
$(document).off('progress-cancel.loading_suppliers');
|
$(document).off('progress-cancel.loading_suppliers');
|
||||||
|
|
@ -133,14 +141,20 @@ function show_loading_dialog_suppliers(title, message, submessage) {
|
||||||
|
|
||||||
// ИСПРАВЛЕННАЯ функция для скрытия диалога загрузки
|
// ИСПРАВЛЕННАЯ функция для скрытия диалога загрузки
|
||||||
function hide_loading_dialog_suppliers() {
|
function hide_loading_dialog_suppliers() {
|
||||||
|
// Принудительное закрытие: soft .hide() в jey_theme/Bootstrap не всегда
|
||||||
|
// убирает модал (он зависает, и следующий диалог накладывается сверху).
|
||||||
if (loading_dialog_suppliers) {
|
if (loading_dialog_suppliers) {
|
||||||
try {
|
try {
|
||||||
loading_dialog_suppliers.hide();
|
loading_dialog_suppliers.$wrapper.modal('hide');
|
||||||
loading_dialog_suppliers = null;
|
loading_dialog_suppliers.$wrapper.remove();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Error hiding loading dialog suppliers:', e);
|
console.error('Error hiding loading dialog suppliers:', e);
|
||||||
|
}
|
||||||
loading_dialog_suppliers = null;
|
loading_dialog_suppliers = null;
|
||||||
}
|
}
|
||||||
|
if ($('.modal:visible').length === 0) {
|
||||||
|
$('.modal-backdrop').remove();
|
||||||
|
$('body').removeClass('modal-open');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -181,10 +195,7 @@ function set_loading_success_suppliers(message, submessage, callback, delay = 20
|
||||||
|
|
||||||
// Автоматически закрываем через указанную задержку
|
// Автоматически закрываем через указанную задержку
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
if (loading_dialog_suppliers) {
|
hide_loading_dialog_suppliers();
|
||||||
loading_dialog_suppliers.hide();
|
|
||||||
loading_dialog_suppliers = null;
|
|
||||||
}
|
|
||||||
if (callback) callback();
|
if (callback) callback();
|
||||||
}, delay);
|
}, delay);
|
||||||
} else if (callback) {
|
} else if (callback) {
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,20 @@
|
||||||
|
// Надёжное закрытие прогресс-бара. frappe.hide_progress() в jey_theme/Bootstrap
|
||||||
|
// не всегда убирает модал (он зависает, и следующий confirm/alert накладывается
|
||||||
|
// сверху). Принудительно: modal('hide') + remove() + чистка осиротевшего backdrop.
|
||||||
|
function close_units_progress() {
|
||||||
|
if (frappe.cur_progress) {
|
||||||
|
try {
|
||||||
|
frappe.cur_progress.$wrapper.modal('hide');
|
||||||
|
frappe.cur_progress.$wrapper.remove();
|
||||||
|
} catch (e) {}
|
||||||
|
frappe.cur_progress = null;
|
||||||
|
}
|
||||||
|
if ($('.modal:visible').length === 0) {
|
||||||
|
$('.modal-backdrop').remove();
|
||||||
|
$('body').removeClass('modal-open');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
frappe.listview_settings['E-Taxes Unit'] = {
|
frappe.listview_settings['E-Taxes Unit'] = {
|
||||||
add_fields: ['status', 'mapped_unit'],
|
add_fields: ['status', 'mapped_unit'],
|
||||||
|
|
||||||
|
|
@ -92,10 +109,19 @@ function show_verification_code_units(code) {
|
||||||
|
|
||||||
// Функция для скрытия диалога загрузки для units
|
// Функция для скрытия диалога загрузки для units
|
||||||
function hide_loading_dialog_units() {
|
function hide_loading_dialog_units() {
|
||||||
|
// Принудительное закрытие: soft .hide() в jey_theme/Bootstrap не всегда
|
||||||
|
// убирает модал (он зависает, и следующий диалог накладывается сверху).
|
||||||
if (loading_dialog_units) {
|
if (loading_dialog_units) {
|
||||||
loading_dialog_units.hide();
|
try {
|
||||||
|
loading_dialog_units.$wrapper.modal('hide');
|
||||||
|
loading_dialog_units.$wrapper.remove();
|
||||||
|
} catch (e) {}
|
||||||
loading_dialog_units = null;
|
loading_dialog_units = null;
|
||||||
}
|
}
|
||||||
|
if ($('.modal:visible').length === 0) {
|
||||||
|
$('.modal-backdrop').remove();
|
||||||
|
$('body').removeClass('modal-open');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Функция для обновления сообщения в диалоге загрузки для units
|
// Функция для обновления сообщения в диалоге загрузки для units
|
||||||
|
|
@ -135,10 +161,7 @@ function set_loading_success_units(message, submessage, callback, delay = 1500)
|
||||||
|
|
||||||
// Автоматически закрываем через указанную задержку
|
// Автоматически закрываем через указанную задержку
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
if (loading_dialog_units) {
|
hide_loading_dialog_units();
|
||||||
loading_dialog_units.hide();
|
|
||||||
loading_dialog_units = null;
|
|
||||||
}
|
|
||||||
if (callback) callback();
|
if (callback) callback();
|
||||||
}, delay);
|
}, delay);
|
||||||
} else if (callback) {
|
} else if (callback) {
|
||||||
|
|
@ -781,7 +804,7 @@ function process_invoices_for_units(invoices, token, accumulated_data, current_i
|
||||||
|
|
||||||
// Проверка отмены
|
// Проверка отмены
|
||||||
if (window.cancelUnitsLoading) {
|
if (window.cancelUnitsLoading) {
|
||||||
frappe.hide_progress();
|
close_units_progress();
|
||||||
$(document).off('progress-cancel.loading_units');
|
$(document).off('progress-cancel.loading_units');
|
||||||
frappe.show_alert({
|
frappe.show_alert({
|
||||||
message: __('Unit extraction cancelled'),
|
message: __('Unit extraction cancelled'),
|
||||||
|
|
@ -792,7 +815,7 @@ function process_invoices_for_units(invoices, token, accumulated_data, current_i
|
||||||
|
|
||||||
// Если все инвойсы обработаны
|
// Если все инвойсы обработаны
|
||||||
if (current_index >= invoices.length) {
|
if (current_index >= invoices.length) {
|
||||||
frappe.hide_progress();
|
close_units_progress();
|
||||||
$(document).off('progress-cancel.loading_units');
|
$(document).off('progress-cancel.loading_units');
|
||||||
|
|
||||||
// Показываем итоговый результат с разбивкой по источникам
|
// Показываем итоговый результат с разбивкой по источникам
|
||||||
|
|
@ -864,7 +887,7 @@ function process_invoices_for_units(invoices, token, accumulated_data, current_i
|
||||||
}, 50); // 50ms задержка между инвойсами для предотвращения перегрузки
|
}, 50); // 50ms задержка между инвойсами для предотвращения перегрузки
|
||||||
|
|
||||||
} else if (r.message && r.message.error === 'unauthorized') {
|
} else if (r.message && r.message.error === 'unauthorized') {
|
||||||
frappe.hide_progress();
|
close_units_progress();
|
||||||
$(document).off('progress-cancel.loading_units');
|
$(document).off('progress-cancel.loading_units');
|
||||||
|
|
||||||
frappe.confirm(
|
frappe.confirm(
|
||||||
|
|
|
||||||
|
|
@ -844,7 +844,7 @@ function process_employees_one_by_one(listview, asan_login_name, employees_queue
|
||||||
created_count, updated_count, error_count, errors, current_index) {
|
created_count, updated_count, error_count, errors, current_index) {
|
||||||
// Check if finished
|
// Check if finished
|
||||||
if (employees_queue.length === 0) {
|
if (employees_queue.length === 0) {
|
||||||
frappe.hide_progress();
|
closeAmasProgress();
|
||||||
$(document).off('progress-cancel.loading_amas_employees');
|
$(document).off('progress-cancel.loading_amas_employees');
|
||||||
|
|
||||||
const total = created_count + updated_count + error_count;
|
const total = created_count + updated_count + error_count;
|
||||||
|
|
@ -858,7 +858,7 @@ function process_employees_one_by_one(listview, asan_login_name, employees_queue
|
||||||
// Check if cancelled
|
// Check if cancelled
|
||||||
if (window.amas_cancel_loading) {
|
if (window.amas_cancel_loading) {
|
||||||
employees_queue = [];
|
employees_queue = [];
|
||||||
frappe.hide_progress();
|
closeAmasProgress();
|
||||||
$(document).off('progress-cancel.loading_amas_employees');
|
$(document).off('progress-cancel.loading_amas_employees');
|
||||||
|
|
||||||
const total = created_count + updated_count + error_count;
|
const total = created_count + updated_count + error_count;
|
||||||
|
|
@ -896,7 +896,7 @@ function process_employees_one_by_one(listview, asan_login_name, employees_queue
|
||||||
message: __('Cancelling import... Finishing current employee.'),
|
message: __('Cancelling import... Finishing current employee.'),
|
||||||
indicator: 'orange'
|
indicator: 'orange'
|
||||||
}, 3);
|
}, 3);
|
||||||
frappe.hide_progress();
|
closeAmasProgress();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Get employee name for progress message
|
// Get employee name for progress message
|
||||||
|
|
|
||||||
|
|
@ -207,10 +207,10 @@ ETaxes.dialogs = {
|
||||||
}],
|
}],
|
||||||
primary_action_label: __('Cancel'),
|
primary_action_label: __('Cancel'),
|
||||||
primary_action: function() {
|
primary_action: function() {
|
||||||
|
// Флаг ставим ПЕРЕД закрытием: hide() его больше не сбрасывает,
|
||||||
|
// поэтому in-flight callback'и пагинации увидят отмену и выйдут.
|
||||||
ETaxes.state.cancelLoading = true;
|
ETaxes.state.cancelLoading = true;
|
||||||
ETaxes.state.loadingDialog.$wrapper.find('.primary-action').prop('disabled', true);
|
ETaxes.dialogs.hide();
|
||||||
ETaxes.state.loadingDialog.$wrapper.find('.primary-action').html(__('Cancelling...'));
|
|
||||||
$('#loading_message').text(__('Cancelling the operation...'));
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -294,15 +294,24 @@ ETaxes.dialogs = {
|
||||||
* Hide loading dialog
|
* Hide loading dialog
|
||||||
*/
|
*/
|
||||||
hide: function() {
|
hide: function() {
|
||||||
|
// Мягкий loadingDialog.hide() в jey_theme/Bootstrap НЕ всегда убирает модал
|
||||||
|
// (он зависает и следующий диалог накладывается сверху). Принудительно:
|
||||||
|
// modal('hide') + remove() + чистка осиротевшего backdrop.
|
||||||
|
// cancelLoading здесь НЕ сбрасываем — иначе отмена потеряется для in-flight
|
||||||
|
// callback'ов; флаг сбрасывается в начале операции / при создании диалога.
|
||||||
if (ETaxes.state.loadingDialog) {
|
if (ETaxes.state.loadingDialog) {
|
||||||
try {
|
try {
|
||||||
ETaxes.state.loadingDialog.hide();
|
ETaxes.state.loadingDialog.$wrapper.modal('hide');
|
||||||
|
ETaxes.state.loadingDialog.$wrapper.remove();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("Error hiding loading dialog:", e);
|
console.error("Error hiding loading dialog:", e);
|
||||||
}
|
}
|
||||||
ETaxes.state.loadingDialog = null;
|
ETaxes.state.loadingDialog = null;
|
||||||
}
|
}
|
||||||
ETaxes.state.cancelLoading = false;
|
if ($('.modal:visible').length === 0) {
|
||||||
|
$('.modal-backdrop').remove();
|
||||||
|
$('body').removeClass('modal-open');
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -124,10 +124,10 @@ VATETaxes.dialogs = {
|
||||||
}],
|
}],
|
||||||
primary_action_label: __('Cancel'),
|
primary_action_label: __('Cancel'),
|
||||||
primary_action: function() {
|
primary_action: function() {
|
||||||
|
// Флаг ставим ПЕРЕД закрытием: hide() его больше не сбрасывает,
|
||||||
|
// поэтому in-flight callback'и пагинации увидят отмену и выйдут.
|
||||||
VATETaxes.cancelLoading = true;
|
VATETaxes.cancelLoading = true;
|
||||||
VATETaxes.loadingDialog.$wrapper.find('.primary-action').prop('disabled', true);
|
VATETaxes.dialogs.hide();
|
||||||
VATETaxes.loadingDialog.$wrapper.find('.primary-action').html(__('Cancelling...'));
|
|
||||||
$('#status_message p').text(__('Cancelling the operation.'));
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -208,17 +208,28 @@ VATETaxes.dialogs = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// Скрыть диалог
|
// Скрыть диалог. Мягкий loadingDialog.hide() в jey_theme/Bootstrap НЕ всегда
|
||||||
|
// убирает модал (он зависает и следующий диалог накладывается сверху). Поэтому
|
||||||
|
// принудительно: modal('hide') + remove() + чистка осиротевшего backdrop —
|
||||||
|
// тот же приём, что и в _closeProgress.
|
||||||
|
// cancelLoading здесь НЕ сбрасываем: иначе отмена потеряется для in-flight
|
||||||
|
// callback'ов. Флаг сбрасывается в начале операции (loadOperations/showLoading).
|
||||||
hide: function() {
|
hide: function() {
|
||||||
if (VATETaxes.loadingDialog) {
|
if (VATETaxes.loadingDialog) {
|
||||||
try {
|
try {
|
||||||
VATETaxes.loadingDialog.hide();
|
VATETaxes.loadingDialog.$wrapper.modal('hide');
|
||||||
|
VATETaxes.loadingDialog.$wrapper.remove();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("Error hiding loading dialog:", e);
|
console.error("Error hiding loading dialog:", e);
|
||||||
}
|
}
|
||||||
VATETaxes.loadingDialog = null;
|
VATETaxes.loadingDialog = null;
|
||||||
}
|
}
|
||||||
VATETaxes.cancelLoading = false;
|
// backdrop/scroll-lock убираем только если не осталось видимых модалов
|
||||||
|
// (иначе сломаем диалог, который показывается следом, напр. выбор даты).
|
||||||
|
if ($('.modal:visible').length === 0) {
|
||||||
|
$('.modal-backdrop').remove();
|
||||||
|
$('body').removeClass('modal-open');
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// Получить HTML для диалога загрузки
|
// Получить HTML для диалога загрузки
|
||||||
|
|
|
||||||
|
|
@ -98,10 +98,10 @@ ETaxes.dialogs = {
|
||||||
}],
|
}],
|
||||||
primary_action_label: __('Cancel'),
|
primary_action_label: __('Cancel'),
|
||||||
primary_action: function() {
|
primary_action: function() {
|
||||||
|
// Флаг ставим ПЕРЕД закрытием: hide() его больше не сбрасывает,
|
||||||
|
// поэтому in-flight callback'и пагинации увидят отмену и выйдут.
|
||||||
ETaxes.cancelLoading = true;
|
ETaxes.cancelLoading = true;
|
||||||
ETaxes.loadingDialog.$wrapper.find('.primary-action').prop('disabled', true);
|
ETaxes.dialogs.hide();
|
||||||
ETaxes.loadingDialog.$wrapper.find('.primary-action').html(__('Cancelling...'));
|
|
||||||
$('#status_message p').text(__('Cancelling the operation.'));
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -203,15 +203,24 @@ ETaxes.dialogs = {
|
||||||
|
|
||||||
// Скрыть диалог
|
// Скрыть диалог
|
||||||
hide: function() {
|
hide: function() {
|
||||||
|
// Мягкий loadingDialog.hide() в jey_theme/Bootstrap НЕ всегда убирает модал
|
||||||
|
// (он зависает и следующий диалог накладывается сверху). Принудительно:
|
||||||
|
// modal('hide') + remove() + чистка осиротевшего backdrop.
|
||||||
|
// cancelLoading здесь НЕ сбрасываем — иначе отмена потеряется для in-flight
|
||||||
|
// callback'ов; флаг сбрасывается в начале операции / при создании диалога.
|
||||||
if (ETaxes.loadingDialog) {
|
if (ETaxes.loadingDialog) {
|
||||||
try {
|
try {
|
||||||
ETaxes.loadingDialog.hide();
|
ETaxes.loadingDialog.$wrapper.modal('hide');
|
||||||
|
ETaxes.loadingDialog.$wrapper.remove();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("Error hiding loading dialog:", e);
|
console.error("Error hiding loading dialog:", e);
|
||||||
}
|
}
|
||||||
ETaxes.loadingDialog = null;
|
ETaxes.loadingDialog = null;
|
||||||
}
|
}
|
||||||
ETaxes.cancelLoading = false;
|
if ($('.modal:visible').length === 0) {
|
||||||
|
$('.modal-backdrop').remove();
|
||||||
|
$('body').removeClass('modal-open');
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// Получить HTML для диалога загрузки
|
// Получить HTML для диалога загрузки
|
||||||
|
|
|
||||||
|
|
@ -92,10 +92,10 @@ ETaxes.dialogs = {
|
||||||
}],
|
}],
|
||||||
primary_action_label: __('Cancel'),
|
primary_action_label: __('Cancel'),
|
||||||
primary_action: function() {
|
primary_action: function() {
|
||||||
|
// Флаг ставим ПЕРЕД закрытием: hide() его больше не сбрасывает,
|
||||||
|
// поэтому in-flight callback'и пагинации увидят отмену и выйдут.
|
||||||
ETaxes.cancelLoading = true;
|
ETaxes.cancelLoading = true;
|
||||||
ETaxes.loadingDialog.$wrapper.find('.primary-action').prop('disabled', true);
|
ETaxes.dialogs.hide();
|
||||||
ETaxes.loadingDialog.$wrapper.find('.primary-action').html(__('Cancelling...'));
|
|
||||||
$('#status_message p').text(__('Cancelling the operation.'));
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -178,15 +178,24 @@ ETaxes.dialogs = {
|
||||||
|
|
||||||
// Скрыть диалог
|
// Скрыть диалог
|
||||||
hide: function() {
|
hide: function() {
|
||||||
|
// Мягкий loadingDialog.hide() в jey_theme/Bootstrap НЕ всегда убирает модал
|
||||||
|
// (он зависает и следующий диалог накладывается сверху). Принудительно:
|
||||||
|
// modal('hide') + remove() + чистка осиротевшего backdrop.
|
||||||
|
// cancelLoading здесь НЕ сбрасываем — иначе отмена потеряется для in-flight
|
||||||
|
// callback'ов; флаг сбрасывается в начале операции / при создании диалога.
|
||||||
if (ETaxes.loadingDialog) {
|
if (ETaxes.loadingDialog) {
|
||||||
try {
|
try {
|
||||||
ETaxes.loadingDialog.hide();
|
ETaxes.loadingDialog.$wrapper.modal('hide');
|
||||||
|
ETaxes.loadingDialog.$wrapper.remove();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("Error hiding loading dialog:", e);
|
console.error("Error hiding loading dialog:", e);
|
||||||
}
|
}
|
||||||
ETaxes.loadingDialog = null;
|
ETaxes.loadingDialog = null;
|
||||||
}
|
}
|
||||||
ETaxes.cancelLoading = false;
|
if ($('.modal:visible').length === 0) {
|
||||||
|
$('.modal-backdrop').remove();
|
||||||
|
$('body').removeClass('modal-open');
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// Получить HTML для диалога загрузки
|
// Получить HTML для диалога загрузки
|
||||||
|
|
@ -1188,6 +1197,23 @@ ETaxes.import = {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Надёжное закрытие прогресс-бара. frappe.hide_progress() в jey_theme/Bootstrap
|
||||||
|
// не всегда убирает модал (он зависает, и summary/диалог накладывается сверху).
|
||||||
|
// Принудительно: modal('hide') + remove() + чистка осиротевшего backdrop.
|
||||||
|
_closeProgress: function() {
|
||||||
|
if (frappe.cur_progress) {
|
||||||
|
try {
|
||||||
|
frappe.cur_progress.$wrapper.modal('hide');
|
||||||
|
frappe.cur_progress.$wrapper.remove();
|
||||||
|
} catch (e) {}
|
||||||
|
frappe.cur_progress = null;
|
||||||
|
}
|
||||||
|
if ($('.modal:visible').length === 0) {
|
||||||
|
$('.modal-backdrop').remove();
|
||||||
|
$('body').removeClass('modal-open');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
// Загрузка выбранных инвойсов
|
// Загрузка выбранных инвойсов
|
||||||
loadSelectedInvoices: function(invoiceIds, token, warehouse, processedCount = 0, currentIndex = 0) {
|
loadSelectedInvoices: function(invoiceIds, token, warehouse, processedCount = 0, currentIndex = 0) {
|
||||||
if (processedCount === 0 && currentIndex === 0) {
|
if (processedCount === 0 && currentIndex === 0) {
|
||||||
|
|
@ -1198,7 +1224,7 @@ ETaxes.import = {
|
||||||
$(document).off('progress-cancel.loading_invoices');
|
$(document).off('progress-cancel.loading_invoices');
|
||||||
|
|
||||||
if (invoiceIds.length === 0) {
|
if (invoiceIds.length === 0) {
|
||||||
frappe.hide_progress();
|
ETaxes.import._closeProgress();
|
||||||
|
|
||||||
const errorsCount = ETaxes.loadingErrors.length;
|
const errorsCount = ETaxes.loadingErrors.length;
|
||||||
const totalInvoices = window.totalInvoicesToProcess || processedCount;
|
const totalInvoices = window.totalInvoicesToProcess || processedCount;
|
||||||
|
|
@ -1215,7 +1241,7 @@ ETaxes.import = {
|
||||||
|
|
||||||
if (ETaxes.cancelLoading) {
|
if (ETaxes.cancelLoading) {
|
||||||
invoiceIds = [];
|
invoiceIds = [];
|
||||||
frappe.hide_progress();
|
ETaxes.import._closeProgress();
|
||||||
ETaxes.import.loadSelectedInvoices(invoiceIds, token, warehouse, processedCount, currentIndex);
|
ETaxes.import.loadSelectedInvoices(invoiceIds, token, warehouse, processedCount, currentIndex);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -1235,7 +1261,7 @@ ETaxes.import = {
|
||||||
message: __('Cancelling import... Finishing current invoice.'),
|
message: __('Cancelling import... Finishing current invoice.'),
|
||||||
indicator: 'orange'
|
indicator: 'orange'
|
||||||
}, 3);
|
}, 3);
|
||||||
frappe.hide_progress();
|
ETaxes.import._closeProgress();
|
||||||
});
|
});
|
||||||
|
|
||||||
frappe.call({
|
frappe.call({
|
||||||
|
|
@ -1279,7 +1305,7 @@ ETaxes.import = {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else if (r.message && r.message.error === 'unauthorized') {
|
} else if (r.message && r.message.error === 'unauthorized') {
|
||||||
frappe.hide_progress();
|
ETaxes.import._closeProgress();
|
||||||
$(document).off('progress-cancel.loading_invoices');
|
$(document).off('progress-cancel.loading_invoices');
|
||||||
|
|
||||||
frappe.confirm(
|
frappe.confirm(
|
||||||
|
|
@ -1409,7 +1435,7 @@ ETaxes.import = {
|
||||||
// Продолжить или завершить обработку
|
// Продолжить или завершить обработку
|
||||||
_continueOrFinish: function(invoiceIds, token, warehouse, processedCount, currentIndex, isLastInvoice) {
|
_continueOrFinish: function(invoiceIds, token, warehouse, processedCount, currentIndex, isLastInvoice) {
|
||||||
if (isLastInvoice) {
|
if (isLastInvoice) {
|
||||||
frappe.hide_progress();
|
ETaxes.import._closeProgress();
|
||||||
$(document).off('progress-cancel.loading_invoices');
|
$(document).off('progress-cancel.loading_invoices');
|
||||||
|
|
||||||
const totalToProcess = window.totalInvoicesToProcess || processedCount;
|
const totalToProcess = window.totalInvoicesToProcess || processedCount;
|
||||||
|
|
@ -1424,7 +1450,7 @@ ETaxes.import = {
|
||||||
|
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
if (invoiceIds.length === 0) {
|
if (invoiceIds.length === 0) {
|
||||||
frappe.hide_progress();
|
ETaxes.import._closeProgress();
|
||||||
}
|
}
|
||||||
|
|
||||||
ETaxes.import.loadSelectedInvoices(invoiceIds, token, warehouse, processedCount, currentIndex);
|
ETaxes.import.loadSelectedInvoices(invoiceIds, token, warehouse, processedCount, currentIndex);
|
||||||
|
|
|
||||||
|
|
@ -92,10 +92,10 @@ ETaxes.dialogs = {
|
||||||
}],
|
}],
|
||||||
primary_action_label: __('Cancel'),
|
primary_action_label: __('Cancel'),
|
||||||
primary_action: function() {
|
primary_action: function() {
|
||||||
|
// Флаг ставим ПЕРЕД закрытием: hide() его больше не сбрасывает,
|
||||||
|
// поэтому in-flight callback'и пагинации увидят отмену и выйдут.
|
||||||
ETaxes.cancelLoading = true;
|
ETaxes.cancelLoading = true;
|
||||||
ETaxes.loadingDialog.$wrapper.find('.primary-action').prop('disabled', true);
|
ETaxes.dialogs.hide();
|
||||||
ETaxes.loadingDialog.$wrapper.find('.primary-action').html(__('Cancelling...'));
|
|
||||||
$('#status_message p').text(__('Cancelling the operation.'));
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -197,15 +197,24 @@ ETaxes.dialogs = {
|
||||||
|
|
||||||
// Скрыть диалог
|
// Скрыть диалог
|
||||||
hide: function() {
|
hide: function() {
|
||||||
|
// Мягкий loadingDialog.hide() в jey_theme/Bootstrap НЕ всегда убирает модал
|
||||||
|
// (он зависает и следующий диалог накладывается сверху). Принудительно:
|
||||||
|
// modal('hide') + remove() + чистка осиротевшего backdrop.
|
||||||
|
// cancelLoading здесь НЕ сбрасываем — иначе отмена потеряется для in-flight
|
||||||
|
// callback'ов; флаг сбрасывается в начале операции / при создании диалога.
|
||||||
if (ETaxes.loadingDialog) {
|
if (ETaxes.loadingDialog) {
|
||||||
try {
|
try {
|
||||||
ETaxes.loadingDialog.hide();
|
ETaxes.loadingDialog.$wrapper.modal('hide');
|
||||||
|
ETaxes.loadingDialog.$wrapper.remove();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("Error hiding loading dialog:", e);
|
console.error("Error hiding loading dialog:", e);
|
||||||
}
|
}
|
||||||
ETaxes.loadingDialog = null;
|
ETaxes.loadingDialog = null;
|
||||||
}
|
}
|
||||||
ETaxes.cancelLoading = false;
|
if ($('.modal:visible').length === 0) {
|
||||||
|
$('.modal-backdrop').remove();
|
||||||
|
$('body').removeClass('modal-open');
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// Получить HTML для диалога загрузки
|
// Получить HTML для диалога загрузки
|
||||||
|
|
@ -1208,6 +1217,23 @@ ETaxes.import = {
|
||||||
},
|
},
|
||||||
|
|
||||||
// Загрузка выбранных инвойсов
|
// Загрузка выбранных инвойсов
|
||||||
|
// Надёжное закрытие прогресс-бара. frappe.hide_progress() в jey_theme/Bootstrap
|
||||||
|
// не всегда убирает модал (он зависает, и summary/диалог накладывается сверху).
|
||||||
|
// Принудительно: modal('hide') + remove() + чистка осиротевшего backdrop.
|
||||||
|
_closeProgress: function() {
|
||||||
|
if (frappe.cur_progress) {
|
||||||
|
try {
|
||||||
|
frappe.cur_progress.$wrapper.modal('hide');
|
||||||
|
frappe.cur_progress.$wrapper.remove();
|
||||||
|
} catch (e) {}
|
||||||
|
frappe.cur_progress = null;
|
||||||
|
}
|
||||||
|
if ($('.modal:visible').length === 0) {
|
||||||
|
$('.modal-backdrop').remove();
|
||||||
|
$('body').removeClass('modal-open');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
loadSelectedInvoices: function(invoiceIds, token, warehouse, processedCount = 0, currentIndex = 0) {
|
loadSelectedInvoices: function(invoiceIds, token, warehouse, processedCount = 0, currentIndex = 0) {
|
||||||
if (processedCount === 0 && currentIndex === 0) {
|
if (processedCount === 0 && currentIndex === 0) {
|
||||||
ETaxes.loadingErrors = [];
|
ETaxes.loadingErrors = [];
|
||||||
|
|
@ -1217,7 +1243,7 @@ ETaxes.import = {
|
||||||
$(document).off('progress-cancel.loading_invoices');
|
$(document).off('progress-cancel.loading_invoices');
|
||||||
|
|
||||||
if (invoiceIds.length === 0) {
|
if (invoiceIds.length === 0) {
|
||||||
frappe.hide_progress();
|
ETaxes.import._closeProgress();
|
||||||
|
|
||||||
const errorsCount = ETaxes.loadingErrors.length;
|
const errorsCount = ETaxes.loadingErrors.length;
|
||||||
const totalInvoices = window.totalInvoicesToProcess || processedCount;
|
const totalInvoices = window.totalInvoicesToProcess || processedCount;
|
||||||
|
|
@ -1234,7 +1260,7 @@ ETaxes.import = {
|
||||||
|
|
||||||
if (ETaxes.cancelLoading) {
|
if (ETaxes.cancelLoading) {
|
||||||
invoiceIds = [];
|
invoiceIds = [];
|
||||||
frappe.hide_progress();
|
ETaxes.import._closeProgress();
|
||||||
ETaxes.import.loadSelectedInvoices(invoiceIds, token, warehouse, processedCount, currentIndex);
|
ETaxes.import.loadSelectedInvoices(invoiceIds, token, warehouse, processedCount, currentIndex);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -1254,7 +1280,7 @@ ETaxes.import = {
|
||||||
message: __('Cancelling import... Finishing current invoice.'),
|
message: __('Cancelling import... Finishing current invoice.'),
|
||||||
indicator: 'orange'
|
indicator: 'orange'
|
||||||
}, 3);
|
}, 3);
|
||||||
frappe.hide_progress();
|
ETaxes.import._closeProgress();
|
||||||
});
|
});
|
||||||
|
|
||||||
frappe.call({
|
frappe.call({
|
||||||
|
|
@ -1298,7 +1324,7 @@ ETaxes.import = {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else if (r.message && r.message.error === 'unauthorized') {
|
} else if (r.message && r.message.error === 'unauthorized') {
|
||||||
frappe.hide_progress();
|
ETaxes.import._closeProgress();
|
||||||
$(document).off('progress-cancel.loading_invoices');
|
$(document).off('progress-cancel.loading_invoices');
|
||||||
|
|
||||||
frappe.confirm(
|
frappe.confirm(
|
||||||
|
|
@ -1428,7 +1454,7 @@ ETaxes.import = {
|
||||||
// Продолжить или завершить обработку
|
// Продолжить или завершить обработку
|
||||||
_continueOrFinish: function(invoiceIds, token, warehouse, processedCount, currentIndex, isLastInvoice) {
|
_continueOrFinish: function(invoiceIds, token, warehouse, processedCount, currentIndex, isLastInvoice) {
|
||||||
if (isLastInvoice) {
|
if (isLastInvoice) {
|
||||||
frappe.hide_progress();
|
ETaxes.import._closeProgress();
|
||||||
$(document).off('progress-cancel.loading_invoices');
|
$(document).off('progress-cancel.loading_invoices');
|
||||||
|
|
||||||
const totalToProcess = window.totalInvoicesToProcess || processedCount;
|
const totalToProcess = window.totalInvoicesToProcess || processedCount;
|
||||||
|
|
@ -1443,7 +1469,7 @@ ETaxes.import = {
|
||||||
|
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
if (invoiceIds.length === 0) {
|
if (invoiceIds.length === 0) {
|
||||||
frappe.hide_progress();
|
ETaxes.import._closeProgress();
|
||||||
}
|
}
|
||||||
|
|
||||||
ETaxes.import.loadSelectedInvoices(invoiceIds, token, warehouse, processedCount, currentIndex);
|
ETaxes.import.loadSelectedInvoices(invoiceIds, token, warehouse, processedCount, currentIndex);
|
||||||
|
|
|
||||||
|
|
@ -92,10 +92,10 @@ SalesETaxes.dialogs = {
|
||||||
}],
|
}],
|
||||||
primary_action_label: __('Cancel'),
|
primary_action_label: __('Cancel'),
|
||||||
primary_action: function() {
|
primary_action: function() {
|
||||||
|
// Флаг ставим ПЕРЕД закрытием: hide() его больше не сбрасывает,
|
||||||
|
// поэтому in-flight callback'и пагинации увидят отмену и выйдут.
|
||||||
SalesETaxes.cancelLoading = true;
|
SalesETaxes.cancelLoading = true;
|
||||||
SalesETaxes.loadingDialog.$wrapper.find('.primary-action').prop('disabled', true);
|
SalesETaxes.dialogs.hide();
|
||||||
SalesETaxes.loadingDialog.$wrapper.find('.primary-action').html(__('Cancelling...'));
|
|
||||||
$('#status_message p').text(__('Cancelling the operation.'));
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -176,17 +176,27 @@ SalesETaxes.dialogs = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// Скрыть диалог
|
// Скрыть диалог. Мягкий loadingDialog.hide() в jey_theme/Bootstrap НЕ всегда
|
||||||
|
// убирает модал (он зависает и следующий диалог накладывается сверху). Поэтому
|
||||||
|
// принудительно: modal('hide') + remove() + чистка осиротевшего backdrop.
|
||||||
|
// cancelLoading здесь НЕ сбрасываем: иначе отмена потеряется для in-flight
|
||||||
|
// callback'ов. Флаг сбрасывается в начале операции (loadInvoices/showLoading).
|
||||||
hide: function() {
|
hide: function() {
|
||||||
if (SalesETaxes.loadingDialog) {
|
if (SalesETaxes.loadingDialog) {
|
||||||
try {
|
try {
|
||||||
SalesETaxes.loadingDialog.hide();
|
SalesETaxes.loadingDialog.$wrapper.modal('hide');
|
||||||
|
SalesETaxes.loadingDialog.$wrapper.remove();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("Error hiding loading dialog:", e);
|
console.error("Error hiding loading dialog:", e);
|
||||||
}
|
}
|
||||||
SalesETaxes.loadingDialog = null;
|
SalesETaxes.loadingDialog = null;
|
||||||
}
|
}
|
||||||
SalesETaxes.cancelLoading = false;
|
// backdrop/scroll-lock убираем только если не осталось видимых модалов
|
||||||
|
// (иначе сломаем диалог, который показывается следом, напр. выбор даты).
|
||||||
|
if ($('.modal:visible').length === 0) {
|
||||||
|
$('.modal-backdrop').remove();
|
||||||
|
$('body').removeClass('modal-open');
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// Получить HTML для диалога загрузки
|
// Получить HTML для диалога загрузки
|
||||||
|
|
@ -1205,6 +1215,23 @@ SalesETaxes.import = {
|
||||||
},
|
},
|
||||||
|
|
||||||
// Загрузка выбранных инвойсов
|
// Загрузка выбранных инвойсов
|
||||||
|
// Надёжное закрытие прогресс-бара. frappe.hide_progress() в jey_theme/Bootstrap
|
||||||
|
// не всегда убирает модал (он зависает, и summary/диалог накладывается сверху).
|
||||||
|
// Принудительно: modal('hide') + remove() + чистка осиротевшего backdrop.
|
||||||
|
_closeProgress: function() {
|
||||||
|
if (frappe.cur_progress) {
|
||||||
|
try {
|
||||||
|
frappe.cur_progress.$wrapper.modal('hide');
|
||||||
|
frappe.cur_progress.$wrapper.remove();
|
||||||
|
} catch (e) {}
|
||||||
|
frappe.cur_progress = null;
|
||||||
|
}
|
||||||
|
if ($('.modal:visible').length === 0) {
|
||||||
|
$('.modal-backdrop').remove();
|
||||||
|
$('body').removeClass('modal-open');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
loadSelectedInvoices: function(invoiceIds, token, warehouse, processedCount = 0, currentIndex = 0) {
|
loadSelectedInvoices: function(invoiceIds, token, warehouse, processedCount = 0, currentIndex = 0) {
|
||||||
if (processedCount === 0 && currentIndex === 0) {
|
if (processedCount === 0 && currentIndex === 0) {
|
||||||
SalesETaxes.loadingErrors = [];
|
SalesETaxes.loadingErrors = [];
|
||||||
|
|
@ -1214,7 +1241,7 @@ SalesETaxes.import = {
|
||||||
$(document).off('progress-cancel.loading_sales_invoices');
|
$(document).off('progress-cancel.loading_sales_invoices');
|
||||||
|
|
||||||
if (invoiceIds.length === 0) {
|
if (invoiceIds.length === 0) {
|
||||||
frappe.hide_progress();
|
SalesETaxes.import._closeProgress();
|
||||||
|
|
||||||
const errorsCount = SalesETaxes.loadingErrors.length;
|
const errorsCount = SalesETaxes.loadingErrors.length;
|
||||||
const totalInvoices = window.totalSalesInvoicesToProcess || processedCount;
|
const totalInvoices = window.totalSalesInvoicesToProcess || processedCount;
|
||||||
|
|
@ -1231,7 +1258,7 @@ SalesETaxes.import = {
|
||||||
|
|
||||||
if (SalesETaxes.cancelLoading) {
|
if (SalesETaxes.cancelLoading) {
|
||||||
invoiceIds = [];
|
invoiceIds = [];
|
||||||
frappe.hide_progress();
|
SalesETaxes.import._closeProgress();
|
||||||
SalesETaxes.import.loadSelectedInvoices(invoiceIds, token, warehouse, processedCount, currentIndex);
|
SalesETaxes.import.loadSelectedInvoices(invoiceIds, token, warehouse, processedCount, currentIndex);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -1251,7 +1278,7 @@ SalesETaxes.import = {
|
||||||
message: __('Cancelling import... Finishing current sales invoice.'),
|
message: __('Cancelling import... Finishing current sales invoice.'),
|
||||||
indicator: 'orange'
|
indicator: 'orange'
|
||||||
}, 3);
|
}, 3);
|
||||||
frappe.hide_progress();
|
SalesETaxes.import._closeProgress();
|
||||||
});
|
});
|
||||||
|
|
||||||
frappe.call({
|
frappe.call({
|
||||||
|
|
@ -1295,7 +1322,7 @@ SalesETaxes.import = {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else if (r.message && r.message.error === 'unauthorized') {
|
} else if (r.message && r.message.error === 'unauthorized') {
|
||||||
frappe.hide_progress();
|
SalesETaxes.import._closeProgress();
|
||||||
$(document).off('progress-cancel.loading_sales_invoices');
|
$(document).off('progress-cancel.loading_sales_invoices');
|
||||||
|
|
||||||
frappe.confirm(
|
frappe.confirm(
|
||||||
|
|
@ -1474,7 +1501,7 @@ SalesETaxes.import = {
|
||||||
// Продолжить или завершить обработку
|
// Продолжить или завершить обработку
|
||||||
_continueOrFinish: function(invoiceIds, token, warehouse, processedCount, currentIndex, isLastInvoice) {
|
_continueOrFinish: function(invoiceIds, token, warehouse, processedCount, currentIndex, isLastInvoice) {
|
||||||
if (isLastInvoice) {
|
if (isLastInvoice) {
|
||||||
frappe.hide_progress();
|
SalesETaxes.import._closeProgress();
|
||||||
$(document).off('progress-cancel.loading_sales_invoices');
|
$(document).off('progress-cancel.loading_sales_invoices');
|
||||||
|
|
||||||
const totalToProcess = window.totalSalesInvoicesToProcess || processedCount;
|
const totalToProcess = window.totalSalesInvoicesToProcess || processedCount;
|
||||||
|
|
@ -1489,7 +1516,7 @@ SalesETaxes.import = {
|
||||||
|
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
if (invoiceIds.length === 0) {
|
if (invoiceIds.length === 0) {
|
||||||
frappe.hide_progress();
|
SalesETaxes.import._closeProgress();
|
||||||
}
|
}
|
||||||
|
|
||||||
SalesETaxes.import.loadSelectedInvoices(invoiceIds, token, warehouse, processedCount, currentIndex);
|
SalesETaxes.import.loadSelectedInvoices(invoiceIds, token, warehouse, processedCount, currentIndex);
|
||||||
|
|
|
||||||
|
|
@ -92,10 +92,10 @@ ETaxes.dialogs = {
|
||||||
}],
|
}],
|
||||||
primary_action_label: __('Cancel'),
|
primary_action_label: __('Cancel'),
|
||||||
primary_action: function() {
|
primary_action: function() {
|
||||||
|
// Флаг ставим ПЕРЕД закрытием: hide() его больше не сбрасывает,
|
||||||
|
// поэтому in-flight callback'и пагинации увидят отмену и выйдут.
|
||||||
ETaxes.cancelLoading = true;
|
ETaxes.cancelLoading = true;
|
||||||
ETaxes.loadingDialog.$wrapper.find('.primary-action').prop('disabled', true);
|
ETaxes.dialogs.hide();
|
||||||
ETaxes.loadingDialog.$wrapper.find('.primary-action').html(__('Cancelling...'));
|
|
||||||
$('#status_message p').text(__('Cancelling the operation.'));
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -197,15 +197,24 @@ ETaxes.dialogs = {
|
||||||
|
|
||||||
// Скрыть диалог
|
// Скрыть диалог
|
||||||
hide: function() {
|
hide: function() {
|
||||||
|
// Мягкий loadingDialog.hide() в jey_theme/Bootstrap НЕ всегда убирает модал
|
||||||
|
// (он зависает и следующий диалог накладывается сверху). Принудительно:
|
||||||
|
// modal('hide') + remove() + чистка осиротевшего backdrop.
|
||||||
|
// cancelLoading здесь НЕ сбрасываем — иначе отмена потеряется для in-flight
|
||||||
|
// callback'ов; флаг сбрасывается в начале операции / при создании диалога.
|
||||||
if (ETaxes.loadingDialog) {
|
if (ETaxes.loadingDialog) {
|
||||||
try {
|
try {
|
||||||
ETaxes.loadingDialog.hide();
|
ETaxes.loadingDialog.$wrapper.modal('hide');
|
||||||
|
ETaxes.loadingDialog.$wrapper.remove();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("Error hiding loading dialog:", e);
|
console.error("Error hiding loading dialog:", e);
|
||||||
}
|
}
|
||||||
ETaxes.loadingDialog = null;
|
ETaxes.loadingDialog = null;
|
||||||
}
|
}
|
||||||
ETaxes.cancelLoading = false;
|
if ($('.modal:visible').length === 0) {
|
||||||
|
$('.modal-backdrop').remove();
|
||||||
|
$('body').removeClass('modal-open');
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// Получить HTML для диалога загрузки
|
// Получить HTML для диалога загрузки
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue