fix(e-taxes): make document-load dialogs fit the screen
The "select records to import" dialogs (VAT operations, sales/purchase invoices, AMAS employees) wasted vertical space: a fixed 500px table plus a context alert pinned to the bottom forced scrolling to reach the content and the buttons. Rework them to the journal_entry pattern: the records table is now the single scroll area sized to the viewport (max-height: calc(100vh - 360px)) with a sticky header, and the top count alert + bottom context alert are merged into one compact header row. Affects journal_entry, sales_order, purchase_order, sales_invoice and employee (AMAS) selection dialogs. No logic/handler changes. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
610b98ca69
commit
c6e2101c26
|
|
@ -529,17 +529,19 @@ function show_employee_selection(listview, asan_login_name, organization_name, e
|
||||||
const existing_count = employees.length - new_count;
|
const existing_count = employees.length - new_count;
|
||||||
|
|
||||||
// Build table (e-taxes style)
|
// Build table (e-taxes style)
|
||||||
let invoiceTable = '<div style="max-height: 500px; overflow-y: auto;">' +
|
// Таблица сотрудников — единственная прокручиваемая область. Высота привязана
|
||||||
'<table class="table table-bordered amas-employees-table" style="width: 100%; table-layout: fixed;">' +
|
// к вьюпорту (calc), чтобы модал целиком помещался в экран. Шапка «липкая».
|
||||||
'<thead><tr>' +
|
let invoiceTable = '<div class="amas-employees-scroll" style="max-height: calc(100vh - 360px); min-height: 220px; overflow-y: auto; border: 1px solid var(--border-color); border-radius: 6px;">' +
|
||||||
'<th style="width: 4%;"><input type="checkbox" class="select-all-employees"></th>' +
|
'<table class="table table-bordered amas-employees-table" style="width: 100%; table-layout: fixed; margin-bottom: 0;">' +
|
||||||
'<th style="width: 20%;">' + __('Full Name') + '</th>' +
|
'<thead style="position: sticky; top: 0; z-index: 1;"><tr>' +
|
||||||
'<th style="width: 10%;">' + __('FIN') + '</th>' +
|
'<th style="width: 4%; background: var(--control-bg, var(--bg-color));"><input type="checkbox" class="select-all-employees"></th>' +
|
||||||
'<th style="width: 20%;">' + __('Position') + '</th>' +
|
'<th style="width: 20%; background: var(--control-bg, var(--bg-color));">' + __('Full Name') + '</th>' +
|
||||||
'<th style="width: 8%;">' + __('Salary') + '</th>' +
|
'<th style="width: 10%; background: var(--control-bg, var(--bg-color));">' + __('FIN') + '</th>' +
|
||||||
'<th style="width: 12%;">' + __('Status') + '</th>' +
|
'<th style="width: 20%; background: var(--control-bg, var(--bg-color));">' + __('Position') + '</th>' +
|
||||||
'<th style="width: 10%;">' + __('Begin Date') + '</th>' +
|
'<th style="width: 8%; background: var(--control-bg, var(--bg-color));">' + __('Salary') + '</th>' +
|
||||||
'<th style="width: 16%;">' + __('In System') + '</th>' +
|
'<th style="width: 12%; background: var(--control-bg, var(--bg-color));">' + __('Status') + '</th>' +
|
||||||
|
'<th style="width: 10%; background: var(--control-bg, var(--bg-color));">' + __('Begin Date') + '</th>' +
|
||||||
|
'<th style="width: 16%; background: var(--control-bg, var(--bg-color));">' + __('In System') + '</th>' +
|
||||||
'</tr></thead><tbody>';
|
'</tr></thead><tbody>';
|
||||||
|
|
||||||
employees.forEach(function(emp, idx) {
|
employees.forEach(function(emp, idx) {
|
||||||
|
|
@ -563,9 +565,19 @@ function show_employee_selection(listview, asan_login_name, organization_name, e
|
||||||
|
|
||||||
invoiceTable += '</tbody></table></div>';
|
invoiceTable += '</tbody></table></div>';
|
||||||
|
|
||||||
const infoMessage = '<div class="alert alert-info">' +
|
// Компактная шапка: счётчик сотрудников слева + организация справа в одну
|
||||||
__('Employees found: ') + employees.length +
|
// строку. Заменяет alert со счётчиком и убирает пустые Section Break-лейблы.
|
||||||
|
const headerHtml =
|
||||||
|
'<div style="display:flex; justify-content:space-between; align-items:center; gap:12px; flex-wrap:wrap; margin-bottom:8px;">' +
|
||||||
|
'<span class="indicator-pill blue" style="font-size:13px;">' +
|
||||||
|
__('Employees found: ') + '<strong>' + employees.length + '</strong>' +
|
||||||
' (' + __('New') + ': ' + new_count + ', ' + __('Already in system') + ': ' + existing_count + ')' +
|
' (' + __('New') + ': ' + new_count + ', ' + __('Already in system') + ': ' + existing_count + ')' +
|
||||||
|
'</span>' +
|
||||||
|
(organization_name
|
||||||
|
? '<span style="color: var(--text-muted);">' +
|
||||||
|
__('Organization: ') + '<strong>' + frappe.utils.escape_html(organization_name) + '</strong>' +
|
||||||
|
'</span>'
|
||||||
|
: '') +
|
||||||
'</div>';
|
'</div>';
|
||||||
|
|
||||||
const default_company = frappe.defaults.get_user_default('Company') || frappe.defaults.get_global_default('company');
|
const default_company = frappe.defaults.get_user_default('Company') || frappe.defaults.get_global_default('company');
|
||||||
|
|
@ -575,9 +587,9 @@ function show_employee_selection(listview, asan_login_name, organization_name, e
|
||||||
size: 'large',
|
size: 'large',
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
fieldname: 'settings_section',
|
fieldname: 'header_html',
|
||||||
fieldtype: 'Section Break',
|
fieldtype: 'HTML',
|
||||||
label: __('Settings')
|
options: headerHtml
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fieldname: 'create_designation',
|
fieldname: 'create_designation',
|
||||||
|
|
@ -585,16 +597,6 @@ function show_employee_selection(listview, asan_login_name, organization_name, e
|
||||||
label: __('Create Designation if not found'),
|
label: __('Create Designation if not found'),
|
||||||
default: 1
|
default: 1
|
||||||
},
|
},
|
||||||
{
|
|
||||||
fieldname: 'employees_section',
|
|
||||||
fieldtype: 'Section Break',
|
|
||||||
label: __('Employees')
|
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'info_html',
|
|
||||||
fieldtype: 'HTML',
|
|
||||||
options: infoMessage
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
fieldname: 'employees_html',
|
fieldname: 'employees_html',
|
||||||
fieldtype: 'HTML',
|
fieldtype: 'HTML',
|
||||||
|
|
|
||||||
|
|
@ -1142,17 +1142,21 @@ VATETaxes.import = {
|
||||||
// Показать диалог выбора операций
|
// Показать диалог выбора операций
|
||||||
showOperationSelection: function(operations, token, company, createAsDraft = 0) {
|
showOperationSelection: function(operations, token, company, createAsDraft = 0) {
|
||||||
VATETaxes.dialogs.hide();
|
VATETaxes.dialogs.hide();
|
||||||
let operationTable = '<div style="max-height: 500px; overflow-y: auto;"><table class="table table-bordered vat-operations-table" style="width: 100%; table-layout: fixed;">';
|
// Таблица операций — единственная прокручиваемая область. Высота привязана к
|
||||||
operationTable += '<thead><tr>' +
|
// вьюпорту (calc), чтобы модал целиком помещался в экран без внешнего скролла.
|
||||||
'<th style="width: 3%;"><input type="checkbox" class="select-all-operations"></th>' +
|
// Шапка таблицы «липкая» (sticky), чтобы заголовки колонок оставались видны
|
||||||
'<th style="width: 8%;">' + __('Date') + '</th>' +
|
// при прокрутке списка.
|
||||||
'<th style="width: 9%;">' + __('TIN') + '</th>' +
|
let operationTable = '<div class="vat-operations-scroll" style="max-height: calc(100vh - 360px); min-height: 220px; overflow-y: auto; border: 1px solid var(--border-color); border-radius: 6px;"><table class="table table-bordered vat-operations-table" style="width: 100%; table-layout: fixed; margin-bottom: 0;">';
|
||||||
'<th style="width: 15%;">' + __('Name') + '</th>' +
|
operationTable += '<thead style="position: sticky; top: 0; z-index: 1;"><tr style="background: var(--control-bg, var(--bg-color));">' +
|
||||||
'<th style="width: 15%;">' + __('Operation Type') + '</th>' +
|
'<th style="width: 3%; background: var(--control-bg, var(--bg-color));"><input type="checkbox" class="select-all-operations"></th>' +
|
||||||
'<th style="width: 9%;">' + __('Classification Code') + '</th>' +
|
'<th style="width: 8%; background: var(--control-bg, var(--bg-color));">' + __('Date') + '</th>' +
|
||||||
'<th style="width: 17%;">' + __('Explanation') + '</th>' +
|
'<th style="width: 9%; background: var(--control-bg, var(--bg-color));">' + __('TIN') + '</th>' +
|
||||||
'<th style="width: 12%;">' + __('Income') + '</th>' +
|
'<th style="width: 15%; background: var(--control-bg, var(--bg-color));">' + __('Name') + '</th>' +
|
||||||
'<th style="width: 12%;">' + __('Expense') + '</th>' +
|
'<th style="width: 15%; background: var(--control-bg, var(--bg-color));">' + __('Operation Type') + '</th>' +
|
||||||
|
'<th style="width: 9%; background: var(--control-bg, var(--bg-color));">' + __('Classification Code') + '</th>' +
|
||||||
|
'<th style="width: 17%; background: var(--control-bg, var(--bg-color));">' + __('Explanation') + '</th>' +
|
||||||
|
'<th style="width: 12%; background: var(--control-bg, var(--bg-color));">' + __('Income') + '</th>' +
|
||||||
|
'<th style="width: 12%; background: var(--control-bg, var(--bg-color));">' + __('Expense') + '</th>' +
|
||||||
'</tr></thead><tbody>';
|
'</tr></thead><tbody>';
|
||||||
|
|
||||||
operations.forEach(function(operation) {
|
operations.forEach(function(operation) {
|
||||||
|
|
@ -1188,8 +1192,17 @@ VATETaxes.import = {
|
||||||
|
|
||||||
operationTable += '</tbody></table></div>';
|
operationTable += '</tbody></table></div>';
|
||||||
|
|
||||||
const infoMessage = '<div class="alert alert-info">' +
|
// Компактная шапка: количество операций + компания в одной строке.
|
||||||
__('New VAT operations found: ') + operations.length +
|
// Заменяет два отдельных alert'а (верхний со счётчиком и нижний с компанией,
|
||||||
|
// который раньше уезжал под таблицу и требовал скролла).
|
||||||
|
const headerHtml =
|
||||||
|
'<div style="display:flex; justify-content:space-between; align-items:center; gap:12px; flex-wrap:wrap; margin-bottom:8px;">' +
|
||||||
|
'<span class="indicator-pill blue" style="font-size:13px;">' +
|
||||||
|
__('New VAT operations found: ') + '<strong>' + operations.length + '</strong>' +
|
||||||
|
'</span>' +
|
||||||
|
'<span style="color: var(--text-muted);">' +
|
||||||
|
__('Company: ') + '<strong>' + frappe.utils.escape_html(company) + '</strong>' +
|
||||||
|
'</span>' +
|
||||||
'</div>';
|
'</div>';
|
||||||
|
|
||||||
const d = new frappe.ui.Dialog({
|
const d = new frappe.ui.Dialog({
|
||||||
|
|
@ -1197,14 +1210,9 @@ VATETaxes.import = {
|
||||||
size: 'large',
|
size: 'large',
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
fieldname: 'info_html',
|
fieldname: 'header_html',
|
||||||
fieldtype: 'HTML',
|
fieldtype: 'HTML',
|
||||||
options: infoMessage
|
options: headerHtml
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'settings_section',
|
|
||||||
fieldtype: 'Section Break',
|
|
||||||
label: __('Import Settings')
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fieldname: 'create_as_draft',
|
fieldname: 'create_as_draft',
|
||||||
|
|
@ -1213,6 +1221,10 @@ VATETaxes.import = {
|
||||||
default: createAsDraft,
|
default: createAsDraft,
|
||||||
description: __('If checked, Journal Entries will be created in Draft status instead of being submitted automatically')
|
description: __('If checked, Journal Entries will be created in Draft status instead of being submitted automatically')
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
fieldname: 'settings_col_break',
|
||||||
|
fieldtype: 'Column Break'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
fieldname: 'auto_create_customers',
|
fieldname: 'auto_create_customers',
|
||||||
fieldtype: 'Check',
|
fieldtype: 'Check',
|
||||||
|
|
@ -1222,19 +1234,12 @@ VATETaxes.import = {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fieldname: 'operations_section',
|
fieldname: 'operations_section',
|
||||||
fieldtype: 'Section Break',
|
fieldtype: 'Section Break'
|
||||||
label: __('Operations')
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fieldname: 'operations_html',
|
fieldname: 'operations_html',
|
||||||
fieldtype: 'HTML',
|
fieldtype: 'HTML',
|
||||||
options: operationTable
|
options: operationTable
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'company_display',
|
|
||||||
fieldtype: 'HTML',
|
|
||||||
options: '<div class="row"><div class="col-xs-12"><div class="alert alert-info">' +
|
|
||||||
__('Selected company: ') + '<strong>' + company + '</strong></div></div></div>'
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
primary_action_label: __('Load Selected'),
|
primary_action_label: __('Load Selected'),
|
||||||
|
|
|
||||||
|
|
@ -1094,13 +1094,13 @@ ETaxes.import = {
|
||||||
|
|
||||||
// Показать диалог выбора инвойсов
|
// Показать диалог выбора инвойсов
|
||||||
showInvoiceSelection: function(invoices, token, warehouse) {
|
showInvoiceSelection: function(invoices, token, warehouse) {
|
||||||
let invoiceTable = '<div style="max-height: 500px; overflow-y: auto;"><table class="table table-bordered etaxes-invoices-table" style="width: 100%; table-layout: fixed;">';
|
let invoiceTable = '<div class="etaxes-purchase-scroll" style="max-height: calc(100vh - 360px); min-height: 220px; overflow-y: auto; border: 1px solid var(--border-color); border-radius: 6px;"><table class="table table-bordered etaxes-invoices-table" style="width: 100%; table-layout: fixed; margin-bottom: 0;">';
|
||||||
invoiceTable += '<thead><tr>' +
|
invoiceTable += '<thead style="position: sticky; top: 0; z-index: 1;"><tr>' +
|
||||||
'<th style="width: 6%;"><input type="checkbox" class="select-all-invoices"></th>' +
|
'<th style="width: 6%; background: var(--control-bg, var(--bg-color));"><input type="checkbox" class="select-all-invoices"></th>' +
|
||||||
'<th style="width: 24%;">' + __('Number') + '</th>' +
|
'<th style="width: 24%; background: var(--control-bg, var(--bg-color));">' + __('Number') + '</th>' +
|
||||||
'<th style="width: 16%;">' + __('Date') + '</th>' +
|
'<th style="width: 16%; background: var(--control-bg, var(--bg-color));">' + __('Date') + '</th>' +
|
||||||
'<th style="width: 38%;">' + __('Supplier') + '</th>' +
|
'<th style="width: 38%; background: var(--control-bg, var(--bg-color));">' + __('Supplier') + '</th>' +
|
||||||
'<th style="width: 16%;">' + __('Amount') + '</th>' +
|
'<th style="width: 16%; background: var(--control-bg, var(--bg-color));">' + __('Amount') + '</th>' +
|
||||||
'</tr></thead><tbody>';
|
'</tr></thead><tbody>';
|
||||||
|
|
||||||
invoices.forEach(function(invoice) {
|
invoices.forEach(function(invoice) {
|
||||||
|
|
@ -1127,8 +1127,14 @@ ETaxes.import = {
|
||||||
|
|
||||||
invoiceTable += '</tbody></table></div>';
|
invoiceTable += '</tbody></table></div>';
|
||||||
|
|
||||||
const infoMessage = '<div class="alert alert-info">' +
|
const infoMessage =
|
||||||
__('New invoices found: ') + invoices.length +
|
'<div style="display:flex; justify-content:space-between; align-items:center; gap:12px; flex-wrap:wrap; margin-bottom:8px;">' +
|
||||||
|
'<span class="indicator-pill blue" style="font-size:13px;">' +
|
||||||
|
__('New invoices found: ') + '<strong>' + invoices.length + '</strong>' +
|
||||||
|
'</span>' +
|
||||||
|
'<span style="color: var(--text-muted);">' +
|
||||||
|
__('Selected warehouse: ') + '<strong>' + frappe.utils.escape_html(warehouse) + '</strong>' +
|
||||||
|
'</span>' +
|
||||||
'</div>';
|
'</div>';
|
||||||
|
|
||||||
const d = new frappe.ui.Dialog({
|
const d = new frappe.ui.Dialog({
|
||||||
|
|
@ -1144,12 +1150,6 @@ ETaxes.import = {
|
||||||
fieldname: 'invoices_html',
|
fieldname: 'invoices_html',
|
||||||
fieldtype: 'HTML',
|
fieldtype: 'HTML',
|
||||||
options: invoiceTable
|
options: invoiceTable
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'warehouse_display',
|
|
||||||
fieldtype: 'HTML',
|
|
||||||
options: '<div class="row"><div class="col-xs-12"><div class="alert alert-info">' +
|
|
||||||
__('Selected warehouse: ') + '<strong>' + warehouse + '</strong></div></div></div>'
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
primary_action_label: __('Load selected'),
|
primary_action_label: __('Load selected'),
|
||||||
|
|
|
||||||
|
|
@ -1113,13 +1113,13 @@ ETaxes.import = {
|
||||||
|
|
||||||
// Показать диалог выбора инвойсов
|
// Показать диалог выбора инвойсов
|
||||||
showInvoiceSelection: function(invoices, token, warehouse) {
|
showInvoiceSelection: function(invoices, token, warehouse) {
|
||||||
let invoiceTable = '<div style="max-height: 500px; overflow-y: auto;"><table class="table table-bordered etaxes-invoices-table" style="width: 100%; table-layout: fixed;">';
|
let invoiceTable = '<div class="etaxes-sales-inv-scroll" style="max-height: calc(100vh - 360px); min-height: 220px; overflow-y: auto; border: 1px solid var(--border-color); border-radius: 6px;"><table class="table table-bordered etaxes-invoices-table" style="width: 100%; table-layout: fixed; margin-bottom: 0;">';
|
||||||
invoiceTable += '<thead><tr>' +
|
invoiceTable += '<thead style="position: sticky; top: 0; z-index: 1;"><tr>' +
|
||||||
'<th style="width: 6%;"><input type="checkbox" class="select-all-invoices"></th>' +
|
'<th style="width: 6%; background: var(--control-bg, var(--bg-color));"><input type="checkbox" class="select-all-invoices"></th>' +
|
||||||
'<th style="width: 24%;">' + __('Number') + '</th>' +
|
'<th style="width: 24%; background: var(--control-bg, var(--bg-color));">' + __('Number') + '</th>' +
|
||||||
'<th style="width: 16%;">' + __('Date') + '</th>' +
|
'<th style="width: 16%; background: var(--control-bg, var(--bg-color));">' + __('Date') + '</th>' +
|
||||||
'<th style="width: 38%;">' + __('Supplier') + '</th>' +
|
'<th style="width: 38%; background: var(--control-bg, var(--bg-color));">' + __('Supplier') + '</th>' +
|
||||||
'<th style="width: 16%;">' + __('Amount') + '</th>' +
|
'<th style="width: 16%; background: var(--control-bg, var(--bg-color));">' + __('Amount') + '</th>' +
|
||||||
'</tr></thead><tbody>';
|
'</tr></thead><tbody>';
|
||||||
|
|
||||||
invoices.forEach(function(invoice) {
|
invoices.forEach(function(invoice) {
|
||||||
|
|
@ -1146,8 +1146,14 @@ ETaxes.import = {
|
||||||
|
|
||||||
invoiceTable += '</tbody></table></div>';
|
invoiceTable += '</tbody></table></div>';
|
||||||
|
|
||||||
const infoMessage = '<div class="alert alert-info">' +
|
const headerHtml =
|
||||||
__('New invoices found: ') + invoices.length +
|
'<div style="display:flex; justify-content:space-between; align-items:center; gap:12px; flex-wrap:wrap; margin-bottom:8px;">' +
|
||||||
|
'<span class="indicator-pill blue" style="font-size:13px;">' +
|
||||||
|
__('New invoices found: ') + '<strong>' + invoices.length + '</strong>' +
|
||||||
|
'</span>' +
|
||||||
|
'<span style="color: var(--text-muted);">' +
|
||||||
|
__('Selected warehouse: ') + '<strong>' + frappe.utils.escape_html(warehouse) + '</strong>' +
|
||||||
|
'</span>' +
|
||||||
'</div>';
|
'</div>';
|
||||||
|
|
||||||
const d = new frappe.ui.Dialog({
|
const d = new frappe.ui.Dialog({
|
||||||
|
|
@ -1155,20 +1161,14 @@ ETaxes.import = {
|
||||||
size: 'large',
|
size: 'large',
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
fieldname: 'info_html',
|
fieldname: 'header_html',
|
||||||
fieldtype: 'HTML',
|
fieldtype: 'HTML',
|
||||||
options: infoMessage
|
options: headerHtml
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fieldname: 'invoices_html',
|
fieldname: 'invoices_html',
|
||||||
fieldtype: 'HTML',
|
fieldtype: 'HTML',
|
||||||
options: invoiceTable
|
options: invoiceTable
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'warehouse_display',
|
|
||||||
fieldtype: 'HTML',
|
|
||||||
options: '<div class="row"><div class="col-xs-12"><div class="alert alert-info">' +
|
|
||||||
__('Selected warehouse: ') + '<strong>' + warehouse + '</strong></div></div></div>'
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
primary_action_label: __('Load selected'),
|
primary_action_label: __('Load selected'),
|
||||||
|
|
|
||||||
|
|
@ -1111,13 +1111,13 @@ SalesETaxes.import = {
|
||||||
// Показать диалог выбора инвойсов
|
// Показать диалог выбора инвойсов
|
||||||
showInvoiceSelection: function(invoices, token, warehouse) {
|
showInvoiceSelection: function(invoices, token, warehouse) {
|
||||||
SalesETaxes.dialogs.hide();
|
SalesETaxes.dialogs.hide();
|
||||||
let invoiceTable = '<div style="max-height: 500px; overflow-y: auto;"><table class="table table-bordered etaxes-sales-invoices-table" style="width: 100%; table-layout: fixed;">';
|
let invoiceTable = '<div class="etaxes-sales-scroll" style="max-height: calc(100vh - 360px); min-height: 220px; overflow-y: auto; border: 1px solid var(--border-color); border-radius: 6px;"><table class="table table-bordered etaxes-sales-invoices-table" style="width: 100%; table-layout: fixed; margin-bottom: 0;">';
|
||||||
invoiceTable += '<thead><tr>' +
|
invoiceTable += '<thead style="position: sticky; top: 0; z-index: 1;"><tr>' +
|
||||||
'<th style="width: 6%;"><input type="checkbox" class="select-all-sales-invoices"></th>' +
|
'<th style="width: 6%; background: var(--control-bg, var(--bg-color));"><input type="checkbox" class="select-all-sales-invoices"></th>' +
|
||||||
'<th style="width: 24%;">' + __('Number') + '</th>' +
|
'<th style="width: 24%; background: var(--control-bg, var(--bg-color));">' + __('Number') + '</th>' +
|
||||||
'<th style="width: 16%;">' + __('Date') + '</th>' +
|
'<th style="width: 16%; background: var(--control-bg, var(--bg-color));">' + __('Date') + '</th>' +
|
||||||
'<th style="width: 38%;">' + __('Customer') + '</th>' +
|
'<th style="width: 38%; background: var(--control-bg, var(--bg-color));">' + __('Customer') + '</th>' +
|
||||||
'<th style="width: 16%;">' + __('Amount') + '</th>' +
|
'<th style="width: 16%; background: var(--control-bg, var(--bg-color));">' + __('Amount') + '</th>' +
|
||||||
'</tr></thead><tbody>';
|
'</tr></thead><tbody>';
|
||||||
|
|
||||||
invoices.forEach(function(invoice) {
|
invoices.forEach(function(invoice) {
|
||||||
|
|
@ -1144,8 +1144,17 @@ SalesETaxes.import = {
|
||||||
|
|
||||||
invoiceTable += '</tbody></table></div>';
|
invoiceTable += '</tbody></table></div>';
|
||||||
|
|
||||||
const infoMessage = '<div class="alert alert-info">' +
|
// Компактная шапка: количество инвойсов + склад в одной строке.
|
||||||
__('Sales invoices found: ') + invoices.length +
|
// Заменяет два отдельных alert'а (верхний со счётчиком и нижний со складом,
|
||||||
|
// который раньше уезжал под таблицу и требовал скролла).
|
||||||
|
const headerHtml =
|
||||||
|
'<div style="display:flex; justify-content:space-between; align-items:center; gap:12px; flex-wrap:wrap; margin-bottom:8px;">' +
|
||||||
|
'<span class="indicator-pill blue" style="font-size:13px;">' +
|
||||||
|
__('Sales invoices found: ') + '<strong>' + invoices.length + '</strong>' +
|
||||||
|
'</span>' +
|
||||||
|
'<span style="color: var(--text-muted);">' +
|
||||||
|
__('Selected delivery warehouse: ') + '<strong>' + frappe.utils.escape_html(warehouse) + '</strong>' +
|
||||||
|
'</span>' +
|
||||||
'</div>';
|
'</div>';
|
||||||
|
|
||||||
const d = new frappe.ui.Dialog({
|
const d = new frappe.ui.Dialog({
|
||||||
|
|
@ -1153,20 +1162,14 @@ SalesETaxes.import = {
|
||||||
size: 'large',
|
size: 'large',
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
fieldname: 'info_html',
|
fieldname: 'header_html',
|
||||||
fieldtype: 'HTML',
|
fieldtype: 'HTML',
|
||||||
options: infoMessage
|
options: headerHtml
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fieldname: 'invoices_html',
|
fieldname: 'invoices_html',
|
||||||
fieldtype: 'HTML',
|
fieldtype: 'HTML',
|
||||||
options: invoiceTable
|
options: invoiceTable
|
||||||
},
|
|
||||||
{
|
|
||||||
fieldname: 'warehouse_display',
|
|
||||||
fieldtype: 'HTML',
|
|
||||||
options: '<div class="row"><div class="col-xs-12"><div class="alert alert-info">' +
|
|
||||||
__('Selected delivery warehouse: ') + '<strong>' + warehouse + '</strong></div></div></div>'
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
primary_action_label: __('Load selected'),
|
primary_action_label: __('Load selected'),
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue