Skip to content

Commit abe6889

Browse files
authored
Shipping Labels: Support extra rates for UPS (#15819)
2 parents 842dafd + 66dc9cc commit abe6889

File tree

16 files changed

+569
-64
lines changed

16 files changed

+569
-64
lines changed

Modules/Sources/Networking/Mapper/ShippingLabelCarriersAndRatesMapper.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,10 @@ private struct ShippingLabelDefaultBoxEnvelope: Decodable {
4949
return ShippingLabelCarriersAndRates(packageID: key,
5050
defaultRates: value.defaultRates,
5151
signatureRequired: value.signatureRequired,
52-
adultSignatureRequired: value.adultSignatureRequired)
52+
adultSignatureRequired: value.adultSignatureRequired,
53+
carbonNeutral: value.carbonNeutral,
54+
saturdayDelivery: value.saturdayDelivery,
55+
additionalHandling: value.additionalHandling)
5356
}
5457
}
5558
}

Modules/Sources/Networking/Mapper/WooShippingLabelRatesMapper.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,10 @@ private struct ShippingLabelDefaultBoxEnvelope: Decodable {
4141
return ShippingLabelCarriersAndRates(packageID: key,
4242
defaultRates: value.defaultRates,
4343
signatureRequired: value.signatureRequired,
44-
adultSignatureRequired: value.adultSignatureRequired)
44+
adultSignatureRequired: value.adultSignatureRequired,
45+
carbonNeutral: value.carbonNeutral,
46+
saturdayDelivery: value.saturdayDelivery,
47+
additionalHandling: value.additionalHandling)
4548
}
4649
}
4750
}

Modules/Sources/Networking/Model/ShippingLabel/Packages/CarriersAndRates/ShippingLabelCarriersAndRates.swift

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,24 @@ public struct ShippingLabelCarriersAndRates: Equatable {
88
public let defaultRates: [ShippingLabelCarrierRate]
99
public let signatureRequired: [ShippingLabelCarrierRate]
1010
public let adultSignatureRequired: [ShippingLabelCarrierRate]
11+
public let carbonNeutral: [ShippingLabelCarrierRate]
12+
public let saturdayDelivery: [ShippingLabelCarrierRate]
13+
public let additionalHandling: [ShippingLabelCarrierRate]
1114

1215
public init(packageID: String?,
1316
defaultRates: [ShippingLabelCarrierRate],
1417
signatureRequired: [ShippingLabelCarrierRate],
15-
adultSignatureRequired: [ShippingLabelCarrierRate]) {
18+
adultSignatureRequired: [ShippingLabelCarrierRate],
19+
carbonNeutral: [ShippingLabelCarrierRate],
20+
saturdayDelivery: [ShippingLabelCarrierRate],
21+
additionalHandling: [ShippingLabelCarrierRate]) {
1622
self.packageID = packageID
1723
self.defaultRates = defaultRates
1824
self.signatureRequired = signatureRequired
1925
self.adultSignatureRequired = adultSignatureRequired
26+
self.carbonNeutral = carbonNeutral
27+
self.saturdayDelivery = saturdayDelivery
28+
self.additionalHandling = additionalHandling
2029
}
2130
}
2231

@@ -30,12 +39,17 @@ extension ShippingLabelCarriersAndRates: Decodable {
3039
let defaultRates = try container.decode(ShippingLabelRatesEnvelope.self, forKey: .defaultRates).rates
3140
let signatureRequired = try container.decode(ShippingLabelRatesEnvelope.self, forKey: .signatureRequired).rates
3241
let adultSignatureRequired = try container.decode(ShippingLabelRatesEnvelope.self, forKey: .adultSignatureRequired).rates
33-
42+
let carbonNeutral = try container.decodeIfPresent(ShippingLabelRatesEnvelope.self, forKey: .carbonNeutral)?.rates ?? []
43+
let saturdayDelivery = try container.decodeIfPresent(ShippingLabelRatesEnvelope.self, forKey: .saturdayDelivery)?.rates ?? []
44+
let additionalHandling = try container.decodeIfPresent(ShippingLabelRatesEnvelope.self, forKey: .additionalHandling)?.rates ?? []
3445

3546
self.init(packageID: packageID,
3647
defaultRates: defaultRates,
3748
signatureRequired: signatureRequired,
38-
adultSignatureRequired: adultSignatureRequired)
49+
adultSignatureRequired: adultSignatureRequired,
50+
carbonNeutral: carbonNeutral,
51+
saturdayDelivery: saturdayDelivery,
52+
additionalHandling: additionalHandling)
3953
}
4054

4155

@@ -44,6 +58,9 @@ extension ShippingLabelCarriersAndRates: Decodable {
4458
case defaultRates = "default"
4559
case signatureRequired
4660
case adultSignatureRequired
61+
case carbonNeutral
62+
case saturdayDelivery
63+
case additionalHandling
4764
}
4865
}
4966

Modules/Tests/NetworkingTests/Remote/WooShippingRemoteTests.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,9 @@ final class WooShippingRemoteTests: XCTestCase {
191191

192192
let successResponse = try XCTUnwrap(result.get())
193193
XCTAssertEqual(successResponse.first?.defaultRates.first, expectedDefaultRate)
194+
XCTAssertEqual(successResponse.first?.carbonNeutral.count, 1)
195+
XCTAssertEqual(successResponse.first?.saturdayDelivery.count, 1)
196+
XCTAssertEqual(successResponse.first?.additionalHandling.count, 2)
194197
}
195198

196199
func test_loadLabelRates_returns_error_on_failure() throws {

Modules/Tests/NetworkingTests/Responses/wooshipping-get-label-rates-success.json

Lines changed: 88 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,94 @@
202202
}
203203
],
204204
"errors": []
205-
}
205+
},
206+
"carbon_neutral": {
207+
"rates": [
208+
{
209+
"rate_id": "rate_91baa7176a004a1093f6e0041f6130fd",
210+
"service_id": "2ndDayAir",
211+
"carrier_id": "upsdap",
212+
"title": "UPS 2nd Day Air®",
213+
"rate": 23.21,
214+
"retail_rate": 68.58,
215+
"list_rate": 77.09,
216+
"is_selected": false,
217+
"tracking": true,
218+
"insurance": 100,
219+
"free_pickup": false,
220+
"caveats": [],
221+
"shipment_id": "shp_43d9931be5ef4a6a802e4c80c3478acd",
222+
"delivery_days": 2,
223+
"delivery_date_guaranteed": false,
224+
"delivery_date": "2025-06-26T23:00:00.000Z"
225+
}
226+
],
227+
"errors": []
228+
},
229+
"additional_handling": {
230+
"rates": [
231+
{
232+
"rate_id": "rate_94066e39fb684518ba0b703625ed7881",
233+
"service_id": "2ndDayAir",
234+
"carrier_id": "upsdap",
235+
"title": "UPS 2nd Day Air®",
236+
"rate": 35.96,
237+
"retail_rate": 105.78,
238+
"list_rate": 114.31,
239+
"is_selected": false,
240+
"tracking": true,
241+
"insurance": 100,
242+
"free_pickup": false,
243+
"caveats": [],
244+
"shipment_id": "shp_dd87ece33f7e4e8db360339fcb3af033",
245+
"delivery_days": 2,
246+
"delivery_date_guaranteed": false,
247+
"delivery_date": "2025-06-26T23:00:00.000Z"
248+
},
249+
{
250+
"rate_id": "rate_5204f3dc16f845debb910b71ce52cce6",
251+
"service_id": "NextDayAirSaver",
252+
"carrier_id": "upsdap",
253+
"title": "UPS Next Day Air Saver®",
254+
"rate": 59.9,
255+
"retail_rate": 170.13,
256+
"list_rate": 187.76,
257+
"is_selected": false,
258+
"tracking": true,
259+
"insurance": 100,
260+
"free_pickup": false,
261+
"caveats": [],
262+
"shipment_id": "shp_dd87ece33f7e4e8db360339fcb3af033",
263+
"delivery_days": 1,
264+
"delivery_date_guaranteed": true,
265+
"delivery_date": "2025-06-25T23:00:00.000Z"
266+
}
267+
],
268+
"errors": []
269+
},
270+
"saturday_delivery": {
271+
"rates": [
272+
{
273+
"rate_id": "rate_16aa2b9dc43442039a94b1fdafbb0c95",
274+
"service_id": "2ndDayAir",
275+
"carrier_id": "upsdap",
276+
"title": "UPS 2nd Day Air®",
277+
"rate": 39.01,
278+
"retail_rate": 87.38,
279+
"list_rate": 95.9,
280+
"is_selected": false,
281+
"tracking": true,
282+
"insurance": 100,
283+
"free_pickup": false,
284+
"caveats": [],
285+
"shipment_id": "shp_6ba05ebf4ad0482b9e77d2923070f316",
286+
"delivery_days": 2,
287+
"delivery_date_guaranteed": false,
288+
"delivery_date": "2025-06-26T23:00:00.000Z"
289+
}
290+
],
291+
"errors": []
292+
}
206293
}
207294
}
208295
}

Modules/Tests/YosemiteTests/Stores/ShippingLabelStoreTests.swift

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1027,9 +1027,12 @@ private extension ShippingLabelStoreTests {
10271027

10281028
func sampleShippingLabelCarriersAndRates() -> [ShippingLabelCarriersAndRates] {
10291029
return [ShippingLabelCarriersAndRates(packageID: "123",
1030-
defaultRates: [sampleShippingLabelCarrierRate()],
1031-
signatureRequired: [],
1032-
adultSignatureRequired: [])]
1030+
defaultRates: [sampleShippingLabelCarrierRate()],
1031+
signatureRequired: [],
1032+
adultSignatureRequired: [],
1033+
carbonNeutral: [],
1034+
saturdayDelivery: [],
1035+
additionalHandling: [])]
10331036
}
10341037

10351038
func sampleShippingLabelCarrierRate() -> ShippingLabelCarrierRate {

Modules/Tests/YosemiteTests/Stores/WooShippingStoreTests.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1231,7 +1231,10 @@ private extension WooShippingStoreTests {
12311231
return [ShippingLabelCarriersAndRates(packageID: "123",
12321232
defaultRates: [sampleLabelRate()],
12331233
signatureRequired: [],
1234-
adultSignatureRequired: [])]
1234+
adultSignatureRequired: [],
1235+
carbonNeutral: [],
1236+
saturdayDelivery: [],
1237+
additionalHandling: [])]
12351238
}
12361239

12371240
func sampleLabelRate() -> ShippingLabelCarrierRate {

WooCommerce/Classes/ViewRelated/Orders/Order Details/Shipping Labels/WooShipping Create Shipping Labels/WooShipping Package and Rate Selection/WooShippingSelectedRate.swift

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,15 @@ struct WooShippingSelectedRate {
1010

1111
/// Rate for shipping with adult signature, if selected.
1212
let adultSignatureRate: ShippingLabelCarrierRate?
13+
14+
/// Rate for shipping with carbon neutral, if selected.
15+
let carbonNeutralRate: ShippingLabelCarrierRate?
16+
17+
/// Rate for shipping with Saturday delivery, if selected.
18+
let saturdayDeliveryRate: ShippingLabelCarrierRate?
19+
20+
/// Rate for shipping with additional handling, if selected.
21+
let additionalHandlingRate: ShippingLabelCarrierRate?
1322
}
1423

1524
extension WooShippingSelectedRate {
@@ -23,11 +32,43 @@ extension WooShippingSelectedRate {
2332
}
2433

2534
var totalRate: Double {
26-
if let signatureRate = signatureRate {
27-
return signatureRate.rate
28-
} else if let adultSignatureRate = adultSignatureRate {
29-
return adultSignatureRate.rate
35+
let totalRateExcludingExtraServices: Double = {
36+
if let signatureRate {
37+
return signatureRate.rate
38+
} else if let adultSignatureRate {
39+
return adultSignatureRate.rate
40+
}
41+
return rate.rate
42+
}()
43+
44+
let allCharges = [totalRateExcludingExtraServices,
45+
surchargeForCarbonNeutralRate,
46+
surchargeForSaturdayDeliveryRate,
47+
surchargeForAdditionalHandlingRate]
48+
49+
return allCharges.reduce(0, +)
50+
}
51+
}
52+
53+
private extension WooShippingSelectedRate {
54+
var surchargeForCarbonNeutralRate: Double {
55+
guard let carbonNeutralRate else {
56+
return 0
57+
}
58+
return carbonNeutralRate.rate - rate.rate
59+
}
60+
61+
var surchargeForSaturdayDeliveryRate: Double {
62+
guard let saturdayDeliveryRate else {
63+
return 0
64+
}
65+
return saturdayDeliveryRate.rate - rate.rate
66+
}
67+
68+
var surchargeForAdditionalHandlingRate: Double {
69+
guard let additionalHandlingRate else {
70+
return 0
3071
}
31-
return rate.rate
72+
return additionalHandlingRate.rate - rate.rate
3273
}
3374
}

0 commit comments

Comments
 (0)