Added bulk edit, all english, and every doctype of invoice az is read-only
This commit is contained in:
parent
905cfeac0c
commit
994917ffbc
File diff suppressed because it is too large
Load Diff
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
frappe.ui.form.on('Purchase Order', {
|
||||
refresh: function(frm) {
|
||||
// Проверяем, установлена ли галочка is_taxes_doc
|
||||
|
|
@ -7,7 +6,7 @@ frappe.ui.form.on('Purchase Order', {
|
|||
frm.set_read_only(true);
|
||||
|
||||
// Альтернативно, можно добавить визуальное предупреждение
|
||||
frm.page.set_indicator(__('Налоговый документ'), 'blue');
|
||||
frm.page.set_indicator(__('Tax Document'), 'blue');
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -42,7 +41,7 @@ frappe.listview_settings['Purchase Order'] = {
|
|||
// Добавляем кнопку в верхнее меню списка
|
||||
onload: function(listview) {
|
||||
// Добавляем кнопку для импорта из E-Taxes
|
||||
listview.page.add_menu_item(__('Импорт из E-Taxes'), function() {
|
||||
listview.page.add_menu_item(__('Import from E-Taxes'), function() {
|
||||
show_etaxes_import_dialog_for_list();
|
||||
});
|
||||
}
|
||||
|
|
@ -58,7 +57,7 @@ var cancel_loading = false;
|
|||
function show_loading_dialog(message, show_progress = false) {
|
||||
if (!loading_dialog) {
|
||||
loading_dialog = new frappe.ui.Dialog({
|
||||
title: __('Загрузка'),
|
||||
title: __('Loading'),
|
||||
fields: [
|
||||
{
|
||||
fieldname: 'status_html',
|
||||
|
|
@ -100,8 +99,8 @@ function show_loading_dialog(message, show_progress = false) {
|
|||
}
|
||||
</style>
|
||||
<div class="mt-3" id="status_message">
|
||||
<h4>${message || __('Пожалуйста, подождите...')}</h4>
|
||||
<p>${__('Операция может занять некоторое время')}</p>
|
||||
<h4>${message || __('Please wait...')}</h4>
|
||||
<p>${__('The operation may take some time')}</p>
|
||||
</div>
|
||||
<!-- Блок для отображения кода верификации -->
|
||||
<div id="verification_code_container" style="display:none; margin-top: 15px;">
|
||||
|
|
@ -121,18 +120,18 @@ function show_loading_dialog(message, show_progress = false) {
|
|||
`
|
||||
}
|
||||
],
|
||||
primary_action_label: __('Отмена'),
|
||||
primary_action_label: __('Cancel'),
|
||||
primary_action: function() {
|
||||
cancel_loading = true;
|
||||
loading_dialog.$wrapper.find('.primary-action').prop('disabled', true);
|
||||
loading_dialog.$wrapper.find('.primary-action').html(__('Отмена в процессе...'));
|
||||
$('#status_message p').text(__('Отмена загрузки. Уже загруженные инвойсы сохранятся.'));
|
||||
loading_dialog.$wrapper.find('.primary-action').html(__('Cancelling...'));
|
||||
$('#status_message p').text(__('Cancelling the loading. Already loaded invoices will be saved.'));
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// Обновляем сообщение
|
||||
$('#status_message h4').text(message || __('Пожалуйста, подождите...'));
|
||||
$('#status_message p').text(__('Операция может занять некоторое время'));
|
||||
$('#status_message h4').text(message || __('Please wait...'));
|
||||
$('#status_message p').text(__('The operation may take some time'));
|
||||
}
|
||||
|
||||
// Показываем или скрываем прогресс-бар
|
||||
|
|
@ -156,7 +155,7 @@ function update_progress(current, total) {
|
|||
if (loading_dialog) {
|
||||
var percent = Math.round((current / total) * 100);
|
||||
$('#progress_bar_fill').css('width', percent + '%');
|
||||
$('#progress_text').text(current + ' из ' + total + ' (' + percent + '%)');
|
||||
$('#progress_text').text(current + ' of ' + total + ' (' + percent + '%)');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -667,34 +666,34 @@ function show_etaxes_import_dialog(frm) {
|
|||
check_token_before_api_call(function() {
|
||||
// Создаем диалог для выбора периода и склада
|
||||
var d = new frappe.ui.Dialog({
|
||||
title: __('Импорт счета-фактуры из E-Taxes'),
|
||||
title: __('Import invoice from E-Taxes'),
|
||||
fields: [
|
||||
{
|
||||
fieldname: 'date_range_section',
|
||||
fieldtype: 'Section Break',
|
||||
label: __('Период')
|
||||
label: __('Period')
|
||||
},
|
||||
{
|
||||
fieldname: 'creationDateFrom',
|
||||
fieldtype: 'Date',
|
||||
label: __('Дата с'),
|
||||
label: __('Date from'),
|
||||
default: moment().subtract(1, 'month').format('YYYY-MM-DD')
|
||||
},
|
||||
{
|
||||
fieldname: 'creationDateTo',
|
||||
fieldtype: 'Date',
|
||||
label: __('Дата по'),
|
||||
label: __('Date to'),
|
||||
default: moment().format('YYYY-MM-DD')
|
||||
},
|
||||
{
|
||||
fieldname: 'settings_section',
|
||||
fieldtype: 'Section Break',
|
||||
label: __('Настройки')
|
||||
label: __('Settings')
|
||||
},
|
||||
{
|
||||
fieldname: 'warehouse',
|
||||
fieldtype: 'Link',
|
||||
label: __('Склад по умолчанию'),
|
||||
label: __('Default warehouse'),
|
||||
options: 'Warehouse',
|
||||
reqd: true,
|
||||
get_query: function() {
|
||||
|
|
@ -707,7 +706,7 @@ function show_etaxes_import_dialog(frm) {
|
|||
}
|
||||
}
|
||||
],
|
||||
primary_action_label: __('Поиск'),
|
||||
primary_action_label: __('Search'),
|
||||
primary_action: function() {
|
||||
var values = d.get_values();
|
||||
|
||||
|
|
@ -718,16 +717,16 @@ function show_etaxes_import_dialog(frm) {
|
|||
|
||||
if (!warehouse) {
|
||||
frappe.msgprint({
|
||||
title: __('Внимание'),
|
||||
title: __('Warning'),
|
||||
indicator: 'orange',
|
||||
message: __('Пожалуйста, выберите склад по умолчанию')
|
||||
message: __('Please select a default warehouse')
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Закрываем диалог
|
||||
d.hide();
|
||||
show_loading_dialog(__('Загрузка счетов-фактур...'));
|
||||
show_loading_dialog(__('Loading invoices...'));
|
||||
|
||||
// Загружаем счета-фактуры
|
||||
load_etaxes_invoices(frm, fromDate, toDate, warehouse);
|
||||
|
|
@ -744,34 +743,34 @@ function show_etaxes_import_dialog_for_list() {
|
|||
check_token_before_api_call(function() {
|
||||
// Создаем диалог для выбора периода и склада
|
||||
var d = new frappe.ui.Dialog({
|
||||
title: __('Импорт счета-фактуры из E-Taxes'),
|
||||
title: __('Import invoice from E-Taxes'),
|
||||
fields: [
|
||||
{
|
||||
fieldname: 'date_range_section',
|
||||
fieldtype: 'Section Break',
|
||||
label: __('Период')
|
||||
label: __('Period')
|
||||
},
|
||||
{
|
||||
fieldname: 'creationDateFrom',
|
||||
fieldtype: 'Date',
|
||||
label: __('Дата с'),
|
||||
label: __('Date from'),
|
||||
default: moment().subtract(1, 'month').format('YYYY-MM-DD')
|
||||
},
|
||||
{
|
||||
fieldname: 'creationDateTo',
|
||||
fieldtype: 'Date',
|
||||
label: __('Дата по'),
|
||||
label: __('Date to'),
|
||||
default: moment().format('YYYY-MM-DD')
|
||||
},
|
||||
{
|
||||
fieldname: 'settings_section',
|
||||
fieldtype: 'Section Break',
|
||||
label: __('Настройки')
|
||||
label: __('Settings')
|
||||
},
|
||||
{
|
||||
fieldname: 'warehouse',
|
||||
fieldtype: 'Link',
|
||||
label: __('Склад по умолчанию'),
|
||||
label: __('Default warehouse'),
|
||||
options: 'Warehouse',
|
||||
reqd: true,
|
||||
get_query: function() {
|
||||
|
|
@ -784,7 +783,7 @@ function show_etaxes_import_dialog_for_list() {
|
|||
}
|
||||
}
|
||||
],
|
||||
primary_action_label: __('Поиск'),
|
||||
primary_action_label: __('Search'),
|
||||
primary_action: function() {
|
||||
var values = d.get_values();
|
||||
|
||||
|
|
@ -795,16 +794,16 @@ function show_etaxes_import_dialog_for_list() {
|
|||
|
||||
if (!warehouse) {
|
||||
frappe.msgprint({
|
||||
title: __('Внимание'),
|
||||
title: __('Warning'),
|
||||
indicator: 'orange',
|
||||
message: __('Пожалуйста, выберите склад по умолчанию')
|
||||
message: __('Please select a default warehouse')
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Закрываем диалог
|
||||
d.hide();
|
||||
show_loading_dialog(__('Загрузка счетов-фактур...'));
|
||||
show_loading_dialog(__('Loading invoices...'));
|
||||
|
||||
// Загружаем счета-фактуры
|
||||
load_etaxes_invoices(null, fromDate, toDate, warehouse);
|
||||
|
|
@ -836,9 +835,9 @@ function load_etaxes_invoices(frm, fromDate, toDate, warehouse) {
|
|||
if (!main_token) {
|
||||
hide_loading_dialog();
|
||||
frappe.msgprint({
|
||||
title: __('Ошибка авторизации'),
|
||||
title: __('Authentication Error'),
|
||||
indicator: 'red',
|
||||
message: __('Не найден токен авторизации. Пожалуйста, завершите процесс авторизации в настройках E-Taxes.')
|
||||
message: __('Authentication token not found. Please complete the authentication process in E-Taxes settings.')
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
|
@ -866,8 +865,8 @@ function load_etaxes_invoices(frm, fromDate, toDate, warehouse) {
|
|||
if (invoices.length > 0) {
|
||||
// Показываем диалог загрузки для проверки дубликатов
|
||||
update_loading_message(
|
||||
__('Проверка на дубликаты...'),
|
||||
__('Фильтрация уже импортированных счетов-фактур')
|
||||
__('Checking for duplicates...'),
|
||||
__('Filtering already imported invoices')
|
||||
);
|
||||
|
||||
// Получаем список уже импортированных инвойсов из E-Taxes Purchase
|
||||
|
|
@ -922,19 +921,19 @@ function load_etaxes_invoices(frm, fromDate, toDate, warehouse) {
|
|||
show_invoice_selection_dialog(frm, filteredInvoices, main_token, warehouse);
|
||||
} else {
|
||||
frappe.msgprint({
|
||||
title: __('Информация'),
|
||||
title: __('Information'),
|
||||
indicator: 'blue',
|
||||
message: __('За указанный период не найдено новых счетов-фактур (все ' +
|
||||
invoices.length + ' уже импортированы)')
|
||||
message: __('No new invoices found for the specified period (all ' +
|
||||
invoices.length + ' are already imported)')
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Error processing purchase data:", e);
|
||||
hide_loading_dialog();
|
||||
frappe.msgprint({
|
||||
title: __('Ошибка'),
|
||||
title: __('Error'),
|
||||
indicator: 'red',
|
||||
message: __('Произошла ошибка при обработке данных: ') + e.message
|
||||
message: __('An error occurred while processing data: ') + e.message
|
||||
});
|
||||
}
|
||||
},
|
||||
|
|
@ -946,7 +945,7 @@ function load_etaxes_invoices(frm, fromDate, toDate, warehouse) {
|
|||
show_invoice_selection_dialog(frm, invoices, main_token, warehouse);
|
||||
|
||||
frappe.show_alert({
|
||||
message: __('Не удалось выполнить проверку дубликатов. Показаны все инвойсы.'),
|
||||
message: __('Failed to check for duplicates. Showing all invoices.'),
|
||||
indicator: 'orange'
|
||||
}, 5);
|
||||
}
|
||||
|
|
@ -956,9 +955,9 @@ function load_etaxes_invoices(frm, fromDate, toDate, warehouse) {
|
|||
hide_loading_dialog();
|
||||
|
||||
frappe.msgprint({
|
||||
title: __('Информация'),
|
||||
title: __('Information'),
|
||||
indicator: 'blue',
|
||||
message: __('За указанный период не найдено счетов-фактур')
|
||||
message: __('No invoices found for the specified period')
|
||||
});
|
||||
}
|
||||
} else if (r.message && r.message.error === 'unauthorized') {
|
||||
|
|
@ -987,9 +986,9 @@ function load_etaxes_invoices(frm, fromDate, toDate, warehouse) {
|
|||
hide_loading_dialog();
|
||||
|
||||
frappe.msgprint({
|
||||
title: __('Ошибка'),
|
||||
title: __('Error'),
|
||||
indicator: 'red',
|
||||
message: r.message ? r.message.message : __('Ошибка загрузки счетов-фактур')
|
||||
message: r.message ? r.message.message : __('Error loading invoices')
|
||||
});
|
||||
}
|
||||
},
|
||||
|
|
@ -997,18 +996,18 @@ function load_etaxes_invoices(frm, fromDate, toDate, warehouse) {
|
|||
console.error("Error fetching invoices:", error);
|
||||
hide_loading_dialog();
|
||||
frappe.msgprint({
|
||||
title: __('Ошибка сети'),
|
||||
title: __('Network Error'),
|
||||
indicator: 'red',
|
||||
message: __('Ошибка при получении данных с сервера: ') + (error || 'Unknown error')
|
||||
message: __('Error fetching data from server: ') + (error || 'Unknown error')
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
hide_loading_dialog();
|
||||
frappe.msgprint({
|
||||
title: __('Ошибка'),
|
||||
title: __('Error'),
|
||||
indicator: 'red',
|
||||
message: __('Не найдены настройки авторизации E-Taxes')
|
||||
message: __('E-Taxes authentication settings not found')
|
||||
});
|
||||
}
|
||||
},
|
||||
|
|
@ -1016,9 +1015,9 @@ function load_etaxes_invoices(frm, fromDate, toDate, warehouse) {
|
|||
console.error("Error fetching Asan login settings:", error);
|
||||
hide_loading_dialog();
|
||||
frappe.msgprint({
|
||||
title: __('Ошибка сети'),
|
||||
title: __('Network Error'),
|
||||
indicator: 'red',
|
||||
message: __('Ошибка при получении настроек авторизации: ') + (error || 'Unknown error')
|
||||
message: __('Error fetching authentication settings: ') + (error || 'Unknown error')
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
@ -1030,10 +1029,10 @@ function show_invoice_selection_dialog(frm, invoices, token, warehouse) {
|
|||
var invoice_table = '<div style="max-height: 500px; overflow-y: auto;"><table class="table table-bordered etaxes-invoices-table">';
|
||||
invoice_table += '<thead><tr>' +
|
||||
'<th style="width: 30px;"><input type="checkbox" class="select-all-invoices"></th>' +
|
||||
'<th>' + __('Номер') + '</th>' +
|
||||
'<th>' + __('Дата') + '</th>' +
|
||||
'<th>' + __('Поставщик') + '</th>' +
|
||||
'<th>' + __('Сумма') + '</th>' +
|
||||
'<th>' + __('Number') + '</th>' +
|
||||
'<th>' + __('Date') + '</th>' +
|
||||
'<th>' + __('Supplier') + '</th>' +
|
||||
'<th>' + __('Amount') + '</th>' +
|
||||
'</tr></thead><tbody>';
|
||||
|
||||
invoices.forEach(function(invoice) {
|
||||
|
|
@ -1063,12 +1062,12 @@ function show_invoice_selection_dialog(frm, invoices, token, warehouse) {
|
|||
|
||||
// Информация о количестве найденных инвойсов
|
||||
let info_message = '<div class="alert alert-info">' +
|
||||
__('Найдено новых счетов-фактур: ') + invoices.length +
|
||||
__('New invoices found: ') + invoices.length +
|
||||
'</div>';
|
||||
|
||||
// Создаем диалог
|
||||
var d = new frappe.ui.Dialog({
|
||||
title: __('Выбор счета-фактуры'),
|
||||
title: __('Select invoice'),
|
||||
fields: [
|
||||
{
|
||||
fieldname: 'info_html',
|
||||
|
|
@ -1084,10 +1083,10 @@ function show_invoice_selection_dialog(frm, invoices, token, warehouse) {
|
|||
fieldname: 'warehouse_display',
|
||||
fieldtype: 'HTML',
|
||||
options: '<div class="row"><div class="col-xs-12"><div class="alert alert-info">' +
|
||||
__('Выбранный склад: ') + '<strong>' + warehouse + '</strong></div></div></div>'
|
||||
__('Selected warehouse: ') + '<strong>' + warehouse + '</strong></div></div></div>'
|
||||
}
|
||||
],
|
||||
primary_action_label: __('Загрузить выбранные'),
|
||||
primary_action_label: __('Load selected'),
|
||||
primary_action: function() {
|
||||
// Получаем выбранные инвойсы
|
||||
var selected_invoice_ids = [];
|
||||
|
|
@ -1097,9 +1096,9 @@ function show_invoice_selection_dialog(frm, invoices, token, warehouse) {
|
|||
|
||||
if (selected_invoice_ids.length === 0) {
|
||||
frappe.msgprint({
|
||||
title: __('Внимание'),
|
||||
title: __('Warning'),
|
||||
indicator: 'orange',
|
||||
message: __('Не выбрано ни одного счета-фактуры')
|
||||
message: __('No invoices selected')
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
|
@ -1109,13 +1108,13 @@ function show_invoice_selection_dialog(frm, invoices, token, warehouse) {
|
|||
|
||||
// Загружаем выбранные инвойсы последовательно
|
||||
// Показываем диалог с прогрессом
|
||||
show_loading_dialog(__('Загрузка инвойсов...'), true);
|
||||
show_loading_dialog(__('Loading invoices...'), true);
|
||||
update_progress(0, selected_invoice_ids.length);
|
||||
|
||||
// Загружаем выбранные инвойсы последовательно
|
||||
load_selected_invoices(frm, selected_invoice_ids, token, warehouse, 0);
|
||||
},
|
||||
secondary_action_label: __('Отмена'),
|
||||
secondary_action_label: __('Cancel'),
|
||||
secondary_action: function() {
|
||||
d.hide();
|
||||
}
|
||||
|
|
@ -1137,8 +1136,8 @@ function load_selected_invoices(frm, invoice_ids, token, warehouse, processed_co
|
|||
// Если был запрос на отмену, показываем соответствующее сообщение
|
||||
if (cancel_loading) {
|
||||
set_loading_success(
|
||||
__('Загрузка отменена'),
|
||||
__('Загружено ' + processed_count + ' инвойсов из ' + (processed_count + invoice_ids.length)),
|
||||
__('Loading cancelled'),
|
||||
__('Loaded ' + processed_count + ' invoices out of ' + (processed_count + invoice_ids.length)),
|
||||
function() {
|
||||
if (frm) {
|
||||
frm.reload_doc();
|
||||
|
|
@ -1150,8 +1149,8 @@ function load_selected_invoices(frm, invoice_ids, token, warehouse, processed_co
|
|||
} else {
|
||||
// Все успешно загружено
|
||||
set_loading_success(
|
||||
__('Загрузка завершена'),
|
||||
__('Загружено ' + processed_count + ' инвойсов'),
|
||||
__('Loading completed'),
|
||||
__('Loaded ' + processed_count + ' invoices'),
|
||||
function() {
|
||||
if (frm) {
|
||||
frm.reload_doc();
|
||||
|
|
@ -1172,8 +1171,8 @@ function load_selected_invoices(frm, invoice_ids, token, warehouse, processed_co
|
|||
|
||||
// Обновляем текст загрузки
|
||||
update_loading_message(
|
||||
__('Загрузка инвойса (' + (processed_count + 1) + ' из ' + (processed_count + invoice_ids.length + 1) + ')'),
|
||||
__('Получение данных счета-фактуры...')
|
||||
__('Loading invoice (' + (processed_count + 1) + ' of ' + (processed_count + invoice_ids.length + 1) + ')'),
|
||||
__('Getting invoice data...')
|
||||
);
|
||||
|
||||
// Получаем детали счета-фактуры
|
||||
|
|
@ -1199,8 +1198,8 @@ function load_selected_invoices(frm, invoice_ids, token, warehouse, processed_co
|
|||
let total = r.message.totalAmount || r.message.amount || 0;
|
||||
|
||||
update_loading_message(
|
||||
__('Загрузка инвойса (' + (processed_count + 1) + ' из ' + (processed_count + invoice_ids.length + 1) + ')'),
|
||||
__('Импорт данных инвойса: ') + serialNumber
|
||||
__('Loading invoice (' + (processed_count + 1) + ' of ' + (processed_count + invoice_ids.length + 1) + ')'),
|
||||
__('Importing invoice data: ') + serialNumber
|
||||
);
|
||||
|
||||
// Импортируем данные инвойса с указанием даты и склада
|
||||
|
|
@ -1222,7 +1221,7 @@ function load_selected_invoices(frm, invoice_ids, token, warehouse, processed_co
|
|||
if (import_r.message && import_r.message.success) {
|
||||
// Показываем уведомление об успешном импорте
|
||||
frappe.show_alert({
|
||||
message: __('Инвойс успешно импортирован: ') + serialNumber,
|
||||
message: __('Invoice successfully imported: ') + serialNumber,
|
||||
indicator: 'green'
|
||||
}, 3);
|
||||
|
||||
|
|
@ -1268,7 +1267,7 @@ function load_selected_invoices(frm, invoice_ids, token, warehouse, processed_co
|
|||
} else {
|
||||
// Обрабатываем ошибку создания E-Taxes Purchase
|
||||
frappe.show_alert({
|
||||
message: __('Ошибка при создании E-Taxes Purchase'),
|
||||
message: __('Error creating E-Taxes Purchase'),
|
||||
indicator: 'red'
|
||||
}, 3);
|
||||
|
||||
|
|
@ -1295,13 +1294,13 @@ function load_selected_invoices(frm, invoice_ids, token, warehouse, processed_co
|
|||
|
||||
// Останавливаем загрузку, так как требуется вмешательство пользователя
|
||||
frappe.msgprint({
|
||||
title: __('Импорт остановлен'),
|
||||
title: __('Import stopped'),
|
||||
indicator: 'red',
|
||||
message: __('Для продолжения необходимо создать недостающие сопоставления')
|
||||
message: __('To continue, you need to create missing mappings')
|
||||
});
|
||||
} else {
|
||||
frappe.show_alert({
|
||||
message: __('Ошибка импорта: ') + serialNumber,
|
||||
message: __('Import error: ') + serialNumber,
|
||||
indicator: 'red'
|
||||
}, 3);
|
||||
|
||||
|
|
@ -1327,7 +1326,7 @@ function load_selected_invoices(frm, invoice_ids, token, warehouse, processed_co
|
|||
callback: function(login_r) {
|
||||
if (login_r.message && login_r.message.found && login_r.message.main_token) {
|
||||
// Показываем диалог с прогрессом снова
|
||||
show_loading_dialog(__('Возобновление загрузки инвойсов...'), true);
|
||||
show_loading_dialog(__('Resuming invoice loading...'), true);
|
||||
update_progress(processed_count, processed_count + invoice_ids.length + 1);
|
||||
|
||||
// Возвращаем текущий инвойс в начало списка
|
||||
|
|
@ -1337,9 +1336,9 @@ function load_selected_invoices(frm, invoice_ids, token, warehouse, processed_co
|
|||
load_selected_invoices(frm, invoice_ids, login_r.message.main_token, warehouse, processed_count);
|
||||
} else {
|
||||
frappe.msgprint({
|
||||
title: __('Ошибка'),
|
||||
title: __('Error'),
|
||||
indicator: 'red',
|
||||
message: __('Не удалось получить токен после авторизации')
|
||||
message: __('Failed to get token after authentication')
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -1356,7 +1355,7 @@ function load_selected_invoices(frm, invoice_ids, token, warehouse, processed_co
|
|||
);
|
||||
} else {
|
||||
frappe.show_alert({
|
||||
message: __('Ошибка загрузки данных инвойса'),
|
||||
message: __('Error loading invoice data'),
|
||||
indicator: 'red'
|
||||
}, 3);
|
||||
|
||||
|
|
@ -1373,12 +1372,12 @@ function load_selected_invoices(frm, invoice_ids, token, warehouse, processed_co
|
|||
function show_unmatched_items_dialog(invoice_data, unmatched_items) {
|
||||
// Создаем таблицу с несопоставленными товарами
|
||||
var items_table = '<div class="text-center mb-3">' +
|
||||
'<p>' + __('Для завершения импорта необходимо создать сопоставления для следующих товаров:') + '</p>' +
|
||||
'<p>' + __('To complete the import, you need to create mappings for the following items:') + '</p>' +
|
||||
'</div>' +
|
||||
'<div style="max-height: 300px; overflow-y: auto;"><table class="table table-bordered">';
|
||||
items_table += '<thead><tr>' +
|
||||
'<th>' + __('Название') + '</th>' +
|
||||
'<th>' + __('Код') + '</th>' +
|
||||
'<th>' + __('Name') + '</th>' +
|
||||
'<th>' + __('Code') + '</th>' +
|
||||
'</tr></thead><tbody>';
|
||||
|
||||
unmatched_items.forEach(function(item) {
|
||||
|
|
@ -1392,7 +1391,7 @@ function show_unmatched_items_dialog(invoice_data, unmatched_items) {
|
|||
|
||||
// Создаем диалог
|
||||
var d = new frappe.ui.Dialog({
|
||||
title: __('Несопоставленные товары'),
|
||||
title: __('Unmapped items'),
|
||||
fields: [
|
||||
{
|
||||
fieldname: 'items_html',
|
||||
|
|
@ -1400,14 +1399,14 @@ function show_unmatched_items_dialog(invoice_data, unmatched_items) {
|
|||
options: items_table
|
||||
}
|
||||
],
|
||||
primary_action_label: __('Перейти к настройкам'),
|
||||
primary_action_label: __('Go to settings'),
|
||||
primary_action: function() {
|
||||
d.hide();
|
||||
|
||||
// Переходим к настройкам E-Taxes
|
||||
frappe.set_route('Form', 'E-Taxes Settings');
|
||||
},
|
||||
secondary_action_label: __('Отмена'),
|
||||
secondary_action_label: __('Cancel'),
|
||||
secondary_action: function() {
|
||||
d.hide();
|
||||
}
|
||||
|
|
@ -1420,22 +1419,22 @@ function show_unmatched_items_dialog(invoice_data, unmatched_items) {
|
|||
function show_unmatched_parties_dialog(invoice_data, unmatched_parties) {
|
||||
// Создаем таблицу с несопоставленными контрагентами
|
||||
var parties_table = '<div class="text-center mb-3">' +
|
||||
'<p>' + __('Для завершения импорта необходимо создать сопоставления для следующих контрагентов:') + '</p>' +
|
||||
'<p>' + __('To complete the import, you need to create mappings for the following partners:') + '</p>' +
|
||||
'</div>' +
|
||||
'<div style="max-height: 300px; overflow-y: auto;"><table class="table table-bordered">';
|
||||
parties_table += '<thead><tr>' +
|
||||
'<th>' + __('Название') + '</th>' +
|
||||
'<th>' + __('ИНН/VOEN') + '</th>' +
|
||||
'<th>' + __('Тип') + '</th>' +
|
||||
'<th>' + __('Name') + '</th>' +
|
||||
'<th>' + __('TIN/VOEN') + '</th>' +
|
||||
'<th>' + __('Type') + '</th>' +
|
||||
'</tr></thead><tbody>';
|
||||
|
||||
unmatched_parties.forEach(function(party) {
|
||||
// Преобразуем тип контрагента для отображения
|
||||
let partyTypeDisplay = '';
|
||||
if (party.type === 'Sender') {
|
||||
partyTypeDisplay = 'Поставщик (Sender)';
|
||||
partyTypeDisplay = 'Supplier (Sender)';
|
||||
} else if (party.type === 'Receiver') {
|
||||
partyTypeDisplay = 'Клиент (Receiver)';
|
||||
partyTypeDisplay = 'Customer (Receiver)';
|
||||
} else {
|
||||
partyTypeDisplay = party.type || '';
|
||||
}
|
||||
|
|
@ -1451,7 +1450,7 @@ function show_unmatched_parties_dialog(invoice_data, unmatched_parties) {
|
|||
|
||||
// Создаем диалог
|
||||
var d = new frappe.ui.Dialog({
|
||||
title: __('Несопоставленные контрагенты'),
|
||||
title: __('Unmapped partners'),
|
||||
fields: [
|
||||
{
|
||||
fieldname: 'parties_html',
|
||||
|
|
@ -1459,14 +1458,14 @@ function show_unmatched_parties_dialog(invoice_data, unmatched_parties) {
|
|||
options: parties_table
|
||||
}
|
||||
],
|
||||
primary_action_label: __('Перейти к настройкам'),
|
||||
primary_action_label: __('Go to settings'),
|
||||
primary_action: function() {
|
||||
d.hide();
|
||||
|
||||
// Переходим к настройкам E-Taxes
|
||||
frappe.set_route('Form', 'E-Taxes Settings');
|
||||
},
|
||||
secondary_action_label: __('Отмена'),
|
||||
secondary_action_label: __('Cancel'),
|
||||
secondary_action: function() {
|
||||
d.hide();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,11 +4,23 @@ frappe.form.link_formatters['E-Taxes Item'] = function(value, doc) {
|
|||
|
||||
frappe.ui.form.on('E-Taxes Settings', {
|
||||
refresh: function(frm) {
|
||||
|
||||
|
||||
frm.fields_dict['item_mappings'].grid.add_custom_button(__('Bulk Edit'), function() {
|
||||
bulk_edit_table(frm, 'item_mappings');
|
||||
});
|
||||
|
||||
// Добавляем кнопку "Bulk Edit" для табличной части party_mappings
|
||||
frm.fields_dict['party_mappings'].grid.add_custom_button(__('Bulk Edit'), function() {
|
||||
bulk_edit_table(frm, 'party_mappings');
|
||||
});
|
||||
|
||||
|
||||
// Кнопка для сопоставления товаров по похожему названию
|
||||
frm.add_custom_button(__('Сопоставить товары по похожему названию'), function() {
|
||||
frm.add_custom_button(__('Match items by similar name'), function() {
|
||||
if(frm.is_dirty()) {
|
||||
frappe.confirm(
|
||||
__('Документ содержит несохраненные изменения. Сохранить перед выполнением операции?'),
|
||||
__('Document contains unsaved changes. Save before performing the operation?'),
|
||||
function() {
|
||||
// Если "Да", сохраняем и выполняем действие
|
||||
frm.save().then(function() {
|
||||
|
|
@ -18,7 +30,7 @@ frappe.ui.form.on('E-Taxes Settings', {
|
|||
function() {
|
||||
// Если "Нет", не делаем ничего
|
||||
frappe.show_alert({
|
||||
message: __('Операция отменена. Сначала сохраните документ.'),
|
||||
message: __('Operation canceled. Please save the document first.'),
|
||||
indicator: 'red'
|
||||
}, 5);
|
||||
}
|
||||
|
|
@ -30,10 +42,10 @@ frappe.ui.form.on('E-Taxes Settings', {
|
|||
|
||||
function match_similar_items() {
|
||||
frappe.confirm(
|
||||
__('Эта операция автоматически сопоставит несопоставленные товары с похожими названиями. Продолжить?'),
|
||||
__('This operation will automatically match unmapped items with similar names. Continue?'),
|
||||
function() {
|
||||
frappe.show_alert({
|
||||
message: __('Выполняется сопоставление товаров...'),
|
||||
message: __('Matching items...'),
|
||||
indicator: 'blue'
|
||||
});
|
||||
|
||||
|
|
@ -42,16 +54,16 @@ frappe.ui.form.on('E-Taxes Settings', {
|
|||
callback: function(r) {
|
||||
if (r.message && r.message.success) {
|
||||
frappe.show_alert({
|
||||
message: __('Сопоставлено {0} из {1} товаров',
|
||||
message: __('Matched {0} of {1} items',
|
||||
[r.message.matched_count, r.message.total_processed]),
|
||||
indicator: 'green'
|
||||
}, 5);
|
||||
frm.reload_doc();
|
||||
} else {
|
||||
frappe.msgprint({
|
||||
title: __('Ошибка'),
|
||||
title: __('Error'),
|
||||
indicator: 'red',
|
||||
message: r.message ? r.message.message : __('Ошибка сопоставления товаров')
|
||||
message: r.message ? r.message.message : __('Error matching items')
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -59,13 +71,13 @@ frappe.ui.form.on('E-Taxes Settings', {
|
|||
}
|
||||
);
|
||||
}
|
||||
}, __('Товары'));
|
||||
}, __('Items'));
|
||||
|
||||
// Кнопка для создания товаров-соответствий
|
||||
frm.add_custom_button(__('Создать товары-соответствия'), function() {
|
||||
frm.add_custom_button(__('Create matching items'), function() {
|
||||
if(frm.is_dirty()) {
|
||||
frappe.confirm(
|
||||
__('Документ содержит несохраненные изменения. Сохранить перед выполнением операции?'),
|
||||
__('Document contains unsaved changes. Save before performing the operation?'),
|
||||
function() {
|
||||
// Если "Да", сохраняем и выполняем действие
|
||||
frm.save().then(function() {
|
||||
|
|
@ -75,7 +87,7 @@ frappe.ui.form.on('E-Taxes Settings', {
|
|||
function() {
|
||||
// Если "Нет", не делаем ничего
|
||||
frappe.show_alert({
|
||||
message: __('Операция отменена. Сначала сохраните документ.'),
|
||||
message: __('Operation canceled. Please save the document first.'),
|
||||
indicator: 'red'
|
||||
}, 5);
|
||||
}
|
||||
|
|
@ -87,11 +99,11 @@ frappe.ui.form.on('E-Taxes Settings', {
|
|||
|
||||
function create_unmapped_items() {
|
||||
frappe.confirm(
|
||||
__('<div style="color: red; font-weight: bold;">ВНИМАНИЕ! Это действие создаст новые товары в системе для всех несопоставленных элементов!</div><p>Это действие необратимо. Вы уверены?</p>'),
|
||||
__('<div style="color: red; font-weight: bold;">WARNING! This action will create new items in the system for all unmapped elements!</div><p>This action is irreversible. Are you sure?</p>'),
|
||||
function() {
|
||||
// Дополнительное подтверждение
|
||||
frappe.confirm(
|
||||
__('Вы действительно уверены, что хотите создать новые товары? Это нельзя будет отменить.'),
|
||||
__('Are you really sure you want to create new items? This cannot be undone.'),
|
||||
function() {
|
||||
frappe.call({
|
||||
method: 'invoice_az.api.create_unmapped_items',
|
||||
|
|
@ -101,15 +113,15 @@ frappe.ui.form.on('E-Taxes Settings', {
|
|||
callback: function(r) {
|
||||
if (r.message && r.message.success) {
|
||||
frappe.show_alert({
|
||||
message: __('Создано {0} новых товаров', [r.message.created_count]),
|
||||
message: __('Created {0} new items', [r.message.created_count]),
|
||||
indicator: 'green'
|
||||
}, 5);
|
||||
frm.reload_doc();
|
||||
} else {
|
||||
frappe.msgprint({
|
||||
title: __('Ошибка'),
|
||||
title: __('Error'),
|
||||
indicator: 'red',
|
||||
message: r.message ? r.message.message : __('Ошибка создания товаров')
|
||||
message: r.message ? r.message.message : __('Error creating items')
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -119,13 +131,13 @@ frappe.ui.form.on('E-Taxes Settings', {
|
|||
}
|
||||
);
|
||||
}
|
||||
}, __('Товары'));
|
||||
}, __('Items'));
|
||||
|
||||
// Кнопка для добавления несопоставленных товаров в таблицу
|
||||
frm.add_custom_button(__('Добавить несопоставленные товары'), function() {
|
||||
frm.add_custom_button(__('Add unmapped items'), function() {
|
||||
if(frm.is_dirty()) {
|
||||
frappe.confirm(
|
||||
__('Документ содержит несохраненные изменения. Сохранить перед выполнением операции?'),
|
||||
__('Document contains unsaved changes. Save before performing the operation?'),
|
||||
function() {
|
||||
// Если "Да", сохраняем и выполняем действие
|
||||
frm.save().then(function() {
|
||||
|
|
@ -135,7 +147,7 @@ frappe.ui.form.on('E-Taxes Settings', {
|
|||
function() {
|
||||
// Если "Нет", не делаем ничего
|
||||
frappe.show_alert({
|
||||
message: __('Операция отменена. Сначала сохраните документ.'),
|
||||
message: __('Operation canceled. Please save the document first.'),
|
||||
indicator: 'red'
|
||||
}, 5);
|
||||
}
|
||||
|
|
@ -170,32 +182,32 @@ frappe.ui.form.on('E-Taxes Settings', {
|
|||
});
|
||||
frm.refresh_field('item_mappings');
|
||||
frappe.show_alert({
|
||||
message: __('Добавлено {0} несопоставленных товаров', [r.message.items.length]),
|
||||
message: __('Added {0} unmapped items', [r.message.items.length]),
|
||||
indicator: 'green'
|
||||
}, 5);
|
||||
} else {
|
||||
frappe.show_alert({
|
||||
message: __('Нет несопоставленных товаров'),
|
||||
message: __('No unmapped items'),
|
||||
indicator: 'blue'
|
||||
}, 5);
|
||||
}
|
||||
} else {
|
||||
frappe.msgprint({
|
||||
title: __('Ошибка'),
|
||||
title: __('Error'),
|
||||
indicator: 'red',
|
||||
message: r.message ? r.message.message : __('Ошибка получения товаров')
|
||||
message: r.message ? r.message.message : __('Error retrieving items')
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}, __('Товары'));
|
||||
}, __('Items'));
|
||||
|
||||
// Аналогичные кнопки для контрагентов
|
||||
frm.add_custom_button(__('Сопоставить контрагентов по похожему названию'), function() {
|
||||
frm.add_custom_button(__('Match partners by similar name'), function() {
|
||||
if(frm.is_dirty()) {
|
||||
frappe.confirm(
|
||||
__('Документ содержит несохраненные изменения. Сохранить перед выполнением операции?'),
|
||||
__('Document contains unsaved changes. Save before performing the operation?'),
|
||||
function() {
|
||||
// Если "Да", сохраняем и выполняем действие
|
||||
frm.save().then(function() {
|
||||
|
|
@ -205,7 +217,7 @@ frappe.ui.form.on('E-Taxes Settings', {
|
|||
function() {
|
||||
// Если "Нет", не делаем ничего
|
||||
frappe.show_alert({
|
||||
message: __('Операция отменена. Сначала сохраните документ.'),
|
||||
message: __('Operation canceled. Please save the document first.'),
|
||||
indicator: 'red'
|
||||
}, 5);
|
||||
}
|
||||
|
|
@ -217,10 +229,10 @@ frappe.ui.form.on('E-Taxes Settings', {
|
|||
|
||||
function match_similar_parties() {
|
||||
frappe.confirm(
|
||||
__('Эта операция автоматически сопоставит несопоставленных контрагентов с похожими названиями. Продолжить?'),
|
||||
__('This operation will automatically match unmapped partners with similar names. Continue?'),
|
||||
function() {
|
||||
frappe.show_alert({
|
||||
message: __('Выполняется сопоставление контрагентов...'),
|
||||
message: __('Matching partners...'),
|
||||
indicator: 'blue'
|
||||
});
|
||||
|
||||
|
|
@ -229,16 +241,16 @@ frappe.ui.form.on('E-Taxes Settings', {
|
|||
callback: function(r) {
|
||||
if (r.message && r.message.success) {
|
||||
frappe.show_alert({
|
||||
message: __('Сопоставлено {0} из {1} контрагентов',
|
||||
message: __('Matched {0} of {1} partners',
|
||||
[r.message.matched_count, r.message.total_processed]),
|
||||
indicator: 'green'
|
||||
}, 5);
|
||||
frm.reload_doc();
|
||||
} else {
|
||||
frappe.msgprint({
|
||||
title: __('Ошибка'),
|
||||
title: __('Error'),
|
||||
indicator: 'red',
|
||||
message: r.message ? r.message.message : __('Ошибка сопоставления контрагентов')
|
||||
message: r.message ? r.message.message : __('Error matching partners')
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -246,12 +258,12 @@ frappe.ui.form.on('E-Taxes Settings', {
|
|||
}
|
||||
);
|
||||
}
|
||||
}, __('Контрагенты'));
|
||||
}, __('Partners'));
|
||||
|
||||
frm.add_custom_button(__('Создать контрагенты-соответствия'), function() {
|
||||
frm.add_custom_button(__('Create matching partners'), function() {
|
||||
if(frm.is_dirty()) {
|
||||
frappe.confirm(
|
||||
__('Документ содержит несохраненные изменения. Сохранить перед выполнением операции?'),
|
||||
__('Document contains unsaved changes. Save before performing the operation?'),
|
||||
function() {
|
||||
// Если "Да", сохраняем и выполняем действие
|
||||
frm.save().then(function() {
|
||||
|
|
@ -261,7 +273,7 @@ frappe.ui.form.on('E-Taxes Settings', {
|
|||
function() {
|
||||
// Если "Нет", не делаем ничего
|
||||
frappe.show_alert({
|
||||
message: __('Операция отменена. Сначала сохраните документ.'),
|
||||
message: __('Operation canceled. Please save the document first.'),
|
||||
indicator: 'red'
|
||||
}, 5);
|
||||
}
|
||||
|
|
@ -273,11 +285,11 @@ frappe.ui.form.on('E-Taxes Settings', {
|
|||
|
||||
function create_unmapped_parties() {
|
||||
frappe.confirm(
|
||||
__('<div style="color: red; font-weight: bold;">ВНИМАНИЕ! Это действие создаст новых контрагентов в системе для всех несопоставленных элементов!</div><p>Это действие необратимо. Вы уверены?</p>'),
|
||||
__('<div style="color: red; font-weight: bold;">WARNING! This action will create new partners in the system for all unmapped elements!</div><p>This action is irreversible. Are you sure?</p>'),
|
||||
function() {
|
||||
// Дополнительное подтверждение
|
||||
frappe.confirm(
|
||||
__('Вы действительно уверены, что хотите создать новых контрагентов? Это нельзя будет отменить.'),
|
||||
__('Are you really sure you want to create new partners? This cannot be undone.'),
|
||||
function() {
|
||||
frappe.call({
|
||||
method: 'invoice_az.api.create_unmapped_parties',
|
||||
|
|
@ -287,15 +299,15 @@ frappe.ui.form.on('E-Taxes Settings', {
|
|||
callback: function(r) {
|
||||
if (r.message && r.message.success) {
|
||||
frappe.show_alert({
|
||||
message: __('Создано {0} новых контрагентов', [r.message.created_count]),
|
||||
message: __('Created {0} new partners', [r.message.created_count]),
|
||||
indicator: 'green'
|
||||
}, 5);
|
||||
frm.reload_doc();
|
||||
} else {
|
||||
frappe.msgprint({
|
||||
title: __('Ошибка'),
|
||||
title: __('Error'),
|
||||
indicator: 'red',
|
||||
message: r.message ? r.message.message : __('Ошибка создания контрагентов')
|
||||
message: r.message ? r.message.message : __('Error creating partners')
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -305,12 +317,12 @@ frappe.ui.form.on('E-Taxes Settings', {
|
|||
}
|
||||
);
|
||||
}
|
||||
}, __('Контрагенты'));
|
||||
}, __('Partners'));
|
||||
|
||||
frm.add_custom_button(__('Добавить несопоставленных контрагентов'), function() {
|
||||
frm.add_custom_button(__('Add unmapped partners'), function() {
|
||||
if(frm.is_dirty()) {
|
||||
frappe.confirm(
|
||||
__('Документ содержит несохраненные изменения. Сохранить перед выполнением операции?'),
|
||||
__('Document contains unsaved changes. Save before performing the operation?'),
|
||||
function() {
|
||||
// Если "Да", сохраняем и выполняем действие
|
||||
frm.save().then(function() {
|
||||
|
|
@ -320,7 +332,7 @@ frappe.ui.form.on('E-Taxes Settings', {
|
|||
function() {
|
||||
// Если "Нет", не делаем ничего
|
||||
frappe.show_alert({
|
||||
message: __('Операция отменена. Сначала сохраните документ.'),
|
||||
message: __('Operation canceled. Please save the document first.'),
|
||||
indicator: 'red'
|
||||
}, 5);
|
||||
}
|
||||
|
|
@ -366,25 +378,166 @@ frappe.ui.form.on('E-Taxes Settings', {
|
|||
});
|
||||
frm.refresh_field('party_mappings');
|
||||
frappe.show_alert({
|
||||
message: __('Добавлено {0} несопоставленных контрагентов', [r.message.parties.length]),
|
||||
message: __('Added {0} unmapped partners', [r.message.parties.length]),
|
||||
indicator: 'green'
|
||||
}, 5);
|
||||
} else {
|
||||
frappe.show_alert({
|
||||
message: __('Нет несопоставленных контрагентов'),
|
||||
message: __('No unmapped partners'),
|
||||
indicator: 'blue'
|
||||
}, 5);
|
||||
}
|
||||
} else {
|
||||
frappe.msgprint({
|
||||
title: __('Ошибка'),
|
||||
title: __('Error'),
|
||||
indicator: 'red',
|
||||
message: r.message ? r.message.message : __('Ошибка получения контрагентов')
|
||||
message: r.message ? r.message.message : __('Error retrieving partners')
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}, __('Контрагенты'));
|
||||
}, __('Partners'));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function bulk_edit_table(frm, table_field) {
|
||||
// Получаем выбранные строки
|
||||
const selected_rows = frm.fields_dict[table_field].grid.get_selected_children();
|
||||
|
||||
if (selected_rows.length === 0) {
|
||||
frappe.msgprint(__("No rows selected. Please select rows to edit."));
|
||||
return;
|
||||
}
|
||||
|
||||
// Получаем метаданные дочернего doctype
|
||||
const child_doctype = selected_rows[0].doctype;
|
||||
const meta = frappe.get_meta(child_doctype);
|
||||
|
||||
// Формируем список полей для редактирования
|
||||
const field_options = [];
|
||||
const field_map = {};
|
||||
|
||||
meta.fields.forEach(df => {
|
||||
// Исключаем служебные поля и поля только для чтения
|
||||
if (!['Section Break', 'Column Break', 'Tab Break', 'HTML', 'Table', 'Button'].includes(df.fieldtype) &&
|
||||
!df.read_only && !df.hidden) {
|
||||
field_options.push({
|
||||
label: __(df.label || frappe.model.unscrub(df.fieldname)),
|
||||
value: df.fieldname
|
||||
});
|
||||
field_map[df.fieldname] = df;
|
||||
}
|
||||
});
|
||||
|
||||
// Создаем диалог
|
||||
const d = new frappe.ui.Dialog({
|
||||
title: __("Bulk Edit Selected Rows"),
|
||||
fields: [
|
||||
{
|
||||
label: __("Field to Edit"),
|
||||
fieldname: "field_to_edit",
|
||||
fieldtype: "Select",
|
||||
options: field_options,
|
||||
reqd: 1
|
||||
},
|
||||
{
|
||||
fieldname: "value_section",
|
||||
fieldtype: "Section Break",
|
||||
label: __("New Value"),
|
||||
collapsible: 0,
|
||||
hidden: 1
|
||||
},
|
||||
{
|
||||
fieldname: "value_container",
|
||||
fieldtype: "HTML",
|
||||
options: '<div id="value_field_container"></div>'
|
||||
}
|
||||
],
|
||||
primary_action_label: __("Apply"),
|
||||
primary_action: function() {
|
||||
// Получаем выбранное поле и значение
|
||||
const field_name = d.get_value("field_to_edit");
|
||||
|
||||
// Если не выбрано поле
|
||||
if (!field_name || !d.new_value_field) {
|
||||
frappe.msgprint(__("Please select a field and enter a value."));
|
||||
return;
|
||||
}
|
||||
|
||||
// Получаем новое значение из динамического поля
|
||||
const new_value = d.new_value_field.get_value();
|
||||
|
||||
// Проверяем, что значение введено
|
||||
if (new_value === undefined || new_value === null || new_value === "") {
|
||||
frappe.msgprint(__("Please enter a new value."));
|
||||
return;
|
||||
}
|
||||
|
||||
// Применяем изменения
|
||||
frappe.show_alert({
|
||||
message: __("Updating rows..."),
|
||||
indicator: 'blue'
|
||||
});
|
||||
|
||||
let count = 0;
|
||||
const total = selected_rows.length;
|
||||
const promises = [];
|
||||
|
||||
selected_rows.forEach(row => {
|
||||
promises.push(
|
||||
frappe.model.set_value(row.doctype, row.name, field_name, new_value)
|
||||
.then(() => {
|
||||
count++;
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
Promise.all(promises).then(() => {
|
||||
frm.refresh_field(table_field);
|
||||
frappe.show_alert({
|
||||
message: __("Updated {0} rows", [count]),
|
||||
indicator: 'green'
|
||||
}, 5);
|
||||
|
||||
d.hide();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Обработчик изменения поля
|
||||
d.fields_dict.field_to_edit.$input.on('change', function() {
|
||||
const field_name = d.get_value("field_to_edit");
|
||||
const field_def = field_map[field_name];
|
||||
|
||||
if (!field_def) return;
|
||||
|
||||
// Показываем секцию для нового значения
|
||||
d.set_df_property("value_section", "hidden", 0);
|
||||
|
||||
// Удаляем предыдущее поле, если оно было
|
||||
if (d.new_value_field) {
|
||||
d.new_value_field.$wrapper.remove();
|
||||
delete d.new_value_field;
|
||||
}
|
||||
|
||||
// Создаем новое поле нужного типа
|
||||
const value_container = d.fields_dict.value_container.$wrapper.find("#value_field_container");
|
||||
|
||||
d.new_value_field = frappe.ui.form.make_control({
|
||||
df: {
|
||||
label: __("New Value for {0}", [__(field_def.label || frappe.model.unscrub(field_def.fieldname))]),
|
||||
fieldname: "new_value",
|
||||
fieldtype: field_def.fieldtype,
|
||||
options: field_def.options || "",
|
||||
reqd: 1
|
||||
},
|
||||
parent: value_container,
|
||||
render_input: true
|
||||
});
|
||||
|
||||
d.new_value_field.refresh();
|
||||
});
|
||||
|
||||
d.show();
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue