added eqm codes to items and etaxes items
This commit is contained in:
parent
6df36695db
commit
0896971525
|
|
@ -669,7 +669,7 @@ def match_similar_items():
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def create_unmapped_items(settings_name):
|
def create_unmapped_items(settings_name):
|
||||||
"""Creating items for unmapped elements from E-Taxes settings table"""
|
"""Creating items for unmapped elements from E-Taxes settings table with EQM Code support"""
|
||||||
# Записываем активность
|
# Записываем активность
|
||||||
record_etaxes_activity()
|
record_etaxes_activity()
|
||||||
|
|
||||||
|
|
@ -693,12 +693,13 @@ def create_unmapped_items(settings_name):
|
||||||
"message": "No unmapped items in table to create"
|
"message": "No unmapped items in table to create"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Batch load E-Taxes Items
|
# Batch load E-Taxes Items с EQM кодом
|
||||||
etaxes_items_data = frappe.get_all('E-Taxes Item',
|
etaxes_items_data = frappe.get_all('E-Taxes Item',
|
||||||
filters={'name': ['in', unmapped_etaxes_items]},
|
filters={'name': ['in', unmapped_etaxes_items]},
|
||||||
fields=['name', 'etaxes_item_name', 'etaxes_item_code',
|
fields=['name', 'etaxes_item_name', 'etaxes_item_code',
|
||||||
'etaxes_product_group_code', 'etaxes_product_group_name',
|
'etaxes_product_group_code', 'etaxes_product_group_name',
|
||||||
'is_service_item', 'is_from_purchase', 'is_from_sales'])
|
'is_service_item', 'is_from_purchase', 'is_from_sales',
|
||||||
|
'eqm_code']) # НОВОЕ: Добавляем eqm_code
|
||||||
|
|
||||||
# Build mapping settings dict
|
# Build mapping settings dict
|
||||||
mapping_settings = {}
|
mapping_settings = {}
|
||||||
|
|
@ -724,6 +725,8 @@ def create_unmapped_items(settings_name):
|
||||||
# Check for custom fields once
|
# Check for custom fields once
|
||||||
product_group_code_field_exists = frappe.db.exists('Custom Field', {'dt': 'Item', 'fieldname': 'etaxes_product_group_code'})
|
product_group_code_field_exists = frappe.db.exists('Custom Field', {'dt': 'Item', 'fieldname': 'etaxes_product_group_code'})
|
||||||
product_group_name_field_exists = frappe.db.exists('Custom Field', {'dt': 'Item', 'fieldname': 'etaxes_product_group_name'})
|
product_group_name_field_exists = frappe.db.exists('Custom Field', {'dt': 'Item', 'fieldname': 'etaxes_product_group_name'})
|
||||||
|
eqm_code_field_exists = frappe.db.exists('Custom Field', {'dt': 'Item', 'fieldname': 'eqm_code'}) # НОВОЕ: Проверяем поле eqm_code
|
||||||
|
|
||||||
product_group_name_field_length = 140
|
product_group_name_field_length = 140
|
||||||
if product_group_name_field_exists:
|
if product_group_name_field_exists:
|
||||||
custom_field = frappe.get_doc('Custom Field', {'dt': 'Item', 'fieldname': 'etaxes_product_group_name'})
|
custom_field = frappe.get_doc('Custom Field', {'dt': 'Item', 'fieldname': 'etaxes_product_group_name'})
|
||||||
|
|
@ -815,6 +818,11 @@ def create_unmapped_items(settings_name):
|
||||||
product_group_name = product_group_name[:product_group_name_field_length]
|
product_group_name = product_group_name[:product_group_name_field_length]
|
||||||
item_doc.etaxes_product_group_name = product_group_name
|
item_doc.etaxes_product_group_name = product_group_name
|
||||||
|
|
||||||
|
# НОВОЕ: Добавляем EQM код если поле существует и код есть
|
||||||
|
if eqm_code_field_exists and etaxes_item_data.eqm_code:
|
||||||
|
item_doc.eqm_code = etaxes_item_data.eqm_code
|
||||||
|
frappe.log_error(f"Added EQM Code {etaxes_item_data.eqm_code} to item {item_doc.item_name}", "EQM Code Transfer")
|
||||||
|
|
||||||
# Add tax template
|
# Add tax template
|
||||||
tax_template = individual_settings.get('item_tax_template') or settings_doc.default_item_tax_template
|
tax_template = individual_settings.get('item_tax_template') or settings_doc.default_item_tax_template
|
||||||
if tax_template and frappe.db.exists('Item Tax Template', tax_template):
|
if tax_template and frappe.db.exists('Item Tax Template', tax_template):
|
||||||
|
|
@ -840,6 +848,7 @@ def create_unmapped_items(settings_name):
|
||||||
created_count += 1
|
created_count += 1
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
frappe.log_error(f"Error creating item for {etaxes_item_data.etaxes_item_name}: {str(e)}", "Create Item Error")
|
||||||
error_count += 1
|
error_count += 1
|
||||||
|
|
||||||
# Save settings
|
# Save settings
|
||||||
|
|
@ -2082,7 +2091,7 @@ def refresh_item_mappings_display(settings_name):
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def process_single_invoice_for_items(token, invoice_id, source_type='purchase'):
|
def process_single_invoice_for_items(token, invoice_id, source_type='purchase'):
|
||||||
"""Processing a single invoice for item extraction with name length handling"""
|
"""Processing a single invoice for item extraction with EQM Code assignment"""
|
||||||
# Записываем активность
|
# Записываем активность
|
||||||
record_etaxes_activity()
|
record_etaxes_activity()
|
||||||
|
|
||||||
|
|
@ -2176,6 +2185,39 @@ def process_single_invoice_for_items(token, invoice_id, source_type='purchase'):
|
||||||
product_group_name = product_group_name[:1000]
|
product_group_name = product_group_name[:1000]
|
||||||
frappe.log_error(f"Product group name truncated for item {item_name}: original length {len(product_group.get('name', {}).get('az', ''))}", "Product Group Name Truncation")
|
frappe.log_error(f"Product group name truncated for item {item_name}: original length {len(product_group.get('name', {}).get('az', ''))}", "Product Group Name Truncation")
|
||||||
|
|
||||||
|
# НОВОЕ: Поиск 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)
|
||||||
|
|
||||||
|
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")
|
||||||
|
|
||||||
|
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 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
|
||||||
|
|
||||||
|
|
@ -2192,7 +2234,8 @@ def process_single_invoice_for_items(token, invoice_id, source_type='purchase'):
|
||||||
'source_invoice': serial_number,
|
'source_invoice': serial_number,
|
||||||
'is_from_purchase': is_from_purchase,
|
'is_from_purchase': is_from_purchase,
|
||||||
'is_from_sales': is_from_sales,
|
'is_from_sales': is_from_sales,
|
||||||
'status': 'New'
|
'status': 'New',
|
||||||
|
'eqm_code': eqm_code # НОВОЕ: Добавляем EQM код
|
||||||
}
|
}
|
||||||
|
|
||||||
# Создаём записи для уникальных товаров
|
# Создаём записи для уникальных товаров
|
||||||
|
|
@ -3798,7 +3841,7 @@ def process_single_invoice_for_reference_data(token, invoice_id, source_type='pu
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def create_reference_data_from_single_invoice(invoice_details, source_type):
|
def create_reference_data_from_single_invoice(invoice_details, source_type):
|
||||||
"""Создает все 4 типа доктайпов из одного инвойса - оптимизированная версия"""
|
"""Создает все 4 типа доктайпов из одного инвойса с EQM кодами - оптимизированная версия"""
|
||||||
try:
|
try:
|
||||||
stats = {
|
stats = {
|
||||||
'items_created': 0,
|
'items_created': 0,
|
||||||
|
|
@ -3816,7 +3859,7 @@ def create_reference_data_from_single_invoice(invoice_details, source_type):
|
||||||
sender = invoice_details.get('sender', {})
|
sender = invoice_details.get('sender', {})
|
||||||
receiver = invoice_details.get('receiver', {})
|
receiver = invoice_details.get('receiver', {})
|
||||||
|
|
||||||
# === СОЗДАНИЕ ТОВАРОВ ===
|
# === СОЗДАНИЕ ТОВАРОВ С EQM КОДАМИ ===
|
||||||
processed_items = set()
|
processed_items = set()
|
||||||
for item in items:
|
for item in items:
|
||||||
item_name = item.get('productName', '').strip()
|
item_name = item.get('productName', '').strip()
|
||||||
|
|
@ -3859,6 +3902,38 @@ def create_reference_data_from_single_invoice(invoice_details, source_type):
|
||||||
if len(product_group_name) > 1000:
|
if len(product_group_name) > 1000:
|
||||||
product_group_name = 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")
|
||||||
|
|
||||||
|
# Ищем запись и получаем и 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")
|
||||||
|
|
||||||
|
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")
|
||||||
|
|
||||||
|
# Логируем финальное значение
|
||||||
|
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")
|
||||||
|
|
||||||
# Определяем, является ли товар услугой
|
# Определяем, является ли товар услугой
|
||||||
is_service = 1 if product_group_type == 'service' else 0
|
is_service = 1 if product_group_type == 'service' else 0
|
||||||
|
|
||||||
|
|
@ -3866,7 +3941,8 @@ def create_reference_data_from_single_invoice(invoice_details, source_type):
|
||||||
is_from_purchase = 1 if source_type == 'purchase' else 0
|
is_from_purchase = 1 if source_type == 'purchase' else 0
|
||||||
is_from_sales = 1 if source_type == 'sales' else 0
|
is_from_sales = 1 if source_type == 'sales' else 0
|
||||||
|
|
||||||
doc = frappe.get_doc({
|
# Создаем документ с EQM кодом
|
||||||
|
doc_data = {
|
||||||
'doctype': 'E-Taxes Item',
|
'doctype': 'E-Taxes Item',
|
||||||
'etaxes_item_name': item_name,
|
'etaxes_item_name': item_name,
|
||||||
'etaxes_item_code': item_code,
|
'etaxes_item_code': item_code,
|
||||||
|
|
@ -3880,7 +3956,13 @@ def create_reference_data_from_single_invoice(invoice_details, source_type):
|
||||||
'is_from_purchase': is_from_purchase,
|
'is_from_purchase': is_from_purchase,
|
||||||
'is_from_sales': is_from_sales,
|
'is_from_sales': is_from_sales,
|
||||||
'status': 'New'
|
'status': 'New'
|
||||||
})
|
}
|
||||||
|
|
||||||
|
# НОВОЕ: Добавляем 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)
|
doc.insert(ignore_permissions=True, ignore_if_duplicate=True)
|
||||||
stats['items_created'] += 1
|
stats['items_created'] += 1
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
"etaxes_item_code",
|
"etaxes_item_code",
|
||||||
"etaxes_unit",
|
"etaxes_unit",
|
||||||
"etaxes_price",
|
"etaxes_price",
|
||||||
|
"eqm_code",
|
||||||
"product_group_section",
|
"product_group_section",
|
||||||
"etaxes_product_group_code",
|
"etaxes_product_group_code",
|
||||||
"etaxes_product_group_name",
|
"etaxes_product_group_name",
|
||||||
|
|
@ -156,11 +157,17 @@
|
||||||
"label": "Tax Template",
|
"label": "Tax Template",
|
||||||
"options": "Item Tax Template",
|
"options": "Item Tax Template",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "eqm_code",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"label": "EQM Code",
|
||||||
|
"options": "EQM Codes"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2025-07-16 20:19:56.319865",
|
"modified": "2025-09-22 17:32:18.795605",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Invoice Az",
|
"module": "Invoice Az",
|
||||||
"name": "E-Taxes Item",
|
"name": "E-Taxes Item",
|
||||||
|
|
|
||||||
|
|
@ -18,13 +18,30 @@ def get_active_settings():
|
||||||
|
|
||||||
return frappe.get_doc('E-Taxes Settings', settings_list[0].name)
|
return frappe.get_doc('E-Taxes Settings', settings_list[0].name)
|
||||||
|
|
||||||
def record_etaxes_activity():
|
@frappe.whitelist()
|
||||||
"""Record E-Taxes API activity to optimize token renewal"""
|
def record_etaxes_activity(asan_login_name=None):
|
||||||
|
"""Записывает время последней активности с e-taxes напрямую"""
|
||||||
try:
|
try:
|
||||||
frappe.cache().set_value("etaxes_last_activity", frappe.utils.now(), expires_in_sec=3600)
|
# Если имя не указано, получаем дефолтный профиль
|
||||||
|
if not asan_login_name:
|
||||||
|
default_settings = frappe.get_all(
|
||||||
|
"Asan Login",
|
||||||
|
filters={"is_default": 1},
|
||||||
|
fields=["name"],
|
||||||
|
limit=1
|
||||||
|
)
|
||||||
|
|
||||||
|
if not default_settings:
|
||||||
|
return
|
||||||
|
|
||||||
|
asan_login_name = default_settings[0].name
|
||||||
|
|
||||||
|
# Обновляем поле last_activity_time напрямую через БД
|
||||||
|
frappe.db.set_value("Asan Login", asan_login_name, "last_activity_time", now_datetime(), update_modified=False)
|
||||||
|
frappe.db.commit()
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
# Don't fail the whole operation if activity recording fails
|
frappe.log_error(f"Error recording activity: {str(e)}", "Activity Recording Error")
|
||||||
frappe.log_error(f"Error recording E-Taxes activity: {str(e)}", "E-Taxes Activity Recording")
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_sales_invoices(token, filters=None):
|
def get_sales_invoices(token, filters=None):
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue