Skip to content

Label Regeneration After Failed DAO Label Generation

Background

When a DAO shipping label is created via package-dao-shipping (v2.x), the package automatically schedules an async bulk order completion job via async-bulk-order-completion. The sequence is:

  1. Labels are generated → fetch_dao_label action fires
  2. create_async_order_completion_batch() is called — a job is inserted into order_completion_jobs and each order is inserted into order_completion_orders
  3. Action Scheduler picks up the job and marks orders as completed

Affected sites: Barberklingen.dk, Kaffedrengen.dk

What Goes Wrong

If label generation fails partway through (e.g. DAO API timeout, server error), the async job may still have been enqueued and completed — meaning the orders are marked completed in WooCommerce even though no label was physically produced. The completed status prevents the standard reprint flow from working.

Recovery Process

1. Open the database in read-only mode

Connect to the site's database via a read-only replica or use a read-only MySQL user. Do not run UPDATE/DELETE statements at this stage.

For Barberklingen.dk and Kaffedrengen.dk the database credentials are in Vault under the respective site key. See Vault.


2. Identify the affected job(s)

Find jobs created around the time of the incident. The created_at column reflects when the bulk action was triggered, not when labels were attempted.

SELECT
    id,
    user_id,
    completed,
    created_at,
    completed_at
FROM wp_order_completion_jobs
ORDER BY created_at DESC
LIMIT 20;

Narrow by time window once you know the approximate time of the incident:

SELECT
    j.id          AS job_id,
    j.created_at  AS job_started,
    j.completed_at,
    j.completed,
    COUNT(o.id)   AS order_count
FROM wp_order_completion_jobs j
JOIN wp_order_completion_orders o ON o.job_id = j.id
WHERE j.created_at BETWEEN '2025-01-15 08:00:00' AND '2025-01-15 10:00:00'
GROUP BY j.id
ORDER BY j.created_at DESC;

Table prefix

The default WordPress table prefix is wp_. Verify against the site's config/application.php ($table_prefix) — it may differ per environment.


3. Extract the order IDs from the affected job

Once you have the job_id:

SELECT order_id
FROM wp_order_completion_orders
WHERE job_id = 42
ORDER BY id ASC;

This returns the list of WooCommerce order IDs that were processed in the failing batch.


4. Build the label regeneration URL

The DAO shipping module (v2.x) exposes a bulk label action via the WP admin URL. Construct the URL by appending each order_id as a post[] parameter:

Barberklingen.dk

https://barberklingen.dk/wp/wp-admin/edit.php?action=fetch_dao_label&post[]=ORDER_ID&post[]=ORDER_ID

Kaffedrengen.dk

https://kaffedrengen.dk/wp/wp-admin/edit.php?action=fetch_dao_label&post[]=ORDER_ID&post[]=ORDER_ID

Generating the URL from the SQL result

Copy the raw order IDs from your SQL client into a text editor (e.g. Sublime Text) — one ID per line — then use Find & Replace to transform them:

  1. Find: ^(\d+)$ (regex mode)
  2. Replace: &post[]=\1
  3. Prefix the result with the base URL

The final URL should look like:

https://barberklingen.dk/wp/wp-admin/edit.php?action=fetch_dao_label&post[]=4215106&post[]=4219764&post[]=4219778

5. Trigger label regeneration

  1. Log into the WP admin for the affected site as an administrator
  2. Paste the constructed URL directly into the browser address bar
  3. Hit enter — the page will process the bulk action and generate a combined PDF label file
  4. Download the file when prompted

Warning

The URL must be opened in a browser where you are already authenticated as a WP admin. The action is protected by standard WP admin nonce validation.


6. Send labels to warehouse

Forward the downloaded PDF to the warehouse via the normal channel. Note in your communication how many labels are included so they can cross-reference against their own manifest.


7. Verify label count

Cross-reference the number of labels in the PDF against the number of orders in the completed job:

SELECT COUNT(*) AS completed_order_count
FROM wp_order_completion_orders
WHERE job_id = 42
  AND completed_at IS NOT NULL;

The number of labels in the PDF should match completed_order_count. Note that the PDF also contains summary pages, category pages and other non-label content — page count alone is not a reliable indicator. Count the actual shipping labels.

On Kaffedrengen.dk, orders that include a recycle bag produce two labels each: a shipping label and a return label, both printed in the same run. The label count will therefore exceed the order count for batches that contain recycle bag orders — this is expected.