Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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
4 changes: 4 additions & 0 deletions Networking/Networking.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,7 @@
CE19CB11222486A600E8AF7A /* order-statuses.json in Resources */ = {isa = PBXBuildFile; fileRef = CE19CB10222486A500E8AF7A /* order-statuses.json */; };
CE20179320E3EFA7005B4C18 /* broken-orders.json in Resources */ = {isa = PBXBuildFile; fileRef = CE20179220E3EFA7005B4C18 /* broken-orders.json */; };
CE227093228DD44C00C0626C /* ProductStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE227092228DD44C00C0626C /* ProductStatus.swift */; };
CE2678432A26102A00FD9AEB /* order-alternative-types.json in Resources */ = {isa = PBXBuildFile; fileRef = CE2678422A26102A00FD9AEB /* order-alternative-types.json */; };
CE43066A23465F340073CBFF /* Refund.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE43066923465F340073CBFF /* Refund.swift */; };
CE43066C2347C5F90073CBFF /* OrderItemRefund.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE43066B2347C5F90073CBFF /* OrderItemRefund.swift */; };
CE43066E2347CBA70073CBFF /* OrderItemTaxRefund.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE43066D2347CBA70073CBFF /* OrderItemTaxRefund.swift */; };
Expand Down Expand Up @@ -1579,6 +1580,7 @@
CE19CB10222486A500E8AF7A /* order-statuses.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "order-statuses.json"; sourceTree = "<group>"; };
CE20179220E3EFA7005B4C18 /* broken-orders.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "broken-orders.json"; sourceTree = "<group>"; };
CE227092228DD44C00C0626C /* ProductStatus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProductStatus.swift; sourceTree = "<group>"; };
CE2678422A26102A00FD9AEB /* order-alternative-types.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "order-alternative-types.json"; sourceTree = "<group>"; };
CE43066923465F340073CBFF /* Refund.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Refund.swift; sourceTree = "<group>"; };
CE43066B2347C5F90073CBFF /* OrderItemRefund.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderItemRefund.swift; sourceTree = "<group>"; };
CE43066D2347CBA70073CBFF /* OrderItemTaxRefund.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderItemTaxRefund.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2541,6 +2543,7 @@
B554FA8C2180B59700C54DFF /* notifications-load-hashes.json */,
AE2D6624272A941C004A2C3A /* null-data.json */,
B5C6FCD520A3768900A4F8E4 /* order.json */,
CE2678422A26102A00FD9AEB /* order-alternative-types.json */,
DEF13C5F29668C420024A02B /* order-without-data.json */,
034480C227A42F9100DFACD2 /* order-with-charge.json */,
02C254D62563999200A04423 /* order-shipping-labels.json */,
Expand Down Expand Up @@ -3620,6 +3623,7 @@
74ABA1C9213F19FE00FFAD30 /* top-performers-month.json in Resources */,
3158FE7026129D7500E566B9 /* wcpay-account-rejected-listed.json in Resources */,
743E84F622172D3E00FAC9D7 /* shipment_tracking_single.json in Resources */,
CE2678432A26102A00FD9AEB /* order-alternative-types.json in Resources */,
D865CE5B278CA10B002C8520 /* stripe-payment-intent-requires-payment-method.json in Resources */,
CC9A254626442CA7005DE56E /* shipping-label-eligibility-failure.json in Resources */,
4524CD9C242CEFAB00B2F20A /* product-on-sale-with-empty-sale-price.json in Resources */,
Expand Down
6 changes: 5 additions & 1 deletion Networking/Networking/Model/OrderItem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,11 @@ public struct OrderItem: Codable, Equatable, Hashable, GeneratedFakeable, Genera
let decimalPrice = try container.decodeIfPresent(Decimal.self, forKey: .price) ?? Decimal(0)
let price = NSDecimalNumber(decimal: decimalPrice)

let sku = try container.decodeIfPresent(String.self, forKey: .sku)
// Even though a plain install of WooCommerce Core provides String values,
// some plugins alter the field value from String to Int or Decimal.
let sku = container.failsafeDecodeIfPresent(targetType: String.self,
forKey: .sku,
alternativeTypes: [.decimal(transform: { NSDecimalNumber(decimal: $0).stringValue })])
let subtotal = try container.decode(String.self, forKey: .subtotal)
let subtotalTax = try container.decode(String.self, forKey: .subtotalTax)
let taxClass = try container.decode(String.self, forKey: .taxClass)
Expand Down
16 changes: 16 additions & 0 deletions Networking/Networking/Model/ShippingLineTax.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,22 @@ public struct ShippingLineTax: Decodable, Hashable, GeneratedFakeable {
self.subtotal = subtotal
self.total = total
}

/// The public initializer for ShippingLineTax.
///
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)

// Even though a plain install of WooCommerce Core provides Int values,
// some plugins alter the field value from Int to String.
let taxID = container.failsafeDecodeIfPresent(targetType: Int64.self,
forKey: .taxID,
alternativeTypes: [.string(transform: { Int64($0) ?? 0 })]) ?? 0
let subtotal = try container.decode(String.self, forKey: .subtotal)
let total = try container.decode(String.self, forKey: .total)

self.init(taxID: taxID, subtotal: subtotal, total: total)
}
}

/// Defines all of the ShippingLineTax CodingKeys.
Expand Down
15 changes: 15 additions & 0 deletions Networking/NetworkingTests/Mapper/OrderMapperTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,15 @@ final class OrderMapperTests: XCTestCase {
XCTAssertNil(compositeProduct.parent)
XCTAssertEqual(component.parent, 830)
}

func test_that_order_alternative_types_are_properly_parsed() throws {
// Given
let order = try XCTUnwrap(mapLoadOrderResponseWithAlternativeTypes())

// Then
XCTAssertEqual(order.shippingLines.first?.taxes.first?.taxID, 1)
XCTAssertEqual(order.items.first?.sku, "123")
}
}


Expand Down Expand Up @@ -531,4 +540,10 @@ private extension OrderMapperTests {
return mapOrder(from: "order-with-composite-product")
}

/// Returns the Order output upon receiving `order-alternative-types`
///
func mapLoadOrderResponseWithAlternativeTypes() -> Order? {
return mapOrder(from: "order-alternative-types")
}

}
209 changes: 209 additions & 0 deletions Networking/NetworkingTests/Responses/order-alternative-types.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
{
"data": {
"id": 963,
"parent_id": 0,
"is_editable": true,
"needs_payment": true,
"needs_processing": true,
"number": "963",
"status": "processing",
"order_key": "abc123",
"currency": "USD",
"date_created_gmt": "2018-04-03T23:05:12",
"date_modified_gmt": "2018-04-03T23:05:14",
"discount_total": "30.00",
"discount_tax": "1.20",
"shipping_total": "0.00",
"shipping_tax": "0.00",
"cart_tax": "1.20",
"total": "31.20",
"total_tax": "1.20",
"customer_id": 11,
"customer_note": "",
"billing": {
"first_name": "Johnny",
"last_name": "Appleseed",
"company": "",
"address_1": "234 70th Street",
"address_2": "",
"city": "Niagara Falls",
"state": "NY",
"postcode": "14304",
"country": "US",
"email": "[email protected]",
"phone": "333-333-3333"
},
"shipping": {
"first_name": "Johnny",
"last_name": "Appleseed",
"company": "",
"address_1": "234 70th Street",
"address_2": "",
"city": "Niagara Falls",
"state": "NY",
"postcode": "14304",
"country": "US",
"email": "[email protected]",
"phone": "333-333-3333"
},
"shipping_lines": [
{
"id": 123,
"method_title": "International Priority Mail Express Flat Rate",
"method_id": "usps",
"instance_id": "5",
"total": "133.00",
"total_tax": "0.00",
"taxes": [
{
"id": "1",
"total": "0.62125",
"subtotal": ""
}
],
"meta_data": [
{
"id": 1307,
"key": "Package 1",
"value": "1 × 1 × 1 (in) 4lbs × 1"
},
{
"id": 1308,
"key": "Package 2",
"value": "1 × 1 × 1 (in) 1lbs × 1"
}
]
}
],
"fee_lines": [
{
"id": 60,
"name": "$125.50 fee",
"tax_class": "",
"tax_status": "taxable",
"amount": "125.5",
"total": "125.50",
"total_tax": "0.00",
"taxes": [],
"meta_data": []
}
],
"tax_lines": [
{
"id": 1330,
"rate_code": "US-NY-STATE-2",
"rate_id": 6,
"label": "State",
"compound": true,
"tax_total": "7.71",
"shipping_tax_total": "0.00",
"rate_percent": 4.5,
"meta_data": []
}
],
"payment_method": "stripe",
"payment_method_title": "Credit Card (Stripe)",
"payment_url": "http://www.automattic.com",
"date_paid_gmt": "2018-04-03T23:05:14",
"date_completed_gmt": null,
"line_items": [
{
"id": 890,
"name": "Fruits Basket (Mix & Match Product)",
"product_id": 52,
"variation_id": 0,
"quantity": 2,
"tax_class": "",
"subtotal": "50.00",
"subtotal_tax": "2.00",
"total": "30.00",
"total_tax": "1.20",
"taxes": [
{
"id": 1,
"total": "1.2",
"subtotal": "2"
}
],
"meta_data": [],
"sku": 123,
"price": 30
},
{
"id": 891,
"name": "Fruits Bundle",
"product_id": 234,
"variation_id": 0,
"quantity": 1.5,
"tax_class": "",
"subtotal": "10.00",
"subtotal_tax": "0.40",
"total": "0.00",
"total_tax": "0.00",
"taxes": [
{
"id": 1,
"total": "0",
"subtotal": "0.4"
}
],
"meta_data": [],
"sku": "5555-A",
"price": 0.00
}
],
"coupon_lines": [
{
"id": 894,
"code": "30$off",
"discount": "30",
"discount_tax": "1.2",
"meta_data": [
{
"id": 6515,
"key": "coupon_data",
"value": {
"id": 673,
"code": "30$off",
"amount": "30",
"date_created": {
"date": "2017-10-29 18:20:07.000000",
"timezone_type": 3,
"timezone": "America/New_York"
},
"date_modified": {
"date": "2017-10-29 18:20:07.000000",
"timezone_type": 3,
"timezone": "America/New_York"
},
"date_expires": null,
"discount_type": "fixed_cart",
"description": "",
"usage_count": 2,
"individual_use": false,
"product_ids": [],
"excluded_product_ids": [],
"usage_limit": 0,
"usage_limit_per_user": 0,
"limit_usage_to_x_items": null,
"free_shipping": false,
"product_categories": [],
"excluded_product_categories": [],
"exclude_sale_items": false,
"minimum_amount": "",
"maximum_amount": "",
"email_restrictions": [],
"used_by": [
"1",
"1"
],
"virtual": false,
"meta_data": []
}
}
]
}
]
}
}

2 changes: 1 addition & 1 deletion RELEASE-NOTES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

13.9
-----

- [*] 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]

13.8
-----
Expand Down