Skip to content

Commit a55729f

Browse files
authored
Merge pull request #997 from woocommerce/issue/945-custom-tracking-name
Order Fulfillment: pre-populate custom tracking provider name with last name entered by the user
2 parents 25527a5 + 37777fd commit a55729f

File tree

7 files changed

+245
-15
lines changed

7 files changed

+245
-15
lines changed

Storage/Storage/Model/PreselectedProvider.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@
44
public struct PreselectedProvider: Codable, Equatable {
55
public let siteID: Int
66
public let providerName: String
7+
public let providerURL: String?
78

8-
public init(siteID: Int, providerName: String) {
9+
public init(siteID: Int, providerName: String, providerURL: String? = nil) {
910
self.siteID = siteID
1011
self.providerName = providerName
12+
self.providerURL = providerURL
1113
}
1214

1315
public static func == (lhs: PreselectedProvider, rhs: PreselectedProvider) -> Bool {

WooCommerce/Classes/ViewModels/ManualTrackingViewModel.swift

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ final class AddCustomTrackingViewModel: ManualTrackingViewModel {
224224
}
225225

226226
var shipmentProvider: ShipmentTrackingProvider?
227+
227228
var shipmentProviderGroupName: String?
228229

229230
var providerCellName: String {
@@ -233,8 +234,14 @@ final class AddCustomTrackingViewModel: ManualTrackingViewModel {
233234
let providerCellAccessoryType = UITableViewCell.AccessoryType.none
234235

235236
var canCommit: Bool {
236-
return providerName?.isEmpty == false &&
237+
let returnValue = providerName?.isEmpty == false &&
237238
trackingNumber?.isEmpty == false
239+
240+
if returnValue {
241+
saveSelectedCustomShipmentProvider()
242+
}
243+
244+
return returnValue
238245
}
239246

240247
let isAdding: Bool = true
@@ -244,5 +251,44 @@ final class AddCustomTrackingViewModel: ManualTrackingViewModel {
244251
init(order: Order, initialName: String? = nil) {
245252
self.order = order
246253
self.providerName = initialName
254+
255+
loadSelectedCustomShipmentProvider()
256+
}
257+
}
258+
259+
260+
private extension AddCustomTrackingViewModel {
261+
func saveSelectedCustomShipmentProvider() {
262+
guard let providerName = providerName else {
263+
return
264+
}
265+
266+
let siteID = order.siteID
267+
268+
let action = AppSettingsAction.addCustomTrackingProvider(siteID: siteID, providerName: providerName, providerURL: trackingLink) { error in
269+
guard let error = error else {
270+
return
271+
}
272+
273+
DDLogError("⛔️ Save selected Custom Tracking Provider Failure: [siteID = \(siteID)]. Error: \(error)")
274+
}
275+
276+
StoresManager.shared.dispatch(action)
277+
}
278+
279+
func loadSelectedCustomShipmentProvider() {
280+
let siteID = order.siteID
281+
282+
let action = AppSettingsAction.loadCustomTrackingProvider(siteID: siteID) { [weak self] (provider, error) in
283+
guard let error = error else {
284+
self?.providerName = provider?.name
285+
self?.trackingLink = provider?.url
286+
return
287+
}
288+
289+
DDLogError("⛔️ Read selected Custom Tracking Provider Failure: [siteID = \(siteID)]. Error: \(error)")
290+
}
291+
292+
StoresManager.shared.dispatch(action)
247293
}
248294
}

Yosemite/Yosemite.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@
109109
D87F614C22657B150031A13B /* AppSettingsStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = D87F614B22657B150031A13B /* AppSettingsStore.swift */; };
110110
D87F615E2265B1BC0031A13B /* AppSettingsStoreTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D87F615D2265B1BC0031A13B /* AppSettingsStoreTests.swift */; };
111111
D87F61602265B2400031A13B /* shipment-provider.plist in Resources */ = {isa = PBXBuildFile; fileRef = D87F615F2265B2400031A13B /* shipment-provider.plist */; };
112+
D8BD6A4C229D07C9007CAD6C /* custom-shipment-provider.plist in Resources */ = {isa = PBXBuildFile; fileRef = D8BD6A4B229D07C8007CAD6C /* custom-shipment-provider.plist */; };
112113
/* End PBXBuildFile section */
113114

114115
/* Begin PBXContainerItemProxy section */
@@ -231,6 +232,7 @@
231232
D87F614B22657B150031A13B /* AppSettingsStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppSettingsStore.swift; sourceTree = "<group>"; };
232233
D87F615D2265B1BC0031A13B /* AppSettingsStoreTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppSettingsStoreTests.swift; sourceTree = "<group>"; };
233234
D87F615F2265B2400031A13B /* shipment-provider.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "shipment-provider.plist"; sourceTree = "<group>"; };
235+
D8BD6A4B229D07C8007CAD6C /* custom-shipment-provider.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "custom-shipment-provider.plist"; sourceTree = "<group>"; };
234236
/* End PBXFileReference section */
235237

236238
/* Begin PBXFrameworksBuildPhase section */
@@ -475,6 +477,7 @@
475477
B5C9DE1D2087FF20006B910A /* Mockups */ = {
476478
isa = PBXGroup;
477479
children = (
480+
D8BD6A4B229D07C8007CAD6C /* custom-shipment-provider.plist */,
478481
D87F615F2265B2400031A13B /* shipment-provider.plist */,
479482
B5C9DE1E2087FF20006B910A /* MockupProcessor.swift */,
480483
B5C9DE202087FF20006B910A /* MockupAcount.swift */,
@@ -627,6 +630,7 @@
627630
isa = PBXResourcesBuildPhase;
628631
buildActionMask = 2147483647;
629632
files = (
633+
D8BD6A4C229D07C9007CAD6C /* custom-shipment-provider.plist in Resources */,
630634
B5BC71DD21139EDD005CF5AA /* Responses in Resources */,
631635
D87F61602265B2400031A13B /* shipment-provider.plist in Resources */,
632636
);

Yosemite/Yosemite/Actions/AppSettingsAction.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,18 @@ public enum AppSettingsAction: Action {
1414
case loadTrackingProvider(siteID: Int,
1515
onCompletion: (ShipmentTrackingProvider?, ShipmentTrackingProviderGroup?, Error?) -> Void)
1616

17+
/// Adds a custom shipment tracking provider with `providerName` and `providerURL` associated with the `siteID`
18+
///
19+
case addCustomTrackingProvider(siteID: Int,
20+
providerName: String,
21+
providerURL: String?,
22+
onCompletion: (Error?) -> Void)
23+
24+
/// Loads the stored shipment tracking provider associated with the `siteID`
25+
///
26+
case loadCustomTrackingProvider(siteID: Int,
27+
onCompletion: (ShipmentTrackingProvider?, Error?) -> Void)
28+
1729
/// Clears the stored providers
1830
///
1931
case resetStoredProviders(onCompletion: ((Error?) -> Void)?)

Yosemite/Yosemite/Stores/AppSettingsStore.swift

Lines changed: 94 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,15 @@ public class AppSettingsStore: Store {
2828
return documents!.appendingPathComponent(Constants.shipmentProvidersFileName)
2929
}()
3030

31+
/// URL to the plist file that we use to store the user selected
32+
/// custom shipment tracing provider. Not declared as `private` so it can
33+
/// be overridden in tests
34+
///
35+
lazy var customSelectedProvidersURL: URL = {
36+
let documents = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first
37+
return documents!.appendingPathComponent(Constants.customShipmentProvidersFileName)
38+
}()
39+
3140
/// Registers for supported Actions.
3241
///
3342
override public func registerSupportedActions(in dispatcher: Dispatcher) {
@@ -47,10 +56,21 @@ public class AppSettingsStore: Store {
4756
addTrackingProvider(siteID: siteID,
4857
providerName: providerName,
4958
onCompletion: onCompletion)
50-
5159
case .loadTrackingProvider(let siteID, let onCompletion):
5260
loadTrackingProvider(siteID: siteID,
5361
onCompletion: onCompletion)
62+
case .addCustomTrackingProvider(let siteID,
63+
let providerName,
64+
let providerURL,
65+
let onCompletion):
66+
addCustomTrackingProvider(siteID: siteID,
67+
providerName: providerName,
68+
providerURL: providerURL,
69+
onCompletion: onCompletion)
70+
case .loadCustomTrackingProvider(let siteID,
71+
let onCompletion):
72+
loadCustomTrackingProvider(siteID: siteID,
73+
onCompletion: onCompletion)
5474
case .resetStoredProviders(let onCompletion):
5575
resetStoredProviders(onCompletion: onCompletion)
5676
}
@@ -64,34 +84,59 @@ private extension AppSettingsStore {
6484
func addTrackingProvider(siteID: Int,
6585
providerName: String,
6686
onCompletion: (Error?) -> Void) {
67-
guard FileManager.default.fileExists(atPath: selectedProvidersURL.path) else {
87+
addProvider(siteID: siteID,
88+
providerName: providerName,
89+
fileURL: selectedProvidersURL,
90+
onCompletion: onCompletion)
91+
92+
}
93+
94+
func addCustomTrackingProvider(siteID: Int,
95+
providerName: String,
96+
providerURL: String?,
97+
onCompletion: (Error?) -> Void) {
98+
addProvider(siteID: siteID,
99+
providerName: providerName,
100+
providerURL: providerURL,
101+
fileURL: customSelectedProvidersURL,
102+
onCompletion: onCompletion)
103+
}
104+
105+
func addProvider(siteID: Int,
106+
providerName: String,
107+
providerURL: String? = nil,
108+
fileURL: URL,
109+
onCompletion: (Error?) -> Void) {
110+
guard FileManager.default.fileExists(atPath: fileURL.path) else {
68111
insertNewProvider(siteID: siteID,
69112
providerName: providerName,
113+
providerURL: providerURL,
114+
toFileURL: fileURL,
70115
onCompletion: onCompletion)
71116
onCompletion(nil)
72117
return
73118
}
74119

75120
do {
76-
let data = try fileStorage.data(for: selectedProvidersURL)
121+
let data = try fileStorage.data(for: fileURL)
77122
let decoder = PropertyListDecoder()
78123
let settings = try decoder.decode([PreselectedProvider].self, from: data)
79124
upsertTrackingProvider(siteID: siteID,
80125
providerName: providerName,
81126
preselectedData: settings,
127+
toFileURL: fileURL,
82128
onCompletion: onCompletion)
83129
} catch {
84130
let error = AppSettingsStoreErrors.parsePreselectedProvider
85131
onCompletion(error)
86132

87133
DDLogError("⛔️ Saving a tracking provider locally failed: siteID \(siteID). Error: \(error)")
88134
}
89-
90135
}
91136

92137
func loadTrackingProvider(siteID: Int,
93138
onCompletion: (ShipmentTrackingProvider?, ShipmentTrackingProviderGroup?, Error?) -> Void) {
94-
guard let allSavedProviders = read() else {
139+
guard let allSavedProviders = read(from: selectedProvidersURL) else {
95140
let error = AppSettingsStoreErrors.readPreselectedProvider
96141
onCompletion(nil, nil, error)
97142
return
@@ -115,12 +160,43 @@ private extension AppSettingsStore {
115160
onCompletion(provider?.toReadOnly(), provider?.group?.toReadOnly(), nil)
116161
}
117162

163+
func loadCustomTrackingProvider(siteID: Int,
164+
onCompletion: (ShipmentTrackingProvider?, Error?) -> Void) {
165+
guard let allSavedProviders = read(from: customSelectedProvidersURL) else {
166+
let error = AppSettingsStoreErrors.readPreselectedProvider
167+
onCompletion(nil, error)
168+
return
169+
}
170+
171+
let providerName = allSavedProviders.filter {
172+
$0.siteID == siteID
173+
}.first?.providerName
174+
175+
let providerURL = allSavedProviders.filter {
176+
$0.siteID == siteID
177+
}.first?.providerURL
178+
179+
guard let name = providerName else {
180+
let error = AppSettingsStoreErrors.readPreselectedProvider
181+
onCompletion(nil, error)
182+
return
183+
}
184+
185+
let customProvider = ShipmentTrackingProvider(siteID: siteID,
186+
name: name,
187+
url: providerURL ?? "")
188+
onCompletion(customProvider, nil)
189+
}
190+
118191
func upsertTrackingProvider(siteID: Int,
119192
providerName: String,
193+
providerURL: String? = nil,
120194
preselectedData: [PreselectedProvider],
195+
toFileURL: URL,
121196
onCompletion: (Error?) -> Void) {
122197
let newPreselectedProvider = PreselectedProvider(siteID: siteID,
123-
providerName: providerName)
198+
providerName: providerName,
199+
providerURL: providerURL)
124200

125201
var dataToSave = preselectedData
126202

@@ -131,34 +207,37 @@ private extension AppSettingsStore {
131207
dataToSave.append(newPreselectedProvider)
132208
}
133209

134-
write(dataToSave, onCompletion: onCompletion)
210+
write(dataToSave, to: toFileURL, onCompletion: onCompletion)
135211
}
136212

137213
func insertNewProvider(siteID: Int,
138214
providerName: String,
215+
providerURL: String? = nil,
216+
toFileURL: URL,
139217
onCompletion: (Error?) -> Void) {
140218
let preselectedProvider = PreselectedProvider(siteID: siteID,
141-
providerName: providerName)
219+
providerName: providerName,
220+
providerURL: providerURL)
142221

143-
write([preselectedProvider], onCompletion: onCompletion)
222+
write([preselectedProvider], to: toFileURL, onCompletion: onCompletion)
144223
}
145224

146-
func write(_ data: [PreselectedProvider], onCompletion: (Error?) -> Void) {
225+
func write(_ data: [PreselectedProvider], to fileURL: URL, onCompletion: (Error?) -> Void) {
147226
let encoder = PropertyListEncoder()
148227
encoder.outputFormat = .xml
149228
do {
150229
let encodedData = try encoder.encode(data)
151-
try fileStorage.write(encodedData, to: selectedProvidersURL)
230+
try fileStorage.write(encodedData, to: fileURL)
152231
onCompletion(nil)
153232
} catch {
154233
let error = AppSettingsStoreErrors.writePreselectedProvider
155234
onCompletion(error)
156235
}
157236
}
158237

159-
func read() -> [PreselectedProvider]? {
238+
func read(from url: URL) -> [PreselectedProvider]? {
160239
do {
161-
let data = try fileStorage.data(for: selectedProvidersURL)
240+
let data = try fileStorage.data(for: url)
162241
let decoder = PropertyListDecoder()
163242
return try decoder.decode([PreselectedProvider].self, from: data)
164243
} catch {
@@ -169,6 +248,7 @@ private extension AppSettingsStore {
169248
func resetStoredProviders(onCompletion: ((Error?) -> Void)? = nil) {
170249
do {
171250
try fileStorage.deleteFile(at: selectedProvidersURL)
251+
try fileStorage.deleteFile(at: customSelectedProvidersURL)
172252
onCompletion?(nil)
173253
} catch {
174254
let error = AppSettingsStoreErrors.deletePreselectedProvider
@@ -196,4 +276,5 @@ enum AppSettingsStoreErrors: Error {
196276
///
197277
private enum Constants {
198278
static let shipmentProvidersFileName = "shipment-providers.plist"
279+
static let customShipmentProvidersFileName = "custom-shipment-providers.plist"
199280
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<array>
5+
<dict>
6+
<key>providerURL</key>
7+
<string>http://some.where</string>
8+
<key>providerName</key>
9+
<string>post.at</string>
10+
<key>siteID</key>
11+
<integer>156590080</integer>
12+
</dict>
13+
<dict>
14+
<key>providerURL</key>
15+
<string>http://some.where</string>
16+
<key>providerName</key>
17+
<string>A mock provider</string>
18+
<key>siteID</key>
19+
<integer>1234</integer>
20+
</dict>
21+
</array>
22+
</plist>

0 commit comments

Comments
 (0)