### Start WordPress Playground Server Source: https://github.com/starktail/woocommerce_fusion/blob/version-15/README.md Initiate a WordPress playground server using the specified blueprint and site URL. This is part of the development setup for testing. ```bash npx @wp-playground/cli server --blueprint wp_woo_blueprint.json --site-url=https://woo-test.localhost ``` -------------------------------- ### Install and Enable Pre-commit Hooks Source: https://github.com/starktail/woocommerce_fusion/blob/version-15/README.md Set up pre-commit for code formatting and linting. Install pre-commit and then enable it for the repository. An optional step to run it against all files is also provided. ```bash cd apps/woocommerce_fusion pre-commit install #(optional) Run against all the files pre-commit run --all-files ``` -------------------------------- ### Install WooCommerce Fusion App Source: https://github.com/starktail/woocommerce_fusion/blob/version-15/README.md Use the bench CLI to install the WooCommerce Fusion app. Ensure you are in your bench directory and provide the repository URL and branch. ```bash cd $PATH_TO_YOUR_BENCH bench get-app $URL_OF_THIS_REPO --branch develop bench install-app woocommerce_fusion ``` -------------------------------- ### Install WooCommerce Fusion App Source: https://context7.com/starktail/woocommerce_fusion/llms.txt Install the WooCommerce Fusion app using bench commands. Ensure you are in your Frappe bench directory. ```bash cd $PATH_TO_YOUR_BENCH bench get-app https://github.com/dvdl16/woocommerce_fusion --branch develop bench install-app woocommerce_fusion ``` -------------------------------- ### Start Caddy Web Server Source: https://github.com/starktail/woocommerce_fusion/blob/version-15/README.md Run the Caddy web server using the provided configuration file. This is typically used in conjunction with the WordPress playground for local development. ```bash caddy run --config wp_woo_caddy --adapter caddyfile ``` -------------------------------- ### Install and Run Semgrep for Frappe Framework Source: https://github.com/starktail/woocommerce_fusion/blob/version-15/README.md Install Semgrep and clone the Frappe Framework-specific Semgrep rules repository. Then, run Semgrep against the app's code using the cloned rules. ```bash # Install semgrep python3 -m pip install semgrep # Clone the rules repository git clone --depth 1 https://github.com/frappe/semgrep-rules.git frappe-semgrep-rules # Run semgrep specifying rules folder as config semgrep --config=/workspace/development/frappe-semgrep-rules/rules apps/woocommerce_fusion ``` -------------------------------- ### Navigate to App Directory Source: https://github.com/starktail/woocommerce_fusion/blob/version-15/README.md Change the current directory to the WooCommerce Fusion app within your frappe-bench setup. ```bash cd frappe-bench/apps/woocommerce_fusion ``` -------------------------------- ### Install Cypress Dependencies Source: https://github.com/starktail/woocommerce_fusion/blob/version-15/README.md Install system dependencies required for running Cypress tests, particularly on Ubuntu/Debian-based systems. This includes various graphical and accessibility libraries. ```bash sudo apt update # Dependencies for cypress: https://docs.cypress.io/guides/continuous-integration/introduction#UbuntuDebian sudo apt-get install libgtk2.0-0 libgtk-3-0 libgbm-dev libnotify-dev libgconf-2-4 libnss3 libxss1 libasound2 libxtst6 xauth xvfb sudo apt-get install chromium ``` -------------------------------- ### Start Local WooCommerce Instance with WordPress Playground Source: https://context7.com/starktail/woocommerce_fusion/llms.txt Launch a local WooCommerce instance using WordPress Playground for integration testing. This provides a controlled environment for testing the application's interaction with WooCommerce. ```bash # Start local WooCommerce (WordPress Playground) for integration tests npx @wp-playground/cli server --blueprint wp_woo_blueprint.json --site-url=https://woo-test.localhost ``` -------------------------------- ### Set Environment Variables for Integration Tests Source: https://context7.com/starktail/woocommerce_fusion/llms.txt Configure necessary environment variables to run integration tests against a local WooCommerce instance. This setup is essential for testing the synchronization logic. ```bash # Set environment variables for integration tests against a local WooCommerce instance export WOO_INTEGRATION_TESTS_WEBSERVER="https://woo-test.localhost" export WOO_API_CONSUMER_KEY="ck_test_123456789" export WOO_API_CONSUMER_SECRET="cs_test_abcdefg" export DEV_SERVER=1 ``` -------------------------------- ### run_sales_order_sync Source: https://context7.com/starktail/woocommerce_fusion/llms.txt Initiates a bidirectional sync between ERPNext Sales Orders and WooCommerce Orders. It can start from either an ERPNext Sales Order or a WooCommerce Order, using the most recently modified document as the master. ```APIDOC ## run_sales_order_sync ### Description Initiates a bidirectional sync between ERPNext Sales Orders and WooCommerce Orders. It can start from either an ERPNext Sales Order or a WooCommerce Order, using the most recently modified document as the master. ### Method Signature `run_sales_order_sync(sales_order_name=None, woocommerce_order_name=None, enqueue=False)` ### Parameters - **sales_order_name** (str, optional): The name of the ERPNext Sales Order to sync. - **woocommerce_order_name** (str, optional): The name of the WooCommerce Order to sync. - **enqueue** (bool, optional): If True, the sync task will be enqueued for background processing. Defaults to False. ### Request Example ```python # Sync from a WooCommerce Order name sales_order, wc_order = run_sales_order_sync(woocommerce_order_name="myshop.example.com~101") # Sync from an ERPNext Sales Order name sales_order, wc_order = run_sales_order_sync(sales_order_name="SAL-ORD-2024-00042") # Trigger async sync run_sales_order_sync(woocommerce_order_name="myshop.example.com~101", enqueue=True) ``` ### Response Returns a tuple containing the synced ERPNext Sales Order document and the synced WooCommerce Order document. ``` -------------------------------- ### Sync ERPNext Sales Orders with WooCommerce Orders Source: https://context7.com/starktail/woocommerce_fusion/llms.txt Use `run_sales_order_sync` for bidirectional sync. It compares `date_modified` timestamps to determine the master document. Accepts either an ERPNext Sales Order or WooCommerce Order name as a starting point. Can be run asynchronously with `enqueue=True`. ```python import frappe from woocommerce_fusion.tasks.sync_sales_orders import ( run_sales_order_sync, sync_woocommerce_orders_modified_since, get_list_of_wc_orders, ) # --- Sync from a WooCommerce Order name (creates or updates an ERPNext Sales Order) --- sales_order, wc_order = run_sales_order_sync( woocommerce_order_name="myshop.example.com~101" ) print(sales_order.name) # "SAL-ORD-2024-00042" print(sales_order.customer) # "jane.doe@example.com" print(wc_order.status) # "processing" # --- Sync from an ERPNext Sales Order name (pushes status/line items back to WooCommerce) --- sales_order, wc_order = run_sales_order_sync(sales_order_name="SAL-ORD-2024-00042") # --- Trigger async sync (enqueued in background queue) --- run_sales_order_sync(woocommerce_order_name="myshop.example.com~101", enqueue=True) # --- Scheduled hourly sync: fetch all orders modified since last sync date --- sync_woocommerce_orders_modified_since(date_time_from="2024-06-01 10:00:00") # Updates WooCommerce Integration Settings.wc_last_sync_date on completion # --- Fetch WooCommerce Orders modified since a date (paginated, all servers) --- wc_orders = get_list_of_wc_orders(date_time_from="2024-06-01 00:00:00") print(len(wc_orders)) # e.g. 38 # --- Fetch WooCommerce Orders linked to a specific Sales Order --- so = frappe.get_doc("Sales Order", "SAL-ORD-2024-00042") wc_orders = get_list_of_wc_orders(sales_order=so) print(wc_orders[0].id) # e.g. 101 ``` -------------------------------- ### WooCommerceResource: Count WooCommerce Orders Source: https://context7.com/starktail/woocommerce_fusion/llms.txt Get the total count of WooCommerce Orders across all enabled servers using the `get_count` method. ```python import frappe # Count total WooCommerce Orders across all enabled servers count = frappe.get_doc({"doctype": "WooCommerce Order"}).get_count({}) print(count) # e.g. 1543 ``` -------------------------------- ### Run UI Integration Tests Source: https://github.com/starktail/woocommerce_fusion/blob/version-15/README.md Execute UI integration tests for the WooCommerce Fusion app in headless mode using the Chromium browser. ```bash bench --site test_site run-ui-tests woocommerce_fusion --headless --browser chromium ``` -------------------------------- ### Configure WooCommerce Server in ERPNext Source: https://context7.com/starktail/woocommerce_fusion/llms.txt Create a WooCommerce Server document to store connection credentials and synchronization settings for a single WooCommerce site. This allows ERPNext to connect to multiple WooCommerce stores. ```python import frappe wc_server = frappe.new_doc("WooCommerce Server") wc_server.woocommerce_server_url = "https://myshop.example.com" wc_server.api_consumer_key = "ck_xxxxxxxxxxxxxxxxxxxx" wc_server.api_consumer_secret = "cs_xxxxxxxxxxxxxxxxxxxx" wc_server.enable_sync = 1 wc_server.company = "My Company" wc_server.warehouse = "Stores - MC" wc_server.uom = "Nos" wc_server.item_group = "All Item Groups" wc_server.enable_stock_level_synchronisation = 1 wc_server.enable_price_list_sync = 1 wc_server.price_list = "Standard Selling" # Optional: map payment methods to bank accounts (JSON) wc_server.payment_method_bank_account_mapping = '{"bacs": "1000-000 Bank Account", "cod": ""}' wc_server.payment_method_gl_account_mapping = '{"bacs": "1200-000 Debtors"}' wc_server.insert() # The server name is auto-derived from the URL domain, e.g. "myshop.example.com" print(wc_server.name) # "myshop.example.com" ``` -------------------------------- ### Run Integration Tests with Coverage Source: https://context7.com/starktail/woocommerce_fusion/llms.txt Execute all integration tests for the WooCommerce Fusion app and generate a coverage report. This command helps in assessing the test coverage and identifying potential issues. ```bash # Run all tests with coverage bench --site test_site run-tests --app woocommerce_fusion --coverage ``` -------------------------------- ### Run App Tests with Coverage Source: https://github.com/starktail/woocommerce_fusion/blob/version-15/README.md Execute all tests for the WooCommerce Fusion app within the specified site context, including generating code coverage reports. ```bash bench --site test_site run-tests --app woocommerce_fusion --coverage ``` -------------------------------- ### Set Environment Variables for Tests Source: https://github.com/starktail/woocommerce_fusion/blob/version-15/README.md Configure necessary environment variables for running integration tests, including the webserver URL and WooCommerce API credentials. ```bash export WOO_INTEGRATION_TESTS_WEBSERVER="https://woo-test.localhost" export WOO_API_CONSUMER_KEY="ck_test_123456789" export WOO_API_CONSUMER_SECRET="cs_test_abcdefg" export DEV_SERVER=1 ``` -------------------------------- ### Sync ERPNext Items with WooCommerce Products Source: https://context7.com/starktail/woocommerce_fusion/llms.txt Use `run_item_sync` for bidirectional sync of items and products, including variants and variable products. It supports creating new items/products on either side. Can be run asynchronously with `enqueue=True`. ```python import frappe from woocommerce_fusion.tasks.sync_items import ( run_item_sync, sync_woocommerce_products_modified_since, get_list_of_wc_products, ) # --- Sync from a WooCommerce Product name (creates or updates an ERPNext Item) --- item, wc_product = run_item_sync(woocommerce_product_name="myshop.example.com~88") print(item.item_code) # "88" (or SKU if configured) print(item.item_name) # "Blue T-Shirt" print(wc_product.sku) # "TSHIRT-BLUE-M" # --- Sync from an ERPNext Item (creates or updates the WooCommerce Product) --- item, wc_product = run_item_sync(item_code="TSHIRT-BLUE-M") print(wc_product.woocommerce_id) # 88 print(wc_product.regular_price) # "29.99" # --- Async item sync (enqueued in background) --- run_item_sync(item_code="TSHIRT-BLUE-M", enqueue=True) # --- Scheduled hourly sync: fetch all products modified since last sync date --- sync_woocommerce_products_modified_since(date_time_from="2024-06-01 00:00:00") # Updates WooCommerce Integration Settings.wc_last_sync_date_items on completion # --- Fetch WooCommerce Products modified since a date (paginated) --- wc_products = get_list_of_wc_products(date_time_from="2024-06-01 00:00:00") for p in wc_products: print(p.name, p.woocommerce_name, p.sku) ``` -------------------------------- ### run_item_sync Source: https://context7.com/starktail/woocommerce_fusion/llms.txt Handles bidirectional sync between ERPNext Items and WooCommerce Products, including creation of new products on either side and support for variants. ```APIDOC ## run_item_sync ### Description Handles bidirectional sync between ERPNext Items and WooCommerce Products, including creation of new products on either side. Variant items and variable products (with attributes) are fully supported. ### Method Signature `run_item_sync(item_code=None, woocommerce_product_name=None, enqueue=False)` ### Parameters - **item_code** (str, optional): The ERPNext item code to sync. - **woocommerce_product_name** (str, optional): The name of the WooCommerce Product to sync. - **enqueue** (bool, optional): If True, the sync task will be enqueued for background processing. Defaults to False. ### Request Example ```python # Sync from a WooCommerce Product name item, wc_product = run_item_sync(woocommerce_product_name="myshop.example.com~88") # Sync from an ERPNext Item item, wc_product = run_item_sync(item_code="TSHIRT-BLUE-M") # Async item sync run_item_sync(item_code="TSHIRT-BLUE-M", enqueue=True) ``` ### Response Returns a tuple containing the synced ERPNext Item document and the synced WooCommerce Product document. ``` -------------------------------- ### Synchronize Sales Order Lifecycle with `SynchroniseSalesOrder` Class Source: https://context7.com/starktail/woocommerce_fusion/llms.txt The `SynchroniseSalesOrder` class manages the complete sync process for a single order pair. It handles finding counterparts, creating/updating documents, and auto-creating Payment Entries for paid orders. Initialize with either a WooCommerce Order document or an ERPNext Sales Order document. ```python from woocommerce_fusion.tasks.sync_sales_orders import SynchroniseSalesOrder import frappe # Sync starting from a WooCommerce Order document wc_order = frappe.get_doc({"doctype": "WooCommerce Order", "name": "myshop.example.com~55"}) wc_order.load_from_db() sync = SynchroniseSalesOrder(woocommerce_order=wc_order) sync.run() # After run(), access the synced documents: print(sync.sales_order.name) # "SAL-ORD-2024-00055" print(sync.sales_order.customer) # "Acme Corp" print(sync.woocommerce_order.total) # "299.00" # If a payment was auto-created: if sync.sales_order.woocommerce_payment_entry: print(sync.sales_order.woocommerce_payment_entry) # "PE-2024-00100" # Sync starting from a submitted ERPNext Sales Order (pushes changes to WooCommerce) so = frappe.get_doc("Sales Order", "SAL-ORD-2024-00055") sync = SynchroniseSalesOrder(sales_order=so) sync.run() ``` -------------------------------- ### WooCommerceResource: Load and List WooCommerce Orders Source: https://context7.com/starktail/woocommerce_fusion/llms.txt Demonstrates loading a single WooCommerce Order by its composite name and listing multiple orders with filters. These operations interact with the WooCommerce REST API. ```python import frappe # Load a single WooCommerce Order by its composite name (triggers GET /wp-json/wc/v3/orders/42) wc_order = frappe.get_doc({"doctype": "WooCommerce Order", "name": "myshop.example.com~42"}) wc_order.load_from_db() print(wc_order.status) # "processing" print(wc_order.total) # "149.99" print(wc_order.line_items) # JSON string of order line items # List WooCommerce Orders with filters (triggers GET /wp-json/wc/v3/orders?after=...&per_page=100) wc_order_doc = frappe.get_doc({"doctype": "WooCommerce Order"}) orders = wc_order_doc.get_list(args={ "filters": [ ["WooCommerce Order", "date_modified", ">", "2024-01-01 00:00:00"], ["WooCommerce Order", "status", "=", "processing"], ], "page_length": 20, "start": 0, "as_doc": True, }) for order in orders: print(order.name, order.status, order.total) ``` -------------------------------- ### SynchroniseSalesOrder Class Source: https://context7.com/starktail/woocommerce_fusion/llms.txt Encapsulates the full sync lifecycle for a single order pair, handling document creation, updates, and payment entry creation. ```APIDOC ## SynchroniseSalesOrder Class ### Description Encapsulates the full sync lifecycle for a single order pair: finding counterparts, creating missing documents, updating stale ones, and auto-creating Payment Entries for paid orders. ### Initialization `SynchroniseSalesOrder(woocommerce_order=None, sales_order=None)` ### Parameters - **woocommerce_order** (Document, optional): A WooCommerce Order document to start the sync from. - **sales_order** (Document, optional): An ERPNext Sales Order document to start the sync from. ### Method `run()`: Executes the synchronization process. ### Accessing Synced Documents After calling `run()`: - `sync.sales_order`: The synced ERPNext Sales Order document. - `sync.woocommerce_order`: The synced WooCommerce Order document. - `sync.sales_order.woocommerce_payment_entry`: The name of the auto-created Payment Entry, if any. ### Request Example ```python # Sync starting from a WooCommerce Order document wc_order = frappe.get_doc({"doctype": "WooCommerce Order", "name": "myshop.example.com~55"}) wc_order.load_from_db() sync = SynchroniseSalesOrder(woocommerce_order=wc_order) sync.run() # Sync starting from a submitted ERPNext Sales Order so = frappe.get_doc("Sales Order", "SAL-ORD-2024-00055") sync = SynchroniseSalesOrder(sales_order=so) sync.run() ``` ``` -------------------------------- ### WooCommerce Order Created Webhook Endpoint Source: https://context7.com/starktail/woocommerce_fusion/llms.txt Configure ERPNext to receive order creation events from WooCommerce via a webhook. The endpoint validates the request signature and enqueues an order sync job. ```shell # Endpoint: POST /api/method/woocommerce_fusion.woocommerce_endpoint.order_created # Required WooCommerce Webhook Headers: # x-wc-webhook-source: https://myshop.example.com # x-wc-webhook-event: created # x-wc-webhook-signature: # Configure in WooCommerce Admin > WooCommerce > Settings > Advanced > Webhooks: # Topic: Order created # Delivery URL: https://your-erpnext.com/api/method/woocommerce_fusion.woocommerce_endpoint.order_created # Secret: (copy from WooCommerce Server > secret field in ERPNext) # Example curl test (without signature validation in dev mode): # curl -X POST https://your-erpnext.com/api/method/woocommerce_fusion.woocommerce_endpoint.order_created \ # -H "Content-Type: application/json" \ # -H "x-wc-webhook-source: https://myshop.example.com" \ # -H "x-wc-webhook-event: created" \ # -d '{"id": 101, "status": "processing", "total": "49.99"}' # Response: HTTP 200 OK # The handler enqueues: # frappe.enqueue(run_sales_order_sync, queue="long", woocommerce_order_name="myshop.example.com~101") ``` -------------------------------- ### Instrumented WooCommerce API Client with Request Logging Source: https://context7.com/starktail/woocommerce_fusion/llms.txt Extends the WooCommerce API client to log all REST API calls to the WooCommerce Request Log doctype in ERPNext. Ensure WooCommerce Server > enable_woocommerce_request_logs is enabled for logging to function. Logs include URL, endpoint, method, parameters, request data, response, status, and time elapsed. ```python from woocommerce_fusion.tasks.utils import APIWithRequestLogging # Used internally by WooCommerceResource._init_api(): wc_api = APIWithRequestLogging( url="https://myshop.example.com", consumer_key="ck_xxxxxxxxxxxxxxxxxxxx", consumer_secret="cs_xxxxxxxxxxxxxxxxxxxx", version="wc/v3", timeout=40, verify_ssl=True, ) # All requests are logged to WooCommerce Request Log if # WooCommerce Server > enable_woocommerce_request_logs is enabled. # The log records: url, endpoint, method, params, request data, response, status, time_elapsed # Direct API usage: response = wc_api.get("products", params={"per_page": 10, "status": "publish"}) print(response.status_code) # 200 products = response.json() print(products[0]["name"]) # "Blue T-Shirt" # Update a product: response = wc_api.put("products/88", data={"regular_price": "34.99"}) print(response.status_code) # 200 # Logging is async (enqueued) and cached per-server URL with a 24h Redis TTL: # is_woocommerce_request_logging_enabled("https://myshop.example.com") -> True/False ``` -------------------------------- ### WooCommerceResource: Generate and Parse Record Names Source: https://context7.com/starktail/woocommerce_fusion/llms.txt Utilities for generating and parsing composite document names used by the WooCommerce Fusion app. These names combine the WooCommerce domain and record ID. ```python from woocommerce_fusion.woocommerce.woocommerce_api import ( WooCommerceResource, generate_woocommerce_record_name_from_domain_and_id, get_domain_and_id_from_woocommerce_record_name, parse_domain_from_url, ) # Generate the composite document name used throughout the app name = generate_woocommerce_record_name_from_domain_and_id("myshop.example.com", 42) print(name) # "myshop.example.com~42" # Parse it back domain, record_id = get_domain_and_id_from_woocommerce_record_name("myshop.example.com~42") print(domain, record_id) # "myshop.example.com", 42 # Parse domain from a full URL domain = parse_domain_from_url("https://myshop.example.com") print(domain) # "myshop.example.com" ``` -------------------------------- ### Frappe Scheduled Tasks for Automated Sync Source: https://context7.com/starktail/woocommerce_fusion/llms.txt Defines Frappe scheduled tasks for automating synchronization jobs between ERPNext and WooCommerce. These tasks are configured in the `hooks.py` file and run at specified intervals (hourly, daily). ```python # Configured in hooks.py: scheduler_events = { "hourly_long": [ # Sync WooCommerce Orders modified since last run -> create/update Sales Orders "woocommerce_fusion.tasks.sync_sales_orders.sync_woocommerce_orders_modified_since", # Sync WooCommerce Products modified since last run -> create/update Items "woocommerce_fusion.tasks.sync_items.sync_woocommerce_products_modified_since", ], "daily_long": [ # Push stock levels for ALL enabled items to all linked WooCommerce servers "woocommerce_fusion.tasks.stock_update.update_stock_levels_for_all_enabled_items_in_background", # Push item prices from ERPNext price lists to WooCommerce regular_price/sale_price "woocommerce_fusion.tasks.sync_item_prices.run_item_price_sync_in_background", ], } ``` -------------------------------- ### sync_woocommerce_products_modified_since Source: https://context7.com/starktail/woocommerce_fusion/llms.txt Performs a scheduled hourly sync by fetching all WooCommerce products modified since a specified date and time. ```APIDOC ## sync_woocommerce_products_modified_since ### Description Performs a scheduled hourly sync by fetching all WooCommerce products modified since a specified date and time. Updates the `wc_last_sync_date_items` in WooCommerce Integration Settings upon completion. ### Method Signature `sync_woocommerce_products_modified_since(date_time_from)` ### Parameters - **date_time_from** (str): The date and time from which to fetch modified products (e.g., "YYYY-MM-DD HH:MM:SS"). ### Request Example ```python sync_woocommerce_products_modified_since(date_time_from="2024-06-01 00:00:00") ``` ``` -------------------------------- ### Manually Trigger Scheduled Tasks Source: https://context7.com/starktail/woocommerce_fusion/llms.txt Execute scheduled synchronization tasks from the bench console. These tasks are useful for bulk updates or manual triggering of data sync processes. ```python from woocommerce_fusion.tasks.sync_sales_orders import sync_woocommerce_orders_modified_since from woocommerce_fusion.tasks.sync_items import sync_woocommerce_products_modified_since from woocommerce_fusion.tasks.stock_update import update_stock_levels_for_all_enabled_items_in_background sync_woocommerce_orders_modified_since() sync_woocommerce_products_modified_since() update_stock_levels_for_all_enabled_items_in_background() ``` -------------------------------- ### Stock Level Synchronisation Source: https://context7.com/starktail/woocommerce_fusion/llms.txt Manually push stock levels for a single item or enqueue a background job for all items. Stock updates are triggered automatically on stock changes in ERPNext. ```APIDOC ## Stock Level Synchronisation — `update_stock_levels_on_woocommerce_site` Stock levels are pushed from ERPNext to WooCommerce. Updates are triggered automatically when Stock Entries, Stock Reconciliations, Sales Invoices, or Delivery Notes are submitted/cancelled. A daily background job pushes stock for all enabled items. ### Manually push stock for a single item to all its linked WooCommerce servers ```python success = update_stock_levels_on_woocommerce_site(item_code="TSHIRT-BLUE-M") print(success) # True ``` Internally computes: `stock_quantity = sum(actual_qty)` across configured warehouses. Optionally subtracts `reserved_qty` if `wc_server.subtract_reserved_stock` is enabled. Sends `PUT /wp-json/wc/v3/products/{woocommerce_id}` with `{"stock_quantity": 42}`. For a variant item, it automatically resolves the parent and uses: `PUT /wp-json/wc/v3/products/{parent_id}/variations/{variant_id}`. ### Enqueue stock push for all non-disabled items (daily scheduled task) ```python update_stock_levels_for_all_enabled_items_in_background() ``` Processes items in batches of 500 and enqueues one job per item. ### Automatic Triggering via Hooks The `doc_event` hook fires automatically on stock changes: - `Stock Entry`: `{"on_submit": "...update_stock_levels_for_woocommerce_item"}` - `Stock Reconciliation`: `{"on_submit": "...update_stock_levels_for_woocommerce_item"}` - `Sales Invoice`: `{"on_submit": "...update_stock_levels_for_woocommerce_item"}` - `Delivery Note`: `{"on_submit": "...update_stock_levels_for_woocommerce_item"}` ``` -------------------------------- ### get_list_of_wc_products Source: https://context7.com/starktail/woocommerce_fusion/llms.txt Fetches a list of WooCommerce Products modified since a specified date and time. Supports pagination for large result sets. ```APIDOC ## get_list_of_wc_products ### Description Fetches a list of WooCommerce Products modified since a specified date and time. Supports pagination for large result sets. ### Method Signature `get_list_of_wc_products(date_time_from)` ### Parameters - **date_time_from** (str): The date and time from which to fetch modified products (e.g., "YYYY-MM-DD HH:MM:SS"). ### Request Example ```python wc_products = get_list_of_wc_products(date_time_from="2024-06-01 00:00:00") for p in wc_products: print(p.name, p.woocommerce_name, p.sku) ``` ### Response Returns a list of WooCommerce Product documents. ``` -------------------------------- ### Payment Method Mapping for WooCommerce Fusion Source: https://github.com/starktail/woocommerce_fusion/blob/version-15/docs/woocommerce_fusion_configure.md Configure payment method mapping for syncing payments from WooCommerce to ERPNext. This JSON object maps WooCommerce payment methods (keys) to ERPNext bank accounts (values). An empty string for 'cod' indicates no specific bank account mapping for Cash on Delivery. ```json { "bacs": "1000-000 Bank Account", "cheque": "1000-100 Other Bank Account", "cod": "" } ``` -------------------------------- ### Order Created Webhook Endpoint Source: https://context7.com/starktail/woocommerce_fusion/llms.txt Configure WooCommerce to call this ERPNext webhook endpoint when a new order is created. The endpoint validates the signature and enqueues an order sync job. ```APIDOC ## Webhook Endpoint — `order_created` WooCommerce can call the ERPNext webhook endpoint directly when a new order is created. The endpoint validates the HMAC-SHA256 request signature and enqueues an order sync job. ### Endpoint `POST /api/method/woocommerce_fusion.woocommerce_endpoint.order_created` ### Required WooCommerce Webhook Headers - `x-wc-webhook-source`: `https://myshop.example.com` - `x-wc-webhook-event`: `created` - `x-wc-webhook-signature`: `` ### Configuration in WooCommerce Admin Go to `WooCommerce > Settings > Advanced > Webhooks`: - **Topic**: `Order created` - **Delivery URL**: `https://your-erpnext.com/api/method/woocommerce_fusion.woocommerce_endpoint.order_created` - **Secret**: (copy from WooCommerce Server > secret field in ERPNext) ### Example curl test (without signature validation in dev mode) ```bash curl -X POST https://your-erpnext.com/api/method/woocommerce_fusion.woocommerce_endpoint.order_created \ -H "Content-Type: application/json" \ -H "x-wc-webhook-source: https://myshop.example.com" \ -H "x-wc-webhook-event: created" \ -d '{"id": 101, "status": "processing", "total": "49.99"}' ``` **Response**: HTTP 200 OK The handler enqueues: `frappe.enqueue(run_sales_order_sync, queue="long", woocommerce_order_name="myshop.example.com~101")` ``` -------------------------------- ### Configure Event Hooks for Real-time Triggers Source: https://context7.com/starktail/woocommerce_fusion/llms.txt Define event hooks to trigger specific actions upon document events like submission or cancellation. These hooks are crucial for real-time data synchronization between ERPNext and WooCommerce. ```python doc_events = { # Stock changes trigger stock level push to WooCommerce "Stock Entry": {"on_submit": "...update_stock_levels_for_woocommerce_item", "on_cancel": "...update_stock_levels_for_woocommerce_item"}, "Stock Reconciliation": {"on_submit": "...update_stock_levels_for_woocommerce_item"}, "Sales Invoice": {"on_submit": "...update_stock_levels_for_woocommerce_item"}, "Delivery Note": {"on_submit": "...update_stock_levels_for_woocommerce_item"}, # Item Price changes push updated prices to WooCommerce immediately "Item Price": {"on_update": "...update_item_price_for_woocommerce_item_from_hook"}, # Sales Order submission triggers order sync "Sales Order": {"on_submit": "...run_sales_order_sync_from_hook"}, # Item save/insert triggers product sync "Item": {"on_update": "...run_item_sync_from_hook", "after_insert": "...run_item_sync_from_hook"}, } ``` -------------------------------- ### Item Price Synchronisation Source: https://context7.com/starktail/woocommerce_fusion/llms.txt Synchronize ERPNext Item Prices to WooCommerce `regular_price` and `sale_price` fields. Supports sale prices with validity date ranges using a secondary price list. ```APIDOC ## Item Price Synchronisation — `run_item_price_sync` ERPNext Item Prices are pushed to WooCommerce `regular_price` and optionally `sale_price` fields. A secondary Sales Price List can be configured for sale prices with validity date ranges, which map to WooCommerce's `date_on_sale_from` / `date_on_sale_to`. ### Sync all item prices for all enabled items across all servers ```python run_item_price_sync() ``` Queries Item Price records linked to the configured `price_list` on each WooCommerce Server. Updates WooCommerce Product `regular_price` for each matched product. ### Sync prices for a specific item only ```python run_item_price_sync(item_code="TSHIRT-BLUE-M") ``` ### Sync triggered by an Item Price update (enqueued automatically via hook) `hooks.py`: `"Item Price": {"on_update": "...update_item_price_for_woocommerce_item_from_hook"}` ### Using the class directly for fine-grained control ```python wc_server = frappe.get_doc("WooCommerce Server", "myshop.example.com") sync = SynchroniseItemPrice( servers=[wc_server], item_code="TSHIRT-BLUE-M" ) sync.run() ``` `sync.item_price_list` contains the matched ERPNext Item Price records. `sync.sale_price_map` contains the `woocommerce_id` -> `sale_price` mapping. ### Example: WooCommerce Product after price sync ```json { "regular_price": "29.99", <-- from wc_server.price_list "sale_price": "19.99", <-- from wc_server.sales_price_list "date_on_sale_from": "2024-07-01T00:00:00", <-- from Item Price.valid_from "date_on_sale_to": "2024-07-31T00:00:00" <-- from Item Price.valid_upto } ``` ``` -------------------------------- ### Synchronize Item Prices to WooCommerce Source: https://context7.com/starktail/woocommerce_fusion/llms.txt Sync all item prices for enabled items across all servers or for a specific item. This process updates the `regular_price` and optionally `sale_price` fields in WooCommerce, including sale price validity dates. ```python import frappe from woocommerce_fusion.tasks.sync_item_prices import ( run_item_price_sync, run_item_price_sync_in_background, SynchroniseItemPrice, ) # --- Sync all item prices for all enabled items across all servers --- run_item_price_sync() # Queries Item Price records linked to the configured price_list on each WooCommerce Server # Updates WooCommerce Product regular_price for each matched product # --- Sync prices for a specific item only --- run_item_price_sync(item_code="TSHIRT-BLUE-M") # --- Sync triggered by an Item Price update (enqueued automatically via hook) --- # hooks.py: "Item Price": {"on_update": "...update_item_price_for_woocommerce_item_from_hook"} # --- Using the class directly for fine-grained control --- wc_server = frappe.get_doc("WooCommerce Server", "myshop.example.com") sync = SynchroniseItemPrice( servers=[wc_server], item_code="TSHIRT-BLUE-M" ) sync.run() # sync.item_price_list contains the matched ERPNext Item Price records # sync.sale_price_map contains the woocommerce_id -> sale price mapping # --- Example: WooCommerce Product after price sync --- # regular_price: "29.99" <- from wc_server.price_list # sale_price: "19.99" <- from wc_server.sales_price_list # date_on_sale_from: "2024-07-01T00:00:00" <- from Item Price.valid_from # date_on_sale_to: "2024-07-31T00:00:00" <- from Item Price.valid_upto ``` -------------------------------- ### get_list_of_wc_orders Source: https://context7.com/starktail/woocommerce_fusion/llms.txt Fetches a list of WooCommerce Orders, optionally filtered by modification date or linked to a specific ERPNext Sales Order. ```APIDOC ## get_list_of_wc_orders ### Description Fetches a list of WooCommerce Orders, optionally filtered by modification date or linked to a specific ERPNext Sales Order. This function supports pagination for large result sets. ### Method Signature `get_list_of_wc_orders(date_time_from=None, sales_order=None)` ### Parameters - **date_time_from** (str, optional): The date and time from which to fetch modified orders (e.g., "YYYY-MM-DD HH:MM:SS"). - **sales_order** (Document, optional): An ERPNext Sales Order document to filter orders by. ### Request Example ```python # Fetch orders modified since a specific date wc_orders = get_list_of_wc_orders(date_time_from="2024-06-01 00:00:00") # Fetch orders linked to a specific Sales Order so = frappe.get_doc("Sales Order", "SAL-ORD-2024-00042") wc_orders = get_list_of_wc_orders(sales_order=so) ``` ### Response Returns a list of WooCommerce Order documents. ``` -------------------------------- ### sync_woocommerce_orders_modified_since Source: https://context7.com/starktail/woocommerce_fusion/llms.txt Performs a scheduled hourly sync by fetching all WooCommerce orders modified since a specified date and time. ```APIDOC ## sync_woocommerce_orders_modified_since ### Description Performs a scheduled hourly sync by fetching all WooCommerce orders modified since a specified date and time. Updates the `wc_last_sync_date` in WooCommerce Integration Settings upon completion. ### Method Signature `sync_woocommerce_orders_modified_since(date_time_from)` ### Parameters - **date_time_from** (str): The date and time from which to fetch modified orders (e.g., "YYYY-MM-DD HH:MM:SS"). ### Request Example ```python sync_woocommerce_orders_modified_since(date_time_from="2024-06-01 10:00:00") ``` ``` -------------------------------- ### Update Stock Levels on WooCommerce Site Source: https://context7.com/starktail/woocommerce_fusion/llms.txt Manually push stock for a single item to all linked WooCommerce servers. This function computes the stock quantity and optionally subtracts reserved stock before sending an update to WooCommerce. ```python import frappe from woocommerce_fusion.tasks.stock_update import ( update_stock_levels_on_woocommerce_site, update_stock_levels_for_all_enabled_items_in_background, ) # --- Manually push stock for a single item to all its linked WooCommerce servers --- success = update_stock_levels_on_woocommerce_site(item_code="TSHIRT-BLUE-M") # Internally computes: stock_quantity = sum(actual_qty) across configured warehouses # Optionally subtracts reserved_qty if wc_server.subtract_reserved_stock is enabled # Sends PUT /wp-json/wc/v3/products/{woocommerce_id} with {"stock_quantity": 42} print(success) # True # For a variant item, it automatically resolves the parent and uses: # PUT /wp-json/wc/v3/products/{parent_id}/variations/{variant_id} # --- Enqueue stock push for all non-disabled items (daily scheduled task) --- update_stock_levels_for_all_enabled_items_in_background() # Processes items in batches of 500 and enqueues one job per item # --- The doc_event hook fires automatically on stock changes: # hooks.py registers: # "Stock Entry": {"on_submit": "...update_stock_levels_for_woocommerce_item"} # "Stock Reconciliation": {"on_submit": "...update_stock_levels_for_woocommerce_item"} # "Sales Invoice": {"on_submit": "...update_stock_levels_for_woocommerce_item"} # "Delivery Note": {"on_submit": "...update_stock_levels_for_woocommerce_item"} ``` -------------------------------- ### JSONPath for Custom Field Mapping Source: https://context7.com/starktail/woocommerce_fusion/llms.txt Enables configurable field mappings between ERPNext and WooCommerce using JSONPath expressions. This allows arbitrary fields to be mapped without code changes. Configure mappings in ERPNext under WooCommerce Server > Item Field Map or Order Line Item Field Map. ```python # Configured via WooCommerce Server > Item Field Map (for Products) # and WooCommerce Server > Order Line Item Field Map (for Sales Order Items) # Example Item Field Map configuration (set in UI): # ERPNext Field Name: "custom_short_description" # WooCommerce Field Name: "$.short_description" # Example Order Line Item Field Map: # ERPNext Field Name: "custom_tax_class" # WooCommerce Field Name: "$.tax_class" # Example: Metadata field mapping # ERPNext Field Name: "custom_gift_message" # WooCommerce Field Name: "$.meta_data[?(@.key=='gift_message')].value" # The mapping is applied in SynchroniseItem.set_item_fields() and set_product_fields(): from jsonpath_ng.ext import parse import frappe # Example: reading a WooCommerce product field via JSONPath wc_product_dict = { "name": "Blue T-Shirt", "short_description": "

Premium cotton tee

", "meta_data": [ {"key": "gift_message", "value": "Happy Birthday!"}, {"key": "gift_wrap", "value": "1"} ] } jsonpath_expr = parse("$.meta_data[?(@.key=='gift_message')].value") matches = jsonpath_expr.find(wc_product_dict) print(matches[0].value) # "Happy Birthday!" # Writing back to a WooCommerce field: jsonpath_expr = parse("$.short_description") jsonpath_expr.update(wc_product_dict, "

Organic cotton tee

") print(wc_product_dict["short_description"]) # "

Organic cotton tee

" ``` -------------------------------- ### WC_ORDER_STATUS_MAPPING Order Status Translation Source: https://context7.com/starktail/woocommerce_fusion/llms.txt Utilize mappings to translate order status strings between ERPNext and WooCommerce. This ensures consistent display and filtering of orders across both systems. ```python from woocommerce_fusion.woocommerce.doctype.woocommerce_order.woocommerce_order import ( WC_ORDER_STATUS_MAPPING, WC_ORDER_STATUS_MAPPING_REVERSE, ) # ERPNext label -> WooCommerce status slug print(WC_ORDER_STATUS_MAPPING["Processing"]) print(WC_ORDER_STATUS_MAPPING["Shipped"]) print(WC_ORDER_STATUS_MAPPING["Pending Payment"]) print(WC_ORDER_STATUS_MAPPING["Cancelled"]) # WooCommerce status slug -> ERPNext label (reverse mapping) print(WC_ORDER_STATUS_MAPPING_REVERSE["processing"]) print(WC_ORDER_STATUS_MAPPING_REVERSE["completed"]) print(WC_ORDER_STATUS_MAPPING_REVERSE["on-hold"]) # Full mapping: # "Pending Payment" -> "pending" # "On hold" -> "on-hold" # "Failed" -> "failed" # "Cancelled" -> "cancelled" # "Processing" -> "processing" # "Refunded" -> "refunded" # "Shipped" -> "completed" # "Ready for Pickup" -> "ready-pickup" # "Picked up" -> "pickup" # "Delivered" -> "delivered" # "Draft" -> "checkout-draft" # "Trash" -> "trash" # "Partially Shipped" -> "partial-shipped" ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.