Skip to content

Commit

Permalink
Create custom unmarshaller for orders (#100)
Browse files Browse the repository at this point in the history
* Create custom unmarshaller for orders

- We noticed an issue where some older orders were being sent
with line items that had their properties field set an empty
JSON object rather than the expected array. This was causing
an error when attempting to unmarshal.

* cleanup tests

Co-authored-by: Gord Currie <[email protected]>
  • Loading branch information
gordcurrie and Gord Currie authored Apr 13, 2020
1 parent c833331 commit 2fe6b77
Show file tree
Hide file tree
Showing 8 changed files with 533 additions and 0 deletions.
3 changes: 3 additions & 0 deletions fixtures/orderlineitems/properties_empty_object.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"properties": {}
}
3 changes: 3 additions & 0 deletions fixtures/orderlineitems/properties_invalid0.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"properties": {
}
5 changes: 5 additions & 0 deletions fixtures/orderlineitems/properties_invalid1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"properties": {
"name": 2
}
}
7 changes: 7 additions & 0 deletions fixtures/orderlineitems/properties_invalid2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"properties": [
{
"name": 2
}
]
}
6 changes: 6 additions & 0 deletions fixtures/orderlineitems/properties_object.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"properties": {
"name": "property 1",
"value": 3
}
}
88 changes: 88 additions & 0 deletions fixtures/orderlineitems/valid.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
{
"fulfillable_quantity": 1,
"fulfillment_service": "manual",
"fulfillment_status": "partial",
"gift_card": true,
"grams": 100,
"id": 254721536,
"name": "Soda",
"pre_tax_price": "9.00",
"price": "12.34",
"product_exists": true,
"product_id": 111475476,
"properties": [
{
"name": "note 1",
"value": "one"
},
{
"name": "note 2",
"value": 2
}
],
"quantity": 1,
"requires_shipping": true,
"sku": "sku-123",
"tax_lines": [
{
"price": 13.50,
"rate": 0.06,
"title": "State tax"
},
{
"price": 12.50,
"rate": 0.05,
"title": "Federal tax"
}
],
"taxable": true,
"title": "Soda Title",
"total_discount": "1.23",
"variant_id": 1234,
"variant_inventory_management": "shopify",
"variant_title": "Test Variant",
"vendor": "Test Vendor",
"origin_location": {
"id": 123,
"address1": "100 some street",
"address2": "",
"city": "Winnipeg",
"company": "Acme Corporation",
"country": "Canada",
"country_code": "CA",
"first_name": "Bob",
"last_name": "Smith",
"latitude": 49.811550,
"longitude": -97.189480,
"name": "test address",
"phone": "8675309",
"province": "Manitoba",
"province_code": "MB",
"zip": "R3Y 0L6"
},
"destination_location": {
"id": 124,
"address1": "200 some street",
"address2": "",
"city": "Winnipeg",
"company": "Acme Corporation",
"country": "Canada",
"country_code": "CA",
"first_name": "Bob",
"last_name": "Smith",
"latitude": 49.811550,
"longitude": -97.189480,
"name": "test address",
"phone": "8675309",
"province": "Manitoba",
"province_code": "MB",
"zip": "R3Y 0L6"
},
"applied_discount": {
"applied_discount": "test discount",
"description": "my test discount",
"value": "0.05",
"value_type": "percent",
"amount": "25.00"
}
}
39 changes: 39 additions & 0 deletions order.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package goshopify

import (
"encoding/json"
"fmt"
"net/http"
"time"
Expand Down Expand Up @@ -184,6 +185,43 @@ type LineItem struct {
AppliedDiscount *AppliedDiscount `json:"applied_discount,omitempty"`
}

// UnmarshalJSON custom unmarsaller for LineItem required to mitigate some older orders having LineItem.Properies
// which are empty JSON objects rather than the expected array.
func (li *LineItem) UnmarshalJSON(data []byte) error {
type alias LineItem
aux := &struct {
Properties json.RawMessage `json:"properties"`
*alias
}{alias: (*alias)(li)}

err := json.Unmarshal(data, &aux)
if err != nil {
return err
}
// if the first character is a '[' we unmarshal into an array
if len(aux.Properties) > 0 && aux.Properties[0] == '[' {
var p []NoteAttribute
err = json.Unmarshal(aux.Properties, &p)
if err != nil {
return err
}
li.Properties = p
} else { // else we unmarshal it into a struct
var p NoteAttribute
err = json.Unmarshal(aux.Properties, &p)
if err != nil {
return err
}
if p.Name == "" && p.Value == nil { // if the struct is empty we set properties to nil
li.Properties = nil
} else {
li.Properties = []NoteAttribute{p} // else we set them to an array with the property nested
}
}

return nil
}

type LineItemProperty struct {
Message string `json:"message"`
}
Expand Down Expand Up @@ -310,6 +348,7 @@ func (s *OrderServiceOp) ListWithPagination(options interface{}) ([]Order, *Pagi

return resource.Orders, pagination, nil
}

// Count orders
func (s *OrderServiceOp) Count(options interface{}) (int, error) {
path := fmt.Sprintf("%s/count.json", ordersBasePath)
Expand Down
Loading

0 comments on commit 2fe6b77

Please sign in to comment.