870 lines
36 KiB
Python
870 lines
36 KiB
Python
# ======= PYTHON API FUNCTIONS =======
|
||
|
||
import frappe
|
||
import requests
|
||
import json
|
||
from frappe.utils import nowdate, now, cint, now_datetime, get_datetime
|
||
|
||
# Список кодов игорной деятельности
|
||
GAMBLING_ACTIVITY_CODES = [
|
||
'92000',
|
||
'9200003',
|
||
'9200004',
|
||
'9200001',
|
||
'9200002',
|
||
'9200005'
|
||
]
|
||
|
||
@frappe.whitelist()
|
||
def force_update_gambling_fields(company_name, field_updates=None):
|
||
"""Форсированное обновление полей игорной деятельности"""
|
||
import json
|
||
|
||
try:
|
||
# Парсим JSON если нужно
|
||
if isinstance(field_updates, str):
|
||
field_updates = json.loads(field_updates) if field_updates else {}
|
||
|
||
# Проверяем существование компании
|
||
if not frappe.db.exists("Company", company_name):
|
||
return {"success": False, "message": f"Company {company_name} not found"}
|
||
|
||
# Получаем текущие данные компании
|
||
company = frappe.get_doc("Company", company_name)
|
||
|
||
# Проверяем что это игорная деятельность
|
||
if company.main_activity not in GAMBLING_ACTIVITY_CODES:
|
||
return {"success": False, "message": "This operation is only allowed for gambling activities"}
|
||
|
||
# Получаем текущие значения
|
||
current_seller = company.seller or 0
|
||
current_organizer = company.organizer or 0
|
||
|
||
# Применяем новые значения
|
||
new_seller = field_updates.get('seller', current_seller)
|
||
new_organizer = field_updates.get('organizer', current_organizer)
|
||
|
||
# Валидация: хотя бы одна галочка должна быть активна
|
||
if not new_seller and not new_organizer:
|
||
return {
|
||
"success": False,
|
||
"message": "At least one of Seller or Organizer must be checked for gambling activities"
|
||
}
|
||
|
||
# Белый список разрешенных полей для игорной деятельности
|
||
allowed_gambling_fields = ['seller', 'organizer']
|
||
|
||
# Фильтруем только разрешенные поля
|
||
filtered_updates = {
|
||
field: value for field, value in field_updates.items()
|
||
if field in allowed_gambling_fields
|
||
}
|
||
|
||
if not filtered_updates:
|
||
return {"success": False, "message": "No valid gambling fields to update"}
|
||
|
||
# Выполняем обновление через SQL
|
||
set_clauses = []
|
||
values = []
|
||
|
||
for field, value in filtered_updates.items():
|
||
set_clauses.append(f"`{field}` = %s")
|
||
values.append(cint(value))
|
||
|
||
if set_clauses:
|
||
sql = f"""
|
||
UPDATE `tabCompany`
|
||
SET {', '.join(set_clauses)}, `modified` = NOW(), `modified_by` = %s
|
||
WHERE `name` = %s
|
||
"""
|
||
values.append(frappe.session.user)
|
||
values.append(company_name)
|
||
|
||
frappe.db.sql(sql, tuple(values))
|
||
frappe.db.commit()
|
||
|
||
# Очищаем кэш
|
||
frappe.clear_cache(doctype="Company")
|
||
|
||
# Логируем изменение
|
||
frappe.logger().info(f"Gambling fields updated for company {company_name}: {filtered_updates}")
|
||
|
||
return {
|
||
"success": True,
|
||
"message": f"Gambling fields updated successfully",
|
||
"updated_fields": filtered_updates
|
||
}
|
||
|
||
except Exception as e:
|
||
frappe.log_error(f"Error in force_update_gambling_fields: {str(e)}", "Gambling Fields Update Error")
|
||
return {
|
||
"success": False,
|
||
"message": f"Error updating gambling fields: {str(e)}"
|
||
}
|
||
|
||
@frappe.whitelist()
|
||
def validate_gambling_activity(company_name, main_activity=None):
|
||
"""Валидация игорной деятельности и автоматическая настройка полей"""
|
||
try:
|
||
if not frappe.db.exists("Company", company_name):
|
||
return {"success": False, "message": f"Company {company_name} not found"}
|
||
|
||
company = frappe.get_doc("Company", company_name)
|
||
|
||
# Используем переданный main_activity или текущий
|
||
activity_code = main_activity or company.main_activity
|
||
|
||
if not activity_code:
|
||
return {"success": True, "is_gambling": False, "message": "No main activity set"}
|
||
|
||
is_gambling = activity_code in GAMBLING_ACTIVITY_CODES
|
||
|
||
updates_needed = {}
|
||
|
||
if is_gambling:
|
||
# Для игорной деятельности
|
||
if not company.seller and not company.organizer:
|
||
# Автоматически включаем обе галочки
|
||
updates_needed['seller'] = 1
|
||
updates_needed['organizer'] = 1
|
||
|
||
else:
|
||
# Для негавой деятельности - выключаем галочки
|
||
if company.seller or company.organizer:
|
||
updates_needed['seller'] = 0
|
||
updates_needed['organizer'] = 0
|
||
|
||
# Применяем изменения если нужно
|
||
if updates_needed:
|
||
set_clauses = []
|
||
values = []
|
||
|
||
for field, value in updates_needed.items():
|
||
set_clauses.append(f"`{field}` = %s")
|
||
values.append(cint(value))
|
||
|
||
sql = f"""
|
||
UPDATE `tabCompany`
|
||
SET {', '.join(set_clauses)}, `modified` = NOW(), `modified_by` = %s
|
||
WHERE `name` = %s
|
||
"""
|
||
values.append(frappe.session.user)
|
||
values.append(company_name)
|
||
|
||
frappe.db.sql(sql, tuple(values))
|
||
frappe.db.commit()
|
||
|
||
frappe.clear_cache(doctype="Company")
|
||
|
||
return {
|
||
"success": True,
|
||
"is_gambling": is_gambling,
|
||
"updates_applied": updates_needed,
|
||
"message": f"Activity validation completed for {activity_code}"
|
||
}
|
||
|
||
except Exception as e:
|
||
frappe.log_error(f"Error in validate_gambling_activity: {str(e)}", "Gambling Activity Validation Error")
|
||
return {
|
||
"success": False,
|
||
"message": f"Error validating gambling activity: {str(e)}"
|
||
}
|
||
|
||
@frappe.whitelist()
|
||
def get_company_profile(asan_login_name=None):
|
||
"""Получает профиль компании из E-Taxes"""
|
||
record_etaxes_activity()
|
||
|
||
try:
|
||
if not asan_login_name:
|
||
default_settings = get_default_asan_login()
|
||
if not default_settings.get("found", False):
|
||
return {"success": False, "message": "No Asan Login settings found."}
|
||
asan_login_name = default_settings.get("name")
|
||
|
||
asan_login = frappe.get_doc("Asan Login", asan_login_name)
|
||
|
||
if not asan_login.main_token:
|
||
return {"success": False, "message": "Main token not found. Please authenticate first."}
|
||
|
||
if asan_login.auth_status != "Fully Authenticated":
|
||
return {"success": False, "message": "Not fully authenticated. Please complete authentication process."}
|
||
|
||
url = "https://new.e-taxes.gov.az/api/po/profile/public/v2/profile"
|
||
|
||
headers = {
|
||
"Accept": "application/json, text/plain, */*",
|
||
"Accept-Language": "ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7",
|
||
"Cache-Control": "no-cache",
|
||
"Pragma": "no-cache",
|
||
"x-authorization": f"Bearer {asan_login.main_token}"
|
||
}
|
||
|
||
response = requests.get(url, headers=headers, timeout=15)
|
||
|
||
if response.status_code == 500:
|
||
return {
|
||
"error": "server_error",
|
||
"message": "E-Taxes service temporarily unavailable. Please try again in a few minutes.",
|
||
"status_code": 500
|
||
}
|
||
|
||
if response.status_code == 401:
|
||
frappe.db.set_value("Asan Login", asan_login_name, "auth_status", "Not Authenticated")
|
||
frappe.db.commit()
|
||
|
||
return {
|
||
"error": "unauthorized",
|
||
"message": "Authentication required. Please login again.",
|
||
"status_code": 401
|
||
}
|
||
|
||
response.raise_for_status()
|
||
profile_data = response.json()
|
||
|
||
frappe.logger().info(f"Company profile retrieved successfully for {asan_login_name}")
|
||
|
||
return {
|
||
"success": True,
|
||
"data": profile_data,
|
||
"message": "Company profile retrieved successfully"
|
||
}
|
||
|
||
except requests.exceptions.HTTPError as e:
|
||
if e.response.status_code == 401:
|
||
return {
|
||
"error": "unauthorized",
|
||
"message": "Authentication required. Please login again.",
|
||
"status_code": 401
|
||
}
|
||
elif e.response.status_code == 500:
|
||
return {
|
||
"error": "server_error",
|
||
"message": "E-Taxes service temporarily unavailable. Please try again in a few minutes.",
|
||
"status_code": 500
|
||
}
|
||
|
||
frappe.log_error(f"HTTP error in get_company_profile: {str(e)}", "Company Profile API Error")
|
||
return {
|
||
"error": "http_error",
|
||
"message": "An error occurred while fetching company profile"
|
||
}
|
||
|
||
except requests.exceptions.RequestException as e:
|
||
frappe.log_error(f"Request error in get_company_profile: {str(e)}", "Company Profile API Error")
|
||
return {
|
||
"error": "network_error",
|
||
"message": "Network error occurred. Please check your connection and try again."
|
||
}
|
||
|
||
except Exception as e:
|
||
frappe.log_error(f"Unexpected error in get_company_profile: {str(e)}\n{frappe.get_traceback()}", "Company Profile Error")
|
||
return {
|
||
"error": "unknown_error",
|
||
"message": "An unknown error occurred, please try again in a few minutes."
|
||
}
|
||
|
||
@frappe.whitelist()
|
||
def get_tax_authorities(asan_login_name=None):
|
||
"""Получает справочник налоговых органов из E-Taxes"""
|
||
record_etaxes_activity()
|
||
|
||
try:
|
||
if not asan_login_name:
|
||
default_settings = get_default_asan_login()
|
||
if not default_settings.get("found", False):
|
||
return {"success": False, "message": "No Asan Login settings found."}
|
||
asan_login_name = default_settings.get("name")
|
||
|
||
asan_login = frappe.get_doc("Asan Login", asan_login_name)
|
||
|
||
if not asan_login.main_token:
|
||
return {"success": False, "message": "Main token not found. Please authenticate first."}
|
||
|
||
if asan_login.auth_status != "Fully Authenticated":
|
||
return {"success": False, "message": "Not fully authenticated. Please complete authentication process."}
|
||
|
||
url = "https://new.e-taxes.gov.az/api/po/dictionary/public/v1/taxAuthorities"
|
||
|
||
headers = {
|
||
"Accept": "application/json, text/plain, */*",
|
||
"Accept-Language": "ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7",
|
||
"Cache-Control": "no-cache",
|
||
"Pragma": "no-cache",
|
||
"x-authorization": f"Bearer {asan_login.main_token}"
|
||
}
|
||
|
||
response = requests.get(url, headers=headers, timeout=15)
|
||
|
||
if response.status_code == 500:
|
||
return {
|
||
"error": "server_error",
|
||
"message": "E-Taxes service temporarily unavailable. Please try again in a few minutes.",
|
||
"status_code": 500
|
||
}
|
||
|
||
if response.status_code == 401:
|
||
frappe.db.set_value("Asan Login", asan_login_name, "auth_status", "Not Authenticated")
|
||
frappe.db.commit()
|
||
|
||
return {
|
||
"error": "unauthorized",
|
||
"message": "Authentication required. Please login again.",
|
||
"status_code": 401
|
||
}
|
||
|
||
response.raise_for_status()
|
||
tax_authorities_data = response.json()
|
||
|
||
frappe.logger().info(f"Tax authorities dictionary retrieved successfully for {asan_login_name}")
|
||
|
||
return {
|
||
"success": True,
|
||
"data": tax_authorities_data,
|
||
"message": "Tax authorities dictionary retrieved successfully"
|
||
}
|
||
|
||
except requests.exceptions.HTTPError as e:
|
||
if e.response.status_code == 401:
|
||
return {
|
||
"error": "unauthorized",
|
||
"message": "Authentication required. Please login again.",
|
||
"status_code": 401
|
||
}
|
||
elif e.response.status_code == 500:
|
||
return {
|
||
"error": "server_error",
|
||
"message": "E-Taxes service temporarily unavailable. Please try again in a few minutes.",
|
||
"status_code": 500
|
||
}
|
||
|
||
frappe.log_error(f"HTTP error in get_tax_authorities: {str(e)}", "Tax Authorities API Error")
|
||
return {
|
||
"error": "http_error",
|
||
"message": "An error occurred while fetching tax authorities dictionary"
|
||
}
|
||
|
||
except requests.exceptions.RequestException as e:
|
||
frappe.log_error(f"Request error in get_tax_authorities: {str(e)}", "Tax Authorities API Error")
|
||
return {
|
||
"error": "network_error",
|
||
"message": "Network error occurred. Please check your connection and try again."
|
||
}
|
||
|
||
except Exception as e:
|
||
frappe.log_error(f"Unexpected error in get_tax_authorities: {str(e)}\n{frappe.get_traceback()}", "Tax Authorities Error")
|
||
return {
|
||
"error": "unknown_error",
|
||
"message": "An unknown error occurred, please try again in a few minutes."
|
||
}
|
||
|
||
@frappe.whitelist()
|
||
def get_property_types(asan_login_name=None):
|
||
"""Получает справочник типов собственности из E-Taxes"""
|
||
record_etaxes_activity()
|
||
|
||
try:
|
||
if not asan_login_name:
|
||
default_settings = get_default_asan_login()
|
||
if not default_settings.get("found", False):
|
||
return {"success": False, "message": "No Asan Login settings found."}
|
||
asan_login_name = default_settings.get("name")
|
||
|
||
asan_login = frappe.get_doc("Asan Login", asan_login_name)
|
||
|
||
if not asan_login.main_token:
|
||
return {"success": False, "message": "Main token not found. Please authenticate first."}
|
||
|
||
if asan_login.auth_status != "Fully Authenticated":
|
||
return {"success": False, "message": "Not fully authenticated. Please complete authentication process."}
|
||
|
||
url = "https://new.e-taxes.gov.az/api/po/profile/public/v1/dictionary/propertyTypes"
|
||
|
||
headers = {
|
||
"Accept": "application/json, text/plain, */*",
|
||
"Accept-Language": "ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7",
|
||
"Cache-Control": "no-cache",
|
||
"Pragma": "no-cache",
|
||
"x-authorization": f"Bearer {asan_login.main_token}"
|
||
}
|
||
|
||
response = requests.get(url, headers=headers, timeout=15)
|
||
|
||
if response.status_code == 500:
|
||
return {
|
||
"error": "server_error",
|
||
"message": "E-Taxes service temporarily unavailable. Please try again in a few minutes.",
|
||
"status_code": 500
|
||
}
|
||
|
||
if response.status_code == 401:
|
||
frappe.db.set_value("Asan Login", asan_login_name, "auth_status", "Not Authenticated")
|
||
frappe.db.commit()
|
||
|
||
return {
|
||
"error": "unauthorized",
|
||
"message": "Authentication required. Please login again.",
|
||
"status_code": 401
|
||
}
|
||
|
||
response.raise_for_status()
|
||
property_types_data = response.json()
|
||
|
||
frappe.logger().info(f"Property types dictionary retrieved successfully for {asan_login_name}")
|
||
|
||
return {
|
||
"success": True,
|
||
"data": property_types_data,
|
||
"message": "Property types dictionary retrieved successfully"
|
||
}
|
||
|
||
except requests.exceptions.HTTPError as e:
|
||
if e.response.status_code == 401:
|
||
return {
|
||
"error": "unauthorized",
|
||
"message": "Authentication required. Please login again.",
|
||
"status_code": 401
|
||
}
|
||
elif e.response.status_code == 500:
|
||
return {
|
||
"error": "server_error",
|
||
"message": "E-Taxes service temporarily unavailable. Please try again in a few minutes.",
|
||
"status_code": 500
|
||
}
|
||
|
||
frappe.log_error(f"HTTP error in get_property_types: {str(e)}", "Property Types API Error")
|
||
return {
|
||
"error": "http_error",
|
||
"message": "An error occurred while fetching property types dictionary"
|
||
}
|
||
|
||
except requests.exceptions.RequestException as e:
|
||
frappe.log_error(f"Request error in get_property_types: {str(e)}", "Property Types API Error")
|
||
return {
|
||
"error": "network_error",
|
||
"message": "Network error occurred. Please check your connection and try again."
|
||
}
|
||
|
||
except Exception as e:
|
||
frappe.log_error(f"Unexpected error in get_property_types: {str(e)}\n{frappe.get_traceback()}", "Property Types Error")
|
||
return {
|
||
"error": "unknown_error",
|
||
"message": "An unknown error occurred, please try again in a few minutes."
|
||
}
|
||
|
||
@frappe.whitelist()
|
||
def get_tax_authority_name_by_code(code, asan_login_name=None):
|
||
"""Получает название налогового органа по коду"""
|
||
try:
|
||
tax_authorities_result = get_tax_authorities(asan_login_name)
|
||
|
||
if not tax_authorities_result.get("success"):
|
||
return {
|
||
"success": False,
|
||
"message": tax_authorities_result.get("message", "Failed to get tax authorities dictionary")
|
||
}
|
||
|
||
tax_authorities = tax_authorities_result.get("data", [])
|
||
|
||
if tax_authorities and isinstance(tax_authorities, list):
|
||
for authority in tax_authorities:
|
||
if authority.get("code") == code:
|
||
name = authority.get("name", {})
|
||
if isinstance(name, dict) and name.get("az"):
|
||
return {
|
||
"success": True,
|
||
"name": name.get("az"),
|
||
"code": code
|
||
}
|
||
elif isinstance(name, str):
|
||
return {
|
||
"success": True,
|
||
"name": name,
|
||
"code": code
|
||
}
|
||
|
||
return {
|
||
"success": True,
|
||
"name": code,
|
||
"code": code,
|
||
"message": "Tax authority name not found, returning code"
|
||
}
|
||
|
||
except Exception as e:
|
||
frappe.log_error(f"Error in get_tax_authority_name_by_code: {str(e)}", "Tax Authority Name Error")
|
||
return {
|
||
"success": False,
|
||
"message": "An error occurred while getting tax authority name"
|
||
}
|
||
|
||
@frappe.whitelist()
|
||
def get_property_type_name_by_code(code, asan_login_name=None):
|
||
"""Получает название типа собственности по коду"""
|
||
try:
|
||
property_types_result = get_property_types(asan_login_name)
|
||
|
||
if not property_types_result.get("success"):
|
||
return {
|
||
"success": False,
|
||
"message": property_types_result.get("message", "Failed to get property types dictionary")
|
||
}
|
||
|
||
property_types = property_types_result.get("data", {})
|
||
|
||
if property_types and isinstance(property_types, dict):
|
||
for property_type in property_types.values():
|
||
if isinstance(property_type, dict) and property_type.get("code") == code:
|
||
name = property_type.get("name", {})
|
||
if isinstance(name, dict) and name.get("az"):
|
||
return {
|
||
"success": True,
|
||
"name": name.get("az"),
|
||
"code": code
|
||
}
|
||
elif isinstance(name, str):
|
||
return {
|
||
"success": True,
|
||
"name": name,
|
||
"code": code
|
||
}
|
||
|
||
return {
|
||
"success": True,
|
||
"name": code,
|
||
"code": code,
|
||
"message": "Property type name not found, returning code"
|
||
}
|
||
|
||
except Exception as e:
|
||
frappe.log_error(f"Error in get_property_type_name_by_code: {str(e)}", "Property Type Name Error")
|
||
return {
|
||
"success": False,
|
||
"message": "An error occurred while getting property type name"
|
||
}
|
||
|
||
@frappe.whitelist()
|
||
def force_update_declaration_defaults(company_name, mdss, icbari, issizlik):
|
||
"""Обновление полей умолчаний деклараций на компании, минуя проверку submit-статуса"""
|
||
try:
|
||
if not frappe.db.exists("Company", company_name):
|
||
return {"success": False, "message": f"Company {company_name} not found"}
|
||
|
||
frappe.db.sql("""
|
||
UPDATE `tabCompany`
|
||
SET `mdssüzrə` = %s,
|
||
`icbaritibbisığortaüzrə` = %s,
|
||
`işsizlikdənsığortaüzrə` = %s,
|
||
`modified` = NOW(),
|
||
`modified_by` = %s
|
||
WHERE `name` = %s
|
||
""", (mdss or '', icbari or '', issizlik or '', frappe.session.user, company_name))
|
||
|
||
frappe.db.commit()
|
||
return {"success": True}
|
||
|
||
except Exception as e:
|
||
frappe.log_error(f"Error in force_update_declaration_defaults: {str(e)}", "Declaration Defaults Error")
|
||
return {"success": False, "message": str(e)}
|
||
|
||
|
||
@frappe.whitelist()
|
||
def force_update_single_field(company_name, field_name, field_value):
|
||
"""Форсированное обновление одного поля компании"""
|
||
try:
|
||
if not company_name or not field_name:
|
||
return {"success": False, "message": "Company name and field name are required"}
|
||
|
||
if not frappe.db.exists("Company", company_name):
|
||
return {"success": False, "message": f"Company {company_name} not found"}
|
||
|
||
allowed_fields = [
|
||
'main_activity', 'tax_id', 'phone_no', 'email',
|
||
'director_name_etaxes', 'business_classification',
|
||
'tax_authority', 'property_type', 'vat_certificate_number'
|
||
]
|
||
|
||
if field_name not in allowed_fields:
|
||
return {"success": False, "message": f"Field {field_name} is not allowed for force update"}
|
||
|
||
if field_name == 'main_activity' and field_value:
|
||
if not frappe.db.exists("Main type of activity", field_value):
|
||
return {"success": False, "message": f"Main type of activity {field_value} does not exist"}
|
||
|
||
frappe.db.sql("""
|
||
UPDATE `tabCompany`
|
||
SET `{field}` = %s, `modified` = NOW(), `modified_by` = %s
|
||
WHERE `name` = %s
|
||
""".format(field=field_name), (field_value, frappe.session.user, company_name))
|
||
|
||
frappe.db.commit()
|
||
frappe.clear_cache(doctype="Company")
|
||
|
||
# Если обновляли main_activity, проверяем игорную деятельность
|
||
if field_name == 'main_activity':
|
||
validate_gambling_activity(company_name, field_value)
|
||
|
||
return {
|
||
"success": True,
|
||
"message": f"Field {field_name} updated successfully"
|
||
}
|
||
|
||
except Exception as e:
|
||
frappe.log_error(f"Error in force_update_single_field: {str(e)}", "Force Update Error")
|
||
return {
|
||
"success": False,
|
||
"message": f"Error updating field: {str(e)}"
|
||
}
|
||
|
||
@frappe.whitelist()
|
||
def force_update_company(company_name, field_updates=None, additional_activities=None, affiliate_names=None, affiliate_tins=None):
|
||
"""Форсированное обновление полей компании через прямые SQL-запросы"""
|
||
import json
|
||
|
||
try:
|
||
# Парсим JSON если нужно
|
||
if isinstance(field_updates, str):
|
||
field_updates = json.loads(field_updates) if field_updates else {}
|
||
if isinstance(additional_activities, str):
|
||
additional_activities = json.loads(additional_activities) if additional_activities else []
|
||
if isinstance(affiliate_names, str):
|
||
affiliate_names = json.loads(affiliate_names) if affiliate_names else []
|
||
if isinstance(affiliate_tins, str):
|
||
affiliate_tins = json.loads(affiliate_tins) if affiliate_tins else []
|
||
|
||
# Проверяем существование компании
|
||
if not frappe.db.exists("Company", company_name):
|
||
return {"success": False, "message": f"Company {company_name} not found"}
|
||
|
||
# Обновляем основные поля через SQL
|
||
if field_updates:
|
||
set_clauses = []
|
||
values = []
|
||
|
||
for field, value in field_updates.items():
|
||
set_clauses.append(f"`{field}` = %s")
|
||
values.append(value)
|
||
|
||
if set_clauses:
|
||
sql = f"""
|
||
UPDATE `tabCompany`
|
||
SET {', '.join(set_clauses)}, `modified` = NOW(), `modified_by` = %s
|
||
WHERE `name` = %s
|
||
"""
|
||
values.append(frappe.session.user)
|
||
values.append(company_name)
|
||
|
||
frappe.db.sql(sql, tuple(values))
|
||
|
||
# Обработка additional activities
|
||
activities_added = 0
|
||
if additional_activities and len(additional_activities) > 0:
|
||
# ИСПРАВЛЕНО: Правильное имя таблицы
|
||
table_name = "Company Additional Activity" # БЕЗ "Types" в конце!
|
||
|
||
if not frappe.db.table_exists(table_name):
|
||
frappe.log_error(f"Table '{table_name}' does not exist", "Table Check Error")
|
||
return {"success": False, "message": f"Table '{table_name}' does not exist"}
|
||
|
||
# Удаляем старые записи
|
||
frappe.db.sql(f"""DELETE FROM `tab{table_name}` WHERE parent = %s""", company_name)
|
||
|
||
# Добавляем новые additional activities
|
||
for idx, activity_code in enumerate(additional_activities):
|
||
if activity_code and activity_code.strip():
|
||
# Проверяем существование activity в справочнике
|
||
activity_exists = frappe.db.exists("Main type of activity", activity_code.strip())
|
||
|
||
if activity_exists:
|
||
# Генерируем уникальное имя
|
||
record_name = frappe.generate_hash(length=10)
|
||
|
||
frappe.db.sql(f"""
|
||
INSERT INTO `tab{table_name}`
|
||
(name, parent, parenttype, parentfield, idx, activity_type, docstatus, creation, modified, modified_by, owner)
|
||
VALUES (%s, %s, %s, %s, %s, %s, %s, NOW(), NOW(), %s, %s)
|
||
""", (
|
||
record_name,
|
||
company_name,
|
||
'Company',
|
||
'additional_activity_types', # fieldname остается тем же
|
||
idx + 1,
|
||
activity_code.strip(),
|
||
0,
|
||
frappe.session.user,
|
||
frappe.session.user
|
||
))
|
||
|
||
activities_added += 1
|
||
frappe.logger().info(f"Added additional activity: {activity_code} for company {company_name}")
|
||
else:
|
||
frappe.logger().warning(f"Activity code {activity_code} not found in Main type of activity")
|
||
|
||
# Проверяем, что записи действительно добавились
|
||
count = frappe.db.sql(f"""
|
||
SELECT COUNT(*) FROM `tab{table_name}`
|
||
WHERE parent = %s
|
||
""", company_name)[0][0]
|
||
|
||
frappe.logger().info(f"Total additional activities in DB after update: {count}")
|
||
|
||
# Обработка affiliate organizations
|
||
affiliates_added = 0
|
||
if (affiliate_names or affiliate_tins):
|
||
# ИСПРАВЛЕНО: Правильное имя таблицы
|
||
table_name = "Company Affiliate Organization" # В единственном числе!
|
||
|
||
if frappe.db.table_exists(table_name):
|
||
# Удаляем старые записи
|
||
frappe.db.sql(f"""DELETE FROM `tab{table_name}` WHERE parent = %s""", company_name)
|
||
|
||
# Добавляем новые affiliate organizations
|
||
max_length = max(len(affiliate_names or []), len(affiliate_tins or []))
|
||
for idx in range(max_length):
|
||
org_name = affiliate_names[idx] if affiliate_names and idx < len(affiliate_names) else ""
|
||
org_tin = affiliate_tins[idx] if affiliate_tins and idx < len(affiliate_tins) else ""
|
||
|
||
if org_name or org_tin:
|
||
if not org_name and org_tin:
|
||
org_name = f"Organization (TIN: {org_tin})"
|
||
|
||
record_name = frappe.generate_hash(length=10)
|
||
|
||
frappe.db.sql(f"""
|
||
INSERT INTO `tab{table_name}`
|
||
(name, parent, parenttype, parentfield, idx, organization_name, organization_tin, docstatus, creation, modified, modified_by, owner)
|
||
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, NOW(), NOW(), %s, %s)
|
||
""", (
|
||
record_name,
|
||
company_name,
|
||
'Company',
|
||
'affiliate_organizations', # fieldname остается тем же
|
||
idx + 1,
|
||
org_name,
|
||
org_tin or None,
|
||
0,
|
||
frappe.session.user,
|
||
frappe.session.user
|
||
))
|
||
|
||
affiliates_added += 1
|
||
frappe.logger().info(f"Added affiliate organization: {org_name} (TIN: {org_tin}) for company {company_name}")
|
||
else:
|
||
frappe.logger().error(f"Table '{table_name}' does not exist")
|
||
|
||
# Коммитим изменения
|
||
frappe.db.commit()
|
||
|
||
# Очищаем весь кэш для компании
|
||
frappe.clear_cache(doctype="Company")
|
||
frappe.clear_document_cache("Company", company_name)
|
||
|
||
# Если обновляли main_activity, проверяем игорную деятельность
|
||
if field_updates and 'main_activity' in field_updates:
|
||
validate_gambling_activity(company_name, field_updates['main_activity'])
|
||
|
||
# Возвращаем детальную информацию об обновлении
|
||
return {
|
||
"success": True,
|
||
"message": "Company updated successfully",
|
||
"updated_fields": len(field_updates) if field_updates else 0,
|
||
"additional_activities_added": activities_added,
|
||
"affiliates_added": affiliates_added
|
||
}
|
||
|
||
except Exception as e:
|
||
frappe.log_error(f"Error in force_update_company: {str(e)}\n{frappe.get_traceback()}", "Company Update Error")
|
||
frappe.db.rollback()
|
||
return {
|
||
"success": False,
|
||
"message": f"Error updating company: {str(e)}"
|
||
}
|
||
|
||
# Helper functions
|
||
def record_etaxes_activity():
|
||
"""Placeholder for activity recording"""
|
||
pass
|
||
|
||
def get_default_asan_login():
|
||
"""Получает настройки по умолчанию для Asan Login"""
|
||
try:
|
||
default_login = frappe.get_list(
|
||
"Asan Login",
|
||
filters={"is_default": 1},
|
||
fields=["name"]
|
||
)
|
||
|
||
if default_login:
|
||
asan_login = frappe.get_doc("Asan Login", default_login[0].name)
|
||
return {
|
||
"found": True,
|
||
"name": asan_login.name,
|
||
"phone": asan_login.phone,
|
||
"user_id": asan_login.user_id,
|
||
"auth_status": asan_login.auth_status,
|
||
"bearer_token": asan_login.bearer_token,
|
||
"main_token": asan_login.main_token,
|
||
"selected_certificate": asan_login.selected_certificate
|
||
}
|
||
else:
|
||
return {"found": False, "message": "No Asan Login settings found."}
|
||
|
||
except Exception as e:
|
||
return {"found": False, "error": str(e)}
|
||
|
||
@frappe.whitelist()
|
||
def check_company_structure(company_name):
|
||
"""Диагностическая функция для проверки структуры Company"""
|
||
try:
|
||
company = frappe.get_doc("Company", company_name)
|
||
|
||
# Проверяем наличие полей
|
||
has_additional_activities = hasattr(company, 'additional_activity_types')
|
||
has_affiliate_orgs = hasattr(company, 'affiliate_organizations')
|
||
|
||
# ИСПРАВЛЕНО: Правильные имена таблиц
|
||
table1_exists = frappe.db.table_exists("Company Additional Activity")
|
||
table2_exists = frappe.db.table_exists("Company Affiliate Organization")
|
||
|
||
# Получаем текущее количество записей
|
||
activities_count = 0
|
||
affiliates_count = 0
|
||
|
||
if table1_exists:
|
||
activities_count = frappe.db.sql("""
|
||
SELECT COUNT(*) FROM `tabCompany Additional Activity`
|
||
WHERE parent = %s
|
||
""", company_name)[0][0]
|
||
|
||
if table2_exists:
|
||
affiliates_count = frappe.db.sql("""
|
||
SELECT COUNT(*) FROM `tabCompany Affiliate Organization`
|
||
WHERE parent = %s
|
||
""", company_name)[0][0]
|
||
|
||
# Получаем метаданные о child tables
|
||
meta = frappe.get_meta("Company")
|
||
child_tables = []
|
||
for field in meta.fields:
|
||
if field.fieldtype == "Table":
|
||
child_tables.append({
|
||
"fieldname": field.fieldname,
|
||
"options": field.options,
|
||
"label": field.label
|
||
})
|
||
|
||
return {
|
||
"success": True,
|
||
"has_additional_activities_field": has_additional_activities,
|
||
"has_affiliate_orgs_field": has_affiliate_orgs,
|
||
"table1_exists": table1_exists,
|
||
"table2_exists": table2_exists,
|
||
"activities_count_in_db": activities_count,
|
||
"affiliates_count_in_db": affiliates_count,
|
||
"child_tables": child_tables
|
||
}
|
||
|
||
except Exception as e:
|
||
return {
|
||
"success": False,
|
||
"error": str(e)
|
||
} |