From 1d048c9738f95c0bcbc84bf4e5fdfb5cef835322 Mon Sep 17 00:00:00 2001 From: JensFalk Date: Mon, 8 Jun 2026 14:23:15 +0200 Subject: [PATCH] README.md aktualisiert --- README.md | 139 +++--------------------------------------------------- 1 file changed, 7 insertions(+), 132 deletions(-) diff --git a/README.md b/README.md index 68bf505..3673c2c 100644 --- a/README.md +++ b/README.md @@ -1,141 +1,16 @@ # erpnext_custom -Custom App für NEXTErp mit WooCommerce ACF Sync (Advanced Custom Fields). +Custom App für NEXTErp mit zuverlässigem Sync von Custom Fields zu WooCommerce (ACF / Meta Data). ## 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 +- Sync beliebiger Custom Fields aus ERPNext-Item nach WooCommerce +- Verwendung von `meta_data` (stabiler als ACF-Block) +- Manueller Sync-Button im Item-Formular -## Installation (empfohlener Weg) +## Installation -### 1. App auf dem Server erstellen +### 1. App erstellen ```bash 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 - -```bash -cd ~/frappe-bench/apps/erpnext_custom/erpnext_custom -``` - -# Hier die aktuelle api.py einfügen (z.B. per cat > api.py << 'EOF' ...) z.B. -```bash -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 - -```bash -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 \ No newline at end of file +bench new-app erpnext_custom \ No newline at end of file