Skip to content

Commit b11e98a

Browse files
committed
Create POSSystemStatusService to load WC plugin and POS feature switch value from one system status API request.
1 parent b124751 commit b11e98a

File tree

2 files changed

+87
-2
lines changed

2 files changed

+87
-2
lines changed

Modules/Sources/Networking/Mapper/SingleItemMapper.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,20 @@ import Foundation
22

33
/// SingleItemMapper: Maps generic REST API requests for a single item
44
///
5-
struct SingleItemMapper<Output: Decodable>: Mapper {
5+
public struct SingleItemMapper<Output: Decodable>: Mapper {
66
/// Site Identifier associated to the items that will be parsed.
77
///
88
/// We're injecting this field via `JSONDecoder.userInfo` because SiteID is not returned by our endpoints.
99
///
1010
let siteID: Int64
1111

12+
public init(siteID: Int64) {
13+
self.siteID = siteID
14+
}
15+
1216
/// (Attempts) to convert a dictionary into Output.
1317
///
14-
func map(response: Data) throws -> Output {
18+
public func map(response: Data) throws -> Output {
1519
let decoder = JSONDecoder()
1620
decoder.dateDecodingStrategy = .formatted(DateFormatter.Defaults.dateTimeFormatter)
1721
decoder.userInfo = [
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import Foundation
2+
import Networking
3+
4+
public protocol POSSystemStatusServiceProtocol {
5+
/// Loads WooCommerce plugin and POS feature switch value remotely for eligibility checks.
6+
/// - Parameter siteID: The site ID to fetch information for.
7+
/// - Returns: POSPluginAndFeatureInfo containing plugin and feature data.
8+
/// - Throws: Network or parsing errors.
9+
func loadWooCommercePluginAndPOSFeatureSwitch(siteID: Int64) async throws -> POSPluginAndFeatureInfo
10+
}
11+
12+
/// Contains WooCommerce plugin information and POS feature switch value.
13+
public struct POSPluginAndFeatureInfo {
14+
public let wcPlugin: SystemPlugin?
15+
public let featureValue: Bool?
16+
17+
public init(wcPlugin: SystemPlugin?, featureValue: Bool?) {
18+
self.wcPlugin = wcPlugin
19+
self.featureValue = featureValue
20+
}
21+
}
22+
23+
/// Service for fetching POS-related system status information.
24+
public final class POSSystemStatusService: POSSystemStatusServiceProtocol {
25+
private let remote: SystemStatusRemote
26+
27+
public init(credentials: Credentials?) {
28+
let network = AlamofireNetwork(credentials: credentials)
29+
remote = SystemStatusRemote(network: network)
30+
}
31+
32+
public func loadWooCommercePluginAndPOSFeatureSwitch(siteID: Int64) async throws -> POSPluginAndFeatureInfo {
33+
let mapper = SingleItemMapper<POSPluginEligibilitySystemStatus>(siteID: siteID)
34+
let systemStatus: POSPluginEligibilitySystemStatus = try await remote.loadSystemStatus(
35+
for: siteID,
36+
fields: [.activePlugins, .settings],
37+
mapper: mapper
38+
)
39+
40+
// Finds WooCommerce plugin from active plugins response.
41+
guard let wcPlugin = systemStatus.activePlugins.first(where: { $0.plugin == Constants.wcPluginPath }) else {
42+
return POSPluginAndFeatureInfo(wcPlugin: nil, featureValue: nil)
43+
}
44+
45+
// Extracts POS feature value from settings response.
46+
let featureValue = systemStatus.settings.enabledFeatures.contains(SiteSettingsFeature.pointOfSale.rawValue) ? true : nil
47+
return POSPluginAndFeatureInfo(wcPlugin: wcPlugin, featureValue: featureValue)
48+
}
49+
}
50+
51+
private extension POSSystemStatusService {
52+
enum Constants {
53+
static let wcPluginPath = "woocommerce/woocommerce.php"
54+
}
55+
}
56+
57+
// MARK: - Errors
58+
59+
public enum POSSystemStatusServiceError: Error {
60+
case wooCommercePluginNotFound
61+
}
62+
63+
// MARK: - Network Response Structs
64+
65+
private struct POSPluginEligibilitySystemStatus: Decodable {
66+
let activePlugins: [SystemPlugin]
67+
let settings: POSEligibilitySystemStatusSettings
68+
69+
enum CodingKeys: String, CodingKey {
70+
case activePlugins = "active_plugins"
71+
case settings
72+
}
73+
}
74+
75+
private struct POSEligibilitySystemStatusSettings: Decodable {
76+
let enabledFeatures: [String]
77+
78+
enum CodingKeys: String, CodingKey {
79+
case enabledFeatures = "enabled_features"
80+
}
81+
}

0 commit comments

Comments
 (0)