-
Notifications
You must be signed in to change notification settings - Fork 20
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
Keep live rates enabled even with WC Shipping active #2812
Keep live rates enabled even with WC Shipping active #2812
Conversation
public function init_core_wizard_shipping_config() { | ||
if ( $this->is_wc_shipping_activated() ) { | ||
return; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This methods looks for options set by the WC setup wizard to preconfigure shipping methods. The options it looks for were removed in WC 3.6 and are no longer set by newer versions of WC. This plugin requires WC ≥ 8.8.
Instead of conditionally loading this, I removed it altogether.
|
||
// Initialize user choices from the core setup wizard. | ||
// Note: Avoid doing so on non-primary requests so we don't duplicate efforts. | ||
if ( ! defined( 'DOING_AJAX' ) && is_admin() && ! isset( $_GET['noheader'] ) ) { | ||
$this->init_core_wizard_shipping_config(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No longer needed. See https://github.com/Automattic/woocommerce-services/pull/2812/files#r1753818509
There is another thing that needs to be figured out in this PR - support for available packages which are taken into account when calculating live rates. I'm currently working on that. |
One more thing we need to figure out is that when live rates are calculated, existing packages are taken into account. When WCShipping is installed, it migrates packages from WCS&T and stores them under a new option name. With WCShipping present, WCS&T's settings page is no longer registered, and so merchants can no longer edit the available packages on that page. Even if they could, WCS&T would be updating the old option which is still referenced by the live rates logic (provided by WCS&T) but not by the label purchase logic (provided by WCShipping). In WCShip, the only way to edit packages is in the label purchase modal. @Automattic/escargot How do you suggest we approach this? Some ideas that came to mind are:
|
How about we remove the link, and then just add a check to use the new saved packages instead of the old one for the calculations if it is present? Seem like the most minimal amount of changes? |
I'll try this approach. 👍 |
Unfortunately, another issue is that in the label purchase modal in WCShipping, there is no notion of enabled/disabled package - all are available. In WCS&T, you could enable selected carrier-provided and define custom packages. Your choices would then be reflected in which packages are presented in WCS&T's label purchase modal, as well as sent to the Connect Server to decide what packages are used for box packing during live rates calculation. A way to define these packages seems necessary. How do you think we should implement it? |
I created this "normalise" method for our custom packages that maps new field names and removes all new package keys since WCS will reject the requests if it finds unknown key/parameters: |
This PR is ready for review again. Please verify especially the packages data structure to make sure the data format is correct (item no. 8 in the description). |
@@ -3,6 +3,7 @@ | |||
"version": "2.8.1", | |||
"scripts": { | |||
"start": "cross-env NODE_ENV=development CALYPSO_CLIENT=true webpack-dev-server --hot --inline --watch --content-base dist --port 8085 --host 0.0.0.0", | |||
"watch": "cross-env NODE_ENV=development CALYPSO_CLIENT=true webpack --watch", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I needed this for my local dev. 😅 Can be removed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No way! Keeper for sure! 😄
This is now ready for review again. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR! I have 2 questions but otherwise tested ok for me!
Tested live rates with new packages 👍
Tested checking out the order and the shipping cost there 👍
Confirmed the packages are brought over after migration 👍
Questions:
Will updating "service packages" for live rates going to be a problem?
* @return void | ||
*/ | ||
public static function register_option_overwriting_hooks() { | ||
// Intercept reads of "wc_connect_options[packages]" and "wc_connect_options[predefined_packages]". |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These comments are helpful, thank you!
|
||
// Intercept updates to "wc_connect_options[packages]" and "wc_connect_options[predefined_packages]". | ||
add_action( 'update_option_wc_connect_options', array( self::class, 'intercept_packages_update' ), 10, 2 ); | ||
add_action( 'update_option_wc_connect_options', array( self::class, 'intercept_predefined_packages_update' ), 10, 2 ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The 2 update_
functions here will always overwrite WooShipping's packages and predefined packages if the user edits live rate settings under WCS&T's code, regardless if there are any new changes from WCShipping. This may "delete" any new "saved templates" (the blue star) created from WCShipping's side.
If WCS&T can update wc_connect_options
and can overwrite wcshipping_options
but WooShipping can only update wcshipping_options
but can't modify wc_connect_options
, then losing saved templates (blue star) is the only problem. We can fix this by adding another level of array_merge
to combine them. However, if WooShipping can also update wc_connect_options
, then this will get really messy and we should avoid doing that.
Also, when I clicked "edit" in one of my custom box via http://localhost/wp-admin/admin.php?page=wc-settings&tab=shipping§ion=woocommerce-services-settings, these 2 hooks don't get fired. Is that the same for you too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The 2 update_ functions here will always overwrite WooShipping's packages and predefined packages if the user edits live rate settings under WCS&T's code, regardless if there are any new changes from WCShipping. This may "delete" any new "saved templates" (the blue star) created from WCShipping's side.
They won't! If you look at this method, it first gets WCShip's current options value and then it only replaces the packages
key.
Whatever WCS&T is writing there is based on current WCShip packages, too, because the read is intercepted as well.
If WCS&T can update wc_connect_options and can overwrite wcshipping_options but WooShipping can only update wcshipping_options but can't modify wc_connect_options, then losing saved templates (blue star) is the only problem.
WCS&T modifies its entire wc_connect_options
but the value of the packages
key is replaced with whatever is in wcshipping_options[packages]
. In pseudocode, it is doing:
wc_connect_options = {
...wc_connect_options,
packages: wcshipping_options.packages,
};
And after a merchant is done modifying the packages in the above object (note they came from the WCShip options), when WCS&T is writing to wc_connect_options
, it also writes to just the packages
field of WCShip:
const wcshipping_options = get_from_db( 'wcshipping_options' )
save( 'wc_connect_options', submitted_form_data );
save( 'wcshipping_options', {
...wcshipping_options,
packages: submitted_form_data.packages,
} );
Also, when I clicked "edit" in one of my custom box via http://localhost/wp-admin/admin.php?page=wc-settings&tab=shipping§ion=woocommerce-services-settings, these 2 hooks don't get fired. Is that the same for you too?
Please make sure you also have the WC Shipping plugin enabled. Without it, this compatibility layer will not be registered at all.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whatever WCS&T is writing there is based on current WCShip packages, too, because the read is intercepted as well.
... it also writes to just the packages field of WCShip:
Interesting... that's brilliant! Both read & write are intercepted and but the read-inside-the-write is also intercepted first, so you are reading the WCShipping, turns it to WCS&T settings, then write it, essentially syncing the new database config back to the old ones before writing. 👍
Ok I need a moment to visualize this...
https://xkcd.com/555/
@harriswong Thank you for the review!
Could you please elaborate on what you mean by updating service packages? I've responded to the other comments in places where you have posted them. |
Yes i can. I was thinking if someone goes to http://localhost/wp-admin/admin.php?page=wc-settings&tab=shipping§ion=woocommerce-services-settings and update the "Service packages" there, not "custom package". Then, this will save and update the WCS&T's configuration because this UI is loaded from WCS&T. That means the changes here won't get updated back in WCShipping's config. But the explanation you have above #2812 (comment) covered this. Every save action in WCS&T will saves a copy to WCShipping as well. 👍 |
That's right! An update to "Service packages" (a.k.a. carrier packages) changes the |
Double checked again and this time I ensured |
'predefined_packages' => self::EXAMPLE_WCSHIPPING_OPTIONS['predefined_packages'], | ||
) | ||
), | ||
get_option( 'wc_connect_options' ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice test, the setup starts with something in both wc_connect_options
and wcshipping_options
. This merges the two together when wc_connect_options
is requested. 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tested again and looks good to me. 👍
I have 1 suggestion! What do you think about adding another test for this situation:
For this one, the test starts with
wc_connect_options = [101, 201]
wcshipping_options = [301, 401, 501]
Then we click "save" and add a new package, update_option(wc_connect_options, [601]);
// adding a completely new config
Then, we verify the following:
wc_connect_options = [101, 201, 301, 401, 501, 601]
wcshipping_options = [101, 201, 301, 401, 501, 601]
This will help make sure a new item introduced will get saved in both configs.
Just a suggestion though, please feel free to merge!
'predefined_packages' => self::EXAMPLE_WC_CONNECT_OPTIONS['predefined_packages'], | ||
) | ||
), | ||
get_option( 'wcshipping_options' ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
Props @harriswong
Thanks for the review and testing! I've added the test case you suggested. Just a note that if the starting state is:
The expected result will be This is because we read from In a real-world example, if packages are first migrated from WCS&T to WCShip, WCShip's package list should be equal to WCS&T's so then the list would be Does that make sense? By the way there is one quirk of this PR that I thought might not require fixing in this iteration - we can do it separately if needed. That quirk is that if you update the packages in WCShip's purchase modal, the WCS&T option will not get updated. It is not a concern as long as this PR applies because we read WCShip's options anyway but if you disable WCShip, the package list in it will be from the last time you clicked "Save" in the WCS&T package manager we've reintroduced, not when you last clicked save in the WCShip purchase modal. Please LMK if this sounds concerning. I don't think it is. :) One way to fix this would be to either prevent changes to |
@harriswong I managed to work around it. :) I've rewritten the filter of Could you please give it another look? |
remove_filter( 'option_wc_connect_options', array( WC_Connect_Compatibility_WCShipping_Packages::class, 'intercept_packages_read' ) ); | ||
remove_filter( 'option_wc_connect_options', array( WC_Connect_Compatibility_WCShipping_Packages::class, 'intercept_predefined_packages_read' ) ); | ||
|
||
// Assert the original `wc_connect_options` remain unchanged throughout the entire test. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the updates! I tested a migration and unserialized the before-and-after for wc_connect_options
and wcshipping_options
, I confirmed that updating WCShipping doesn't update WCS&T's options.
I added a comment regarding the PHP docs but the last 3 commits look good to me.
*/ | ||
public static function intercept_predefined_packages_update( $old_wc_connect_options, $wc_connect_options ) { | ||
public static function intercept_predefined_packages_update( $wc_connect_options, $old_wc_connect_options ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should probably update the @param
comments
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done! Thanks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
last commit LGTM PS. Who would have thought that the |
Description
Context for development decisions: p1726023174650669-slack-C04KWSNPSE5
This PR keeps live rates enabled even when both WCS&T and WCShip are active. It does this by bringing back the registration of live rates shipping method registration, as well as bringing back the WCS&T settings page (hidden but available through the shipping method settings and in the future, also through the WCShipping settings page).
Additionally, it uses package data from WCShipping if a store has been migrated from WCS&T to WCShipping. Since the two extensions use different package data formats, this PR introduces remapping of package data formats on both reads and writes to
wc_connect_options
.Breaking changes
The changes described below do not affect how WCShipping stores data, only how WCS&T remaps WCShipping's package data for its own purposes.
However, since WCS&T is writing data to WCShipping's options field when an update is requested from the WCS&T settings page that this PR reinstates for package management, it does affect the values that end up in
wcshipping_options[packages]
.To clean up the package data in WCShipping (not a required step; just for the sake of clarity), separate PRs will have to be implemented there.
1) Outer dimensions of custom packages
This is a feature that seems long deprecated but still supported in the codebase.
In WCS&T, predefined packages have outer dimensions (dimensions of the box used for calculating shipping rates) and inner dimensions (dimensions of the inside of the box used for box packing cart contents).
The WCS&T
wc_connect_options
option allows the key "outer_dimensions" to be defined on custom packages too. This used to be a feature of the extension but it was removed in Sep 2019.Although it is no longer possible to set outer dimensions in WCS&T, the field was never unset if a custom package had it set (AFAIK). This means that some stores might have this key lying around for some old custom packages, although it is not presented anywhere anymore.
We could continue passing this key around however since the package edit modal in both WCS&T and WCShipping does not allow you to edit outer dimensions - it only supports inner dimensions (labelled simply as "Dimensions") - there is no way to edit them. This means that merchants effectively have no way to edit the dimensions used for calculating live rates for some very old packages, if they have any still around.
Because of the above, I decided to not support this field in this PR and to only carry over the
inner_dimensions
field which is the one that merchants can edit (and is the only one set for custom packages created after Sep 2019).2) Custom package type value stored under
type
/isLetter
/is_letter
WCS&T used to define packages as a boolean
is_letter
. If a package is a letter, it means it's an envelope. Otherwise, it's a box.WCShipping introduces a new field called
type
which can have the value ofbox
orenvelope
. To support old packages, the fieldis_letter
is still kept around, asisLetter
. In addition to that, a package might also haveis_letter
set.Since it seems these are generally in sync for the packages defined by WCShipping, I have opted to only keep the
type
field after consulting with the team (p1726489562638679-slack-C04KWSNPSE5).Testing instructions
Testing live rates pre-migration:
Testing live rates post-migration (after going through all of the above tests):
admin.php?page=wc-settings&tab=shipping§ion=woocommerce-services-settings
and verify you can see the packages you previously had in WCS&T.Testing WCShipping deactivation (after going through all of the above tests):
Checklist
changelog.txt
entry addedreadme.txt
entry added