245 lines
7.4 KiB
Python
245 lines
7.4 KiB
Python
import frappe
|
|
import requests
|
|
import json
|
|
from invoice_az.auth import record_etaxes_activity, get_default_asan_login
|
|
|
|
# Constants
|
|
BASE_URL = "https://new.e-taxes.gov.az"
|
|
FIND_BY_FIN_URL = f"{BASE_URL}/api/po/profile/public/v1/taxpayer/findByFinAndPassport"
|
|
|
|
DEFAULT_HEADERS = {
|
|
"Accept": "application/json, text/plain, */*",
|
|
"Accept-Language": "en-US,en;q=0.9",
|
|
"Content-Type": "application/json",
|
|
"Cache-Control": "no-cache",
|
|
"Pragma": "no-cache"
|
|
}
|
|
|
|
|
|
@frappe.whitelist()
|
|
def fetch_supplier_data_from_etaxes(supplier_name):
|
|
"""
|
|
Fetch Individual supplier data from E-Taxes by FIN and Passport Serial Number
|
|
|
|
Args:
|
|
supplier_name: Name of Supplier document
|
|
|
|
Returns:
|
|
dict: {
|
|
"success": bool,
|
|
"data": {
|
|
"fin": str,
|
|
"fullName": str,
|
|
"phone": str,
|
|
"dateOfBirth": str,
|
|
"firstname": str,
|
|
"lastname": str,
|
|
"patronimyc": str
|
|
},
|
|
"message": str
|
|
}
|
|
"""
|
|
try:
|
|
# Record activity for token renewal
|
|
record_etaxes_activity()
|
|
|
|
# Get Supplier document
|
|
supplier = frappe.get_doc("Supplier", supplier_name)
|
|
|
|
# Validate supplier type
|
|
if supplier.supplier_type != "Individual":
|
|
return {
|
|
"success": False,
|
|
"message": "This function only works for Individual suppliers"
|
|
}
|
|
|
|
# Check required fields
|
|
if not supplier.fin:
|
|
return {
|
|
"success": False,
|
|
"message": "FIN is required. Please fill FIN field first."
|
|
}
|
|
|
|
if not supplier.passport_serial_number:
|
|
return {
|
|
"success": False,
|
|
"message": "Passport Serial Number is required. Please fill Passport Serial Number field first."
|
|
}
|
|
|
|
# Get authentication token
|
|
asan_login = get_default_asan_login()
|
|
if not asan_login.get("found") or not asan_login.get("main_token"):
|
|
return {
|
|
"success": False,
|
|
"message": "E-Taxes authentication not found. Please login via ASAN."
|
|
}
|
|
|
|
token = asan_login.get("main_token")
|
|
|
|
# Build headers
|
|
headers = DEFAULT_HEADERS.copy()
|
|
headers["x-authorization"] = f"Bearer {token}"
|
|
|
|
# Build payload
|
|
payload = {
|
|
"fin": supplier.fin,
|
|
"passportSerialNumber": supplier.passport_serial_number
|
|
}
|
|
|
|
# Make API request
|
|
response = requests.post(
|
|
FIND_BY_FIN_URL,
|
|
data=json.dumps(payload),
|
|
headers=headers,
|
|
timeout=30
|
|
)
|
|
|
|
# Handle 401 Unauthorized
|
|
if response.status_code == 401:
|
|
return {
|
|
"success": False,
|
|
"message": "Authentication expired. Please login again via ASAN."
|
|
}
|
|
|
|
# Handle 500 Server Error
|
|
if response.status_code == 500:
|
|
return {
|
|
"success": False,
|
|
"message": "E-Taxes service error. Please try again later."
|
|
}
|
|
|
|
# Handle 404 Not Found (person not found)
|
|
if response.status_code == 404:
|
|
return {
|
|
"success": False,
|
|
"message": "Person not found in E-Taxes system. Please check FIN and Passport Serial Number."
|
|
}
|
|
|
|
# Handle errors with E-Taxes message format
|
|
# Accept both 200 (OK) and 201 (Created) as success
|
|
if response.status_code not in [200, 201]:
|
|
try:
|
|
error_data = response.json()
|
|
# Try to get Azerbaijani message first
|
|
if isinstance(error_data, dict) and "message" in error_data:
|
|
if isinstance(error_data["message"], dict) and "az" in error_data["message"]:
|
|
return {
|
|
"success": False,
|
|
"message": error_data["message"]["az"]
|
|
}
|
|
elif isinstance(error_data["message"], str):
|
|
return {
|
|
"success": False,
|
|
"message": error_data["message"]
|
|
}
|
|
except:
|
|
pass
|
|
|
|
return {
|
|
"success": False,
|
|
"message": f"E-Taxes error (status {response.status_code})"
|
|
}
|
|
|
|
response.raise_for_status()
|
|
|
|
# Parse response
|
|
result = response.json()
|
|
|
|
return {
|
|
"success": True,
|
|
"data": result
|
|
}
|
|
|
|
except requests.exceptions.RequestException as e:
|
|
frappe.log_error(
|
|
f"Error fetching supplier data from E-Taxes: {str(e)}",
|
|
"Fetch Supplier Data Error"
|
|
)
|
|
return {
|
|
"success": False,
|
|
"message": f"Network error: {str(e)}"
|
|
}
|
|
except Exception as e:
|
|
frappe.log_error(
|
|
f"Unexpected error fetching supplier data: {str(e)}\n{frappe.get_traceback()}",
|
|
"Fetch Supplier Data Error"
|
|
)
|
|
return {
|
|
"success": False,
|
|
"message": f"Error: {str(e)}"
|
|
}
|
|
|
|
|
|
@frappe.whitelist()
|
|
def update_supplier_from_etaxes(supplier_name):
|
|
"""
|
|
Fetch data from E-Taxes and update Supplier fields
|
|
|
|
Args:
|
|
supplier_name: Name of Supplier document
|
|
|
|
Returns:
|
|
dict: Success/error response with update details
|
|
"""
|
|
try:
|
|
# Fetch data from E-Taxes
|
|
fetch_result = fetch_supplier_data_from_etaxes(supplier_name)
|
|
|
|
if not fetch_result.get("success"):
|
|
return fetch_result
|
|
|
|
data = fetch_result.get("data")
|
|
|
|
# Get Supplier document
|
|
supplier = frappe.get_doc("Supplier", supplier_name)
|
|
|
|
# Update fields from E-Taxes response
|
|
updated_fields = []
|
|
|
|
# Date of birth
|
|
if data.get("dateOfBirth") and not supplier.date_of_birth:
|
|
supplier.date_of_birth = data.get("dateOfBirth")
|
|
updated_fields.append("Date of Birth")
|
|
|
|
# First name
|
|
if data.get("firstname"):
|
|
supplier.first_name_individual = data.get("firstname")
|
|
updated_fields.append("First Name")
|
|
|
|
# Last name
|
|
if data.get("lastname"):
|
|
supplier.last_name_individual = data.get("lastname")
|
|
updated_fields.append("Last Name")
|
|
|
|
# Patronymic (middle name / father's name)
|
|
if data.get("patronimyc"):
|
|
supplier.patronimyc = data.get("patronimyc")
|
|
updated_fields.append("Patronymic")
|
|
|
|
# Phone number (optional)
|
|
if data.get("phone") and not supplier.phone_number_individual:
|
|
supplier.phone_number_individual = data.get("phone")
|
|
updated_fields.append("Phone Number")
|
|
|
|
# Note: Supplier Name is not updated to preserve user's custom name
|
|
|
|
# Save supplier
|
|
supplier.save()
|
|
frappe.db.commit()
|
|
|
|
return {
|
|
"success": True,
|
|
"message": f"Supplier data updated successfully. Updated fields: {', '.join(updated_fields)}",
|
|
"updated_fields": updated_fields
|
|
}
|
|
|
|
except Exception as e:
|
|
frappe.log_error(
|
|
f"Error updating supplier from E-Taxes: {str(e)}\n{frappe.get_traceback()}",
|
|
"Update Supplier Error"
|
|
)
|
|
return {
|
|
"success": False,
|
|
"message": f"Error: {str(e)}"
|
|
}
|