Skip to content

Commit aca7a6b

Browse files
committed
Merge branch 'trunk' into WOOMOB-618-voice-over-issues-in-shipping-labels
# Conflicts: # WooCommerce/WooCommerce.xcodeproj/project.pbxproj
2 parents 3d67589 + 1aef4ef commit aca7a6b

File tree

164 files changed

+5706
-1293
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

164 files changed

+5706
-1293
lines changed

Modules/Package.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,7 @@ enum XcodeSupport {
342342
.xcodeTarget(
343343
XcodeTargetNames.notificationExtension,
344344
dependencies: [
345-
"Networking",
345+
"NetworkingCore",
346346
"WooFoundation",
347347
.product(name: "KeychainAccess", package: "KeychainAccess"),
348348
]

Modules/Sources/Experiments/DefaultFeatureFlagService.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ public struct DefaultFeatureFlagService: FeatureFlagService {
100100
case .pointOfSaleOrdersi1:
101101
return true
102102
case .pointOfSaleOrdersi2:
103-
return buildConfig == .localDeveloper || buildConfig == .alpha
103+
return true
104104
case .pointOfSaleBarcodeScanningi2:
105105
return buildConfig == .localDeveloper || buildConfig == .alpha
106106
default:

Modules/Sources/Fakes/Networking.generated.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1451,6 +1451,7 @@ extension Networking.ShippingLabelAccountSettings {
14511451
isEmailReceiptsEnabled: .fake(),
14521452
paperSize: .fake(),
14531453
lastSelectedPackageID: .fake(),
1454+
lastOrderCompleted: .fake(),
14541455
addPaymentMethodURL: .fake()
14551456
)
14561457
}
@@ -2483,6 +2484,19 @@ extension Networking.WooShippingSelectedRate {
24832484
)
24842485
}
24852486
}
2487+
extension Networking.WooShippingShipment {
2488+
/// Returns a "ready to use" type filled with fake values.
2489+
///
2490+
public static func fake() -> Networking.WooShippingShipment {
2491+
.init(
2492+
siteID: .fake(),
2493+
orderID: .fake(),
2494+
index: .fake(),
2495+
items: .fake(),
2496+
shippingLabel: .fake()
2497+
)
2498+
}
2499+
}
24862500
extension Networking.WooShippingShipmentItem {
24872501
/// Returns a "ready to use" type filled with fake values.
24882502
///

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 = [

Modules/Sources/Networking/Model/Copiable/Models+Copiable.generated.swift

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2424,6 +2424,7 @@ extension Networking.ShippingLabelAccountSettings {
24242424
isEmailReceiptsEnabled: CopiableProp<Bool> = .copy,
24252425
paperSize: CopiableProp<ShippingLabelPaperSize> = .copy,
24262426
lastSelectedPackageID: CopiableProp<String> = .copy,
2427+
lastOrderCompleted: CopiableProp<Bool> = .copy,
24272428
addPaymentMethodURL: NullableCopiableProp<URL> = .copy
24282429
) -> Networking.ShippingLabelAccountSettings {
24292430
let siteID = siteID ?? self.siteID
@@ -2438,6 +2439,7 @@ extension Networking.ShippingLabelAccountSettings {
24382439
let isEmailReceiptsEnabled = isEmailReceiptsEnabled ?? self.isEmailReceiptsEnabled
24392440
let paperSize = paperSize ?? self.paperSize
24402441
let lastSelectedPackageID = lastSelectedPackageID ?? self.lastSelectedPackageID
2442+
let lastOrderCompleted = lastOrderCompleted ?? self.lastOrderCompleted
24412443
let addPaymentMethodURL = addPaymentMethodURL ?? self.addPaymentMethodURL
24422444

24432445
return Networking.ShippingLabelAccountSettings(
@@ -2453,6 +2455,7 @@ extension Networking.ShippingLabelAccountSettings {
24532455
isEmailReceiptsEnabled: isEmailReceiptsEnabled,
24542456
paperSize: paperSize,
24552457
lastSelectedPackageID: lastSelectedPackageID,
2458+
lastOrderCompleted: lastOrderCompleted,
24562459
addPaymentMethodURL: addPaymentMethodURL
24572460
)
24582461
}
@@ -3481,7 +3484,7 @@ extension Networking.WooShippingAddress {
34813484
extension Networking.WooShippingConfig {
34823485
public func copy(
34833486
siteID: CopiableProp<Int64> = .copy,
3484-
shipments: CopiableProp<[String: [WooShippingShipmentItem]]> = .copy,
3487+
shipments: CopiableProp<[WooShippingShipment]> = .copy,
34853488
shippingLabelData: NullableCopiableProp<WooShippingLabelData> = .copy
34863489
) -> Networking.WooShippingConfig {
34873490
let siteID = siteID ?? self.siteID
@@ -3724,6 +3727,30 @@ extension Networking.WooShippingPackagesResponse {
37243727
}
37253728
}
37263729

3730+
extension Networking.WooShippingShipment {
3731+
public func copy(
3732+
siteID: CopiableProp<Int64> = .copy,
3733+
orderID: CopiableProp<Int64> = .copy,
3734+
index: CopiableProp<String> = .copy,
3735+
items: CopiableProp<[WooShippingShipmentItem]> = .copy,
3736+
shippingLabel: NullableCopiableProp<ShippingLabel> = .copy
3737+
) -> Networking.WooShippingShipment {
3738+
let siteID = siteID ?? self.siteID
3739+
let orderID = orderID ?? self.orderID
3740+
let index = index ?? self.index
3741+
let items = items ?? self.items
3742+
let shippingLabel = shippingLabel ?? self.shippingLabel
3743+
3744+
return Networking.WooShippingShipment(
3745+
siteID: siteID,
3746+
orderID: orderID,
3747+
index: index,
3748+
items: items,
3749+
shippingLabel: shippingLabel
3750+
)
3751+
}
3752+
}
3753+
37273754
extension Networking.WooShippingShipmentItem {
37283755
public func copy(
37293756
id: CopiableProp<Int64> = .copy,

Modules/Sources/Networking/Model/ShippingLabel/Shipments/WooShippingConfigResponse.swift

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,14 @@ public struct WooShippingConfig: Decodable, Equatable, GeneratedFakeable, Genera
1515
/// The remote ID of the site that owns this shipping label config info.
1616
public let siteID: Int64
1717

18-
/// Shipments of this order. The keys are the ids of the shipment.
19-
public let shipments: WooShippingShipments
18+
/// Shipments of this order.
19+
public let shipments: [WooShippingShipment]
2020

2121
/// Holds info about the shipping labels
2222
public let shippingLabelData: WooShippingLabelData?
2323

2424
public init(siteID: Int64,
25-
shipments: WooShippingShipments,
25+
shipments: [WooShippingShipment],
2626
shippingLabelData: WooShippingLabelData?) {
2727
self.siteID = siteID
2828
self.shipments = shipments
@@ -39,17 +39,46 @@ public struct WooShippingConfig: Decodable, Equatable, GeneratedFakeable, Genera
3939
throw WooShippingConfigDecodingError.missingSiteID
4040
}
4141

42+
guard let orderID = decoder.userInfo[.orderID] as? Int64 else {
43+
throw WooShippingConfigDecodingError.missingOrderID
44+
}
45+
4246
let container = try decoder.container(keyedBy: CodingKeys.self)
43-
let shipments: WooShippingShipments = {
47+
let shippingLabelData = try container.decodeIfPresent(WooShippingLabelData.self, forKey: .shippingLabelData)
48+
49+
let shipments: [WooShippingShipment] = {
4450
guard let shipmentsString = try? container.decodeIfPresent(String.self, forKey: .shipments),
4551
let data = shipmentsString.data(using: .utf8) else {
46-
return [:]
52+
return []
4753
}
4854

49-
return (try? JSONDecoder().decode(WooShippingShipments.self, from: data)) ?? [:]
55+
guard let contents = (try? JSONDecoder().decode(WooShippingShipments.self, from: data)) else {
56+
return []
57+
}
58+
59+
let labels = shippingLabelData?.currentOrderLabels ?? []
60+
var shipments = [WooShippingShipment]()
61+
for (index, items) in contents {
62+
let label: ShippingLabel? = {
63+
let purchasedLabels = labels.filter {
64+
$0.shipmentID == index && $0.status == .purchased
65+
}
66+
let sortedLabels = purchasedLabels.sorted { $0.dateCreated > $1.dateCreated }
67+
if let completedLabel = sortedLabels.first(where: { $0.refund == nil }) {
68+
return completedLabel
69+
} else {
70+
return sortedLabels.first
71+
}
72+
}()
73+
shipments.append(WooShippingShipment(siteID: siteID,
74+
orderID: orderID,
75+
index: index,
76+
items: items,
77+
shippingLabel: label))
78+
}
79+
return shipments
5080
}()
5181

52-
let shippingLabelData = try container.decodeIfPresent(WooShippingLabelData.self, forKey: .shippingLabelData)
5382
self.init(siteID: siteID,
5483
shipments: shipments,
5584
shippingLabelData: shippingLabelData)
@@ -135,4 +164,5 @@ public extension WooShippingLabelData {
135164
//
136165
enum WooShippingConfigDecodingError: Error {
137166
case missingSiteID
167+
case missingOrderID
138168
}

Modules/Sources/Networking/Model/ShippingLabel/Shipments/WooShippingShipmentItem.swift

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,42 @@
11
import Foundation
22
import Codegen
3-
import WooFoundation
43

5-
/// Represents a shipment in Shipping Labels for the WooCommerce Shipping extension.
4+
/// Represents a shipment from the WooCommerce Shipping extension.
5+
///
6+
public struct WooShippingShipment: Equatable, GeneratedFakeable, GeneratedCopiable {
7+
/// ID of the site that the shipment belongs to.
8+
public let siteID: Int64
9+
10+
/// ID of the order that the shipment belongs to.
11+
public let orderID: Int64
12+
13+
/// Index of the shipment.
14+
/// The expected format is a numeric string, e.g: "0", "1", etc.
15+
public let index: String
16+
17+
/// Contents of the shipment
18+
public let items: [WooShippingShipmentItem]
19+
20+
/// The latest label purchased for the shipment
21+
public let shippingLabel: ShippingLabel?
22+
23+
public init(siteID: Int64,
24+
orderID: Int64,
25+
index: String,
26+
items: [WooShippingShipmentItem],
27+
shippingLabel: ShippingLabel?) {
28+
self.siteID = siteID
29+
self.orderID = orderID
30+
self.index = index
31+
self.items = items
32+
self.shippingLabel = shippingLabel
33+
}
34+
}
35+
36+
/// Represents a shipment item from the WooCommerce Shipping extension.
637
///
738
public struct WooShippingShipmentItem: Codable, Equatable, GeneratedFakeable, GeneratedCopiable {
8-
/// ID of the shipment
39+
/// ID of the order item
940
public let id: Int64
1041

1142
/// Items of the shipment
@@ -18,3 +49,10 @@ public struct WooShippingShipmentItem: Codable, Equatable, GeneratedFakeable, Ge
1849
}
1950

2051
public typealias WooShippingShipments = [String: [WooShippingShipmentItem]]
52+
53+
public extension WooShippingShipmentItem {
54+
var quantity: Decimal {
55+
guard let subItems else { return 0 }
56+
return subItems.count > 0 ? Decimal(subItems.count) : 1
57+
}
58+
}

Modules/Sources/Networking/Model/ShippingLabel/ShippingLabelAccountSettings.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ public struct ShippingLabelAccountSettings: Equatable, GeneratedFakeable, Genera
4343
/// Uses the `id` for predefined packages or `name` for custom packages.
4444
public let lastSelectedPackageID: String
4545

46+
/// Whether to mark order as completed after last label purchase
47+
/// This is available only in the new Woo Shipping plugin.
48+
public let lastOrderCompleted: Bool
49+
4650
/// URL to open the web view for adding new payment methods
4751
public let addPaymentMethodURL: URL?
4852

@@ -58,6 +62,7 @@ public struct ShippingLabelAccountSettings: Equatable, GeneratedFakeable, Genera
5862
isEmailReceiptsEnabled: Bool,
5963
paperSize: ShippingLabelPaperSize,
6064
lastSelectedPackageID: String,
65+
lastOrderCompleted: Bool,
6166
addPaymentMethodURL: URL?) {
6267
self.siteID = siteID
6368
self.canManagePayments = canManagePayments
@@ -71,6 +76,7 @@ public struct ShippingLabelAccountSettings: Equatable, GeneratedFakeable, Genera
7176
self.isEmailReceiptsEnabled = isEmailReceiptsEnabled
7277
self.paperSize = paperSize
7378
self.lastSelectedPackageID = lastSelectedPackageID
79+
self.lastOrderCompleted = lastOrderCompleted
7480
self.addPaymentMethodURL = addPaymentMethodURL
7581
}
7682
}
@@ -105,6 +111,7 @@ extension ShippingLabelAccountSettings: Decodable {
105111

106112
let userMetaContainer = try container.nestedContainer(keyedBy: UserMetaKeys.self, forKey: .userMeta)
107113
let lastSelectedPackageID = try userMetaContainer.decode(String.self, forKey: .lastSelectedPackageID)
114+
let lastOrderCompleted = (try? userMetaContainer.decodeIfPresent(Bool.self, forKey: .lastOrderCompleted)) ?? false
108115

109116
self.init(siteID: siteID,
110117
canManagePayments: canManagePayments,
@@ -118,6 +125,7 @@ extension ShippingLabelAccountSettings: Decodable {
118125
isEmailReceiptsEnabled: isEmailReceiptsEnabled,
119126
paperSize: paperSize,
120127
lastSelectedPackageID: lastSelectedPackageID,
128+
lastOrderCompleted: lastOrderCompleted,
121129
addPaymentMethodURL: addPaymentMethodURL)
122130
}
123131
}
@@ -150,6 +158,7 @@ private extension ShippingLabelAccountSettings {
150158

151159
private enum UserMetaKeys: String, CodingKey {
152160
case lastSelectedPackageID = "last_box_id"
161+
case lastOrderCompleted = "last_order_completed"
153162
}
154163
}
155164

Modules/Sources/Networking/Remote/ProductsRemote.swift

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ public final class ProductsRemote: Remote, ProductsRemoteProtocol {
259259
productsPerPage: String = POSConstants.productsPerPage,
260260
productTypes: [ProductType],
261261
orderBy: OrderKey = .name,
262-
order: Order = .ascending) -> [String: String] {
262+
order: Order = .ascending) -> [String: any Hashable] {
263263
[
264264
ParameterKey.page: String(pageNumber),
265265
ParameterKey.perPage: productsPerPage,
@@ -276,7 +276,7 @@ public final class ProductsRemote: Remote, ProductsRemoteProtocol {
276276

277277
private func makePagedPointOfSaleProductsRequest(for siteID: Int64,
278278
pageNumber: Int,
279-
parameters: [String: String]) async throws -> PagedItems<POSProduct> {
279+
parameters: [String: any Hashable]) async throws -> PagedItems<POSProduct> {
280280
let request = JetpackRequest(wooApiVersion: .mark3,
281281
method: .get,
282282
siteID: siteID,
@@ -318,8 +318,13 @@ public final class ProductsRemote: Remote, ProductsRemoteProtocol {
318318
productTypes: productTypes)
319319

320320
parameters.updateValue(query, forKey: ParameterKey.search)
321+
322+
// Takes precedence over `search` from WC 9.9 to 10.1
321323
parameters.updateValue(query, forKey: ParameterKey.searchNameOrSKU)
322324

325+
// Takes precedence over `search_name_or_sku` from WC 10.1+ and is combined with `search` value
326+
parameters.updateValue([SearchField.name, SearchField.sku, SearchField.globalUniqueID], forKey: ParameterKey.searchFields)
327+
323328
return try await makePagedPointOfSaleProductsRequest(
324329
for: siteID,
325330
pageNumber: pageNumber,
@@ -749,6 +754,7 @@ public extension ProductsRemote {
749754
static let include: String = "include"
750755
static let search: String = "search"
751756
static let searchNameOrSKU: String = "search_name_or_sku"
757+
static let searchFields: String = "search_fields"
752758
static let orderBy: String = "orderby"
753759
static let order: String = "order"
754760
static let sku: String = "sku"
@@ -776,6 +782,12 @@ public extension ProductsRemote {
776782
static let productSegment = "product"
777783
static let itemsSold = "items_sold"
778784
}
785+
786+
private enum SearchField {
787+
static let name = "name"
788+
static let sku = "sku"
789+
static let globalUniqueID = "global_unique_id"
790+
}
779791
}
780792

781793
private extension ProductsRemote {

0 commit comments

Comments
 (0)