From ef6e4197eff2100e6fdb1343e69d80d725c1915a Mon Sep 17 00:00:00 2001 From: Ali <010109ali@gmail.com> Date: Mon, 22 Dec 2025 15:48:34 +0400 Subject: [PATCH] now assets category creates in patches, instead of hooks --- jey_erp/custom_fields.py | 77 +++++++++++- jey_erp/hooks.py | 4 +- jey_erp/patches.txt | 3 +- .../patches/v1_0/create_asset_categories.py | 110 ++++++++++++++++++ 4 files changed, 190 insertions(+), 4 deletions(-) create mode 100644 jey_erp/patches/v1_0/create_asset_categories.py diff --git a/jey_erp/custom_fields.py b/jey_erp/custom_fields.py index 06c3599..6e90c5f 100644 --- a/jey_erp/custom_fields.py +++ b/jey_erp/custom_fields.py @@ -501,6 +501,80 @@ def create_custom_fields(): label='Additional Comment', fieldtype='Small Text', insert_after='comments_column_break' + ), + + # === E-TAXES INTEGRATION SECTION === + dict( + fieldname='etaxes_section', + label='E-Taxes Integration', + fieldtype='Section Break', + insert_after='additional_comment', + collapsible=1 + ), + + # Temporary field for user input + dict( + fieldname='customer_object_name', + label='Customer Object Name', + fieldtype='Data', + insert_after='etaxes_section', + description='Selected customer object from E-Taxes (auto-filled)', + read_only=1, + allow_on_submit=1, + no_copy=1 + ), + + # Column break + dict( + fieldname='etaxes_column_break', + fieldtype='Column Break', + insert_after='customer_object_name' + ), + + # E-Taxes tracking fields (read-only after creation) + dict( + fieldname='etaxes_invoice_id', + label='E-Taxes Invoice ID', + fieldtype='Data', + insert_after='etaxes_column_break', + read_only=1, + in_list_view=1, + allow_on_submit=1, + no_copy=1 + ), + + dict( + fieldname='etaxes_serial_number', + label='E-Taxes Serial Number', + fieldtype='Data', + insert_after='etaxes_invoice_id', + read_only=1, + in_list_view=1, + allow_on_submit=1, + no_copy=1 + ), + + dict( + fieldname='etaxes_verification_code', + label='E-Taxes Verification Code', + fieldtype='Data', + insert_after='etaxes_serial_number', + read_only=1, + allow_on_submit=1, + no_copy=1 + ), + + dict( + fieldname='etaxes_send_status', + label='E-Taxes Status', + fieldtype='Select', + options='\nNot Sent\nSent and Signed\nCreated, not signed', + default='Not Sent', + insert_after='etaxes_verification_code', + read_only=1, + in_list_view=1, + allow_on_submit=1, + no_copy=1 ) ], "Sales Invoice Item": [ @@ -581,7 +655,8 @@ def create_custom_fields(): dict( fieldname='product_group_code', label='Product Group Code', - fieldtype='Data', + fieldtype='Link', + options='E-Taxes Item Group', insert_after='item_name', in_list_view=0, in_standard_filter=0 diff --git a/jey_erp/hooks.py b/jey_erp/hooks.py index 47009e5..687e23a 100644 --- a/jey_erp/hooks.py +++ b/jey_erp/hooks.py @@ -63,8 +63,8 @@ def after_migrate_combined(): show_item_tax_template_in_sales_invoice() from jey_erp.custom.vat_calculations import patch_sales_documents patch_sales_documents() - from jey_erp.custom.create_asset_categories import create_asset_categories - create_asset_categories() + # from jey_erp.custom.create_asset_categories import create_asset_categories + # create_asset_categories() fixtures = [ diff --git a/jey_erp/patches.txt b/jey_erp/patches.txt index f15c3a9..ad6ef03 100644 --- a/jey_erp/patches.txt +++ b/jey_erp/patches.txt @@ -3,4 +3,5 @@ # Read docs to understand patches: https://frappeframework.com/docs/v14/user/en/database-migrations [post_model_sync] -# Patches added in this section will be executed after doctypes are migrated \ No newline at end of file +# Patches added in this section will be executed after doctypes are migrated +jey_erp.patches.v1_0.create_asset_categories \ No newline at end of file diff --git a/jey_erp/patches/v1_0/create_asset_categories.py b/jey_erp/patches/v1_0/create_asset_categories.py new file mode 100644 index 0000000..b73e23d --- /dev/null +++ b/jey_erp/patches/v1_0/create_asset_categories.py @@ -0,0 +1,110 @@ +import frappe + + +def execute(): + """ + Создает категории активов с настройками счетов + Этот патч выполняется только один раз + """ + + # Проверка существования таблицы Company + if not frappe.db.table_exists("Company"): + frappe.log_error("Company table not found", "Asset Categories Patch") + return + + # Получаем первую компанию + company = frappe.get_all("Company", limit=1) + if not company: + frappe.log_error("No company found in the system", "Asset Categories Patch") + return + + company_name = company[0].name + + # Список категорий активов + asset_categories = [ + "Binalar, tikililər və qurğular", + "Maşınlar və avadanlıqlar", + "Yüksək texnologiyalar məhsulu olan hesablama texnikası", + "Nəqliyyat vasitələri", + "Digər əsas vəsaitlər", + "Düzən torpaqlar", + "Dağ torpaqlar", + "Orta və yüksək dağ torpaqlar", + "Şəhərin mövcud hüdudundan kənarda olan kənd təsərrüfatı təyinatlı torpaqlar", + "Sənaye, tikinti, nəqliyyat, rabitə, ticarət-məişət xidməti və digər xüsusi təyinatlı torpaq sahələri" + ] + + # Находим нужные счета + try: + accumulated_depreciation = get_account_by_name( + "Tikililər üzrə yığılmış amortizasiya", + company_name + ) + depreciation_expense = get_account_by_name( + "Amortizasiya xərci", + company_name + ) + fixed_asset = get_account_by_name( + "Digər uzunmüddətli aktivlər", + company_name + ) + except Exception as e: + frappe.log_error(f"Required accounts not found: {str(e)}", "Asset Categories Patch") + return + + # Создаем категории активов + created_count = 0 + skipped_count = 0 + + for category_name in asset_categories: + try: + if not frappe.db.exists("Asset Category", category_name): + asset_category = frappe.new_doc("Asset Category") + asset_category.asset_category_name = category_name + asset_category.enable_cwip_accounting = 0 + + # Добавляем accounts + asset_category.append("accounts", { + "company_name": company_name, + "fixed_asset_account": fixed_asset, + "accumulated_depreciation_account": accumulated_depreciation, + "depreciation_expense_account": depreciation_expense, + "capital_work_in_progress_account": "" + }) + + asset_category.insert(ignore_permissions=True) + created_count += 1 + + frappe.msgprint(f"Created Asset Category: {category_name}") + else: + skipped_count += 1 + except Exception as e: + frappe.log_error( + f"Failed to create Asset Category '{category_name}': {str(e)}", + "Asset Categories Patch" + ) + + # Коммитим все изменения разом + frappe.db.commit() + + # Выводим итоговую информацию + message = f"Asset Categories Patch completed. Created: {created_count}, Skipped: {skipped_count}" + print(message) + frappe.msgprint(message) + + +def get_account_by_name(account_name, company): + """Get account by account_name field""" + account = frappe.db.get_value( + "Account", + { + "account_name": account_name, + "company": company + }, + "name" + ) + + if not account: + raise ValueError(f"Account not found: {account_name} for company {company}") + + return account