Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[HPOS CLI] Add support for backfilling specific properties or metadata #45171

Merged
merged 18 commits into from Mar 13, 2024

Conversation

jorgeatorres
Copy link
Member

@jorgeatorres jorgeatorres commented Feb 27, 2024

Submission Review Guidelines:

Changes proposed in this Pull Request:

In #44281 we introduced the wp wc hpos backfill command which allows backfilling an order from/to the HPOS or posts datastore, regardless of which datastore is currently active. This allows merchants to fix one off errors where some data might've been modified outside of the CRUD layer.

While this works ok, sometimes there might be a need to sync just some specific metadata or properties from/to either datastore instead of the whole order. This PR introduces --meta-keys and --props arguments to wp wc hpos backfill which do precisely that.
While ideally orders would be backfilled in their entirety, this at least provides a last resort for some possible tricky cases.

Closes #41910.

How to test the changes in this Pull Request:

Using the WooCommerce Testing Instructions Guide, include your detailed testing instructions:

  1. Make sure HPOS is set as datastore in WC > Settings > Advanced > Features and also that sync (compatibility mode) is disabled.
    Note: It shouldn't really matter which datastore is set and we'll test syncing both ways, but this will make testing instructions more straightforward.
  2. Make sure your site has at least one order with billing details. Take note of its ID.
  3. Run wp wc cot sync to ensure that things are 100% synced between datastores.
  4. Open the order from step 2 for editing:
    • Change its status to any status.
    • Change the billing first name to any value you like.
    • Add some metadata using the metadata metabox ("Custom Fields") and make a note of the "Name" you used for the field.
  5. Run wp wc hpos diff <order_id> and confirm that the changes made above are listed as differences.
  6. Run wp wc hpos backfill <order_id> --from=hpos --to=posts --props=billing_first_name to backfill the billing first name alone.
  7. Run wp wc hpos diff <order_id> again and confirm that the status is no longer listed as being different. This proves that the --props arg limited the backfill to only that prop (leaving "status" and meta alone).
  8. Let's add some metadata to the posts version with wp post meta update <order_id> my_posts_meta my_meta_value.
  9. Run wp wc hpos diff <order_id> to confirm that the new meta is listed as a difference (with a value only on the 'post' side).
  10. Let's migrate my_posts_meta from the post to the HPOS order by running wp wc hpos backfill <order_id> --from=posts --to=hpos --meta_keys=my_posts_meta. Run wp wc hpos diff <order_id> to confirm that this difference has now disappeared.
  11. Now let's migrate the HPOS meta you added on step 4 by running wp wc hpos backfill <order_id> --from=posts --to=hpos --meta_keys=<meta_key>. Again, verify that the difference is gone with wp wc hpos diff <order_id>.
  12. Finally, let's backfill a property (in this case, the status, which we've left alone thus far) from posts to HPOS: wp wc hpos backfill <order_id> --from=posts --to=hpos --props=status. Verify once more with wp wc hpos diff <order_id>.
  13. Thank you for following such long testing instructions. You're a beautiful person 😸.

Changelog entry

  • Automatically create a changelog entry from the details below.

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

Comment

@github-actions github-actions bot added the plugin: woocommerce Issues related to the WooCommerce Core plugin. label Feb 27, 2024
Copy link
Contributor

github-actions bot commented Feb 27, 2024

Test Results Summary

Commit SHA: ba3bac2

Test 🧪Passed ✅Failed 🚨Broken 🚧Skipped ⏭️Unknown ❔Total 📊Duration ⏱️
API Tests25900202610m 39s
E2E Tests1700018203526m 58s

To view the full API test report, click here.
To view the full E2E test report, click here.
To view all test reports, visit the WooCommerce Test Reports Dashboard.

@jorgeatorres jorgeatorres marked this pull request as ready for review March 12, 2024 19:29
@jorgeatorres jorgeatorres requested review from a team and lsinger and removed request for a team March 12, 2024 19:31
Copy link
Contributor

Hi @lsinger,

Apart from reviewing the code changes, please make sure to review the testing instructions as well.

You can follow this guide to find out what good testing instructions should look like:
https://github.com/woocommerce/woocommerce/wiki/Writing-high-quality-testing-instructions

@jorgeatorres jorgeatorres added the focus: custom order tables / HPOS Issues related to High-Performance Order Storage (HPOS) née Custom Order Tables. label Mar 12, 2024
$order_hpos = $this->sut->get_order_from_datastore( $order->get_id(), 'hpos' );
$this->assertEquals( $order_hpos->get_billing_first_name(), $order_cpt->get_billing_first_name() );
$this->assertEquals( $order_hpos->get_status(), $order_cpt->get_status() );
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder if it could be beneficial here to add a last scenario where we re-enable sync and see that even if partial backfills happened in the meantime, sync still behaves as intended. What do you think? 🤔

Copy link
Member Author

Choose a reason for hiding this comment

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

Added in c7fa5fe.

* Updates an order (in this datastore) from another order object.
*
* @param \WC_Abstract_Order $order Source order.
* @return bool Whether the order was updated.
Copy link
Contributor

@lsinger lsinger Mar 13, 2024

Choose a reason for hiding this comment

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

Is there ever a situation where we don't return true? If not -- should there be? Or will there be one in the future? If we only ever return true, having a return value feels a bit misleading, as a caller of the method might believe based on the return value that it can fail.

Copy link
Member Author

Choose a reason for hiding this comment

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

So this docblock was just copied over from the parent class, which does return a value based on whether the post was updated or not. That said, it's a bit misleading too since the metadata update could've failed (which in that case is actually all order data except status/date) and that's not taken into account.

Similarly, save_meta_data() doesn't tell us whether the meta was updated, so I'd say that right now we can't really tell whether the order was correctly updated or not, so the bool seems useless but we might eventually provided we make some adjustments elsewhere.

* @param bool $should_save Whether to trigger a full save after metadata is changed.
*/
return apply_filters(
'woocommerce_orders_table_datastore_should_save_after_meta_change',
Copy link
Contributor

Choose a reason for hiding this comment

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

For improving readability a bit, could we pull out the boolean value into its own variable (e.g., $should_save) that we then pass to apply_filters?

Copy link
Member Author

Choose a reason for hiding this comment

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

Done in 70a77f2.

Copy link
Contributor

@lsinger lsinger left a comment

Choose a reason for hiding this comment

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

This tests as described and looks good to me -- very nice job. ☺️

I did leave a few comments, but I'd consider none of them blocking. Please handle them as you see fit and feel free to re-request a review if you prefer.

@jorgeatorres jorgeatorres merged commit b3c328d into trunk Mar 13, 2024
33 checks passed
@jorgeatorres jorgeatorres deleted the fix/41910 branch March 13, 2024 22:29
@github-actions github-actions bot added this to the 8.8.0 milestone Mar 13, 2024
@github-actions github-actions bot added the needs: analysis Indicates if the PR requires a PR testing scrub session. label Mar 13, 2024
@alopezari alopezari added needs: internal testing Indicates if the PR requires further testing conducted by Solaris status: analysis complete Indicates if a PR has been analysed by Solaris and removed needs: analysis Indicates if the PR requires a PR testing scrub session. labels Mar 14, 2024
@Stojdza
Copy link
Contributor

Stojdza commented Mar 19, 2024

Thank you for following such long testing instructions. You're a beautiful person

Thank you for such detailed testing instructions 🙌

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
focus: custom order tables / HPOS Issues related to High-Performance Order Storage (HPOS) née Custom Order Tables. needs: internal testing Indicates if the PR requires further testing conducted by Solaris plugin: woocommerce Issues related to the WooCommerce Core plugin. status: analysis complete Indicates if a PR has been analysed by Solaris
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[CLI] Allow syncing of only missing data or even specific properties
4 participants