diff --git a/nexterp_custom/api.py b/nexterp_custom/api.py index ff0cb17..f91de94 100644 --- a/nexterp_custom/api.py +++ b/nexterp_custom/api.py @@ -4,26 +4,30 @@ from frappe import _ @frappe.whitelist() def sync_custom_fields_to_woocommerce(item_code): - """Sync Custom Fields vom Item nach WooCommerce (ACF)""" + """Sync Custom Fields vom Item nach WooCommerce ACF""" if not item_code: frappe.throw(_("Kein Item Code angegeben")) - doc = frappe.get_doc("Item", item_code) + 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 - # Hier die Felder definieren: ERPNext-Feldname : ACF-Feldname in WordPress + # Hier die Felder definieren: ERPNext-Feld : ACF-Feld field_mapping = { "custom_zustand2": "zustand2", - # Weitere Felder hier hinzufügen, z.B.: + # Weitere Felder hier hinzufügen: # "custom_mein_feld": "mein_feld", # "custom_preisstufe": "preisstufe", - # "custom_bemerkung": "bemerkung", } success_count = 0 + errors = [] for wc_link in doc.woocommerce_servers: if not wc_link.enable_sync or not wc_link.woocommerce_id: @@ -32,46 +36,64 @@ def sync_custom_fields_to_woocommerce(item_code): 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 + + # Basis URL vorbereiten base_url = wc_server.woocommerce_server_url.rstrip("/") if not base_url.endswith("/wp-json/wc/v3"): base_url += "/wp-json/wc/v3" - url = f"{base_url}/products/{wc_link.woocommerce_id}" + url = "{}/products/{}".format(base_url, wc_link.woocommerce_id) auth = (wc_server.api_key, wc_server.api_secret) - # Aktuelles Produkt holen - resp = requests.get(url, auth=auth, timeout=20) + # Produkt holen + resp = requests.get(url, auth=auth, timeout=15) resp.raise_for_status() product = resp.json() - # ACF Daten aufbauen / mergen + # ACF Daten mergen acf_data = product.get("acf", {}) - # Felder übertragen + 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 an WooCommerce - update_resp = requests.put(url, json=payload, auth=auth, timeout=20) + # Update durchführen + update_resp = requests.put(url, json=payload, auth=auth, timeout=15) update_resp.raise_for_status() success_count += 1 + except requests.exceptions.RequestException as e: + error_msg = "API-Fehler fuer Produkt {}: {}".format(wc_link.woocommerce_id, str(e)) + errors.append(error_msg) + frappe.log_error(error_msg, "WooCommerce ACF Sync") + except Exception as e: - frappe.log_error( - "Fehler beim Sync Custom Fields für Item {}: {}".format(item_code, str(e)), - "ACF Custom Fields Sync" - ) + error_msg = "Unerwarteter Fehler fuer Item {} / WC-ID {}: {}".format(item_code, wc_link.woocommerce_id, str(e)) + errors.append(error_msg) + frappe.log_error(error_msg, "WooCommerce ACF Sync") + # Zusammenfassung if success_count > 0: - frappe.msgprint( - "Custom Fields fuer {} WooCommerce-Produkt(e) synchronisiert".format(success_count), - alert=True, - indicator="green" - ) + msg = "Custom Fields fuer {} WooCommerce-Produkt(e) erfolgreich synchronisiert".format(success_count) + if errors: + msg += " ({} Fehler)".format(len(errors)) + frappe.msgprint(msg, alert=True, indicator="green") return True - return False \ No newline at end of file + 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 \ No newline at end of file