Files
erpnext_custom/nexterp_custom/api.py
T

107 lines
4.0 KiB
Python
Raw Normal View History

2026-06-06 19:45:39 +02:00
import frappe
import requests
from frappe import _
@frappe.whitelist()
def sync_custom_fields_to_woocommerce(item_code):
2026-06-06 19:50:17 +02:00
"""Sync Custom Fields vom Item nach WooCommerce ACF
Liest die Zuordnungen dynamisch aus dem DocType 'WooCommerce ACF Mapping'"""
2026-06-06 19:45:39 +02:00
if not item_code:
frappe.throw(_("Kein Item Code angegeben"))
2026-06-06 19:47:50 +02:00
try:
doc = frappe.get_doc("Item", item_code)
except Exception:
frappe.throw(_("Item {0} nicht gefunden").format(item_code))
2026-06-06 19:45:39 +02:00
if not doc.get("woocommerce_servers"):
2026-06-06 19:47:50 +02:00
frappe.msgprint(_("Item hat keine verknüpften WooCommerce Server"), indicator="orange")
2026-06-06 19:45:39 +02:00
return False
2026-06-06 19:50:17 +02:00
# Dynamisches Mapping aus dem DocType laden
field_mapping = {}
mappings = frappe.get_all("WooCommerce ACF Mapping",
filters={"enabled": 1},
fields=["erp_field", "acf_field"])
for m in mappings:
if m.erp_field and m.acf_field:
field_mapping[m.erp_field] = m.acf_field
if not field_mapping:
frappe.msgprint(_("Keine aktivierten Mappings im DocType 'WooCommerce ACF Mapping' gefunden"),
indicator="orange")
return False
2026-06-06 19:45:39 +02:00
success_count = 0
2026-06-06 19:47:50 +02:00
errors = []
2026-06-06 19:45:39 +02:00
for wc_link in doc.woocommerce_servers:
if not wc_link.enable_sync or not wc_link.woocommerce_id:
continue
try:
wc_server = frappe.get_doc("WooCommerce Server", wc_link.woocommerce_server)
2026-06-06 19:47:50 +02:00
if not wc_server.api_key or not wc_server.api_secret:
errors.append("WooCommerce Server {} hat keine Zugangsdaten".format(wc_link.woocommerce_server))
continue
# Basis URL vorbereiten
2026-06-06 19:45:39 +02:00
base_url = wc_server.woocommerce_server_url.rstrip("/")
if not base_url.endswith("/wp-json/wc/v3"):
base_url += "/wp-json/wc/v3"
2026-06-06 19:47:50 +02:00
url = "{}/products/{}".format(base_url, wc_link.woocommerce_id)
2026-06-06 19:45:39 +02:00
auth = (wc_server.api_key, wc_server.api_secret)
2026-06-06 19:47:50 +02:00
# Produkt holen
resp = requests.get(url, auth=auth, timeout=15)
2026-06-06 19:45:39 +02:00
resp.raise_for_status()
product = resp.json()
2026-06-06 19:47:50 +02:00
# ACF Daten mergen
2026-06-06 19:45:39 +02:00
acf_data = product.get("acf", {})
2026-06-06 19:47:50 +02:00
updated_fields = 0
2026-06-06 19:45:39 +02:00
for erp_field, acf_field in field_mapping.items():
value = doc.get(erp_field)
if value is not None:
acf_data[acf_field] = value
2026-06-06 19:47:50 +02:00
updated_fields += 1
2026-06-06 19:45:39 +02:00
2026-06-06 19:47:50 +02:00
if updated_fields == 0:
continue
2026-06-06 19:45:39 +02:00
payload = {"acf": acf_data}
2026-06-06 19:47:50 +02:00
# Update durchführen
update_resp = requests.put(url, json=payload, auth=auth, timeout=15)
2026-06-06 19:45:39 +02:00
update_resp.raise_for_status()
success_count += 1
2026-06-06 19:47:50 +02:00
except requests.exceptions.RequestException as e:
2026-06-06 19:50:17 +02:00
error_msg = "API-Fehler für Produkt {}: {}".format(wc_link.woocommerce_id, str(e))
2026-06-06 19:47:50 +02:00
errors.append(error_msg)
frappe.log_error(error_msg, "WooCommerce ACF Sync")
2026-06-06 19:45:39 +02:00
except Exception as e:
2026-06-06 19:50:17 +02:00
error_msg = "Unerwarteter Fehler für Item {} / WC-ID {}: {}".format(item_code, wc_link.woocommerce_id, str(e))
2026-06-06 19:47:50 +02:00
errors.append(error_msg)
frappe.log_error(error_msg, "WooCommerce ACF Sync")
2026-06-06 19:45:39 +02:00
2026-06-06 19:47:50 +02:00
# Zusammenfassung
2026-06-06 19:45:39 +02:00
if success_count > 0:
2026-06-06 19:50:17 +02:00
msg = "Custom Fields für {} WooCommerce-Produkt(e) erfolgreich synchronisiert".format(success_count)
2026-06-06 19:47:50 +02:00
if errors:
2026-06-06 19:50:17 +02:00
msg += " ({} Fehler aufgetreten)".format(len(errors))
2026-06-06 19:47:50 +02:00
frappe.msgprint(msg, alert=True, indicator="green")
2026-06-06 19:45:39 +02:00
return True
2026-06-06 19:47:50 +02:00
else:
if errors:
frappe.msgprint("Fehler beim Sync:\n" + "\n".join(errors[:3]), indicator="red")
else:
frappe.msgprint("Keine Felder wurden synchronisiert.", indicator="orange")
return False