Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,11 @@ extension KeyedDecodingContainer {
return nil
}

/// Decodes a Decimal for the specified key. Supported Encodings = [Decimal / Int / String]
///
/// This method *does NOT throw*. We want this behavior so that if a malformed entity is received, we just skip it, rather
/// than breaking the entire parsing chain.
///
func failsafeDecodeIfPresent(decimalForKey key: KeyedDecodingContainer<K>.Key) -> Decimal? {
if let decimal = failsafeDecodeIfPresent(Decimal.self, forKey: key) {
return decimal
Expand All @@ -125,6 +130,10 @@ extension KeyedDecodingContainer {
return Decimal(integerLiteral: integerAsDecimal)
}

if let stringAsDecimal = failsafeDecodeIfPresent(String.self, forKey: key) {
return Decimal(string: stringAsDecimal)
}

return nil
}

Expand Down
6 changes: 5 additions & 1 deletion Networking/Networking/Model/Product/Product.swift
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,11 @@ public struct Product: Codable, GeneratedCopiable, Equatable, GeneratedFakeable
})
]) ?? false

let stockQuantity = try container.decodeIfPresent(Decimal.self, forKey: .stockQuantity)
// Even though WooCommerce Core returns Int or null values,
// some plugins alter the field value from Int to Decimal or String.
// We handle this as an optional Decimal value.
let stockQuantity = container.failsafeDecodeIfPresent(decimalForKey: .stockQuantity)

let stockStatusKey = try container.decode(String.self, forKey: .stockStatusKey)

let backordersKey = try container.decode(String.self, forKey: .backordersKey)
Expand Down
6 changes: 5 additions & 1 deletion Networking/Networking/Model/Product/ProductVariation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,11 @@ public struct ProductVariation: Codable, GeneratedCopiable, Equatable, Generated
})
]) ?? false

let stockQuantity = try container.decodeIfPresent(Decimal.self, forKey: .stockQuantity)
// Even though WooCommerce Core returns Int or null values,
// some plugins alter the field value from Int to Decimal or String.
// We handle this as an optional Decimal value.
let stockQuantity = container.failsafeDecodeIfPresent(decimalForKey: .stockQuantity)

let stockStatusKey = try container.decode(String.self, forKey: .stockStatusKey)
let stockStatus = ProductStockStatus(rawValue: stockStatusKey)
let backordersKey = try container.decode(String.self, forKey: .backordersKey)
Expand Down
1 change: 1 addition & 0 deletions Networking/NetworkingTests/Mapper/ProductMapperTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ final class ProductMapperTests: XCTestCase {
XCTAssertEqual(product.downloads.first?.downloadID, "12345")
XCTAssertEqual(product.backordersAllowed, true)
XCTAssertEqual(product.onSale, false)
XCTAssertNil(product.stockQuantity)
}

/// Verifies that the `salePrice` field of the Product are parsed correctly when the product is on sale, and the sale price is an empty string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ final class ProductVariationMapperTests: XCTestCase {
XCTAssertEqual(productVariation.weight, "2.5")
XCTAssertEqual(productVariation.backordersAllowed, true)
XCTAssertEqual(productVariation.onSale, false)
XCTAssertEqual(productVariation.stockQuantity, 16)
}

/// Test that the fields for variations of a subscription product are properly parsed.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
"tax_status": "taxable",
"tax_class": "",
"manage_stock": "parent",
"stock_quantity": null,
"stock_quantity": "",
"stock_status": "instock",
"backorders": "no",
"backorders_allowed": "1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"tax_status": "taxable",
"tax_class": "",
"manage_stock": "parent",
"stock_quantity": 16,
"stock_quantity": "16",
"stock_status": "instock",
"backorders": "notify",
"backorders_allowed": "1",
Expand Down
1 change: 1 addition & 0 deletions RELEASE-NOTES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
-----
- [*] Orders: Allow alternative types for the `taxID` in `ShippingLineTax` or `sku` in `OrderItem`, as some third-party plugins alter the type in the API. This helps with the order list not loading due to order decoding errors. [https://github.com/woocommerce/woocommerce-ios/pull/9844]
- [*] Payments: Location permissions request is not shown to TTP users who grant "Allow once" permission on first foregrounding the app any more [https://github.com/woocommerce/woocommerce-ios/pull/9821]
- [*] Products: Allow alternative types for `stockQuantity` in `Product` and `ProductVariation`, as some third-party plugins alter the type in the API. This helps with the product list not loading due to product decoding errors. [https://github.com/woocommerce/woocommerce-ios/pull/9850]
- [*] Products: Allow alternative types for the `backordersAllowed` and `onSale` in `Product` and `ProductVariation`, as some third-party plugins alter the types in the API. This helps with the product list not loading due to product decoding errors. [https://github.com/woocommerce/woocommerce-ios/pull/9849]
- [*] Products: Allow alternative types for the `sku` and `weight` in `ProductVariation`, as some third-party plugins alter the types in the API. This helps with the product variation list not loading due to product variation decoding errors. [https://github.com/woocommerce/woocommerce-ios/pull/9847]
- [*] Products: Allow alternative types for the `sku` and `weight` in `Product`, the dimensions in `ProductDimensions`, and the `downloadID` in `ProductDownload`, as some third-party plugins alter the types in the API. This helps with the product list not loading due to product decoding errors. [https://github.com/woocommerce/woocommerce-ios/pull/9846]
Expand Down