-
Notifications
You must be signed in to change notification settings - Fork 121
[POS as a tab i2] Support loading WC plugin and POS feature switch from system status endpoint #15906
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
[POS as a tab i2] Support loading WC plugin and POS feature switch from system status endpoint #15906
Changes from all commits
b124751
b11e98a
3a26eb2
961d2f9
4520838
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,82 @@ | ||
| import Foundation | ||
| import Networking | ||
|
|
||
| public protocol POSSystemStatusServiceProtocol { | ||
| /// Loads WooCommerce plugin and POS feature switch value remotely for eligibility checks. | ||
| /// - Parameter siteID: The site ID to fetch information for. | ||
| /// - Returns: POSPluginAndFeatureInfo containing plugin and feature data. | ||
| /// - Throws: Network or parsing errors. | ||
| func loadWooCommercePluginAndPOSFeatureSwitch(siteID: Int64) async throws -> POSPluginAndFeatureInfo | ||
| } | ||
|
|
||
| /// Contains WooCommerce plugin information and POS feature switch value. | ||
| public struct POSPluginAndFeatureInfo { | ||
| public let wcPlugin: SystemPlugin? | ||
| public let featureValue: Bool? | ||
|
|
||
| public init(wcPlugin: SystemPlugin?, featureValue: Bool?) { | ||
| self.wcPlugin = wcPlugin | ||
| self.featureValue = featureValue | ||
| } | ||
| } | ||
|
|
||
| /// Service for fetching POS-related system status information. | ||
| public final class POSSystemStatusService: POSSystemStatusServiceProtocol { | ||
| private let remote: SystemStatusRemote | ||
|
|
||
| public init(credentials: Credentials?) { | ||
| let network = AlamofireNetwork(credentials: credentials) | ||
| remote = SystemStatusRemote(network: network) | ||
| } | ||
|
|
||
| /// Test-friendly initializer that accepts a network implementation. | ||
| init(network: Network) { | ||
| remote = SystemStatusRemote(network: network) | ||
| } | ||
|
|
||
| public func loadWooCommercePluginAndPOSFeatureSwitch(siteID: Int64) async throws -> POSPluginAndFeatureInfo { | ||
| let mapper = SingleItemMapper<POSPluginEligibilitySystemStatus>(siteID: siteID) | ||
| let systemStatus: POSPluginEligibilitySystemStatus = try await remote.loadSystemStatus( | ||
| for: siteID, | ||
| fields: [.activePlugins, .settings], | ||
| mapper: mapper | ||
| ) | ||
|
|
||
| // Finds WooCommerce plugin from active plugins response. | ||
| guard let wcPlugin = systemStatus.activePlugins.first(where: { $0.plugin == Constants.wcPluginPath }) else { | ||
| return POSPluginAndFeatureInfo(wcPlugin: nil, featureValue: nil) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If no WooCommerce plugin path is found at this point of execution, should we throw here rather than returning a
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good question - I thought about it before, and decided to keep this service simple and just return data if available and throw errors when the app fails to retrieve the data. The use case determines how to handle when the plugin / feature value isn't available. Ideally, all the plugin related checks can be in Yosemite. However, right now |
||
| } | ||
|
|
||
| // Extracts POS feature value from settings response. | ||
| let featureValue = systemStatus.settings.enabledFeatures?.contains(SiteSettingsFeature.pointOfSale.rawValue) == true ? true : nil | ||
| return POSPluginAndFeatureInfo(wcPlugin: wcPlugin, featureValue: featureValue) | ||
| } | ||
| } | ||
|
|
||
| private extension POSSystemStatusService { | ||
| enum Constants { | ||
| static let wcPluginPath = "woocommerce/woocommerce.php" | ||
| } | ||
| } | ||
|
|
||
| // MARK: - Network Response Structs | ||
|
|
||
| private struct POSPluginEligibilitySystemStatus: Decodable { | ||
| let activePlugins: [SystemPlugin] | ||
| let settings: POSEligibilitySystemStatusSettings | ||
|
|
||
| enum CodingKeys: String, CodingKey { | ||
| case activePlugins = "active_plugins" | ||
| case settings | ||
| } | ||
| } | ||
|
|
||
| private struct POSEligibilitySystemStatusSettings: Decodable { | ||
| // As `settings.enable_features` was introduced in WC version 9.9.0, this field is optional. | ||
| // Ref: https://github.com/woocommerce/woocommerce/pull/57168 | ||
|
Comment on lines
+75
to
+76
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice 💯 |
||
| let enabledFeatures: [String]? | ||
|
|
||
| enum CodingKeys: String, CodingKey { | ||
| case enabledFeatures = "enabled_features" | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| { | ||
| "data": { | ||
| "active_plugins":[ | ||
| { | ||
| "plugin": "woocommerce/woocommerce.php", | ||
| "name": "WooCommerce", | ||
| "version": "10.0.0-dev", | ||
| "version_latest": "10.0.0-dev", | ||
| "url": "https://woocommerce.com/", | ||
| "author_name": "Automattic", | ||
| "author_url": "https://woocommerce.com", | ||
| "network_activated": false | ||
| } | ||
| ], | ||
| "settings": { | ||
| "api_enabled": false, | ||
| "force_ssl": false, | ||
| "currency": "USD", | ||
| "currency_symbol": "$", | ||
| "currency_position": "left", | ||
| "thousand_separator": ",", | ||
| "decimal_separator": ".", | ||
| "number_of_decimals": 2, | ||
| "geolocation_enabled": false, | ||
| "taxonomies": { | ||
| "external": "external", | ||
| "grouped": "grouped", | ||
| "simple": "simple", | ||
| "variable": "variable" | ||
| }, | ||
| "product_visibility_terms": { | ||
| "exclude-from-catalog": "exclude-from-catalog", | ||
| "exclude-from-search": "exclude-from-search", | ||
| "featured": "featured", | ||
| "outofstock": "outofstock", | ||
| "rated-1": "rated-1", | ||
| "rated-2": "rated-2", | ||
| "rated-3": "rated-3", | ||
| "rated-4": "rated-4", | ||
| "rated-5": "rated-5" | ||
| }, | ||
| "woocommerce_com_connected": "no", | ||
| "enforce_approved_download_dirs": true, | ||
| "order_datastore": "Automattic\\WooCommerce\\Internal\\DataStores\\Orders\\OrdersTableDataStore", | ||
| "HPOS_enabled": true, | ||
| "HPOS_sync_enabled": false, | ||
| "enabled_features": [ | ||
| "analytics", | ||
| "marketplace", | ||
| "order_attribution", | ||
| "site_visibility_badge", | ||
| "remote_logging", | ||
| "email_improvements", | ||
| "custom_order_tables" | ||
| ] | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| { | ||
| "data": { | ||
| "active_plugins":[ | ||
| { | ||
| "plugin": "woocommerce/woocommerce.php", | ||
| "name": "WooCommerce", | ||
| "version": "10.0.0-dev", | ||
| "version_latest": "10.0.0-dev", | ||
| "url": "https://woocommerce.com/", | ||
| "author_name": "Automattic", | ||
| "author_url": "https://woocommerce.com", | ||
| "network_activated": false | ||
| } | ||
| ], | ||
| "settings": { | ||
| "api_enabled": false, | ||
| "force_ssl": false, | ||
| "currency": "USD", | ||
| "currency_symbol": "$", | ||
| "currency_position": "left", | ||
| "thousand_separator": ",", | ||
| "decimal_separator": ".", | ||
| "number_of_decimals": 2, | ||
| "geolocation_enabled": false, | ||
| "taxonomies": { | ||
| "external": "external", | ||
| "grouped": "grouped", | ||
| "simple": "simple", | ||
| "variable": "variable" | ||
| }, | ||
| "product_visibility_terms": { | ||
| "exclude-from-catalog": "exclude-from-catalog", | ||
| "exclude-from-search": "exclude-from-search", | ||
| "featured": "featured", | ||
| "outofstock": "outofstock", | ||
| "rated-1": "rated-1", | ||
| "rated-2": "rated-2", | ||
| "rated-3": "rated-3", | ||
| "rated-4": "rated-4", | ||
| "rated-5": "rated-5" | ||
| }, | ||
| "woocommerce_com_connected": "no", | ||
| "enforce_approved_download_dirs": true, | ||
| "order_datastore": "Automattic\\WooCommerce\\Internal\\DataStores\\Orders\\OrdersTableDataStore", | ||
| "HPOS_enabled": true, | ||
| "HPOS_sync_enabled": false, | ||
| "enabled_features": [ | ||
| "analytics", | ||
| "marketplace", | ||
| "order_attribution", | ||
| "site_visibility_badge", | ||
| "remote_logging", | ||
| "email_improvements", | ||
| "point_of_sale", | ||
| "custom_order_tables" | ||
| ] | ||
| } | ||
| } | ||
| } |
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.
Currently unused, but I think we're missing the settings field here?
Uh oh!
There was an error while loading. Please reload this page.
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.
SystemStatusMapper/SystemStatuscurrently does not need the settings field for the use case of this remote method (as in the fields in the deleted line 21), thus I don't think we need to fetch it for performance reason.