monkey patched asset categories
This commit is contained in:
parent
d5c92eef7d
commit
8865bb7b18
|
|
@ -21,9 +21,11 @@ def get_system_asset_categories():
|
||||||
|
|
||||||
def create_asset_categories():
|
def create_asset_categories():
|
||||||
"""
|
"""
|
||||||
Создает категории активов с настройками счетов
|
УСТАРЕЛО: Функция оставлена для обратной совместимости.
|
||||||
"""
|
Новые установки используют хук setup_wizard_complete.
|
||||||
|
|
||||||
|
Создает категории активов для первой компании в системе.
|
||||||
|
"""
|
||||||
# Проверка существования таблицы Company
|
# Проверка существования таблицы Company
|
||||||
if not frappe.db.table_exists("Company"):
|
if not frappe.db.table_exists("Company"):
|
||||||
frappe.log_error("Company table not found", "Asset Categories Patch")
|
frappe.log_error("Company table not found", "Asset Categories Patch")
|
||||||
|
|
@ -37,66 +39,8 @@ def create_asset_categories():
|
||||||
|
|
||||||
company_name = company[0].name
|
company_name = company[0].name
|
||||||
|
|
||||||
# Получаем список системных категорий
|
# Используем новую функцию
|
||||||
asset_categories = get_system_asset_categories()
|
_create_categories_for_company(company_name)
|
||||||
|
|
||||||
# Находим нужные счета
|
|
||||||
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):
|
def get_account_by_name(account_name, company):
|
||||||
|
|
@ -116,6 +60,112 @@ def get_account_by_name(account_name, company):
|
||||||
return account
|
return account
|
||||||
|
|
||||||
|
|
||||||
|
def create_asset_categories_for_company(company_name):
|
||||||
|
"""
|
||||||
|
Создает категории активов для конкретной компании.
|
||||||
|
Вызывается как фоновая задача после setup wizard.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
company_name: Название компании
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
# Проверяем, что компания существует
|
||||||
|
if not frappe.db.exists("Company", company_name):
|
||||||
|
frappe.log_error(
|
||||||
|
f"Company '{company_name}' not found",
|
||||||
|
"Asset Categories Creation"
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
# Проверка идемпотентности: если категории уже есть, не создаем
|
||||||
|
system_categories = get_system_asset_categories()
|
||||||
|
existing_categories = frappe.db.count(
|
||||||
|
"Asset Category",
|
||||||
|
filters={"asset_category_name": ["in", system_categories]}
|
||||||
|
)
|
||||||
|
|
||||||
|
if existing_categories > 0:
|
||||||
|
frappe.log_error(
|
||||||
|
f"Asset categories already exist ({existing_categories} found). Skipping creation.",
|
||||||
|
"Asset Categories Creation - Info"
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
# Создаем категории
|
||||||
|
_create_categories_for_company(company_name)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
# Не пробрасываем исключение - это фоновая задача
|
||||||
|
frappe.log_error(
|
||||||
|
f"Failed to create asset categories for {company_name}: {str(e)}",
|
||||||
|
"Asset Categories Creation - Error"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _create_categories_for_company(company_name):
|
||||||
|
"""
|
||||||
|
Внутренняя функция для создания категорий активов.
|
||||||
|
Извлечена из create_asset_categories для переиспользования.
|
||||||
|
"""
|
||||||
|
asset_categories = get_system_asset_categories()
|
||||||
|
|
||||||
|
# Находим нужные счета
|
||||||
|
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 for {company_name}: {str(e)}",
|
||||||
|
"Asset Categories Creation - Error"
|
||||||
|
)
|
||||||
|
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
|
||||||
|
|
||||||
|
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
|
||||||
|
else:
|
||||||
|
skipped_count += 1
|
||||||
|
except Exception as e:
|
||||||
|
frappe.log_error(
|
||||||
|
f"Failed to create Asset Category '{category_name}': {str(e)}",
|
||||||
|
"Asset Categories Creation - Error"
|
||||||
|
)
|
||||||
|
|
||||||
|
frappe.db.commit()
|
||||||
|
|
||||||
|
message = f"Asset Categories created for {company_name}. Created: {created_count}, Skipped: {skipped_count}"
|
||||||
|
frappe.log_error(message, "Asset Categories Creation - Success")
|
||||||
|
print(message)
|
||||||
|
|
||||||
|
|
||||||
def prevent_delete_system_asset_categories(doc, method):
|
def prevent_delete_system_asset_categories(doc, method):
|
||||||
"""
|
"""
|
||||||
Запрещает удаление системных категорий активов
|
Запрещает удаление системных категорий активов
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,11 @@ doc_events = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Setup Wizard
|
||||||
|
# ------------
|
||||||
|
|
||||||
|
setup_wizard_complete = "jey_erp.setup.setup_wizard_handler.setup_wizard_complete_handler"
|
||||||
|
|
||||||
after_migrate = "jey_erp.hooks.after_migrate_combined"
|
after_migrate = "jey_erp.hooks.after_migrate_combined"
|
||||||
|
|
||||||
def after_migrate_combined():
|
def after_migrate_combined():
|
||||||
|
|
@ -64,10 +69,12 @@ def after_migrate_combined():
|
||||||
show_item_tax_template_in_sales_invoice()
|
show_item_tax_template_in_sales_invoice()
|
||||||
from jey_erp.custom.vat_calculations import patch_sales_documents
|
from jey_erp.custom.vat_calculations import patch_sales_documents
|
||||||
patch_sales_documents()
|
patch_sales_documents()
|
||||||
from jey_erp.custom.create_asset_categories import create_asset_categories
|
# REMOVED: Asset categories creation moved to setup_wizard_complete hook
|
||||||
create_asset_categories()
|
# from jey_erp.custom.create_asset_categories import create_asset_categories
|
||||||
|
# create_asset_categories()
|
||||||
|
|
||||||
after_install = "jey_erp.custom.create_asset_categories.create_asset_categories"
|
# REMOVED: Asset categories creation moved to setup_wizard_complete hook
|
||||||
|
# after_install = "jey_erp.custom.create_asset_categories.create_asset_categories"
|
||||||
|
|
||||||
fixtures = [
|
fixtures = [
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -4,3 +4,4 @@
|
||||||
|
|
||||||
[post_model_sync]
|
[post_model_sync]
|
||||||
# Patches added in this section will be executed after doctypes are migrated
|
# Patches added in this section will be executed after doctypes are migrated
|
||||||
|
jey_erp.patches.create_asset_categories_post_migration
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
import frappe
|
||||||
|
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
"""
|
||||||
|
Патч для создания категорий активов на существующих установках.
|
||||||
|
Выполняется при bench migrate после обновления кода.
|
||||||
|
"""
|
||||||
|
# Проверяем, что патч не был уже выполнен
|
||||||
|
system_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"
|
||||||
|
]
|
||||||
|
|
||||||
|
# Если хотя бы одна категория существует, считаем что патч уже выполнен
|
||||||
|
if frappe.db.exists("Asset Category", {"asset_category_name": system_categories[0]}):
|
||||||
|
return
|
||||||
|
|
||||||
|
# Проверяем, что компания существует
|
||||||
|
companies = frappe.get_all("Company", limit=1)
|
||||||
|
if not companies:
|
||||||
|
return # Нет компании - патч не нужен
|
||||||
|
|
||||||
|
company_name = companies[0].name
|
||||||
|
|
||||||
|
# Импортируем и запускаем создание
|
||||||
|
from jey_erp.custom.create_asset_categories import create_asset_categories_for_company
|
||||||
|
create_asset_categories_for_company(company_name)
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
# Empty file to make this a Python package
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
import frappe
|
||||||
|
|
||||||
|
|
||||||
|
def setup_wizard_complete_handler(args):
|
||||||
|
"""
|
||||||
|
Вызывается после завершения ERPNext setup wizard.
|
||||||
|
Ставит в очередь фоновую задачу для создания категорий активов.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
args: Словарь с параметрами визарда, включая:
|
||||||
|
- company_name: Название созданной компании
|
||||||
|
- country: Выбранная страна
|
||||||
|
- currency: Валюта по умолчанию
|
||||||
|
"""
|
||||||
|
company_name = args.get("company_name")
|
||||||
|
|
||||||
|
if not company_name:
|
||||||
|
# Fallback: получаем первую компанию
|
||||||
|
companies = frappe.get_all("Company", limit=1)
|
||||||
|
if companies:
|
||||||
|
company_name = companies[0].name
|
||||||
|
else:
|
||||||
|
frappe.log_error(
|
||||||
|
"Company name not found in setup wizard args and no companies exist",
|
||||||
|
"Asset Categories Setup"
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
# Ставим в очередь фоновую задачу (некритично, не блокирует визард)
|
||||||
|
frappe.enqueue(
|
||||||
|
"jey_erp.custom.create_asset_categories.create_asset_categories_for_company",
|
||||||
|
queue="default",
|
||||||
|
timeout=300,
|
||||||
|
enqueue_after_commit=True,
|
||||||
|
at_front=False, # Некритично, может подождать
|
||||||
|
company_name=company_name
|
||||||
|
)
|
||||||
|
|
||||||
|
frappe.msgprint(
|
||||||
|
f"Категории активов будут созданы в фоновом режиме для {company_name}",
|
||||||
|
title="Настройка выполняется",
|
||||||
|
indicator="blue"
|
||||||
|
)
|
||||||
Loading…
Reference in New Issue