Files
erpnext_custom/README.md
T
2026-06-07 13:44:06 +02:00

4.6 KiB

erpnext_custom

Custom App für NEXTErp mit WooCommerce ACF Sync (Advanced Custom Fields).

Funktionen

  • Übertragung beliebiger Custom Fields aus dem ERPNext-Item nach WooCommerce (ACF)
  • Dynamisches Mapping über das DocType WooCommerce ACF Mapping
  • Funktioniert mit mehreren WooCommerce Servern

Installation (empfohlener Weg)

1. App auf dem Server erstellen

cd ~/frappe-bench
bench new-app erpnext_custom

Bei den Fragen folgendes eingeben:

App Title: NEXTErp Custom App Description: WooCommerce ACF Custom Fields Sync App Publisher: Jens Falk App Email: service@falk.plus (oder deine Email) Branch Name: main oder einfach Enter drücken

cd ~/frappe-bench/apps/erpnext_custom/erpnext_custom

Hier die aktuelle api.py einfügen (z.B. per cat > api.py << 'EOF' ...)

cat > api.py << 'EOF' import frappe import requests from frappe import _

@frappe.whitelist() def sync_custom_fields_to_woocommerce(item_code): """Sync Custom Fields vom Item nach WooCommerce ACF (dynamisch aus DocType)"""

if not item_code:
    frappe.throw(_("Kein Item Code angegeben"))

try:
    doc = frappe.get_doc("Item", item_code)
except Exception:
    frappe.throw(_("Item {0} nicht gefunden").format(item_code))

if not doc.get("woocommerce_servers"):
    frappe.msgprint(_("Item hat keine verknüpften WooCommerce Server"), indicator="orange")
    return False

# Dynamisches Mapping aus dem DocType "WooCommerce ACF Mapping"
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

success_count = 0
errors = []

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)
        
        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
        
        base_url = wc_server.woocommerce_server_url.rstrip("/")
        if not base_url.endswith("/wp-json/wc/v3"):
            base_url += "/wp-json/wc/v3"
        
        url = "{}/products/{}".format(base_url, wc_link.woocommerce_id)
        auth = (wc_server.api_key, wc_server.api_secret)
        
        resp = requests.get(url, auth=auth, timeout=15)
        resp.raise_for_status()
        product = resp.json()
        
        acf_data = product.get("acf", {})
        
        updated_fields = 0
        for erp_field, acf_field in field_mapping.items():
            value = doc.get(erp_field)
            if value is not None:
                acf_data[acf_field] = value
                updated_fields += 1
        
        if updated_fields == 0:
            continue
            
        payload = {"acf": acf_data}
        
        update_resp = requests.put(url, json=payload, auth=auth, timeout=15)
        update_resp.raise_for_status()
        
        success_count += 1
        
    except Exception as e:
        error_msg = "Fehler für Item {} / WC-ID {}: {}".format(item_code, wc_link.woocommerce_id, str(e))
        errors.append(error_msg)
        frappe.log_error(error_msg, "WooCommerce ACF Sync")

if success_count > 0:
    msg = "Custom Fields für {} WooCommerce-Produkt(e) erfolgreich synchronisiert".format(success_count)
    if errors:
        msg += " ({} Fehler)".format(len(errors))
    frappe.msgprint(msg, alert=True, indicator="green")
    return True
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

EOF

Installation abschließen

bench --site erp.berchmans.de install-app erpnext_custom --force
bench --site erp.berchmans.de migrate
bench restart

Weiterer Schritt (nach Installation)
Danach das DocType WooCommerce ACF Mapping anlegen