fix: respect data loading checkboxes in reference data loading
Checkbox values (load_items, load_units, load_customers, load_suppliers) were collected in the dialog but never passed through the loading pipeline, causing all data types to always be created regardless of user selection. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
dca5a13de3
commit
d3775786a3
|
|
@ -3764,7 +3764,9 @@ def get_reference_data_lists(data_type, limit=100, offset=0):
|
|||
return {'success': False, 'message': str(e)}
|
||||
|
||||
@frappe.whitelist()
|
||||
def process_single_invoice_for_reference_data(token, invoice_id, source_type='purchase'):
|
||||
def process_single_invoice_for_reference_data(token, invoice_id, source_type='purchase',
|
||||
load_items=1, load_units=1,
|
||||
load_customers=1, load_suppliers=1):
|
||||
"""Обрабатывает один инвойс и создает все 4 типа доктайпов"""
|
||||
record_etaxes_activity()
|
||||
|
||||
|
|
@ -3805,8 +3807,12 @@ def process_single_invoice_for_reference_data(token, invoice_id, source_type='pu
|
|||
'message': invoice_details.get('message', 'Failed to get invoice details')
|
||||
}
|
||||
|
||||
# Создаем все доктайпы из одного инвойса
|
||||
result = create_reference_data_from_single_invoice(invoice_details, source_type)
|
||||
# Создаем доктайпы из одного инвойса (только выбранные типы)
|
||||
result = create_reference_data_from_single_invoice(
|
||||
invoice_details, source_type,
|
||||
load_items=int(load_items), load_units=int(load_units),
|
||||
load_customers=int(load_customers), load_suppliers=int(load_suppliers)
|
||||
)
|
||||
|
||||
return result
|
||||
|
||||
|
|
@ -3818,8 +3824,10 @@ def process_single_invoice_for_reference_data(token, invoice_id, source_type='pu
|
|||
}
|
||||
|
||||
@frappe.whitelist()
|
||||
def create_reference_data_from_single_invoice(invoice_details, source_type):
|
||||
"""Создает все 4 типа доктайпов из одного инвойса с EQM кодами - оптимизированная версия"""
|
||||
def create_reference_data_from_single_invoice(invoice_details, source_type,
|
||||
load_items=1, load_units=1,
|
||||
load_customers=1, load_suppliers=1):
|
||||
"""Создает доктайпы из одного инвойса с EQM кодами - оптимизированная версия"""
|
||||
try:
|
||||
stats = {
|
||||
'items_created': 0,
|
||||
|
|
@ -3838,152 +3846,154 @@ def create_reference_data_from_single_invoice(invoice_details, source_type):
|
|||
receiver = invoice_details.get('receiver', {})
|
||||
|
||||
# === СОЗДАНИЕ ТОВАРОВ С EQM КОДАМИ ===
|
||||
processed_items = set()
|
||||
for item in items:
|
||||
item_name = item.get('productName', '').strip()
|
||||
if not item_name:
|
||||
continue
|
||||
if int(load_items):
|
||||
processed_items = set()
|
||||
for item in items:
|
||||
item_name = item.get('productName', '').strip()
|
||||
if not item_name:
|
||||
continue
|
||||
|
||||
# Обрезаем до 140 символов
|
||||
if len(item_name) > 140:
|
||||
item_name = item_name[:140]
|
||||
# Обрезаем до 140 символов
|
||||
if len(item_name) > 140:
|
||||
item_name = item_name[:140]
|
||||
|
||||
if item_name in processed_items:
|
||||
continue
|
||||
if item_name in processed_items:
|
||||
continue
|
||||
|
||||
processed_items.add(item_name)
|
||||
processed_items.add(item_name)
|
||||
|
||||
# Проверяем существование
|
||||
if frappe.db.exists('E-Taxes Item', item_name):
|
||||
stats['items_skipped'] += 1
|
||||
continue
|
||||
# Проверяем существование
|
||||
if frappe.db.exists('E-Taxes Item', item_name):
|
||||
stats['items_skipped'] += 1
|
||||
continue
|
||||
|
||||
try:
|
||||
# Создаем товар
|
||||
item_code = item.get('itemId', '') or f"CODE-{serial_number}"
|
||||
try:
|
||||
# Создаем товар
|
||||
item_code = item.get('itemId', '') or f"CODE-{serial_number}"
|
||||
|
||||
# Обрабатываем группу товаров
|
||||
product_group = item.get('productGroup', {})
|
||||
product_group_code = product_group.get('code', '') if product_group else ''
|
||||
product_group_type = product_group.get('type', '') if product_group else ''
|
||||
# Обрабатываем группу товаров
|
||||
product_group = item.get('productGroup', {})
|
||||
product_group_code = product_group.get('code', '') if product_group else ''
|
||||
product_group_type = product_group.get('type', '') if product_group else ''
|
||||
|
||||
# Получаем название группы товаров
|
||||
product_group_name = ''
|
||||
if product_group and product_group.get('name'):
|
||||
names = product_group.get('name', {})
|
||||
if isinstance(names, dict):
|
||||
product_group_name = names.get('az', '') or names.get('en', '') or names.get('ru', '')
|
||||
elif isinstance(names, str):
|
||||
product_group_name = names
|
||||
# Получаем название группы товаров
|
||||
product_group_name = ''
|
||||
if product_group and product_group.get('name'):
|
||||
names = product_group.get('name', {})
|
||||
if isinstance(names, dict):
|
||||
product_group_name = names.get('az', '') or names.get('en', '') or names.get('ru', '')
|
||||
elif isinstance(names, str):
|
||||
product_group_name = names
|
||||
|
||||
# Обрезаем название группы товаров до 1000 символов
|
||||
if len(product_group_name) > 1000:
|
||||
product_group_name = product_group_name[:1000]
|
||||
# Обрезаем название группы товаров до 1000 символов
|
||||
if len(product_group_name) > 1000:
|
||||
product_group_name = product_group_name[:1000]
|
||||
|
||||
# НОВОЕ: Поиск EQM Code по коду группы товаров - возвращаем name для Link поля
|
||||
eqm_code = None
|
||||
if product_group_code:
|
||||
try:
|
||||
frappe.log_error(f"[EQM DEBUG] Searching for product_group_code: '{product_group_code}'", "EQM Code Search")
|
||||
# НОВОЕ: Поиск EQM Code по коду группы товаров - возвращаем name для Link поля
|
||||
eqm_code = None
|
||||
if product_group_code:
|
||||
try:
|
||||
frappe.log_error(f"[EQM DEBUG] Searching for product_group_code: '{product_group_code}'", "EQM Code Search")
|
||||
|
||||
# Ищем запись и получаем и name, и eqm_name
|
||||
eqm_record = frappe.db.sql("""
|
||||
SELECT name, eqm_name
|
||||
FROM `tabEQM Codes`
|
||||
WHERE eqm_name LIKE %s
|
||||
LIMIT 1
|
||||
""", (f"{product_group_code} -%",), as_dict=True)
|
||||
# Ищем запись и получаем и name, и eqm_name
|
||||
eqm_record = frappe.db.sql("""
|
||||
SELECT name, eqm_name
|
||||
FROM `tabEQM Codes`
|
||||
WHERE eqm_name LIKE %s
|
||||
LIMIT 1
|
||||
""", (f"{product_group_code} -%",), as_dict=True)
|
||||
|
||||
frappe.log_error(f"[EQM DEBUG] SQL search result: {eqm_record}", "EQM Code Search")
|
||||
frappe.log_error(f"[EQM DEBUG] SQL search result: {eqm_record}", "EQM Code Search")
|
||||
|
||||
if eqm_record:
|
||||
# ИСПРАВЛЕНИЕ: Сохраняем name (ID записи) для Link поля, а не eqm_name
|
||||
eqm_code = eqm_record[0].get('name') # Изменено с eqm_name на name
|
||||
frappe.log_error(f"[EQM DEBUG] Found EQM Code ID: '{eqm_code}' (description: '{eqm_record[0].get('eqm_name')}') for product group '{product_group_code}' in item {item_name}", "EQM Code Assignment")
|
||||
else:
|
||||
frappe.log_error(f"[EQM DEBUG] EQM Code not found for product group '{product_group_code}' in item {item_name}", "EQM Code Not Found")
|
||||
if eqm_record:
|
||||
# ИСПРАВЛЕНИЕ: Сохраняем name (ID записи) для Link поля, а не eqm_name
|
||||
eqm_code = eqm_record[0].get('name') # Изменено с eqm_name на name
|
||||
frappe.log_error(f"[EQM DEBUG] Found EQM Code ID: '{eqm_code}' (description: '{eqm_record[0].get('eqm_name')}') for product group '{product_group_code}' in item {item_name}", "EQM Code Assignment")
|
||||
else:
|
||||
frappe.log_error(f"[EQM DEBUG] EQM Code not found for product group '{product_group_code}' in item {item_name}", "EQM Code Not Found")
|
||||
|
||||
except Exception as e:
|
||||
frappe.log_error(f"[EQM DEBUG] Error searching EQM Code for '{product_group_code}': {str(e)}", "EQM Code Search Error")
|
||||
except Exception as e:
|
||||
frappe.log_error(f"[EQM DEBUG] Error searching EQM Code for '{product_group_code}': {str(e)}", "EQM Code Search Error")
|
||||
|
||||
# Логируем финальное значение
|
||||
frappe.log_error(f"[EQM DEBUG] Final eqm_code ID to save: '{eqm_code}' for item {item_name}", "EQM Code Final")
|
||||
# Логируем финальное значение
|
||||
frappe.log_error(f"[EQM DEBUG] Final eqm_code ID to save: '{eqm_code}' for item {item_name}", "EQM Code Final")
|
||||
|
||||
# Логируем финальное значение
|
||||
frappe.log_error(f"[EQM DEBUG] Final eqm_code value to save: '{eqm_code}' for item {item_name}", "EQM Code Final")
|
||||
# Логируем финальное значение
|
||||
frappe.log_error(f"[EQM DEBUG] Final eqm_code value to save: '{eqm_code}' for item {item_name}", "EQM Code Final")
|
||||
|
||||
# Определяем, является ли товар услугой
|
||||
is_service = 1 if product_group_type == 'service' else 0
|
||||
# Определяем, является ли товар услугой
|
||||
is_service = 1 if product_group_type == 'service' else 0
|
||||
|
||||
# Определяем источники
|
||||
is_from_purchase = 1 if source_type == 'purchase' else 0
|
||||
is_from_sales = 1 if source_type == 'sales' else 0
|
||||
# Определяем источники
|
||||
is_from_purchase = 1 if source_type == 'purchase' else 0
|
||||
is_from_sales = 1 if source_type == 'sales' else 0
|
||||
|
||||
# Создаем документ с EQM кодом
|
||||
doc_data = {
|
||||
'doctype': 'E-Taxes Item',
|
||||
'etaxes_item_name': item_name,
|
||||
'etaxes_item_code': item_code,
|
||||
'etaxes_unit': item.get('unit', ''),
|
||||
'etaxes_price': item.get('pricePerUnit', 0),
|
||||
'etaxes_product_group_code': product_group_code,
|
||||
'etaxes_product_group_name': product_group_name,
|
||||
'etaxes_product_group_type': product_group_type,
|
||||
'is_service_item': is_service,
|
||||
'source_invoice': serial_number,
|
||||
'is_from_purchase': is_from_purchase,
|
||||
'is_from_sales': is_from_sales,
|
||||
'status': 'New'
|
||||
}
|
||||
# Создаем документ с EQM кодом
|
||||
doc_data = {
|
||||
'doctype': 'E-Taxes Item',
|
||||
'etaxes_item_name': item_name,
|
||||
'etaxes_item_code': item_code,
|
||||
'etaxes_unit': item.get('unit', ''),
|
||||
'etaxes_price': item.get('pricePerUnit', 0),
|
||||
'etaxes_product_group_code': product_group_code,
|
||||
'etaxes_product_group_name': product_group_name,
|
||||
'etaxes_product_group_type': product_group_type,
|
||||
'is_service_item': is_service,
|
||||
'source_invoice': serial_number,
|
||||
'is_from_purchase': is_from_purchase,
|
||||
'is_from_sales': is_from_sales,
|
||||
'status': 'New'
|
||||
}
|
||||
|
||||
# НОВОЕ: Добавляем EQM код если найден
|
||||
if eqm_code:
|
||||
doc_data['eqm_code'] = eqm_code
|
||||
# НОВОЕ: Добавляем EQM код если найден
|
||||
if eqm_code:
|
||||
doc_data['eqm_code'] = eqm_code
|
||||
|
||||
doc = frappe.get_doc(doc_data)
|
||||
doc.insert(ignore_permissions=True, ignore_if_duplicate=True)
|
||||
stats['items_created'] += 1
|
||||
doc = frappe.get_doc(doc_data)
|
||||
doc.insert(ignore_permissions=True, ignore_if_duplicate=True)
|
||||
stats['items_created'] += 1
|
||||
|
||||
except frappe.DuplicateEntryError:
|
||||
stats['items_skipped'] += 1
|
||||
except Exception as e:
|
||||
frappe.log_error(f"Error creating E-Taxes Item {item_name}: {str(e)}", "Create Item Error")
|
||||
except frappe.DuplicateEntryError:
|
||||
stats['items_skipped'] += 1
|
||||
except Exception as e:
|
||||
frappe.log_error(f"Error creating E-Taxes Item {item_name}: {str(e)}", "Create Item Error")
|
||||
|
||||
# === СОЗДАНИЕ ЕДИНИЦ ===
|
||||
processed_units = set()
|
||||
for item in items:
|
||||
unit_name = item.get('unit', '').strip()
|
||||
if not unit_name or unit_name in processed_units:
|
||||
continue
|
||||
if int(load_units):
|
||||
processed_units = set()
|
||||
for item in items:
|
||||
unit_name = item.get('unit', '').strip()
|
||||
if not unit_name or unit_name in processed_units:
|
||||
continue
|
||||
|
||||
processed_units.add(unit_name)
|
||||
processed_units.add(unit_name)
|
||||
|
||||
# Проверяем существование
|
||||
if frappe.db.exists('E-Taxes Unit', unit_name):
|
||||
stats['units_skipped'] += 1
|
||||
continue
|
||||
# Проверяем существование
|
||||
if frappe.db.exists('E-Taxes Unit', unit_name):
|
||||
stats['units_skipped'] += 1
|
||||
continue
|
||||
|
||||
try:
|
||||
source_type_text = 'Purchase' if source_type == 'purchase' else 'Sales'
|
||||
try:
|
||||
source_type_text = 'Purchase' if source_type == 'purchase' else 'Sales'
|
||||
|
||||
doc = frappe.get_doc({
|
||||
'doctype': 'E-Taxes Unit',
|
||||
'etaxes_unit_name': unit_name,
|
||||
'etaxes_unit_code': unit_name,
|
||||
'source_invoice': serial_number,
|
||||
'source_type': source_type_text,
|
||||
'status': 'New'
|
||||
})
|
||||
doc.insert(ignore_permissions=True, ignore_if_duplicate=True)
|
||||
stats['units_created'] += 1
|
||||
doc = frappe.get_doc({
|
||||
'doctype': 'E-Taxes Unit',
|
||||
'etaxes_unit_name': unit_name,
|
||||
'etaxes_unit_code': unit_name,
|
||||
'source_invoice': serial_number,
|
||||
'source_type': source_type_text,
|
||||
'status': 'New'
|
||||
})
|
||||
doc.insert(ignore_permissions=True, ignore_if_duplicate=True)
|
||||
stats['units_created'] += 1
|
||||
|
||||
except frappe.DuplicateEntryError:
|
||||
stats['units_skipped'] += 1
|
||||
except Exception as e:
|
||||
frappe.log_error(f"Error creating E-Taxes Unit {unit_name}: {str(e)}", "Create Unit Error")
|
||||
except frappe.DuplicateEntryError:
|
||||
stats['units_skipped'] += 1
|
||||
except Exception as e:
|
||||
frappe.log_error(f"Error creating E-Taxes Unit {unit_name}: {str(e)}", "Create Unit Error")
|
||||
|
||||
# === СОЗДАНИЕ КЛИЕНТОВ (RECEIVER) ===
|
||||
if receiver:
|
||||
if int(load_customers) and receiver:
|
||||
receiver_name = (receiver.get('name') or '').strip()
|
||||
receiver_tin = (receiver.get('tin') or '').strip()
|
||||
receiver_address = (receiver.get('address') or '').strip()
|
||||
|
|
@ -4021,7 +4031,7 @@ def create_reference_data_from_single_invoice(invoice_details, source_type):
|
|||
sender_name = ' '.join(sender_name.split()) # Убираем лишние пробелы
|
||||
|
||||
if sender_name and sender_tin:
|
||||
if source_type == 'purchase':
|
||||
if source_type == 'purchase' and int(load_suppliers):
|
||||
# Sender = Supplier для purchase инвойсов
|
||||
if not frappe.db.exists('E-Taxes Suppliers', sender_name):
|
||||
try:
|
||||
|
|
@ -4043,7 +4053,7 @@ def create_reference_data_from_single_invoice(invoice_details, source_type):
|
|||
frappe.log_error(f"Error creating E-Taxes Suppliers {sender_name}: {str(e)}", "Create Supplier Error")
|
||||
else:
|
||||
stats['suppliers_skipped'] += 1
|
||||
else:
|
||||
elif source_type != 'purchase' and int(load_customers):
|
||||
# Sender = Customer для sales инвойсов
|
||||
if not frappe.db.exists('E-Taxes Customers', sender_name):
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -983,7 +983,7 @@ function start_reference_data_loading(frm, values) {
|
|||
start_staged_invoice_loading(frm, values);
|
||||
}
|
||||
|
||||
function process_invoices_for_reference_data(invoices, token, accumulated_data, current_index = 0, frm) {
|
||||
function process_invoices_for_reference_data(invoices, token, accumulated_data, current_index = 0, frm, load_flags = null) {
|
||||
// Инициализация при первом вызове
|
||||
if (current_index === 0) {
|
||||
window.cancelReferenceLoading = false;
|
||||
|
|
@ -1050,7 +1050,11 @@ function process_invoices_for_reference_data(invoices, token, accumulated_data,
|
|||
args: {
|
||||
'token': token,
|
||||
'invoice_id': invoice_id,
|
||||
'source_type': source_type
|
||||
'source_type': source_type,
|
||||
'load_items': load_flags ? load_flags.load_items : 1,
|
||||
'load_units': load_flags ? load_flags.load_units : 1,
|
||||
'load_customers': load_flags ? load_flags.load_customers : 1,
|
||||
'load_suppliers': load_flags ? load_flags.load_suppliers : 1
|
||||
},
|
||||
callback: function(r) {
|
||||
if (r.message) {
|
||||
|
|
@ -1071,7 +1075,7 @@ function process_invoices_for_reference_data(invoices, token, accumulated_data,
|
|||
token = token_r.message.token;
|
||||
setTimeout(function() {
|
||||
if (!window.cancelReferenceLoading) {
|
||||
process_invoices_for_reference_data(invoices, token, accumulated_data, current_index, frm);
|
||||
process_invoices_for_reference_data(invoices, token, accumulated_data, current_index, frm, load_flags);
|
||||
}
|
||||
}, 100);
|
||||
} else {
|
||||
|
|
@ -1101,7 +1105,7 @@ function process_invoices_for_reference_data(invoices, token, accumulated_data,
|
|||
// Переходим к следующему инвойсу
|
||||
setTimeout(function() {
|
||||
if (!window.cancelReferenceLoading) {
|
||||
process_invoices_for_reference_data(invoices, token, accumulated_data, current_index + 1, frm);
|
||||
process_invoices_for_reference_data(invoices, token, accumulated_data, current_index + 1, frm, load_flags);
|
||||
}
|
||||
}, 50);
|
||||
|
||||
|
|
@ -1117,14 +1121,14 @@ function process_invoices_for_reference_data(invoices, token, accumulated_data,
|
|||
token = token_r.message.token;
|
||||
setTimeout(function() {
|
||||
if (!window.cancelReferenceLoading) {
|
||||
process_invoices_for_reference_data(invoices, token, accumulated_data, current_index, frm);
|
||||
process_invoices_for_reference_data(invoices, token, accumulated_data, current_index, frm, load_flags);
|
||||
}
|
||||
}, 100);
|
||||
} else {
|
||||
// Переходим к следующему инвойсу
|
||||
setTimeout(function() {
|
||||
if (!window.cancelReferenceLoading) {
|
||||
process_invoices_for_reference_data(invoices, token, accumulated_data, current_index + 1, frm);
|
||||
process_invoices_for_reference_data(invoices, token, accumulated_data, current_index + 1, frm, load_flags);
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
|
|
@ -1134,7 +1138,7 @@ function process_invoices_for_reference_data(invoices, token, accumulated_data,
|
|||
// При других ошибках переходим к следующему инвойсу
|
||||
setTimeout(function() {
|
||||
if (!window.cancelReferenceLoading) {
|
||||
process_invoices_for_reference_data(invoices, token, accumulated_data, current_index + 1, frm);
|
||||
process_invoices_for_reference_data(invoices, token, accumulated_data, current_index + 1, frm, load_flags);
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
|
|
@ -2174,7 +2178,11 @@ function start_staged_invoice_loading(frm, values) {
|
|||
inbox_completed: false,
|
||||
outbox_completed: false,
|
||||
token: null,
|
||||
last_update_count: 0 // Для отслеживания когда показывать обновление
|
||||
last_update_count: 0, // Для отслеживания когда показывать обновление
|
||||
load_items: values.load_items ? 1 : 0,
|
||||
load_units: values.load_units ? 1 : 0,
|
||||
load_customers: values.load_customers ? 1 : 0,
|
||||
load_suppliers: values.load_suppliers ? 1 : 0
|
||||
};
|
||||
|
||||
window.cancelReferenceLoading = false;
|
||||
|
|
@ -2344,7 +2352,12 @@ function check_loading_completion(loading_state, frm) {
|
|||
suppliers_created: 0,
|
||||
suppliers_skipped: 0,
|
||||
total_invoices: loading_state.all_invoices.length
|
||||
}, 0, frm);
|
||||
}, 0, frm, {
|
||||
load_items: loading_state.load_items,
|
||||
load_units: loading_state.load_units,
|
||||
load_customers: loading_state.load_customers,
|
||||
load_suppliers: loading_state.load_suppliers
|
||||
});
|
||||
}, 2000);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue