Skip to content

Commit 494ef48

Browse files
[Shipping Labels] Handle dots in HS tariff number (#15933)
Merging as discussed in p1753281374928639-slack-C03L1NF1EA3
2 parents 46c5f23 + 0ed2f79 commit 494ef48

File tree

4 files changed

+81
-11
lines changed

4 files changed

+81
-11
lines changed

RELEASE-NOTES.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
- [*] Shipping Labels: Optimize data loading on purchase form [https://github.com/woocommerce/woocommerce-ios/pull/15919]
1717
- [*] Shipping Labels: Cache settings and origin addresses to improve loading experience for purchase form [https://github.com/woocommerce/woocommerce-ios/pull/15935]
1818
- [internal] Optimized assets for app size reduction [https://github.com/woocommerce/woocommerce-ios/pull/15881]
19+
- [*] Shipping Labels: Allow dots in HS tariff number input field for customs settings [https://github.com/woocommerce/woocommerce-ios/pull/15933]
1920

2021
22.8
2122
-----

WooCommerce/Classes/ViewRelated/Orders/Order Details/Shipping Labels/WooShipping Create Shipping Labels/WooShipping Customs/WooShippingCustomsFormViewModel.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ private extension WooShippingCustomsFormViewModel {
211211
quantity: $0.itemQuantity,
212212
value: Double($0.valuePerUnit) ?? 0,
213213
weight: Double($0.weightPerUnit) ?? 0,
214-
hsTariffNumber: $0.isValidTariffNumber ? $0.hsTariffNumber : "",
214+
hsTariffNumber: $0.isValidTariffNumber ? $0.sanitizedHSTariffNumber : "",
215215
originCountry: $0.selectedCountry?.code ?? "",
216216
productID: $0.itemProductID
217217
)

WooCommerce/Classes/ViewRelated/Orders/Order Details/Shipping Labels/WooShipping Create Shipping Labels/WooShipping Customs/WooShippingCustomsItemViewModel.swift

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -49,17 +49,11 @@ final class WooShippingCustomsItemViewModel: ObservableObject {
4949
}
5050

5151
var isValidTariffNumber: Bool {
52-
guard hsTariffNumber.isNotEmpty else {
53-
return true
54-
}
55-
56-
// Check if the string contains only digits
57-
let digitsOnly = CharacterSet.decimalDigits.isSuperset(of: CharacterSet(charactersIn: hsTariffNumber))
58-
guard digitsOnly else { return false }
52+
return HSTariffNumberValidator.isNumberValid(hsTariffNumber)
53+
}
5954

60-
// Check the length of the string
61-
let length = hsTariffNumber.count
62-
return length >= 6 && length <= 12
55+
var sanitizedHSTariffNumber: String {
56+
HSTariffNumberValidator.sanitize(hsTariffNumber)
6357
}
6458

6559
@Published var requiredInformationIsEntered: Bool = false
@@ -150,3 +144,41 @@ private extension WooShippingCustomsItemViewModel {
150144
.store(in: &cancellables)
151145
}
152146
}
147+
148+
/// Follows validation logic from `woocommerce-shipping/client/utils/customs.ts`
149+
enum HSTariffNumberValidator {
150+
static let pattern = "^(\\d{1,2}\\.?){3,6}$"
151+
152+
/// Check if the HS Tariff Number is valid.
153+
/// It should be a string of 6 to 12 digits, with optional dots in between every 2 digits.
154+
/// - Parameter tariffNumber: The tariff number string.
155+
/// - Returns: `Bool` if tariff number valid or not.
156+
static func isNumberValid(_ tariffNumber: String) -> Bool {
157+
if tariffNumber.isEmpty {
158+
return true
159+
}
160+
161+
let patternRange = tariffNumber.range(
162+
of: pattern,
163+
options: .regularExpression
164+
)
165+
166+
if patternRange == nil {
167+
return false
168+
}
169+
170+
let digitsOnly = tariffNumber.components(
171+
separatedBy: CharacterSet.decimalDigits.inverted
172+
).joined()
173+
let count = digitsOnly.count
174+
return count >= 6 && count <= 12
175+
}
176+
177+
/// Sanitize the HS Tariff Number
178+
/// Remove all non-digit characters
179+
/// - Parameter tariffNumber: The tariff number string.
180+
/// - Returns: Tariff string without non-digit characters
181+
static func sanitize(_ tariffNumber: String) -> String {
182+
return tariffNumber.components(separatedBy: CharacterSet.decimalDigits.inverted).joined()
183+
}
184+
}

WooCommerce/WooCommerceTests/ViewRelated/Shipping Label/WooShipping Create Shipping Labels/WooShipping Customs/WooShippingCustomsItemViewModelTests.swift

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,4 +109,41 @@ final class WooShippingCustomsItemViewModelTests: XCTestCase {
109109
XCTAssertEqual(viewModel.hsTariffNumberTotalValue?.0, viewModel.hsTariffNumber)
110110
XCTAssertEqual(viewModel.hsTariffNumberTotalValue?.1, Decimal(string: viewModel.valuePerUnit)! * 2)
111111
}
112+
113+
func test_isNumberValid_whenGivenValidTariffNumbers_shouldReturnTrue() {
114+
XCTAssertTrue(HSTariffNumberValidator.isNumberValid("123456"))
115+
XCTAssertTrue(HSTariffNumberValidator.isNumberValid("12.34.56"))
116+
XCTAssertTrue(HSTariffNumberValidator.isNumberValid("12.34.56.78"))
117+
XCTAssertTrue(HSTariffNumberValidator.isNumberValid("12.34.56.78.90"))
118+
XCTAssertTrue(HSTariffNumberValidator.isNumberValid("12.34.56.78.90.12"))
119+
XCTAssertTrue(HSTariffNumberValidator.isNumberValid("123456789012"))
120+
XCTAssertTrue(HSTariffNumberValidator.isNumberValid("12.345.678.90"))
121+
XCTAssertTrue(HSTariffNumberValidator.isNumberValid("1.2.3.4.5.6"))
122+
}
123+
124+
func test_isNumberValid_whenGivenInvalidTariffNumbers_shouldReturnFalse() {
125+
// Less than 6 digits
126+
XCTAssertFalse(HSTariffNumberValidator.isNumberValid("12345"))
127+
XCTAssertFalse(HSTariffNumberValidator.isNumberValid("12.34.5"))
128+
129+
// More than 12 digits
130+
XCTAssertFalse(HSTariffNumberValidator.isNumberValid("1234567890123"))
131+
XCTAssertFalse(HSTariffNumberValidator.isNumberValid("12.34.56.78.90.123"))
132+
133+
// Invalid characters
134+
XCTAssertFalse(HSTariffNumberValidator.isNumberValid("12345a"))
135+
XCTAssertFalse(HSTariffNumberValidator.isNumberValid("12.34.5a"))
136+
137+
// Invalid structure
138+
XCTAssertFalse(HSTariffNumberValidator.isNumberValid("12.34..56"))
139+
XCTAssertFalse(HSTariffNumberValidator.isNumberValid(".123456"))
140+
}
141+
142+
func test_hsTariffNumber_sanitize_whenGivenStringWithNonDigits_shouldReturnOnlyDigits() {
143+
XCTAssertEqual(HSTariffNumberValidator.sanitize("12.34.56"), "123456")
144+
XCTAssertEqual(HSTariffNumberValidator.sanitize("12a34b56c"), "123456")
145+
XCTAssertEqual(HSTariffNumberValidator.sanitize("...123---456..."), "123456")
146+
XCTAssertEqual(HSTariffNumberValidator.sanitize("123456"), "123456")
147+
XCTAssertEqual(HSTariffNumberValidator.sanitize(""), "")
148+
}
112149
}

0 commit comments

Comments
 (0)