Fixed bugs, added new tabs and subtabs, load from everywhere and etc

This commit is contained in:
Ali 2025-07-23 12:39:40 +04:00
parent 85f37a3f67
commit f0c19854fe
21 changed files with 2882 additions and 2157 deletions

File diff suppressed because it is too large Load Diff

View File

@ -851,12 +851,19 @@ function process_invoices_for_items(invoices, token, accumulated_data, current_i
const outboxText = accumulated_data.outbox_count ?
__(' and {0} sales invoices', [accumulated_data.outbox_count]) : '';
let message = __('Created {0} unique items. Skipped {1} duplicates. Total invoices processed: {2}{3}{4}',
[accumulated_data.created_count, accumulated_data.skipped_count,
accumulated_data.total_invoices, inboxText, outboxText]);
// Добавляем информацию об обновлениях, если есть
if (accumulated_data.updated_count > 0) {
message += __(' Updated {0} existing items with new source information.', [accumulated_data.updated_count]);
}
frappe.msgprint({
title: __('Items Loaded Successfully'),
indicator: 'green',
message: __('Created {0} unique items. Skipped {1} duplicates. Total invoices processed: {2}{3}{4}',
[accumulated_data.created_count, accumulated_data.skipped_count,
accumulated_data.total_invoices, inboxText, outboxText])
message: message
});
// ИСПРАВЛЕНО: Refresh list с задержкой для уверенности в очистке состояния
@ -875,13 +882,17 @@ function process_invoices_for_items(invoices, token, accumulated_data, current_i
// Улучшенная логика определения источника
let sourceLabel;
let sourceType;
if (source === 'inbox') {
sourceLabel = __('Purchase');
sourceType = 'purchase';
} else if (source === 'outbox') {
sourceLabel = __('Sales');
sourceType = 'sales';
} else {
// Если _source не установлен или имеет неожиданное значение, считаем как Purchase
sourceLabel = __('Purchase');
sourceType = 'purchase';
// Добавляем отладочную информацию в консоль
console.log('Warning: Invoice', serial_number, 'has unexpected _source:', source);
}
@ -899,12 +910,14 @@ function process_invoices_for_items(invoices, token, accumulated_data, current_i
method: 'invoice_az.api.process_single_invoice_for_items',
args: {
'token': token,
'invoice_id': invoice_id
'invoice_id': invoice_id,
'source_type': sourceType // НОВОЕ: передаем тип источника
},
callback: function(r) {
if (r.message && r.message.success) {
// Обновляем накопленные данные
accumulated_data.created_count += r.message.created_count || 0;
accumulated_data.updated_count += r.message.updated_count || 0; // НОВОЕ: учитываем обновления
accumulated_data.skipped_count += r.message.skipped_count || 0;
accumulated_data.failed_count += r.message.failed_count || 0;

View File

@ -9,7 +9,15 @@
"etaxes_item_code",
"etaxes_unit",
"etaxes_price",
"product_group_section",
"etaxes_product_group_code",
"etaxes_product_group_name",
"etaxes_product_group_type",
"is_service_item",
"source_section",
"source_invoice",
"is_from_purchase",
"is_from_sales",
"status",
"mapped_item",
"item_creation_section",
@ -50,11 +58,62 @@
"options": "AZN",
"read_only": 1
},
{
"fieldname": "product_group_section",
"fieldtype": "Section Break",
"label": "Product Group Information"
},
{
"fieldname": "etaxes_product_group_code",
"fieldtype": "Data",
"label": "Product Group Code",
"length": 50,
"read_only": 1
},
{
"fieldname": "etaxes_product_group_name",
"fieldtype": "Data",
"label": "Product Group Name",
"length": 1000,
"read_only": 1
},
{
"fieldname": "etaxes_product_group_type",
"fieldtype": "Data",
"label": "Product Group Type",
"read_only": 1
},
{
"default": "0",
"fieldname": "is_service_item",
"fieldtype": "Check",
"label": "Is Service Item",
"read_only": 1
},
{
"fieldname": "source_section",
"fieldtype": "Section Break",
"label": "Source Information"
},
{
"description": "Source invoice number",
"fieldname": "source_invoice",
"fieldtype": "Data",
"label": "Source",
"label": "Source Invoice",
"read_only": 1
},
{
"default": "0",
"fieldname": "is_from_purchase",
"fieldtype": "Check",
"label": "From Purchase Invoice",
"read_only": 1
},
{
"default": "0",
"fieldname": "is_from_sales",
"fieldtype": "Check",
"label": "From Sales Invoice",
"read_only": 1
},
{
@ -101,7 +160,7 @@
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2025-07-09 20:19:56.319865",
"modified": "2025-07-16 20:19:56.319865",
"modified_by": "Administrator",
"module": "Invoice Az",
"name": "E-Taxes Item",

View File

@ -14,6 +14,7 @@
"uom",
"is_stock_item",
"is_purchase_item",
"is_sales_item",
"item_tax_template"
],
"fields": [
@ -83,6 +84,13 @@
"fieldtype": "Check",
"label": "Is Purchase Item"
},
{
"default": "0",
"description": "Overrides default Is Sales Item setting",
"fieldname": "is_sales_item",
"fieldtype": "Check",
"label": "Is Sales Item"
},
{
"description": "Overrides default Item Tax Template setting",
"fieldname": "item_tax_template",
@ -93,7 +101,7 @@
],
"istable": 1,
"links": [],
"modified": "2025-05-23 16:00:32.090354",
"modified": "2025-07-16 16:00:32.090354",
"modified_by": "Administrator",
"module": "Invoice Az",
"name": "E-Taxes Item Mapping",

View File

@ -8,7 +8,8 @@
"date",
"total",
"party",
"etaxes_id"
"etaxes_id",
"type"
],
"fields": [
{
@ -30,11 +31,17 @@
"fieldname": "etaxes_id",
"fieldtype": "Data",
"label": "etaxes_id"
},
{
"fieldname": "type",
"fieldtype": "Select",
"label": "type",
"options": "Sales\nPurchase"
}
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2025-05-31 14:13:09.870421",
"modified": "2025-07-22 18:16:56.347313",
"modified_by": "Administrator",
"module": "Invoice Az",
"name": "E-Taxes Sales",

View File

@ -1,233 +1,272 @@
{
"actions": [],
"allow_rename": 1,
"autoname": "field:settings_name",
"creation": "2025-05-06 12:00:00.000000",
"doctype": "DocType",
"engine": "InnoDB",
"field_order": [
"main_tab",
"settings_name",
"is_default",
"is_active",
"general_section",
"similarity_threshold",
"consider_azeri_chars",
"default_item_settings_section",
"default_item_group",
"default_uom",
"is_stock_item",
"is_purchase_item",
"default_item_tax_template",
"default_party_settings_section",
"default_supplier_group",
"default_customer_group",
"default_payment_terms",
"data_upload_tab",
"mappings_tab",
"item_mappings_section",
"item_mappings",
"customer_mappings_section",
"customer_mappings",
"supplier_mappings_section",
"supplier_mappings",
"party_mappings_section",
"party_mappings",
"unit_mappings_section",
"unit_mappings"
],
"fields": [
{
"fieldname": "main_tab",
"fieldtype": "Tab Break",
"label": "Settings"
},
{
"fieldname": "settings_name",
"fieldtype": "Data",
"label": "Settings Name",
"reqd": 1,
"unique": 1
},
{
"fieldname": "is_default",
"fieldtype": "Check",
"label": "Is Default",
"default": 0
},
{
"fieldname": "is_active",
"fieldtype": "Check",
"label": "Is Active",
"default": 1
},
{
"fieldname": "general_section",
"fieldtype": "Section Break",
"label": "General Settings"
},
{
"fieldname": "similarity_threshold",
"fieldtype": "Percent",
"label": "Similarity Threshold (%)",
"default": 95,
"description": "Minimum similarity percentage for automatic mapping"
},
{
"fieldname": "consider_azeri_chars",
"fieldtype": "Check",
"label": "Consider Azerbaijani Characters",
"default": 1,
"description": "Consider replacement of Azerbaijani letters with Latin equivalents when matching"
},
{
"fieldname": "default_item_settings_section",
"fieldtype": "Section Break",
"label": "Default Item Settings"
},
{
"fieldname": "default_item_group",
"fieldtype": "Link",
"label": "Default Item Group",
"options": "Item Group",
"reqd": 1
},
{
"fieldname": "default_uom",
"fieldtype": "Link",
"label": "Default Unit of Measure",
"options": "UOM",
"reqd": 1
},
{
"fieldname": "is_stock_item",
"fieldtype": "Check",
"label": "Is Stock Item",
"default": 1
},
{
"fieldname": "is_purchase_item",
"fieldtype": "Check",
"label": "Is Purchase Item",
"default": 1
},
{
"fieldname": "default_item_tax_template",
"fieldtype": "Link",
"label": "Default Item Tax Template",
"options": "Item Tax Template"
},
{
"fieldname": "default_party_settings_section",
"fieldtype": "Section Break",
"label": "Default Business Partner Settings"
},
{
"fieldname": "default_supplier_group",
"fieldtype": "Link",
"label": "Default Supplier Group",
"options": "Supplier Group"
},
{
"fieldname": "default_customer_group",
"fieldtype": "Link",
"label": "Default Customer Group",
"options": "Customer Group"
},
{
"fieldname": "default_payment_terms",
"fieldtype": "Link",
"label": "Default Payment Terms",
"options": "Payment Terms Template"
},
{
"fieldname": "data_upload_tab",
"fieldtype": "Tab Break",
"label": "Data Upload from Website"
},
{
"fieldname": "mappings_tab",
"fieldtype": "Tab Break",
"label": "Mappings"
},
{
"fieldname": "item_mappings_section",
"fieldtype": "Section Break",
"label": "Item Mappings"
},
{
"fieldname": "item_mappings",
"fieldtype": "Table",
"label": "Item Mappings",
"options": "E-Taxes Item Mapping"
},
{
"fieldname": "customer_mappings_section",
"fieldtype": "Section Break",
"label": "Customer Mappings"
},
{
"fieldname": "customer_mappings",
"fieldtype": "Table",
"label": "Customer Mappings",
"options": "E-Taxes Customer Mappings"
},
{
"fieldname": "supplier_mappings_section",
"fieldtype": "Section Break",
"label": "Supplier Mappings"
},
{
"fieldname": "supplier_mappings",
"fieldtype": "Table",
"label": "Supplier Mappings",
"options": "E-Taxes Supplier Mappings"
},
{
"fieldname": "party_mappings_section",
"fieldtype": "Section Break",
"label": "Business Partner Mappings (Legacy)"
},
{
"fieldname": "party_mappings",
"fieldtype": "Table",
"label": "Business Partner Mappings",
"options": "E-Taxes Party Mapping"
},
{
"fieldname": "unit_mappings_section",
"fieldtype": "Section Break",
"label": "Unit of Measure Mappings"
},
{
"fieldname": "unit_mappings",
"fieldtype": "Table",
"label": "Unit of Measure Mappings",
"options": "E-Taxes Unit Mapping"
}
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2025-07-11 14:00:00.000000",
"modified_by": "Administrator",
"module": "Invoice Az",
"name": "E-Taxes Settings",
"owner": "Administrator",
"permissions": [
{
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"share": 1,
"write": 1
}
],
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1
"actions": [],
"allow_rename": 1,
"autoname": "field:settings_name",
"creation": "2025-05-06 12:00:00",
"doctype": "DocType",
"engine": "InnoDB",
"field_order": [
"main_tab",
"settings_name",
"is_default",
"is_active",
"general_section",
"similarity_threshold",
"consider_azeri_chars",
"default_item_settings_section",
"default_item_group",
"default_uom",
"default_item_tax_template",
"default_party_settings_section",
"default_supplier_group",
"default_customer_group",
"default_payment_terms",
"items_tab",
"items_list_html",
"customers_tab",
"customers_list_html",
"suppliers_tab",
"suppliers_list_html",
"units_tab",
"units_list_html",
"mappings_tab",
"item_mappings_section",
"item_mappings",
"customer_mappings_section",
"customer_mappings",
"supplier_mappings_section",
"supplier_mappings",
"unit_mappings_section",
"unit_mappings",
"data_tab",
"html_nbtb"
],
"fields": [
{
"fieldname": "main_tab",
"fieldtype": "Tab Break",
"label": "Settings"
},
{
"fieldname": "settings_name",
"fieldtype": "Data",
"in_list_view": 1,
"label": "Settings Name",
"reqd": 1,
"unique": 1
},
{
"default": "0",
"fieldname": "is_default",
"fieldtype": "Check",
"label": "Is Default"
},
{
"default": "1",
"fieldname": "is_active",
"fieldtype": "Check",
"label": "Is Active"
},
{
"fieldname": "general_section",
"fieldtype": "Section Break",
"label": "General Settings"
},
{
"default": "95",
"description": "Minimum similarity percentage for automatic mapping",
"fieldname": "similarity_threshold",
"fieldtype": "Percent",
"label": "Similarity Threshold (%)"
},
{
"default": "1",
"description": "Consider replacement of Azerbaijani letters with Latin equivalents when matching",
"fieldname": "consider_azeri_chars",
"fieldtype": "Check",
"label": "Consider Azerbaijani Characters"
},
{
"fieldname": "default_item_settings_section",
"fieldtype": "Section Break",
"label": "Default Item Settings"
},
{
"fieldname": "default_item_group",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Default Item Group",
"options": "Item Group",
"reqd": 1
},
{
"fieldname": "default_uom",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Default Unit of Measure",
"options": "UOM",
"reqd": 1
},
{
"fieldname": "default_item_tax_template",
"fieldtype": "Link",
"label": "Default Item Tax Template",
"options": "Item Tax Template"
},
{
"fieldname": "default_party_settings_section",
"fieldtype": "Section Break",
"label": "Default Business Partner Settings"
},
{
"fieldname": "default_supplier_group",
"fieldtype": "Link",
"label": "Default Supplier Group",
"options": "Supplier Group"
},
{
"fieldname": "default_customer_group",
"fieldtype": "Link",
"label": "Default Customer Group",
"options": "Customer Group"
},
{
"fieldname": "default_payment_terms",
"fieldtype": "Link",
"label": "Default Payment Terms",
"options": "Payment Terms Template"
},
{
"fieldname": "items_tab",
"fieldtype": "Tab Break",
"js_parent_subtab": "Data tab",
"label": "Items"
},
{
"fieldname": "items_list_html",
"fieldtype": "HTML",
"label": "Items List",
"options": "<div id=\"items-list-container\">Loading items...</div>"
},
{
"fieldname": "customers_tab",
"fieldtype": "Tab Break",
"js_parent_subtab": "Data tab",
"label": "Customers"
},
{
"fieldname": "customers_list_html",
"fieldtype": "HTML",
"label": "Customers List",
"options": "<div id=\"customers-list-container\">Loading customers...</div>"
},
{
"fieldname": "suppliers_tab",
"fieldtype": "Tab Break",
"js_parent_subtab": "Data tab",
"label": "Suppliers"
},
{
"fieldname": "suppliers_list_html",
"fieldtype": "HTML",
"label": "Suppliers List",
"options": "<div id=\"suppliers-list-container\">Loading suppliers...</div>"
},
{
"fieldname": "units_tab",
"fieldtype": "Tab Break",
"js_parent_subtab": "Data tab",
"label": "Units"
},
{
"fieldname": "units_list_html",
"fieldtype": "HTML",
"label": "Units List",
"options": "<div id=\"units-list-container\">Loading units...</div>"
},
{
"fieldname": "mappings_tab",
"fieldtype": "Tab Break",
"label": "Mappings"
},
{
"fieldname": "item_mappings_section",
"fieldtype": "Section Break",
"label": "Item Mappings"
},
{
"fieldname": "item_mappings",
"fieldtype": "Table",
"label": "Item Mappings",
"options": "E-Taxes Item Mapping"
},
{
"fieldname": "customer_mappings_section",
"fieldtype": "Section Break",
"label": "Customer Mappings"
},
{
"fieldname": "customer_mappings",
"fieldtype": "Table",
"label": "Customer Mappings",
"options": "E-Taxes Customer Mappings"
},
{
"fieldname": "supplier_mappings_section",
"fieldtype": "Section Break",
"label": "Supplier Mappings"
},
{
"fieldname": "supplier_mappings",
"fieldtype": "Table",
"label": "Supplier Mappings",
"options": "E-Taxes Supplier Mappings"
},
{
"fieldname": "unit_mappings_section",
"fieldtype": "Section Break",
"label": "Unit of Measure Mappings"
},
{
"fieldname": "unit_mappings",
"fieldtype": "Table",
"label": "Unit of Measure Mappings",
"options": "E-Taxes Unit Mapping"
},
{
"fieldname": "html_nbtb",
"fieldtype": "HTML"
},
{
"fieldname": "data_tab",
"fieldtype": "Tab Break",
"label": "Data tab"
}
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2025-07-18 18:13:40.328160",
"modified_by": "Administrator",
"module": "Invoice Az",
"name": "E-Taxes Settings",
"naming_rule": "By fieldname",
"owner": "Administrator",
"permissions": [
{
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"share": 1,
"write": 1
}
],
"sort_field": "modified",
"sort_order": "DESC",
"states": [],
"track_changes": 1
}

View File

@ -244,7 +244,9 @@ def import_sales_invoice_with_mapping(invoice_data, sales_order_name=None, sched
customer_mappings = {}
for mapping in settings.customer_mappings:
if mapping.etaxes_customer_name and mapping.erp_customer:
key = f"{mapping.etaxes_customer_name.lower()}|{mapping.etaxes_tax_id.lower() if mapping.etaxes_tax_id else ''}"
# ИСПРАВЛЕНИЕ: Обрезаем ключ до 140 символов
customer_name = mapping.etaxes_customer_name[:140] if len(mapping.etaxes_customer_name) > 140 else mapping.etaxes_customer_name
key = f"{customer_name.lower()}|{mapping.etaxes_tax_id.lower() if mapping.etaxes_tax_id else ''}"
customer_mappings[key] = mapping.erp_customer
# Get default warehouse
@ -278,9 +280,12 @@ def import_sales_invoice_with_mapping(invoice_data, sales_order_name=None, sched
else:
so = frappe.new_doc('Sales Order')
# ИЗМЕНЕНО: Set customer используя customer_mappings
# ИЗМЕНЕНО: Set customer используя customer_mappings с обрезкой
receiver = invoice_data.get('receiver', {})
receiver_key = f"{receiver.get('name', '').lower()}|{receiver.get('tin', '').lower()}"
receiver_name = receiver.get('name', '')
# ИСПРАВЛЕНИЕ: Обрезаем название клиента до 140 символов для поиска
receiver_name_truncated = receiver_name[:140] if len(receiver_name) > 140 else receiver_name
receiver_key = f"{receiver_name_truncated.lower()}|{receiver.get('tin', '').lower()}"
if receiver_key in customer_mappings and customer_mappings[receiver_key]:
so.customer = customer_mappings[receiver_key]
@ -335,12 +340,15 @@ def import_sales_invoice_with_mapping(invoice_data, sales_order_name=None, sched
item_name = re.sub(r'\s+', ' ', item.get("productName", "")).strip()
item_code = item.get("itemId", "") or f"CODE-{invoice_data.get('serialNumber', '')}"
# Ищем соответствие товара
mapped_item = item_mappings.get(item_name)
# ИСПРАВЛЕНИЕ: Обрезаем название товара до 140 символов для поиска
item_name_truncated = item_name[:140] if len(item_name) > 140 else item_name
# Ищем соответствие товара сначала по обрезанному названию
mapped_item = item_mappings.get(item_name_truncated)
# Если не найдено, ищем без учета регистра
if not mapped_item:
item_name_lower = item_name.lower()
item_name_lower = item_name_truncated.lower()
for mapping_key, mapping_value in item_mappings.items():
if mapping_key.lower() == item_name_lower:
mapped_item = mapping_value
@ -348,7 +356,7 @@ def import_sales_invoice_with_mapping(invoice_data, sales_order_name=None, sched
# Если все еще не найдено, ищем с нормализацией азербайджанских символов
if not mapped_item:
normalized_input = normalize_string(item_name, consider_azeri=True)
normalized_input = normalize_string(item_name_truncated, consider_azeri=True)
for mapping_key, mapping_value in item_mappings.items():
normalized_key = normalize_string(mapping_key, consider_azeri=True)
if normalized_key == normalized_input:
@ -546,7 +554,7 @@ def import_sales_invoice_with_mapping(invoice_data, sales_order_name=None, sched
'success': False,
'message': "An unknown error occurred, please try again in a few minutes."
}
@frappe.whitelist()
def create_sales_invoice_from_order(sales_order_name):
"""Создает Sales Invoice из Sales Order используя стандартную функцию ERPNext"""

0
test_invoice.git/hooks/applypatch-msg.sample Executable file → Normal file
View File

0
test_invoice.git/hooks/commit-msg.sample Executable file → Normal file
View File

0
test_invoice.git/hooks/fsmonitor-watchman.sample Executable file → Normal file
View File

0
test_invoice.git/hooks/post-update.sample Executable file → Normal file
View File

0
test_invoice.git/hooks/pre-applypatch.sample Executable file → Normal file
View File

0
test_invoice.git/hooks/pre-commit.sample Executable file → Normal file
View File

0
test_invoice.git/hooks/pre-merge-commit.sample Executable file → Normal file
View File

0
test_invoice.git/hooks/pre-push.sample Executable file → Normal file
View File

0
test_invoice.git/hooks/pre-rebase.sample Executable file → Normal file
View File

0
test_invoice.git/hooks/pre-receive.sample Executable file → Normal file
View File

0
test_invoice.git/hooks/prepare-commit-msg.sample Executable file → Normal file
View File

0
test_invoice.git/hooks/push-to-checkout.sample Executable file → Normal file
View File

0
test_invoice.git/hooks/update.sample Executable file → Normal file
View File