Skip to content

Conversation

@Konamiman
Copy link
Contributor

@Konamiman Konamiman commented Oct 7, 2025

Changes proposed in this Pull Request:

This pull requests implements the storage of total COGS values for orders when HPOS is disabled.

Closes #61292.

How to test the changes in this Pull Request:

  1. Repeat the testing instructions of Add the Cost of Goods Sold related code and REST APIs for the orders and order items #52067, Add Cost of Goods Sold information in the order editor in admin #55840 and Take in account refunds when calculating Cost of Goods Sold for an order #57838 but with HPOS disabled.

  2. With HPOS enabled and compatibility mode enabled (in WooCommerce - Settings - Advanced - Features), create an order from the store, load it in admin and verify that the total cost value is correct. Then switch off HPOS (wp wc hpos disable), reload the order details page, and verify that the cost data is still correct.

  3. Repeat 2, but in reverse (start with HPOS disabled this time).

Changelog entry

  • Automatically create a changelog entry from the details below.
  • This Pull Request does not require a changelog entry. (Comment required below)
Changelog Entry Details

Significance

  • Patch
  • Minor
  • Major

Type

  • Fix - Fixes an existing bug
  • Add - Adds functionality
  • Update - Update existing functionality
  • Dev - Development related task
  • Tweak - A minor adjustment to the codebase
  • Performance - Address performance issues
  • Enhancement - Improvement to existing functionality

Message

Changelog Entry Comment

Comment

@github-actions github-actions bot added the plugin: woocommerce Issues related to the WooCommerce Core plugin. label Oct 7, 2025
@Konamiman Konamiman marked this pull request as ready for review October 7, 2025 15:16
@woocommercebot woocommercebot requested review from a team and prettyboymp and removed request for a team October 7, 2025 15:16
@github-actions
Copy link
Contributor

github-actions bot commented Oct 7, 2025

Testing Guidelines

Hi @prettyboymp ,

Apart from reviewing the code changes, please make sure to review the testing instructions (Guide) and verify that relevant tests (E2E, Unit, Integration, etc.) have been added or updated as needed.

Reminder: PR reviewers are required to document testing performed. This includes:

  • 🖼️ Screenshots or screen recordings.
  • 📝 List of functionality tested / steps followed.
  • 🌐 Site details (environment attributes such as hosting type, plugins, theme, store size, store age, and relevant settings).
  • 🔍 Any analysis performed, such as assessing potential impacts on environment attributes and other plugins, conducting performance profiling, or using LLM/AI-based analysis.

⚠️ Within the testing details you provide, please ensure that no sensitive information (such as API keys, passwords, user data, etc.) is included in this public issue.

@github-actions
Copy link
Contributor

github-actions bot commented Oct 7, 2025

Test using WordPress Playground

The changes in this pull request can be previewed and tested using a WordPress Playground instance.
WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser.

Test this pull request with WordPress Playground.

Note that this URL is valid for 30 days from when this comment was last updated. You can update it by closing/reopening the PR or pushing a new commit.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 7, 2025

📝 Walkthrough

Walkthrough

Adds conditional loading, persistence, and sync of COGS values across CPT and HPOS order data stores; preserves per-item saved COGS for DB-loaded items; guards HPOS migration from overwriting valid COGS with zeros; adds tests and a changelog entry for these COGS behaviors.

Changes

Cohort / File(s) Summary
Changelog
plugins/woocommerce/changelog/pr-61307
New changelog entry noting patch-level update for storing COGS values for orders when HPOS is disabled.
Order item COGS logic
plugins/woocommerce/includes/class-wc-order-item-product.php
Preserve saved per-item COGS for items loaded from DB (return stored get_cogs_value('edit')) unless refund or missing; otherwise fall back to product-based calculation.
Abstract order item data store
plugins/woocommerce/includes/data-stores/abstract-wc-order-item-type-data-store.php
Read _cogs_value meta into a variable and only cast/filter/set item COGS if metadata exists; skip setting/applying filter when metadata is absent.
CPT order data store (COGS sync)
plugins/woocommerce/includes/data-stores/class-wc-order-data-store-cpt.php
Add CogsAwareTrait and include _cogs_total_value in internal meta keys; add read_cogs_data, update_order_meta_from_object, handle_cogs_value_update and helpers; conditionally read/save/delete _cogs_total_value and apply woocommerce_load_order_cogs_value / woocommerce_save_order_cogs_value filters.
HPOS orders data store migration guard
plugins/woocommerce/src/Internal/DataStores/Orders/OrdersTableDataStore.php
In migrate_post_record, skip migrating cogs_total_value when HPOS order already has a positive COGS and incoming CPT post data is zero to avoid overwriting valid HPOS COGS.
Tests (CPT data store + COGS)
plugins/woocommerce/tests/php/includes/data-stores/class-wc-order-data-store-cpt-test.php
Add Cogs-aware test trait, teardown hook, helpers and numerous tests covering saving/loading/filtering/syncing of COGS, HPOS/backfill scenarios, zero/non-zero values, refunds, and per-item saved COGS behavior.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant Order as WC_Order
    participant CPT_DS as CPT Data Store
    participant Meta as Post Meta (DB)
    participant HPOS_DS as HPOS Data Store

    Note over CPT_DS,Meta: Read CPT order
    CPT_DS->>Meta: get_post_meta(..., '_cogs_total_value')
    alt meta exists and COGS enabled
        CPT_DS->>Order: set_cogs_total_value(filtered value)
    else meta missing
        CPT_DS->>Order: do not set COGS (defer calculation)
    end

    Note over Order,CPT_DS: Save CPT order
    Order->>CPT_DS: update_order_meta_from_object(order)
    CPT_DS->>CPT_DS: handle_cogs_value_update -> apply save filter
    alt filter returns null (don't save)
        CPT_DS->>Meta: delete_post_meta('_cogs_total_value')
    else value non-zero and enabled
        CPT_DS->>Meta: update_post_meta('_cogs_total_value', value)
    end

    Note over HPOS_DS,CPT_DS: Migrate CPT -> HPOS on read
    HPOS_DS->>CPT_DS: migrate_post_record(...)
    alt HPOS has cogs > 0 and incoming CPT value == 0
        HPOS_DS-->>CPT_DS: skip migrating cogs_total_value (preserve HPOS)
    else
        HPOS_DS->>Order: set migrated properties
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Title Check ✅ Passed The title succinctly and accurately reflects the main enhancement of the changeset by specifying support for storing COGS values when HPOS is disabled, matching the pull request’s primary focus. It is clear, concise, and omits extraneous details, making the intent immediately understandable.
Linked Issues Check ✅ Passed The code changes comprehensively address issue #61292 by preserving and loading existing COGS metadata for legacy orders, conditionally syncing item and order COGS values, and adding extensive tests for both legacy and HPOS modes to ensure correct persistence and retrieval. These measures align with the linked issue’s requirements for fixing COGS resetting to zero and retaining correct values.
Out of Scope Changes Check ✅ Passed All modifications are focused on implementing legacy COGS persistence and related metadata synchronization, along with appropriate test coverage and documentation. No unrelated features or extraneous code changes have been introduced, keeping the scope aligned with the linked issue objectives.
Description Check ✅ Passed The pull request description accurately describes the implementation of storing total COGS values for orders when HPOS is disabled, references related testing scenarios, and links to the issue being closed, demonstrating direct relevance to the changeset. It provides sufficient context for reviewers without veering off topic.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch cogs/add-cogs-to-orders-cpt

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (5)
plugins/woocommerce/includes/data-stores/abstract-wc-order-item-type-data-store.php (1)

181-201: Leverage item meta cache and avoid unnecessary datastore call

Use the item’s meta API (already primed by read_meta_data) and optionally apply changes to avoid leaving the item dirty after read.

-            $cogs_metadata = $this->order_item_data_store->get_metadata( $item->get_id(), '_cogs_value', true );
+            $cogs_metadata = $item->get_meta( '_cogs_value', true );
@@
-            if ( '' !== $cogs_metadata && false !== $cogs_metadata ) {
+            if ( '' !== $cogs_metadata && false !== $cogs_metadata ) {
                 $cogs_value = (float) $cogs_metadata;
@@
-                $item->set_cogs_value( (float) $cogs_value );
+                $item->set_cogs_value( (float) $cogs_value );
+                // Optional: keep the object clean after read.
+                $item->apply_changes();
             }
plugins/woocommerce/includes/data-stores/class-wc-order-data-store-cpt.php (2)

273-291: Avoid duplicating COGS save logic; centralize filter + zero-delete handling

This block and update_order_meta_from_object both apply woocommerce_save_order_cogs_value and perform delete/update. Consider funneling both through a shared helper (e.g., reuse handle_cogs_value_update or extract one method) to keep behavior in one place.


1418-1445: update_order_meta_from_object duplication

Same recommendation: reuse a single helper for filter + zero→delete behavior to ensure consistent semantics and reduce drift.

plugins/woocommerce/tests/php/includes/data-stores/class-wc-order-data-store-cpt-test.php (2)

1-1: Add strict types declaration to test file

Per project test guidelines, add declare(strict_types=1); at the top.

+<?php declare(strict_types=1);
-<?php
+// phpcs:ignoreFile WordPress.Files.FileName.InvalidClassFileName

828-1260: Float assertions robustness

Several tests compare floats with assertEquals. Prefer assertEqualsWithDelta to avoid brittle failures from float precision.

Example:

-        $this->assertEquals( $expected_total, (float) get_post_meta( $order->get_id(), '_cogs_total_value', true ) );
+        $this->assertEqualsWithDelta( $expected_total, (float) get_post_meta( $order->get_id(), '_cogs_total_value', true ), 0.00001 );
📜 Review details

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7e62599 and 26fcbe9.

📒 Files selected for processing (6)
  • plugins/woocommerce/changelog/pr-61307 (1 hunks)
  • plugins/woocommerce/includes/class-wc-order-item-product.php (1 hunks)
  • plugins/woocommerce/includes/data-stores/abstract-wc-order-item-type-data-store.php (1 hunks)
  • plugins/woocommerce/includes/data-stores/class-wc-order-data-store-cpt.php (7 hunks)
  • plugins/woocommerce/src/Internal/DataStores/Orders/OrdersTableDataStore.php (1 hunks)
  • plugins/woocommerce/tests/php/includes/data-stores/class-wc-order-data-store-cpt-test.php (4 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{php,js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/code-quality.mdc)

**/*.{php,js,jsx,ts,tsx}: Guard against unexpected inputs
Sanitize and validate any potentially dangerous inputs
Ensure code is backwards compatible
Write code that is readable and intuitive
Ensure code has unit or E2E tests where applicable

Files:

  • plugins/woocommerce/includes/data-stores/abstract-wc-order-item-type-data-store.php
  • plugins/woocommerce/includes/class-wc-order-item-product.php
  • plugins/woocommerce/src/Internal/DataStores/Orders/OrdersTableDataStore.php
  • plugins/woocommerce/tests/php/includes/data-stores/class-wc-order-data-store-cpt-test.php
  • plugins/woocommerce/includes/data-stores/class-wc-order-data-store-cpt.php
**/*.{php,js,jsx,tsx,ts}

📄 CodeRabbit inference engine (.cursor/rules/avoid-regex.mdc)

**/*.{php,js,jsx,tsx,ts}: Avoid using regular expressions unless absolutely necessary to favor readability and maintainability
Only consider regex when no built-in language alternative (string/array APIs) fits the need
Only use regex when performance is critical and faster than alternatives, with measurements to justify
Use regex for complex pattern matching only if the pattern is well-documented and thoroughly tested
Allow regex when maintaining legacy code where an existing, correct pattern is being modified
If regex is necessary, document the pattern extensively to explain what it matches
If regex is necessary, add comprehensive tests covering edge cases and potential security issues
Use named capture groups in regex to improve readability when supported
Validate input before applying regex to ensure it is safe
Assess and mitigate security risks when using regex, including ReDoS and injection vulnerabilities
Avoid regex patterns that can cause catastrophic backtracking (ReDoS)
Do not construct regex from untrusted input to prevent injection attacks
Ensure regex patterns do not overmatch and unintentionally capture unexpected inputs

Files:

  • plugins/woocommerce/includes/data-stores/abstract-wc-order-item-type-data-store.php
  • plugins/woocommerce/includes/class-wc-order-item-product.php
  • plugins/woocommerce/src/Internal/DataStores/Orders/OrdersTableDataStore.php
  • plugins/woocommerce/tests/php/includes/data-stores/class-wc-order-data-store-cpt-test.php
  • plugins/woocommerce/includes/data-stores/class-wc-order-data-store-cpt.php
**/*.{php,js,ts,jsx,tsx}

⚙️ CodeRabbit configuration file

**/*.{php,js,ts,jsx,tsx}: Don't trust that extension developers will follow the best practices, make sure the code:

  • Guards against unexpected inputs.
  • Sanitizes and validates any potentially dangerous inputs.
  • Is backwards compatible.
  • Is readable and intuitive.
  • Has unit or E2E tests where applicable.

Files:

  • plugins/woocommerce/includes/data-stores/abstract-wc-order-item-type-data-store.php
  • plugins/woocommerce/includes/class-wc-order-item-product.php
  • plugins/woocommerce/src/Internal/DataStores/Orders/OrdersTableDataStore.php
  • plugins/woocommerce/tests/php/includes/data-stores/class-wc-order-data-store-cpt-test.php
  • plugins/woocommerce/includes/data-stores/class-wc-order-data-store-cpt.php
plugins/woocommerce/tests/**/*.php

📄 CodeRabbit inference engine (.cursor/rules/woo-phpunit.mdc)

plugins/woocommerce/tests/**/*.php: Ensure test classes define public setUp() and tearDown() methods (not protected)
All PHPUnit test methods must be public, not protected
Add declare(strict_types=1); at the top of each test file
Test classes should extend WC_Unit_Test_Case

Files:

  • plugins/woocommerce/tests/php/includes/data-stores/class-wc-order-data-store-cpt-test.php
plugins/woocommerce/tests/php/**

📄 CodeRabbit inference engine (plugins/woocommerce/CLAUDE.md)

Store PHP test data and fixtures under tests/php/

Files:

  • plugins/woocommerce/tests/php/includes/data-stores/class-wc-order-data-store-cpt-test.php
🧬 Code graph analysis (4)
plugins/woocommerce/includes/class-wc-order-item-product.php (1)
plugins/woocommerce/includes/abstracts/abstract-wc-data.php (1)
  • get_object_read (771-773)
plugins/woocommerce/src/Internal/DataStores/Orders/OrdersTableDataStore.php (2)
plugins/woocommerce/includes/class-wc-order-item-product.php (1)
  • has_cogs (555-557)
plugins/woocommerce/includes/class-wc-order.php (1)
  • has_cogs (2523-2525)
plugins/woocommerce/tests/php/includes/data-stores/class-wc-order-data-store-cpt-test.php (5)
plugins/woocommerce/tests/legacy/framework/helpers/class-wc-helper-product.php (1)
  • create_simple_product (46-72)
plugins/woocommerce/includes/class-wc-order-item-product.php (1)
  • has_cogs (555-557)
plugins/woocommerce/includes/abstracts/abstract-wc-order.php (2)
  • set_cogs_total_value (2601-2605)
  • calculate_cogs_total_value (2537-2557)
plugins/woocommerce/includes/data-stores/class-wc-order-data-store-cpt.php (2)
  • update_order_meta_from_object (1418-1445)
  • update_post_meta (253-406)
plugins/woocommerce/includes/wc-order-functions.php (1)
  • wc_create_refund (557-751)
plugins/woocommerce/includes/data-stores/class-wc-order-data-store-cpt.php (4)
plugins/woocommerce/tests/php/includes/data-stores/class-wc-order-data-store-cpt-test.php (3)
  • has_cogs (886-888)
  • has_cogs (953-955)
  • update_order_meta_from_object (858-860)
plugins/woocommerce/src/Internal/DataStores/Orders/OrdersTableDataStore.php (2)
  • read_cogs_data (1396-1412)
  • update_post_meta (2898-2900)
plugins/woocommerce/includes/data-stores/abstract-wc-order-data-store-cpt.php (2)
  • update_order_meta_from_object (751-817)
  • update_post_meta (460-500)
plugins/woocommerce/includes/abstracts/abstract-wc-order.php (1)
  • set_cogs_total_value (2601-2605)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build
  • GitHub Check: Blocks e2e tests 10/10 - @woocommerce/plugin-woocommerce [e2e]
🔇 Additional comments (9)
plugins/woocommerce/includes/class-wc-order-item-product.php (1)

577-585: Fallback calculation logic is correct.

The original product-based calculation is preserved as a sensible fallback for new items, refunds, and items without saved COGS data. This maintains backwards compatibility while supporting the new preservation behavior.

plugins/woocommerce/changelog/pr-61307 (1)

1-4: Changelog format check

Confirm if the changelog generator expects a “Comment:” key. If yes, change line 4 to “Comment: Add support for storing COGS values for orders when HPOS is disabled”.

plugins/woocommerce/includes/data-stores/class-wc-order-data-store-cpt.php (5)

12-12: Trait usage looks good

COGS feature gating via CogsAwareTrait is correctly wired.

Also applies to: 24-24


85-85: Marking _cogs_total_value as internal meta is correct

Prevents exposure as a custom field and avoids accidental deletion in sync.


189-191: Reading COGS during CPT read

Good conditional load respecting feature and capability.


1453-1469: CPT COGS read path

LGTM. Mirrors HPOS behavior and applies filter before setting.


1482-1510: handle_cogs_value_update is sound

Covers feature gating, null→skip, and zero→delete. Minor: given the pre-check at Line 279, the feature check here is redundant; safe to keep for defensive coding.

plugins/woocommerce/tests/php/includes/data-stores/class-wc-order-data-store-cpt-test.php (2)

6-6: Test scaffolding

Using CogsAwareUnitTestSuiteTrait and disabling feature in tearDown is correct.

Also applies to: 15-16, 41-46


931-960: Consider adding HPOS sync-on-read test for negative COGS

To validate the guard in OrdersTableDataStore (not overwriting non-zero HPOS COGS, including negative refunds), add a counterpart test under HPOS to cover negative values.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
plugins/woocommerce/src/Internal/DataStores/Orders/OrdersTableDataStore.php (1)

1690-1697: Add explicit float cast for type consistency.

The logic correctly prevents overwriting valid HPOS COGS with stale CPT zero values. However, line 1693 should explicitly cast $hpos_cogs to float for type consistency, as recommended in the previous review comment.

Apply this diff:

-			$hpos_cogs = $order->get_cogs_total_value( 'edit' );
+			$hpos_cogs = (float) $order->get_cogs_total_value( 'edit' );

This ensures strict type consistency with the float comparison at line 1694 and aligns with the approach used for $value.

📜 Review details

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 450de5d and 21b6bd4.

📒 Files selected for processing (1)
  • plugins/woocommerce/src/Internal/DataStores/Orders/OrdersTableDataStore.php (2 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{php,js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/code-quality.mdc)

**/*.{php,js,jsx,ts,tsx}: Guard against unexpected inputs
Sanitize and validate any potentially dangerous inputs
Ensure code is backwards compatible
Write code that is readable and intuitive
Ensure code has unit or E2E tests where applicable

Files:

  • plugins/woocommerce/src/Internal/DataStores/Orders/OrdersTableDataStore.php
**/*.{php,js,jsx,tsx,ts}

📄 CodeRabbit inference engine (.cursor/rules/avoid-regex.mdc)

**/*.{php,js,jsx,tsx,ts}: Avoid using regular expressions unless absolutely necessary to favor readability and maintainability
Only consider regex when no built-in language alternative (string/array APIs) fits the need
Only use regex when performance is critical and faster than alternatives, with measurements to justify
Use regex for complex pattern matching only if the pattern is well-documented and thoroughly tested
Allow regex when maintaining legacy code where an existing, correct pattern is being modified
If regex is necessary, document the pattern extensively to explain what it matches
If regex is necessary, add comprehensive tests covering edge cases and potential security issues
Use named capture groups in regex to improve readability when supported
Validate input before applying regex to ensure it is safe
Assess and mitigate security risks when using regex, including ReDoS and injection vulnerabilities
Avoid regex patterns that can cause catastrophic backtracking (ReDoS)
Do not construct regex from untrusted input to prevent injection attacks
Ensure regex patterns do not overmatch and unintentionally capture unexpected inputs

Files:

  • plugins/woocommerce/src/Internal/DataStores/Orders/OrdersTableDataStore.php
**/*.{php,js,ts,jsx,tsx}

⚙️ CodeRabbit configuration file

**/*.{php,js,ts,jsx,tsx}: Don't trust that extension developers will follow the best practices, make sure the code:

  • Guards against unexpected inputs.
  • Sanitizes and validates any potentially dangerous inputs.
  • Is backwards compatible.
  • Is readable and intuitive.
  • Has unit or E2E tests where applicable.

Files:

  • plugins/woocommerce/src/Internal/DataStores/Orders/OrdersTableDataStore.php
🧬 Code graph analysis (1)
plugins/woocommerce/src/Internal/DataStores/Orders/OrdersTableDataStore.php (2)
plugins/woocommerce/includes/class-wc-order.php (1)
  • has_cogs (2523-2525)
plugins/woocommerce/tests/php/src/Internal/DataStores/Orders/OrdersTableDataStoreTests.php (2)
  • has_cogs (3590-3592)
  • has_cogs (3670-3672)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (32)
  • GitHub Check: Blocks e2e tests 10/10 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Blocks e2e tests - Legacy MiniCart 1/3 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Blocks e2e tests 5/10 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Blocks e2e tests - Legacy MiniCart 2/3 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Blocks e2e tests - Legacy MiniCart 3/3 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Blocks e2e tests 6/10 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Blocks e2e tests 7/10 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: PHP: 8.4 WP: latest (HPOS:off) [WP latest] 2/2 - @woocommerce/plugin-woocommerce [unit:php]
  • GitHub Check: PHP: 8.4 WP: latest (HPOS:off) [WP latest] 1/2 - @woocommerce/plugin-woocommerce [unit:php]
  • GitHub Check: Blocks e2e tests 8/10 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Blocks e2e tests 9/10 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests 2/6 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Blocks e2e tests 3/10 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Blocks e2e tests 1/10 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Blocks e2e tests 2/10 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Blocks e2e tests 4/10 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core API tests - @woocommerce/plugin-woocommerce [api]
  • GitHub Check: Core e2e tests 4/6 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Metrics - @woocommerce/plugin-woocommerce [performance]
  • GitHub Check: Core e2e tests 6/6 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: PHP: 8.4 WP: latest - Legacy MiniCart [WP latest] 2/2 - @woocommerce/plugin-woocommerce [unit:php]
  • GitHub Check: Core e2e tests - Legacy MiniCart - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: PHP: 7.4 WP: latest - 1 [WP 6.7.4] 2/2 - @woocommerce/plugin-woocommerce [unit:php]
  • GitHub Check: Core e2e tests 5/6 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests 3/6 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests 1/6 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: PHP: 8.4 WP: latest [WP latest] 1/2 - @woocommerce/plugin-woocommerce [unit:php]
  • GitHub Check: PHP: 7.4 WP: latest - 1 [WP 6.7.4] 1/2 - @woocommerce/plugin-woocommerce [unit:php]
  • GitHub Check: PHP: 8.4 WP: latest - Legacy MiniCart [WP latest] 1/2 - @woocommerce/plugin-woocommerce [unit:php]
  • GitHub Check: PHP: 8.4 WP: latest [WP latest] 2/2 - @woocommerce/plugin-woocommerce [unit:php]
  • GitHub Check: Lint - @woocommerce/plugin-woocommerce
  • GitHub Check: build
🔇 Additional comments (1)
plugins/woocommerce/src/Internal/DataStores/Orders/OrdersTableDataStore.php (1)

105-105: LGTM! Internal meta key addition is correct.

The addition of '_cogs_total_value' to the internal_meta_keys array correctly marks COGS data as internal metadata, ensuring proper handling during CPT/HPOS synchronization.

Copy link
Contributor

@prettyboymp prettyboymp left a comment

Choose a reason for hiding this comment

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

@Konamiman, I'm seeing some calculation issues when running HPOS without syncing enabled, that don't appear to happen otherwise.

Image

To reproduce - note these are the steps I did to create the issue, I'm not 100% sure which cause the problem:

  1. Create a variable with 2 attributes, each with 2 values - generating 4 variations.
  2. Give each variation a price and unique cost.
  3. Go to the shop and add each variation to your cart and checkout.
  4. Process the order so it is complete.
  5. Edit the order.
  6. Click Refund
  7. Refund a specific item.
  8. Check the total cost of goods displayed.

This didn't occur when not using HPOS or when syncing was enabled. And it didn't happen when purchasing only 2 variations.. Though I don't know if it was the number of variations or items in the order.

@Konamiman
Copy link
Contributor Author

@prettyboymp I have followed these steps (both with HPOS enabled and disable, and automatic data sync disabled in both cases) and I get the expected result:

image

Also I tested with two products: one with product-specific attributes and one with general term-based attributes, just in case.

What's the exact issue you experienced? Refunds not visible in the page?

Copy link
Contributor

@prettyboymp prettyboymp left a comment

Choose a reason for hiding this comment

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

@Konamiman, I previously tested in WordPress Playground because my local dev has too much data in HPOS to easily switch to the other states. I'm not sure why the issue is occurring there, but it must be a build issue.

I retested locally, and the issue wasn't there.

@Konamiman Konamiman merged commit a7ba89b into trunk Oct 14, 2025
47 checks passed
@Konamiman Konamiman deleted the cogs/add-cogs-to-orders-cpt branch October 14, 2025 14:21
@github-actions github-actions bot added this to the 10.4.0 milestone Oct 14, 2025
Konamiman added a commit that referenced this pull request Oct 29, 2025
PR #61307 introduced a change: already persisted COGS values for
product line items would be preserved to serve as "snapshots"
of the COGS value at the time of purchase. However this has the
unintended side effect that for orders not yet completed, the COGS
values for these line items will not be recalculated even after
product COGS change. So this commit reverts the change.
Konamiman added a commit that referenced this pull request Oct 29, 2025
PR #61307 introduced a change: already persisted COGS values for
product line items would be preserved to serve as "snapshots"
of the COGS value at the time of purchase. However this has the
unintended side effect that for orders not yet completed, the COGS
values for these line items will not be recalculated even after
product COGS change. So this commit reverts the change.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

plugin: woocommerce Issues related to the WooCommerce Core plugin.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Cost of Goods reverting to 0.00 on Legacy System

3 participants