Skip to content

Commit b4bda32

Browse files
committed
Merge branch 'trunk' into fix/14962-order-editing-canceling-an-order-edit-in-split-view-with-unsynced-changes-doesnt-request-confirmation
2 parents fc31903 + 2198e61 commit b4bda32

File tree

33 files changed

+440
-127
lines changed

33 files changed

+440
-127
lines changed

Fakes/Fakes/Networking.generated.swift

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -871,7 +871,8 @@ extension Networking.Order {
871871
customFields: .fake(),
872872
renewalSubscriptionID: .fake(),
873873
appliedGiftCards: .fake(),
874-
attributionInfo: .fake()
874+
attributionInfo: .fake(),
875+
shippingLabels: .fake()
875876
)
876877
}
877878
}
@@ -1137,6 +1138,26 @@ extension Networking.OrderTaxLine {
11371138
)
11381139
}
11391140
}
1141+
extension Networking.POSProduct {
1142+
/// Returns a "ready to use" type filled with fake values.
1143+
///
1144+
public static func fake() -> Networking.POSProduct {
1145+
.init(
1146+
siteID: .fake(),
1147+
productID: .fake(),
1148+
name: .fake(),
1149+
productTypeKey: .fake(),
1150+
sku: .fake(),
1151+
globalUniqueID: .fake(),
1152+
price: .fake(),
1153+
regularPrice: .fake(),
1154+
salePrice: .fake(),
1155+
onSale: .fake(),
1156+
images: .fake(),
1157+
attributes: .fake()
1158+
)
1159+
}
1160+
}
11401161
extension Networking.PaymentGateway {
11411162
/// Returns a "ready to use" type filled with fake values.
11421163
///

Networking/Networking.xcodeproj/project.pbxproj

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,8 @@
186186
207D816C2D4A30A30097012E /* products-load-simple-products-empty-price.json in Resources */ = {isa = PBXBuildFile; fileRef = 207D816B2D4A30A30097012E /* products-load-simple-products-empty-price.json */; };
187187
209AD3C32AC196E300825D76 /* WooPaymentsPayoutsOverview.swift in Sources */ = {isa = PBXBuildFile; fileRef = 209AD3C22AC196E300825D76 /* WooPaymentsPayoutsOverview.swift */; };
188188
209AD3C52AC19E7500825D76 /* WooPaymentsDepositsOverviewMapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 209AD3C42AC19E7500825D76 /* WooPaymentsDepositsOverviewMapper.swift */; };
189+
20ABC0632D95632D0000EADD /* POSProduct.swift in Sources */ = {isa = PBXBuildFile; fileRef = 20ABC0622D95632D0000EADD /* POSProduct.swift */; };
190+
20ABC0672D95995C0000EADD /* ListMapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 20ABC0662D95995C0000EADD /* ListMapper.swift */; };
189191
20D210C32B1780CE0099E517 /* deposits-overview-all.json in Resources */ = {isa = PBXBuildFile; fileRef = 20D210C22B1780CE0099E517 /* deposits-overview-all.json */; };
190192
20D210C52B1788E60099E517 /* deposits-overview-all-no-default-currency.json in Resources */ = {isa = PBXBuildFile; fileRef = 20D210C42B1788E60099E517 /* deposits-overview-all-no-default-currency.json */; };
191193
20F616482CF4B74600F9FA2A /* POSOrdersRemoteProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 20F616472CF4B74600F9FA2A /* POSOrdersRemoteProtocol.swift */; };
@@ -472,6 +474,11 @@
472474
453954D22C90D84200A3E64A /* meta-data-products-and-orders.json in Resources */ = {isa = PBXBuildFile; fileRef = 453954D12C90D84200A3E64A /* meta-data-products-and-orders.json */; };
473475
453954D42C90E81300A3E64A /* MetaDataRemoteTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 453954D32C90E81300A3E64A /* MetaDataRemoteTests.swift */; };
474476
453954D62C9193BC00A3E64A /* meta-data-products-orders-update.json in Resources */ = {isa = PBXBuildFile; fileRef = 453954D52C9193BC00A3E64A /* meta-data-products-orders-update.json */; };
477+
453B33FD2D47F1F4005C05B0 /* ShippingLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02C254A7256373AB00A04423 /* ShippingLabel.swift */; };
478+
453B33FE2D47F1FB005C05B0 /* ShippingLabelStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02C254AB2563781800A04423 /* ShippingLabelStatus.swift */; };
479+
453B33FF2D47F203005C05B0 /* ShippingLabelRefund.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02C2549F25636F6900A04423 /* ShippingLabelRefund.swift */; };
480+
453B34002D47F20A005C05B0 /* ShippingLabelRefundStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02C254AF256378D000A04423 /* ShippingLabelRefundStatus.swift */; };
481+
453B34012D47F22C005C05B0 /* ShippingLabelAddress.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02C2549925636E1500A04423 /* ShippingLabelAddress.swift */; };
475482
45551F122523E7F1007EF104 /* UserAgent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45551F112523E7F1007EF104 /* UserAgent.swift */; };
476483
45551F142523E7FF007EF104 /* UserAgentTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45551F132523E7FF007EF104 /* UserAgentTests.swift */; };
477484
4568E2222459ADC60007E478 /* SitePostsRemote.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4568E2212459ADC60007E478 /* SitePostsRemote.swift */; };
@@ -1522,6 +1529,8 @@
15221529
207D816B2D4A30A30097012E /* products-load-simple-products-empty-price.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "products-load-simple-products-empty-price.json"; sourceTree = "<group>"; };
15231530
209AD3C22AC196E300825D76 /* WooPaymentsPayoutsOverview.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WooPaymentsPayoutsOverview.swift; sourceTree = "<group>"; };
15241531
209AD3C42AC19E7500825D76 /* WooPaymentsDepositsOverviewMapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WooPaymentsDepositsOverviewMapper.swift; sourceTree = "<group>"; };
1532+
20ABC0622D95632D0000EADD /* POSProduct.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = POSProduct.swift; sourceTree = "<group>"; };
1533+
20ABC0662D95995C0000EADD /* ListMapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListMapper.swift; sourceTree = "<group>"; };
15251534
20D210C22B1780CE0099E517 /* deposits-overview-all.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "deposits-overview-all.json"; sourceTree = "<group>"; };
15261535
20D210C42B1788E60099E517 /* deposits-overview-all-no-default-currency.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "deposits-overview-all-no-default-currency.json"; sourceTree = "<group>"; };
15271536
20F616472CF4B74600F9FA2A /* POSOrdersRemoteProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = POSOrdersRemoteProtocol.swift; sourceTree = "<group>"; };
@@ -3211,6 +3220,7 @@
32113220
EE078D8E2AD2E65400C1199E /* JWToken.swift */,
32123221
DEDA8DA02B182E850076BF0F /* WordPressTheme.swift */,
32133222
DE78DE452B2AE880002E58DE /* WordPressPage.swift */,
3223+
20ABC0622D95632D0000EADD /* POSProduct.swift */,
32143224
);
32153225
path = Model;
32163226
sourceTree = "<group>";
@@ -3744,6 +3754,7 @@
37443754
CEB9BF422BB199600007978A /* ProductBundleStatsMapper.swift */,
37453755
CCF434632906BD7200B4475A /* ProductIDMapper.swift */,
37463756
CE0A0F18223987DF0075ED8D /* ProductListMapper.swift */,
3757+
20ABC0662D95995C0000EADD /* ListMapper.swift */,
37473758
45B204B72489095100FE6526 /* ProductCategoryMapper.swift */,
37483759
26615474242D7C9500A31661 /* ProductCategoryListMapper.swift */,
37493760
D88D5A4A230BCF0A007B6E01 /* ProductReviewListMapper.swift */,
@@ -5014,11 +5025,13 @@
50145025
2680B0D22BED5A4C00E7F1D8 /* AuthenticatedRESTRequest.swift in Sources */,
50155026
2680B0D02BED5A1900E7F1D8 /* WooConstants.swift in Sources */,
50165027
2680B0CF2BED59CE00E7F1D8 /* ApplicationPasswordStorage.swift in Sources */,
5028+
453B34002D47F20A005C05B0 /* ShippingLabelRefundStatus.swift in Sources */,
50175029
2680B0CB2BED58B200E7F1D8 /* ApplicationPasswordNameAndUUID.swift in Sources */,
50185030
26373E0A2BFCEAAF008E6735 /* OrderItemTax.swift in Sources */,
50195031
2680B0CC2BED58B200E7F1D8 /* ApplicationPassword.swift in Sources */,
50205032
26373E122BFCEDB7008E6735 /* OrderFeeLine.swift in Sources */,
50215033
26F2CADD2BED579100F9A5E7 /* ApplicationPasswordUseCase.swift in Sources */,
5034+
453B33FF2D47F203005C05B0 /* ShippingLabelRefund.swift in Sources */,
50225035
26F2CADA2BED578200F9A5E7 /* RequestProcessor.swift in Sources */,
50235036
26F2CADB2BED578200F9A5E7 /* RequestAuthenticator.swift in Sources */,
50245037
26F2CADC2BED578200F9A5E7 /* RequestConverter.swift in Sources */,
@@ -5031,6 +5044,7 @@
50315044
263A6DBC2BEAA49B00C292B2 /* AnyDecodable.swift in Sources */,
50325045
263A6DBD2BEAA49B00C292B2 /* AnyEncodable.swift in Sources */,
50335046
263A6DB92BEAA46F00C292B2 /* SiteSummaryStatsMapper.swift in Sources */,
5047+
453B33FD2D47F1F4005C05B0 /* ShippingLabel.swift in Sources */,
50345048
26373E112BFCEDAE008E6735 /* OrderRefundCondensed.swift in Sources */,
50355049
263A6DBA2BEAA46F00C292B2 /* SiteSummaryStats.swift in Sources */,
50365050
263A6DB62BEAA46000C292B2 /* SiteVisitStatsMapper.swift in Sources */,
@@ -5089,6 +5103,7 @@
50895103
26CFDEE12C0295EA005ABC31 /* MetaContainer.swift in Sources */,
50905104
26373E152BFCEDE9008E6735 /* OrderGiftCard.swift in Sources */,
50915105
269014CB2BEA9253006056E0 /* JetpackRequest.swift in Sources */,
5106+
453B34012D47F22C005C05B0 /* ShippingLabelAddress.swift in Sources */,
50925107
269014CA2BEA924B006056E0 /* NetworkError.swift in Sources */,
50935108
26373E092BFCEA90008E6735 /* OrderItemProductAddOn.swift in Sources */,
50945109
26373E162BFCEDFD008E6735 /* OrderAttributionInfo.swift in Sources */,
@@ -5101,6 +5116,7 @@
51015116
269014C32BEA9134006056E0 /* Mapper.swift in Sources */,
51025117
269014C22BEA912D006056E0 /* Request.swift in Sources */,
51035118
26373E182BFCEF79008E6735 /* KeyedDecodingContainer+Woo.swift in Sources */,
5119+
453B33FE2D47F1FB005C05B0 /* ShippingLabelStatus.swift in Sources */,
51045120
26373E202BFCF6A7008E6735 /* EntityDateModifiedMapper.swift in Sources */,
51055121
26CFDEE02C0295E1005ABC31 /* NoteRange.swift in Sources */,
51065122
26CFDEDE2C0295CB005ABC31 /* NoteBlock.swift in Sources */,
@@ -5427,6 +5443,7 @@
54275443
B572F69A21AC475C003EEFF0 /* DevicesRemote.swift in Sources */,
54285444
3192F220260D33BB0067FEF9 /* WCPayAccount.swift in Sources */,
54295445
68CB800E28D8901B00E169F8 /* CustomerMapper.swift in Sources */,
5446+
20ABC0632D95632D0000EADD /* POSProduct.swift in Sources */,
54305447
45CCFCE227A2C9BF0012E8CB /* InboxNote.swift in Sources */,
54315448
311D412C2783BF7400052F64 /* StripeAccount.swift in Sources */,
54325449
B518662420A099BF00037A38 /* AlamofireNetwork.swift in Sources */,
@@ -5527,6 +5544,7 @@
55275544
264541B72CA64522006C13A2 /* WooShippingRemote.swift in Sources */,
55285545
EE105F452D671F57005AB07F /* WooShippingDestinationAddress.swift in Sources */,
55295546
B96158FC2BF63B4F0080E52A /* String+MinMaxQuantities.swift in Sources */,
5547+
20ABC0672D95995C0000EADD /* ListMapper.swift in Sources */,
55305548
DE50295D28C6068B00551736 /* JetpackUserMapper.swift in Sources */,
55315549
B524194121AC60A700D6FC0A /* DotcomDevice.swift in Sources */,
55325550
D8EDFE2225EE88C9003D2213 /* ReaderConnectionToken.swift in Sources */,
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import Foundation
2+
3+
/// ListMapper: Maps generic WooCommerce REST API Lists
4+
///
5+
struct ListMapper<Output: Decodable>: Mapper {
6+
/// Site Identifier associated to the items that will be parsed.
7+
///
8+
/// We're injecting this field via `JSONDecoder.userInfo` because SiteID is not returned by our endpoints.
9+
///
10+
let siteID: Int64
11+
12+
/// (Attempts) to convert a dictionary into [Product].
13+
///
14+
func map(response: Data) throws -> [Output] {
15+
let decoder = JSONDecoder()
16+
decoder.dateDecodingStrategy = .formatted(DateFormatter.Defaults.dateTimeFormatter)
17+
decoder.userInfo = [
18+
.siteID: siteID
19+
]
20+
21+
if hasDataEnvelope(in: response) {
22+
return try decoder.decode(ListEnvelope<Output>.self, from: response).items
23+
} else {
24+
return try decoder.decode([Output].self, from: response)
25+
}
26+
}
27+
}
28+
29+
/// ListEnvelope Disposable Entity:
30+
/// Our list endpoints return the items in the `data` key.
31+
/// This entity allows us to do parse all the things with JSONDecoder.
32+
///
33+
private struct ListEnvelope<Output: Decodable>: Decodable {
34+
let items: [Output]
35+
36+
private enum CodingKeys: String, CodingKey {
37+
case items = "data"
38+
}
39+
}

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

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1395,7 +1395,8 @@ extension Networking.Order {
13951395
customFields: CopiableProp<[MetaData]> = .copy,
13961396
renewalSubscriptionID: NullableCopiableProp<String> = .copy,
13971397
appliedGiftCards: CopiableProp<[OrderGiftCard]> = .copy,
1398-
attributionInfo: NullableCopiableProp<OrderAttributionInfo> = .copy
1398+
attributionInfo: NullableCopiableProp<OrderAttributionInfo> = .copy,
1399+
shippingLabels: CopiableProp<[ShippingLabel]> = .copy
13991400
) -> Networking.Order {
14001401
let siteID = siteID ?? self.siteID
14011402
let orderID = orderID ?? self.orderID
@@ -1435,6 +1436,7 @@ extension Networking.Order {
14351436
let renewalSubscriptionID = renewalSubscriptionID ?? self.renewalSubscriptionID
14361437
let appliedGiftCards = appliedGiftCards ?? self.appliedGiftCards
14371438
let attributionInfo = attributionInfo ?? self.attributionInfo
1439+
let shippingLabels = shippingLabels ?? self.shippingLabels
14381440

14391441
return Networking.Order(
14401442
siteID: siteID,
@@ -1474,7 +1476,8 @@ extension Networking.Order {
14741476
customFields: customFields,
14751477
renewalSubscriptionID: renewalSubscriptionID,
14761478
appliedGiftCards: appliedGiftCards,
1477-
attributionInfo: attributionInfo
1479+
attributionInfo: attributionInfo,
1480+
shippingLabels: shippingLabels
14781481
)
14791482
}
14801483
}
@@ -1875,6 +1878,51 @@ extension Networking.OrderTaxLine {
18751878
}
18761879
}
18771880

1881+
extension Networking.POSProduct {
1882+
public func copy(
1883+
siteID: CopiableProp<Int64> = .copy,
1884+
productID: CopiableProp<Int64> = .copy,
1885+
name: CopiableProp<String> = .copy,
1886+
productTypeKey: CopiableProp<String> = .copy,
1887+
sku: NullableCopiableProp<String> = .copy,
1888+
globalUniqueID: NullableCopiableProp<String> = .copy,
1889+
price: CopiableProp<String> = .copy,
1890+
regularPrice: NullableCopiableProp<String> = .copy,
1891+
salePrice: NullableCopiableProp<String> = .copy,
1892+
onSale: CopiableProp<Bool> = .copy,
1893+
images: CopiableProp<[ProductImage]> = .copy,
1894+
attributes: CopiableProp<[ProductAttribute]> = .copy
1895+
) -> Networking.POSProduct {
1896+
let siteID = siteID ?? self.siteID
1897+
let productID = productID ?? self.productID
1898+
let name = name ?? self.name
1899+
let productTypeKey = productTypeKey ?? self.productTypeKey
1900+
let sku = sku ?? self.sku
1901+
let globalUniqueID = globalUniqueID ?? self.globalUniqueID
1902+
let price = price ?? self.price
1903+
let regularPrice = regularPrice ?? self.regularPrice
1904+
let salePrice = salePrice ?? self.salePrice
1905+
let onSale = onSale ?? self.onSale
1906+
let images = images ?? self.images
1907+
let attributes = attributes ?? self.attributes
1908+
1909+
return Networking.POSProduct(
1910+
siteID: siteID,
1911+
productID: productID,
1912+
name: name,
1913+
productTypeKey: productTypeKey,
1914+
sku: sku,
1915+
globalUniqueID: globalUniqueID,
1916+
price: price,
1917+
regularPrice: regularPrice,
1918+
salePrice: salePrice,
1919+
onSale: onSale,
1920+
images: images,
1921+
attributes: attributes
1922+
)
1923+
}
1924+
}
1925+
18781926
extension Networking.PaymentGateway {
18791927
public func copy(
18801928
siteID: CopiableProp<Int64> = .copy,

Networking/Networking/Model/Order.swift

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@ public struct Order: Decodable, Sendable, GeneratedCopiable, GeneratedFakeable {
6161
///
6262
public let attributionInfo: OrderAttributionInfo?
6363

64+
/// Shipping labels associated with the order
65+
///
66+
public let shippingLabels: [ShippingLabel]
67+
6468
/// Order struct initializer.
6569
///
6670
public init(siteID: Int64,
@@ -100,7 +104,8 @@ public struct Order: Decodable, Sendable, GeneratedCopiable, GeneratedFakeable {
100104
customFields: [MetaData],
101105
renewalSubscriptionID: String?,
102106
appliedGiftCards: [OrderGiftCard],
103-
attributionInfo: OrderAttributionInfo?) {
107+
attributionInfo: OrderAttributionInfo?,
108+
shippingLabels: [ShippingLabel]) {
104109

105110
self.siteID = siteID
106111
self.orderID = orderID
@@ -145,6 +150,7 @@ public struct Order: Decodable, Sendable, GeneratedCopiable, GeneratedFakeable {
145150
self.renewalSubscriptionID = renewalSubscriptionID
146151
self.appliedGiftCards = appliedGiftCards
147152
self.attributionInfo = attributionInfo
153+
self.shippingLabels = shippingLabels
148154
}
149155

150156

@@ -239,6 +245,11 @@ public struct Order: Decodable, Sendable, GeneratedCopiable, GeneratedFakeable {
239245
return OrderAttributionInfo(metaData: allOrderMetaData)
240246
}()
241247

248+
// Shipping labels
249+
/// This will be an empty array by default because it's not directly parsed from the Order details, so it won't be decoded.
250+
/// It's fetched with a specific API request, while at the same time it has a relationship in Core Data with Order.
251+
let shippingLabels: [ShippingLabel] = []
252+
242253
self.init(siteID: siteID,
243254
orderID: orderID,
244255
parentID: parentID,
@@ -276,7 +287,8 @@ public struct Order: Decodable, Sendable, GeneratedCopiable, GeneratedFakeable {
276287
customFields: customFields,
277288
renewalSubscriptionID: renewalSubscriptionID,
278289
appliedGiftCards: appliedGiftCards,
279-
attributionInfo: attributionInfo)
290+
attributionInfo: attributionInfo,
291+
shippingLabels: shippingLabels)
280292
}
281293

282294
public static var empty: Order {
@@ -317,7 +329,8 @@ public struct Order: Decodable, Sendable, GeneratedCopiable, GeneratedFakeable {
317329
customFields: [],
318330
renewalSubscriptionID: nil,
319331
appliedGiftCards: [],
320-
attributionInfo: nil)
332+
attributionInfo: nil,
333+
shippingLabels: [])
321334
}
322335
}
323336

@@ -365,6 +378,7 @@ internal extension Order {
365378
case taxLines = "tax_lines"
366379
case metadata = "meta_data"
367380
case giftCards = "gift_cards"
381+
case shippingLabels = "shipping_labels"
368382
}
369383
}
370384

@@ -407,7 +421,8 @@ extension Order: Equatable {
407421
lhs.items.count == rhs.items.count &&
408422
lhs.items.sorted() == rhs.items.sorted() &&
409423
lhs.customerNote == rhs.customerNote &&
410-
lhs.attributionInfo == rhs.attributionInfo
424+
lhs.attributionInfo == rhs.attributionInfo &&
425+
lhs.shippingLabels == rhs.shippingLabels
411426
}
412427
}
413428

0 commit comments

Comments
 (0)