Skip to content

Commit 61afa87

Browse files
authored
[POS Settings] Adjust settings Controller-Service interface and dependencies (#16053)
2 parents 64120ad + 3e9979f commit 61afa87

File tree

11 files changed

+546
-254
lines changed

11 files changed

+546
-254
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
2+
public struct POSReceiptInformation: Equatable {
3+
public let storeName: String?
4+
public let storeAddress: String?
5+
public let phone: String?
6+
public let email: String?
7+
public let refundReturnsPolicy: String?
8+
9+
public init(storeName: String?, storeAddress: String?, phone: String?, email: String?, refundReturnsPolicy: String?) {
10+
self.storeName = storeName
11+
self.storeAddress = storeAddress
12+
self.phone = phone
13+
self.email = email
14+
self.refundReturnsPolicy = refundReturnsPolicy
15+
}
16+
17+
public static let empty = POSReceiptInformation(
18+
storeName: nil,
19+
storeAddress: nil,
20+
phone: nil,
21+
email: nil,
22+
refundReturnsPolicy: nil
23+
)
24+
}

Modules/Sources/Yosemite/Tools/POS/PointOfSaleSettingsService.swift

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@ import Networking
33
import Storage
44

55
public protocol PointOfSaleSettingsServiceProtocol {
6-
var siteID: Int64 { get }
7-
func retrievePointOfSaleSettings() async throws -> [SiteSetting]
6+
func retrievePointOfSaleSettings() async throws -> POSReceiptInformation
87
}
98

109
public final class PointOfSaleSettingsService: PointOfSaleSettingsServiceProtocol {
@@ -25,7 +24,19 @@ public final class PointOfSaleSettingsService: PointOfSaleSettingsServiceProtoco
2524
network: network))
2625
}
2726

28-
public func retrievePointOfSaleSettings() async throws -> [SiteSetting] {
29-
return try await settingStoreMethods.retrievePointOfSaleSettings(siteID: siteID)
27+
public func retrievePointOfSaleSettings() async throws -> POSReceiptInformation {
28+
let siteSettings = try await settingStoreMethods.retrievePointOfSaleSettings(siteID: siteID)
29+
return POSReceiptInformation(
30+
storeName: settingValue(from: siteSettings, settingID: "woocommerce_pos_store_name"),
31+
storeAddress: settingValue(from: siteSettings, settingID: "woocommerce_pos_store_address"),
32+
phone: settingValue(from: siteSettings, settingID: "woocommerce_pos_store_phone"),
33+
email: settingValue(from: siteSettings, settingID: "woocommerce_pos_store_email"),
34+
refundReturnsPolicy: settingValue(from: siteSettings, settingID: "woocommerce_pos_refund_returns_policy")
35+
)
36+
}
37+
38+
private func settingValue(from siteSettings: [SiteSetting], settingID: String) -> String? {
39+
let value = siteSettings.first { $0.settingID == settingID }?.value
40+
return value?.isEmpty == true ? nil : value
3041
}
3142
}

Modules/Tests/YosemiteTests/PointOfSale/PointOfSaleSettingsServiceTests.swift

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,17 @@ struct PointOfSaleSettingsServiceTests {
1515
settingStoreMethods: settingStoreMethods)
1616
}
1717

18-
@Test func retrievePointOfSaleSettings_when_empty_settings_then_returns_empty_array() async throws {
18+
@Test func retrievePointOfSaleSettings_when_empty_settings_then_returns_empty_receipt_info() async throws {
1919
// Given
2020
settingStoreMethods.retrievePointOfSaleSettingsResult = .success([])
2121

2222
// When
23-
let settings = try await sut.retrievePointOfSaleSettings()
23+
let receiptInfo = try await sut.retrievePointOfSaleSettings()
2424

2525
// Then
2626
#expect(settingStoreMethods.retrievePointOfSaleSettingsCalled)
2727
#expect(settingStoreMethods.retrievePointOfSaleSettingsSiteID == sampleSiteID)
28-
#expect(settings.isEmpty)
28+
#expect(receiptInfo == POSReceiptInformation.empty)
2929
}
3030

3131
@Test func retrievePointOfSaleSettings_when_network_error_then_throws_error() async throws {
@@ -64,34 +64,23 @@ struct PointOfSaleSettingsServiceTests {
6464
}
6565
}
6666

67-
@Test func retrievePointOfSaleSettings_with_expected_pos_settings_then_returns_all_settings() async throws {
67+
@Test func retrievePointOfSaleSettings_with_expected_pos_settings_then_returns_mapped_receipt_info() async throws {
6868
// Given
6969
let expectedSettings = makeSiteSettings()
7070
settingStoreMethods.retrievePointOfSaleSettingsResult = .success(expectedSettings)
7171

7272
// When
73-
let settings = try await sut.retrievePointOfSaleSettings()
73+
let receiptInfo = try await sut.retrievePointOfSaleSettings()
7474

7575
// Then
7676
#expect(settingStoreMethods.retrievePointOfSaleSettingsCalled)
7777
#expect(settingStoreMethods.retrievePointOfSaleSettingsSiteID == sampleSiteID)
78-
#expect(settings.count == 5)
79-
#expect(settings == expectedSettings)
8078

81-
let storeNameSetting = settings.first { $0.settingID == "woocommerce_pos_store_name" }
82-
#expect(storeNameSetting?.value == "WooCommerce Store")
83-
84-
let addressSetting = settings.first { $0.settingID == "woocommerce_pos_store_address" }
85-
#expect(addressSetting?.value == "123 Commerce Street\nBusiness District")
86-
87-
let phoneSetting = settings.first { $0.settingID == "woocommerce_pos_store_phone" }
88-
#expect(phoneSetting?.value == "+1 (555) 123-4567")
89-
90-
let emailSetting = settings.first { $0.settingID == "woocommerce_pos_store_email" }
91-
#expect(emailSetting?.value == "[email protected]")
92-
93-
let policySetting = settings.first { $0.settingID == "woocommerce_pos_refund_returns_policy" }
94-
#expect(policySetting?.value == "30-day return policy with receipt")
79+
#expect(receiptInfo.storeName == "WooCommerce Store")
80+
#expect(receiptInfo.storeAddress == "123 Commerce Street\nBusiness District")
81+
#expect(receiptInfo.phone == "+1 (555) 123-4567")
82+
#expect(receiptInfo.email == "[email protected]")
83+
#expect(receiptInfo.refundReturnsPolicy == "30-day return policy with receipt")
9584
}
9685

9786
private func makeSiteSettings() -> [SiteSetting] {

WooCommerce/Classes/POS/Models/PointOfSaleSettingsController.swift

Lines changed: 50 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -2,51 +2,34 @@ import Foundation
22
import Combine
33
import struct Yosemite.SiteSetting
44
import enum Yosemite.Plugin
5-
import class Yosemite.PluginsService
6-
import Observation
7-
5+
import struct Yosemite.SystemPlugin
6+
import protocol Yosemite.PluginsServiceProtocol
87
import protocol Yosemite.PointOfSaleSettingsServiceProtocol
9-
import class Yosemite.PointOfSaleSettingsService
10-
import Storage
8+
import struct Yosemite.POSReceiptInformation
9+
import Observation
1110

1211
protocol PointOfSaleSettingsControllerProtocol {
13-
var receiptStoreName: String? { get }
14-
var receiptStoreAddress: String? { get }
15-
var receiptStorePhone: String? { get }
16-
var receiptStoreEmail: String? { get }
17-
var receiptRefundReturnsPolicy: String? { get }
18-
var isLoading: Bool { get }
19-
var shouldShowReceiptInformation: Bool { get }
20-
var storeName: String { get }
21-
var storeAddress: String { get }
22-
2312
var connectedCardReader: CardPresentPaymentCardReader? { get }
24-
25-
func retrievePOSReceiptSettings() async
13+
var storeViewModel: POSSettingsStoreViewModel { get }
2614
}
2715

2816
@Observable final class PointOfSaleSettingsController: PointOfSaleSettingsControllerProtocol {
29-
private(set) var receiptStoreName: String?
30-
private(set) var receiptStoreAddress: String?
31-
private(set) var receiptStorePhone: String?
32-
private(set) var receiptStoreEmail: String?
33-
private(set) var receiptRefundReturnsPolicy: String?
34-
private(set) var isLoading: Bool = false
35-
private(set) var shouldShowReceiptInformation: Bool = false
36-
37-
private let defaultSiteName: String?
38-
private let settingsService: PointOfSaleSettingsServiceProtocol
39-
private let siteSettings: [SiteSetting]
4017
private(set) var connectedCardReader: CardPresentPaymentCardReader?
4118
private var cancellables: AnyCancellable?
4219

43-
init(settingsService: PointOfSaleSettingsServiceProtocol,
20+
let storeViewModel: POSSettingsStoreViewModel
21+
22+
init(siteID: Int64,
23+
settingsService: PointOfSaleSettingsServiceProtocol,
4424
cardPresentPaymentService: CardPresentPaymentFacade,
25+
pluginsService: PluginsServiceProtocol,
4526
defaultSiteName: String? = ServiceLocator.stores.sessionManager.defaultSite?.name,
4627
siteSettings: [SiteSetting] = ServiceLocator.selectedSiteSettings.siteSettings) {
47-
self.settingsService = settingsService
48-
self.defaultSiteName = defaultSiteName
49-
self.siteSettings = siteSettings
28+
self.storeViewModel = POSSettingsStoreViewModel(siteID: siteID,
29+
settingsService: settingsService,
30+
pluginsService: pluginsService,
31+
defaultSiteName: defaultSiteName,
32+
siteSettings: siteSettings)
5033

5134
observeCardReader(from: cardPresentPaymentService)
5235
}
@@ -65,104 +48,53 @@ protocol PointOfSaleSettingsControllerProtocol {
6548
connectedCardReader = cardReader
6649
})
6750
}
68-
69-
var storeName: String {
70-
if let defaultSiteName {
71-
return defaultSiteName
72-
} else {
73-
return Localization.storeNameNotSet
74-
}
75-
}
76-
77-
var storeAddress: String {
78-
SiteAddress(siteSettings: siteSettings).address
79-
}
80-
81-
@MainActor
82-
func retrievePOSReceiptSettings() async {
83-
isLoading = true
84-
85-
shouldShowReceiptInformation = await isPluginSupported(.wooCommerce, minimumVersion: Constants.minimumWooCommerceVersion)
86-
87-
guard shouldShowReceiptInformation else {
88-
isLoading = false
89-
return
90-
}
91-
92-
do {
93-
let siteSettings = try await settingsService.retrievePointOfSaleSettings()
94-
updateReceiptSettings(from: siteSettings)
95-
} catch {
96-
DDLogError("Failed to load POS settings: \(error)")
97-
}
98-
isLoading = false
99-
}
100-
101-
@MainActor
102-
private func isPluginSupported(_ plugin: Plugin,
103-
storageManager: StorageManagerType = ServiceLocator.storageManager,
104-
minimumVersion: String) async -> Bool {
105-
let pluginsService = PluginsService(storageManager: storageManager)
106-
guard let systemPlugin = pluginsService.loadPluginInStorage(siteID: settingsService.siteID, plugin: plugin, isActive: true), systemPlugin.active else {
107-
return false
108-
}
109-
110-
let isSupported = VersionHelpers.isVersionSupported(version: systemPlugin.version,
111-
minimumRequired: minimumVersion)
112-
return isSupported
113-
}
114-
115-
private func updateReceiptSettings(from siteSettings: [SiteSetting]) {
116-
receiptStoreName = settingValue(from: siteSettings, settingID: "woocommerce_pos_store_name")
117-
receiptStoreAddress = settingValue(from: siteSettings, settingID: "woocommerce_pos_store_address")
118-
receiptStorePhone = settingValue(from: siteSettings, settingID: "woocommerce_pos_store_phone")
119-
receiptStoreEmail = settingValue(from: siteSettings, settingID: "woocommerce_pos_store_email")
120-
receiptRefundReturnsPolicy = settingValue(from: siteSettings, settingID: "woocommerce_pos_refund_returns_policy")
121-
}
122-
123-
private func settingValue(from siteSettings: [SiteSetting], settingID: String) -> String? {
124-
let value = siteSettings.first { $0.settingID == settingID }?.value
125-
return value?.isEmpty == true ? nil : value
126-
}
127-
}
128-
129-
private extension PointOfSaleSettingsController {
130-
enum Constants {
131-
static let minimumWooCommerceVersion: String = "10.0"
132-
}
133-
134-
enum Localization {
135-
static let storeNameNotSet = NSLocalizedString(
136-
"pointOfSaleSettingsService.storeNameNotSet",
137-
value: "Not set",
138-
comment: "Text displayed on Point of Sale settings when store has not been provided."
139-
)
140-
}
14151
}
14252

14353
#if DEBUG
14454
final class PointOfSaleSettingsPreviewController: PointOfSaleSettingsControllerProtocol {
145-
var receiptStoreName: String? = "Sample Store"
146-
var receiptStoreAddress: String? = "123 Main Street\nAnytown, ST 12345"
147-
var receiptStorePhone: String? = "+1 (555) 123-4567"
148-
var receiptStoreEmail: String? = "[email protected]"
149-
var receiptRefundReturnsPolicy: String? = "30-day return policy"
150-
var isLoading: Bool = false
151-
var shouldShowReceiptInformation: Bool = true
152-
var storeName: String = "Sample Store"
153-
15455
var connectedCardReader: CardPresentPaymentCardReader? = CardPresentPaymentCardReader(
15556
name: "WisePad 3",
15657
batteryLevel: 0.75
15758
)
15859

159-
var storeAddress: String {
160-
"123 Main Street\nAnytown, ST 12345"
60+
var storeViewModel: POSSettingsStoreViewModel = POSSettingsStoreViewModel(siteID: 123,
61+
settingsService: MockPointOfSaleSettingsService(),
62+
pluginsService: PluginsServicePreview(),
63+
defaultSiteName: "Sample Store",
64+
siteSettings: [])
65+
}
66+
67+
final class MockPointOfSaleSettingsService: PointOfSaleSettingsServiceProtocol {
68+
func retrievePointOfSaleSettings() async throws -> POSReceiptInformation {
69+
return .empty
16170
}
71+
}
16272

163-
func retrievePOSReceiptSettings() async {
164-
// no-op
73+
final class PluginsServicePreview: PluginsServiceProtocol {
74+
func waitForPluginInStorage(siteID: Int64, pluginPath: String, isActive: Bool) async -> SystemPlugin {
75+
return SystemPlugin(siteID: 1234,
76+
plugin: "",
77+
name: "",
78+
version: "",
79+
versionLatest: "",
80+
url: "",
81+
authorName: "",
82+
authorUrl: "",
83+
networkActivated: false,
84+
active: true)
16585
}
16686

87+
func loadPluginInStorage(siteID: Int64, plugin: Plugin, isActive: Bool?) -> SystemPlugin? {
88+
return SystemPlugin(siteID: 1234,
89+
plugin: "",
90+
name: "",
91+
version: "",
92+
versionLatest: "",
93+
url: "",
94+
authorName: "",
95+
authorUrl: "",
96+
networkActivated: false,
97+
active: true)
98+
}
16799
}
168100
#endif

0 commit comments

Comments
 (0)