Skip to content

Commit 9ce1249

Browse files
authored
Merge release/22.7 into trunk (#15896)
2 parents a55e970 + c571b72 commit 9ce1249

File tree

44 files changed

+1035
-111
lines changed

Some content is hidden

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

44 files changed

+1035
-111
lines changed

Modules/Sources/Networking/Mapper/WooShippingConfigMapper.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,5 +44,10 @@ private struct WooShippingConfigMapperEnvelope: Decodable {
4444
extension WooShippingConfigMapper {
4545
/// Load only the relevant fields from remote
4646
///
47-
static let fieldsToLoad = "config.shipments, config.shippingLabelData.currentOrderLabels"
47+
static let fieldsToLoad = [
48+
"config.shipments",
49+
"config.shippingLabelData.currentOrderLabels",
50+
"config.shippingLabelData.storedData.selected_destination",
51+
"config.shippingLabelData.storedData.selected_origin"
52+
].joined(separator: ", ")
4853
}

Modules/Sources/Networking/Model/ShippingLabel/Packages/WooShippingPackagePurchase.swift

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,11 @@ extension WooShippingPackagePurchase {
7373

7474
return rates
7575
}
76+
77+
/// shipment ID to set for hazmat and customs form
78+
var formattedShipmentID: String {
79+
return WooShippingShipmentIDFormatter.formattedShipmentID(shipmentID)
80+
}
7681
}
7782

7883
// MARK: Enodable
@@ -86,7 +91,11 @@ extension WooShippingPackagePurchase: Encodable {
8691
try container.encode(package.boxID, forKey: .boxID)
8792
try container.encode(package.length, forKey: .length)
8893
try container.encode(package.width, forKey: .width)
89-
try container.encode(package.height, forKey: .height)
94+
95+
// workaround because 0 would cause an error for the API request
96+
let packageHeight = package.height > 0 ? package.height : 0.25
97+
try container.encode(packageHeight, forKey: .height)
98+
9099
try container.encode(package.weight, forKey: .weight)
91100
try container.encode(package.isLetter, forKey: .isLetter)
92101
try container.encode(rate.shipmentID, forKey: .shipmentID)
@@ -96,6 +105,20 @@ extension WooShippingPackagePurchase: Encodable {
96105
try container.encode(rate.title, forKey: .serviceName)
97106
try container.encode(productIDs, forKey: .products)
98107

108+
if let hazmat = package.hazmatCategory {
109+
try container.encode(hazmat, forKey: .hazmat)
110+
}
111+
112+
if let form = package.customsForm {
113+
try container.encode(form.contentsType.rawValue, forKey: .contentsType)
114+
try container.encode(form.contentExplanation, forKey: .contentsExplanation)
115+
try container.encode(form.restrictionType.rawValue, forKey: .restrictionType)
116+
try container.encode(form.restrictionComments, forKey: .restrictionComments)
117+
try container.encode(form.nonDeliveryOption.rawValue, forKey: .nonDeliveryOption)
118+
try container.encode(form.itn, forKey: .itn)
119+
try container.encode(form.items, forKey: .items)
120+
}
121+
99122
if selectedRate.signatureRate != nil {
100123
try container.encode(Values.yes, forKey: .signature)
101124
} else if selectedRate.adultSignatureRate != nil {
@@ -140,7 +163,7 @@ extension WooShippingPackagePurchase: Encodable {
140163
/// Converts the hazmat settings to a dictionary as the API expects it.
141164
/// Includes the shipment ID if there are hazmat settings to report.
142165
public func encodedHazmat() -> [String: Any] {
143-
[shipmentID: [
166+
[formattedShipmentID: [
144167
ParameterKeys.isHazmat: package.hazmatCategory != nil,
145168
ParameterKeys.category: package.hazmatCategory ?? String()
146169
]]
@@ -150,9 +173,9 @@ extension WooShippingPackagePurchase: Encodable {
150173
/// Includes the shipment ID with the encoded customs form.
151174
public func encodedCustomsForm() throws -> [String: Any] {
152175
guard let form = package.customsForm else {
153-
return [shipmentID: [:]]
176+
return [formattedShipmentID: [:]]
154177
}
155-
return [shipmentID: [
178+
return [formattedShipmentID: [
156179
ParameterKeys.items: try form.items.map { try $0.toDictionary() },
157180
ParameterKeys.contentsType: form.contentsType.rawValue,
158181
ParameterKeys.contentsExplanation: form.contentExplanation,
@@ -181,6 +204,14 @@ extension WooShippingPackagePurchase: Encodable {
181204
case carbonNeutral = "carbon_neutral"
182205
case saturdayDelivery = "saturday_delivery"
183206
case additionalHandling = "additional_handling"
207+
case hazmat
208+
case contentsType = "contents_type"
209+
case contentsExplanation = "contents_explanation"
210+
case restrictionType = "restriction_type"
211+
case restrictionComments = "restriction_comments"
212+
case nonDeliveryOption = "non_delivery_option"
213+
case itn
214+
case items
184215
}
185216

186217
private enum ParameterKeys {

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

Lines changed: 59 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,18 +60,74 @@ public struct WooShippingLabelData: Decodable, Equatable {
6060
/// Labels purchased for the current order
6161
public let currentOrderLabels: [ShippingLabel]
6262

63-
public init(currentOrderLabels: [ShippingLabel]) {
63+
/// Contains destination addresses
64+
public let storedData: StoredData?
65+
66+
public init(
67+
currentOrderLabels: [ShippingLabel],
68+
storedData: StoredData? = nil
69+
) {
6470
self.currentOrderLabels = currentOrderLabels
71+
self.storedData = storedData
6572
}
6673

6774
public init(from decoder: Decoder) throws {
6875
let container = try decoder.container(keyedBy: CodingKeys.self)
69-
let currentOrderLabels = try container.decodeIfPresent([ShippingLabel].self, forKey: .currentOrderLabels) ?? []
70-
self.init(currentOrderLabels: currentOrderLabels)
76+
77+
let storedData = try container.decodeIfPresent(StoredData.self, forKey: .storedData)
78+
let decodedOrderLabels = try container.decodeIfPresent([ShippingLabel].self, forKey: .currentOrderLabels) ?? []
79+
80+
/// Inject destination addresses into labels if present
81+
let orderLabels: [ShippingLabel]
82+
83+
let destinations = storedData?.selectedDestinations
84+
let origins = storedData?.selectedOrigins
85+
86+
if destinations?.isEmpty == false || origins?.isEmpty == false {
87+
orderLabels = WooShippingLabelData.mapAddresses(
88+
origins: origins,
89+
destinations: destinations,
90+
into: decodedOrderLabels
91+
)
92+
} else {
93+
orderLabels = decodedOrderLabels
94+
}
95+
96+
self.init(
97+
currentOrderLabels: orderLabels,
98+
storedData: storedData
99+
)
71100
}
72101

73102
private enum CodingKeys: String, CodingKey {
74103
case currentOrderLabels
104+
case storedData
105+
}
106+
}
107+
108+
public extension WooShippingLabelData {
109+
typealias WooShippingLabelAddressMap = [String: WooShippingAddress]
110+
111+
struct StoredData: Decodable, Equatable {
112+
let selectedDestinations: WooShippingLabelAddressMap?
113+
let selectedOrigins: WooShippingLabelAddressMap?
114+
115+
public enum CodingKeys: String, CodingKey {
116+
case selectedDestination = "selected_destination"
117+
case selectedOrigin = "selected_origin"
118+
}
119+
120+
public init(from decoder: any Decoder) throws {
121+
let container = try decoder.container(keyedBy: CodingKeys.self)
122+
selectedDestinations = try? container.decodeIfPresent(
123+
WooShippingLabelAddressMap.self,
124+
forKey: CodingKeys.selectedDestination
125+
)
126+
selectedOrigins = try? container.decodeIfPresent(
127+
WooShippingLabelAddressMap.self,
128+
forKey: CodingKeys.selectedOrigin
129+
)
130+
}
75131
}
76132
}
77133

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import Foundation
2+
3+
extension WooShippingLabelData {
4+
static func mapAddresses(
5+
origins: WooShippingLabelAddressMap?,
6+
destinations: WooShippingLabelAddressMap?,
7+
into labels: [ShippingLabel]
8+
) -> [ShippingLabel] {
9+
return labels.map { label in
10+
guard let shipmentID = label.shipmentID else {
11+
return label
12+
}
13+
14+
let formattedID = WooShippingShipmentIDFormatter.formattedShipmentID(shipmentID)
15+
let originAddress = origins?[formattedID] ?? origins?[shipmentID]
16+
let destinationAddress = destinations?[formattedID] ?? destinations?[shipmentID]
17+
18+
return label.copy(
19+
originAddress: originAddress?.toShippingLabelAddress() ?? .copy,
20+
destinationAddress: destinationAddress?.toShippingLabelAddress() ?? .copy
21+
)
22+
}
23+
}
24+
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,12 @@ extension WooShippingAddress: Codable {
5959
// If no name is sent to validation address request, no name will be received in response.
6060
// So make sure to decode it only if it's present.
6161
let name = try container.decodeIfPresent(String.self, forKey: .name) ?? ""
62-
let company = try container.decode(String.self, forKey: .company)
63-
let phone = try container.decode(String.self, forKey: .phone)
62+
let company = try container.decodeIfPresent(String.self, forKey: .company) ?? ""
63+
let phone = try container.decodeIfPresent(String.self, forKey: .phone) ?? ""
6464
let country = try container.decode(String.self, forKey: .country)
6565
let state = try container.decode(String.self, forKey: .state)
6666
let address1 = try container.decodeIfPresent(String.self, forKey: .address1) ?? container.decode(String.self, forKey: .alternateAddress1)
67-
let address2 = try container.decode(String.self, forKey: .address2)
67+
let address2 = try container.decodeIfPresent(String.self, forKey: .address2) ?? ""
6868
let city = try container.decode(String.self, forKey: .city)
6969
let postcode = try container.decode(String.self, forKey: .postcode)
7070

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import Foundation
2+
3+
enum WooShippingShipmentIDFormatter {
4+
/// Turns numeric shipment ID into formatted as `shipment_<id>`
5+
/// - Parameter shipmentID: numeric shipment id
6+
/// - Returns: formated id string
7+
static func formattedShipmentID(_ shipmentID: String) -> String {
8+
return isArgumentIDValid(shipmentID) ?
9+
Values.shipmentIDPrefix + shipmentID :
10+
shipmentID
11+
}
12+
}
13+
14+
private extension WooShippingShipmentIDFormatter {
15+
private enum Values {
16+
static let shipmentIDPrefix = "shipment_"
17+
}
18+
19+
/// Make sure we are formatting incoming numeric ID string
20+
private static func isArgumentIDValid(_ argumentID: String) -> Bool {
21+
return Int(argumentID) != nil
22+
}
23+
}

Modules/Sources/NetworkingCore/Model/ShippingLabel/ShippingLabelAddress.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,4 +117,16 @@ extension ShippingLabelAddress {
117117
init() {
118118
self.init(company: "", name: "", phone: "", country: "", state: "", address1: "", address2: "", city: "", postcode: "")
119119
}
120+
121+
var isEmpty: Bool {
122+
return company.isEmpty &&
123+
name.isEmpty &&
124+
phone.isEmpty &&
125+
country.isEmpty &&
126+
state.isEmpty &&
127+
address1.isEmpty &&
128+
address2.isEmpty &&
129+
city.isEmpty &&
130+
postcode.isEmpty
131+
}
120132
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import Foundation
2+
import XCTest
3+
@testable import Networking
4+
5+
final class WooShippingShipmentIDFormatterTests: XCTestCase {
6+
7+
// MARK: - formattedShipmentID
8+
9+
func test_formatted_shipment_id_when_id_is_numeric_should_return_formatted_id() {
10+
// Given
11+
let sut = WooShippingShipmentIDFormatter.self
12+
let id = "123456"
13+
14+
// When
15+
let formattedID = sut.formattedShipmentID(id)
16+
17+
// Then
18+
XCTAssertEqual(formattedID, "shipment_123456")
19+
}
20+
21+
func test_formatted_shipment_id_when_id_is_already_formatted_should_return_same_id() {
22+
// Given
23+
let sut = WooShippingShipmentIDFormatter.self
24+
let id = "shipment_123456"
25+
26+
// When
27+
let formattedID = sut.formattedShipmentID(id)
28+
29+
// Then
30+
XCTAssertEqual(formattedID, "shipment_123456")
31+
}
32+
33+
func test_formatted_shipment_id_when_non_numeric_should_return_same_id() {
34+
// Given
35+
let sut = WooShippingShipmentIDFormatter.self
36+
let id = "non-numeric-id"
37+
38+
// When
39+
let formattedID = sut.formattedShipmentID(id)
40+
41+
// Then
42+
XCTAssertEqual(formattedID, id)
43+
}
44+
}

0 commit comments

Comments
 (0)