Skip to content

Conversation

@layoutd
Copy link
Contributor

@layoutd layoutd commented Oct 24, 2025

Summary

This PR adds two new parameters to the order generator for more realistic test data generation, plus a new parameter for the coupon generator:

  1. --coupon-ratio: Apply coupons to a percentage of generated orders
  2. --refund-ratio: Refund a percentage of completed orders
  3. --discount_type: Specify discount type when generating coupons

Changes

Order Generator

--coupon-ratio Parameter

  • Accepts a decimal value between 0.0 and 1.0
  • Determines the percentage of orders that should have coupons applied
  • If no coupons exist, automatically creates 6 coupons (3 fixed cart $5-$50, 3 percentage 5%-25%)
  • Backwards compatible with existing --coupons flag (same as using --coupons-ratio=1.0)

Examples:

# Apply coupons to 50% of orders
wp wc generate orders 100 --coupon-ratio=0.5

# Apply coupons to all orders
wp wc generate orders 100 --coupon-ratio=1.0

--refund-ratio Parameter

  • Accepts a decimal value between 0.0 and 1.0
  • Determines the percentage of completed orders that should be refunded
  • Only applies to orders with completed status
  • Refunds are split roughly evenly between full and partial refunds
  • Additionally, ~ 25% of partial refunds will receive a second partial refund
  • Two partial refunds will never reach full refund value
  • Creates realistic refund line items with proper amounts and tax calculations
  • Refund dates are realistic: first refunds within 2 months of completion, second refunds within 1 month of first
  • Refund reasons include item counts: "Partial refund - X products, Y items" or "Full refund"

Examples:

# Refund 30% of completed orders
wp wc generate orders 100 --status=completed --refund-ratio=0.3

# Refund all completed orders
wp wc generate orders 100 --status=completed --refund-ratio=1.0

# Generate orders with both coupons and refunds
wp wc generate orders 100 --status=completed --coupon-ratio=0.5 --refund-ratio=0.3

Coupon Generator

--discount_type Parameter

  • Accepts fixed_cart or percent
  • Allows creating coupons of a specific discount type
  • Maintains backwards compatibility: if not specified, uses WooCommerce default (fixed_cart)
  • Enables the Order generator to create a mix of coupon types when auto-creating coupons

Examples:

# Create 20 percentage coupons with 5-25% discount
wp wc generate coupons 20 --discount_type=percent --min=5 --max=25

# Create 10 fixed cart coupons with $10-$100 discount
wp wc generate coupons 10 --discount_type=fixed_cart --min=10 --max=100

Technical Details

Refund Implementation

  • Uses WooCommerce's wc_create_refund() function
  • Properly calculates line item refund amounts and taxes
  • Preserves tax rate IDs in refund tax arrays
  • Explicitly calculates refund amounts from line items
  • Full refunds include all line items and fees
  • Partial refunds can be:
    • Complete items (subset of order items)
    • Partial quantities (e.g., 2 of 5 items)
  • Full refunds update order status to refunded
  • Tracks already-refunded quantities to prevent over-refunding
  • Division-by-zero guards protect against edge cases

Coupon Implementation

  • Leverages existing Coupon::generate() method with new discount_type parameter
  • Auto-creation ensures realistic mix of fixed and percentage coupons
  • Uses Coupon::get_random() to retrieve existing coupons
  • Backwards compatible with existing code

Testing

Start with 0 orders and 0 coupons!!

Coupon Ratio Tests

  • Verify 6 coupons are created (3 fixed, 3 percent) when none exist

    # First delete all coupons, then:
    wp wc generate orders 20 --coupon-ratio=0.5
    # Check: 6 coupons should exist (3 fixed_cart $5-$50, 3 percent 5-25%)
  • CONTINUE: test coupon-ratio applies coupons to correct percentage of orders

    # Then check: approximately 10 of the above orders should have coupons applied (open all in new tab and look for discounts on first line item)
  • BULK DELETE all orders with WP Admin interface /wp-admin/admin.php?page=wc-orders

  • Test coupon-ratio=1.0 applies coupons to all orders

    wp wc generate orders 10 --coupon-ratio=1.0
    # Check: all 10 orders should have coupons applied (open all in new tab and look for discounts on first line item)
    # NOTE that the orders don't appear in the count in the Coupons table if they're failed, etc.
  • BULK DELETE all orders with WP Admin interface /wp-admin/admin.php?page=wc-orders

  • Test backwards compatibility with --coupons flag

    wp wc generate orders 10 --coupons
    # Check: all orders should have coupons (existing behavior)

Refund Ratio Tests

  • BULK DELETE all orders with WP Admin interface /wp-admin/admin.php?page=wc-orders

  • Test refund-ratio=0.5 refunds approximately 50% of orders

    wp wc generate orders 20 --status=completed --refund-ratio=0.5
    # Check: about 10 orders should have refunds (strikeout prices in orders table)
  • BULK DELETE all orders with WP Admin interface /wp-admin/admin.php?page=wc-orders

  • Test refund-ratio=1.0 refunds all completed orders

    wp wc generate orders 20 --status=completed --refund-ratio=1.0  --date-start=2023-01-01 --date-end=2023-01-31
    # Check: all 20 orders should have refunds (strikeout prices in orders table)
  • CONTINUE: Verify refund amounts match line item totals (not 0.00)

    # Check in WP Admin: refund totals should match refunded items totals (look at some individual orders confirm line item red numbers add up to refund line item)
  • CONTINUE Verify refund dates are realistic

    # Check: all refunds should basically be in Q1 2023 (~2 months for first, ~1 additional month if there's a second refund) Confirm line item refund date is in Q1 2023 and not today
  • CONTINUE Verify partial refund reasons show correct product/item counts

    # Check: partial refunds should have reasons like "Partial refund - 2 products, 3 items" (look at individual order line items and refund item)
  • BULK DELETE all orders with WP Admin interface /wp-admin/admin.php?page=wc-orders

  • Verify ~25% of partial refunds receive a second refund

    wp wc generate orders 100 --status=completed --refund-ratio=1.0 --date-start=2021-01-01 --date-end=2021-01-31
    # Check: approximately 12-13 orders should have 2+ refunds (25% of ~50% partial = ~12.5%) - open all partial refunds (completed with strikethrough price in orders table) and see if any have two refudns 
    # OR use
    # SELECT SUM(cnt) FROM (SELECT count(*) as cnt, parent_order_id FROM wp_wc_orders WHERE parent_order_id!=0 AND wp_wc_orders.date_created_gmt < "2023-01-01" GROUP BY parent_order_id HAVING cnt >= 2 ORDER BY cnt DESC, parent_order_id desc) as tbl;
  • BULK DELETE all orders with WP Admin interface /wp-admin/admin.php?page=wc-orders

  • Test refund-ratio only affects completed orders

    wp wc generate orders 10 --status=processing --refund-ratio=1.0
    # Check: no orders should have refunds (only completed status can be refunded)

Discount Type Tests

  • BULK DELETE all coupons with WP Admin interface /wp-admin/edit.php?post_type=shop_coupon

  • Test creating percentage coupons with discount_type parameter

    wp wc generate coupons 5 --discount_type=percent --min=5 --max=25
    # Check: all 5 coupons should be percentage type with 5-25% discount
  • BULK DELETE all coupons with WP Admin interface /wp-admin/edit.php?post_type=shop_coupon

  • Test creating fixed_cart coupons with discount_type parameter

    wp wc generate coupons 5 --discount_type=fixed_cart --min=10 --max=50
    # Check: all 5 coupons should be fixed_cart type with $10-$50 discount
  • BULK DELETE all coupons with WP Admin interface /wp-admin/edit.php?post_type=shop_coupon

  • Verify default behavior without discount_type (should be fixed_cart)

    wp wc generate coupons 5
    # Check: coupons should default to fixed_cart type

Integration Tests

  • BULK DELETE all orders with WP Admin interface /wp-admin/admin.php?page=wc-orders
  • Test combined coupon-ratio and refund-ratio
    wp wc generate orders 20 --status=completed --coupon-ratio=0.5 --refund-ratio=0.3
    # Check: ~10 orders with coupons, ~6 orders with refunds

@layoutd layoutd self-assigned this Oct 24, 2025
@layoutd layoutd requested a review from Copilot October 24, 2025 10:15
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR enhances the order generator with two new parameters for creating more realistic test data: --coupon-ratio and --refund-ratio. These allow users to specify the percentage of orders that should have coupons applied and the percentage of completed orders that should be refunded, respectively.

Key Changes:

  • Added --coupon-ratio parameter to control coupon application percentage with automatic coupon creation when none exist
  • Added --refund-ratio parameter to generate full or partial refunds on completed orders
  • Implemented automatic creation of 6 coupons (3 fixed, 3 percentage) when the store has no existing coupons

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
includes/Generator/Order.php Implements coupon ratio logic, refund creation functionality, and helper methods for managing coupons and refunds
includes/CLI.php Adds command-line parameter definitions for --coupon-ratio and --refund-ratio

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

layoutd and others added 18 commits October 24, 2025 12:17
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
- Add detailed logging when orders cannot be refunded due to empty line items
- Consolidate refund creation error logs into single formatted message
- Add error logging for invalid order instance check

These improvements will help diagnose why some completed orders aren't receiving refunds when --refund-ratio=1.0 is specified.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
layoutd and others added 6 commits October 24, 2025 15:53
Adds check to ensure refund amount is greater than 0 before calling wc_create_refund(). This prevents "Invalid refund amount" errors that occur when:
- Orders have 100% discount coupons (total = $0)
- Line items have $0 totals
- Calculation results in 0 or negative amount

Logs order ID, calculated amount, and order total when skipping refund.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
The "Invalid refund amount" error occurred because calculated refund amounts slightly exceeded the available order total due to rounding errors in tax calculations.

Changes:
- Calculate maximum refundable amount (order total - already refunded)
- Cap refund amount to maximum available before calling wc_create_refund()
- Round both calculated refund and max refund to 2 decimal places
- Improve error logging to show order total and already refunded amounts

Example of the issue:
- Order total: $24851.03
- Calculated refund (with 3 decimal tax): $24851.04
- Result: $0.01 over limit → "Invalid refund amount" error

This fix ensures refunds never exceed the mathematically available amount, preventing WooCommerce validation errors.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
…partial refunds stay under 50%

For full refunds, use the order's actual total instead of summing line items to avoid rounding discrepancies that created tiny 0.01 refunds. For partial refunds, ensure the total stays below 50% of the order total by removing items if needed, preventing two partial refunds from fully refunding an order.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
…over-refunding

When creating multiple refunds, the code was using original order quantities instead of accounting for items already refunded. This caused second refunds to exceed the original order quantities (e.g., 11 items refunded from an 8-item order).

Now tracks refunded quantities per item and only refunds remaining quantities. All refund logic (full items, partial quantities, and fallback) now calculates remaining quantity = original - already_refunded before processing.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Add division-by-zero guards before all $original_qty divisions
- Change parameter checks from !empty() to isset() to support explicit 0 values
- Remove unused variable $removed_item in refund amount calculation

These changes improve robustness and prevent potential PHP warnings.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- First refunds are created within 2 months of order completion date
- Second refunds are created within 1 month of first refund date
- Update create_refund() to return refund object instead of boolean
- Pass previous refund to second refund for proper date calculation

This makes generated refund data more realistic for testing.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Copy link
Member

@chihsuan chihsuan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice wprk, @layoutd!

Test refund-ratio=0.5 refunds approximately 50% of orders

wp wc generate orders 20 --status=completed --refund-ratio=0.5
# Check: about 10 orders should have refunds (strikeout prices in orders table)

I noticed that only one refund is listed in the orders table, but several orders have a total amount of 0. Is this expected?

Image

@layoutd
Copy link
Contributor Author

layoutd commented Oct 28, 2025

I noticed that only one refund is listed in the orders table, but several orders have a total amount of 0. Is this expected?

This may be due to a lack of products in the store - afaics, they aren't automatically generated so you have to run wp wc generate products 20 first

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants