Skip to content

Commit e73a2d1

Browse files
Stefaniamatteosuppo
authored andcommitted
implemented new shipping options (#2)
1 parent ce47ad9 commit e73a2d1

File tree

2 files changed

+252
-78
lines changed

2 files changed

+252
-78
lines changed

shopify/shopify.go

Lines changed: 190 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,10 @@ import (
2424
"fmt"
2525
"io/ioutil"
2626
"net/http"
27-
"net/http/cookiejar"
28-
"net/url"
2927
"strconv"
30-
"strings"
3128
"time"
3229

30+
"github.com/postmaster/postmaster-go"
3331
jww "github.com/spf13/jwalterweatherman"
3432
)
3533

@@ -47,6 +45,8 @@ type Shopify struct {
4745
Products []Product
4846
}
4947

48+
var tokens = []string{"f04c38b0b44ba72d222034452ce723ff"}
49+
5050
// NewClient inits shopify client
5151
func NewClient(domain string, secrettoken string, publicURL string) Shopify {
5252
shop := Shopify{shopifyDomain: domain, shopifySecretToken: secrettoken, shopifyPublicURL: publicURL}
@@ -171,96 +171,208 @@ func (shopifyClient *Shopify) PlaceOrder(order OrderResponse) (Order, error) {
171171
}
172172

173173
// ShippingOptions returns shipping options and rates for a given shipping address
174-
func (shopifyClient *Shopify) ShippingOptions(order Order) ([]ShippingRate, error) {
174+
func (shopifyClient *Shopify) ShippingOptions(order Order, postmasterKey string, additionalCharge float64) ([]ShippingRate, error) {
175175

176-
var itemsInfo []string
176+
//var itemsInfo []string
177177
var shopifyResponse = new(ShippingRatesResponse)
178178

179-
cartURLStr := "cart/"
180-
181-
// Create CART
182-
for _, itemObj := range order.Items {
183-
itemsInfo = append(itemsInfo, fmt.Sprintf("%d:%d", itemObj.VariantID, itemObj.Quantity))
184-
}
185-
186-
itemsInCartURLStr := cartURLStr + strings.Join(itemsInfo, ",")
187-
188-
completeURL := fmt.Sprintf("https://%s%s%s", shopifyClient.shopifyDomain, baseURLString, itemsInCartURLStr)
189-
jww.INFO.Printf("[ShippingOptions] - Request URL: %s", completeURL)
190-
cookieJar, _ := cookiejar.New(nil)
191-
192-
client := &http.Client{
193-
Jar: cookieJar,
194-
}
195-
196-
r, err := http.NewRequest("GET", completeURL, nil)
197-
resp, err := client.Do(r)
198-
199-
defer resp.Body.Close()
200-
201-
if err != nil {
202-
jww.ERROR.Printf("[ShippingOptions] - Error executing request : %s", err)
203-
return shopifyResponse.ShippingRates, err
204-
}
179+
// type ShippingRate struct {
180+
// Name string `json:"name"`
181+
// Code string `json:"code"`
182+
// Price string `json:"price"`
183+
// Source string `json:"source"`
184+
// DeliveryDate string `json:"delivery_date"`
185+
// DeliveryRange []string `json:"delivery_range"`
186+
// DeliveryDays []int `json:"delivery_days"`
187+
// }
188+
// type ShippingRatesResponse struct {
189+
// ShippingRates []ShippingRate `json:"shipping_rates"`
190+
// }
191+
//
205192

206-
// GET shipping Options given the cart (cookies used)
207193
address := order.ShippingAddress
208194

209-
urlStr := cartURLStr + "shipping_rates.json?"
195+
var pm *postmaster.Postmaster
196+
var rate *postmaster.RateMessage
197+
var quantity = order.Items[0].Quantity
210198

211-
v := url.Values{}
212-
v.Set("shipping_address[zip]", address.PostalCode)
213-
v.Add("shipping_address[country]", address.CountryCode)
214-
v.Add("shipping_address[province]", address.State)
215-
v.Encode()
199+
pm = postmaster.New(postmasterKey)
216200

217-
urlStr = urlStr + v.Encode()
201+
weight := 0.9 * float32(quantity)
202+
//jww.INFO.Printf("[ShippingOptions] - Items weight: %f", weight)
218203

219-
completeURL = fmt.Sprintf("%s%s", shopifyClient.shopifyPublicURL, urlStr)
220-
jww.INFO.Printf("[ShippingOptions] - Request URL: %s", completeURL)
221-
222-
r, err = http.NewRequest("GET", completeURL, nil)
223-
resp, err = client.Do(r)
224-
225-
defer resp.Body.Close()
226-
227-
if err != nil {
228-
jww.ERROR.Printf("[ShippingOptions] - Error executing request : %s", err)
229-
return shopifyResponse.ShippingRates, err
204+
rate = &postmaster.RateMessage{
205+
FromZip: "02143",
206+
ToZip: address.PostalCode,
207+
Weight: weight,
230208
}
209+
response, _ := pm.Rate(rate)
231210

232-
err = json.NewDecoder(resp.Body).Decode(shopifyResponse)
211+
responseBestRates := response.(*postmaster.RateResponseBest)
212+
//jww.INFO.Printf("[ShippingOptions] - Shipping Rates: %#v", responseBestRates.Rates)
233213

234-
if err != nil {
235-
jww.ERROR.Printf("[ShippingOptions] - Decoding error: %#v", err)
236-
jww.ERROR.Printf("[ShippingOptions] - Response: %#v", resp.Body)
237-
return shopifyResponse.ShippingRates, err
238-
}
214+
fedex := responseBestRates.Rates["fedex"]
215+
//usps := responseBestRates.Rates["usps"]
239216

240-
if shopifyResponse.Error != nil {
241-
genericError := errors.New(strings.Join(shopifyResponse.Error, ", "))
242-
return shopifyResponse.ShippingRates, genericError
243-
}
244-
245-
// Address not supported error handling
246-
if shopifyResponse.Country != nil || shopifyResponse.Zip != nil || shopifyResponse.Province != nil {
247-
var errorsArray []string
248-
errorMessageStr := "Address Not supported: "
249-
250-
if shopifyResponse.Country != nil {
251-
errorsArray = append(errorsArray, address.CountryCode+" "+shopifyResponse.Country[0])
252-
}
253-
if shopifyResponse.Zip != nil {
254-
errorsArray = append(errorsArray, address.PostalCode+" "+shopifyResponse.Zip[0])
255-
}
256-
if shopifyResponse.Province != nil {
257-
errorsArray = append(errorsArray, address.State+" "+shopifyResponse.Province[0])
258-
}
259-
errorMessageStr = errorMessageStr + strings.Join(errorsArray, ", ")
260-
addressNotSupported := errors.New(errorMessageStr)
261-
return shopifyResponse.ShippingRates, addressNotSupported
217+
if fedex.Charge == 0 {
218+
jww.ERROR.Printf("[ShippingOptions] - Weight too high")
219+
return shopifyResponse.ShippingRates, errors.New("Weight too high")
262220
}
263221

222+
fedexFloatPrice := float64(fedex.Charge)/100 + additionalCharge
223+
//uspsFloatPrice := float64(usps.Charge)/100 + additionalCharge
224+
225+
shopifyResponse.ShippingRates = append(shopifyResponse.ShippingRates, ShippingRate{Name: "FedEx Ground", Code: "FEDEX_GROUND", Source: "fedex", Price: strconv.FormatFloat(fedexFloatPrice, 'f', 2, 64)})
226+
//shopifyResponse.ShippingRates = append(shopifyResponse.ShippingRates, ShippingRate{Name: "USPS", Code: usps.Service, Source: "usps", Price: strconv.FormatFloat(uspsFloatPrice, 'f', 2, 64)})
227+
228+
//jww.INFO.Printf("[ShippingOptions] - Shipping Rates: %#v", shopifyResponse.ShippingRates)
229+
// cartURLStr := "cart/"
230+
// //cartjsonURL := "cart.json"
231+
//
232+
// // Create CART
233+
// for _, itemObj := range order.Items {
234+
// itemsInfo = append(itemsInfo, fmt.Sprintf("%d:%d", itemObj.VariantID, itemObj.Quantity))
235+
// }
236+
//
237+
// itemsInCartURLStr := cartURLStr + strings.Join(itemsInfo, ",")
238+
//
239+
// storeURL := fmt.Sprintf("https://%s%s", shopifyClient.shopifyDomain, baseURLString)
240+
// completeURL := fmt.Sprintf("%s%s", storeURL, itemsInCartURLStr)
241+
// jww.INFO.Printf("[ShippingOptions] - Request URL: %s", completeURL)
242+
//
243+
// //cartjsonCompleteURL := fmt.Sprintf("%s%s", storeURL, cartjsonURL)
244+
//
245+
// cookieJar, _ := cookiejar.New(nil)
246+
//
247+
// u, _ := url.Parse(storeURL)
248+
//
249+
// client := &http.Client{
250+
// Jar: cookieJar,
251+
// }
252+
//
253+
// // SET CART request
254+
// r, err := http.NewRequest("GET", completeURL, nil)
255+
// resp, err := client.Do(r)
256+
// defer resp.Body.Close()
257+
//
258+
// cookies := cookieJar.Cookies(u)
259+
// for i := 0; i < len(cookies); i++ {
260+
// jww.INFO.Printf("\n\n")
261+
// jww.INFO.Printf("[ShippingOptions] - CookieJar : %d: %#v\n", i, cookies[i])
262+
// cookies[i].Domain = storeURL
263+
// cookies[i].Path = "/"
264+
// }
265+
266+
// HTMLCartData, err := ioutil.ReadAll(resp.Body)
267+
// jww.INFO.Printf("BODY RESPONSE: %s", string(HTMLCartData))
268+
// //tokenFound, _ := regexp.MatchString("Shopify.Checkout.token = \"([a-zA-Z0-9]+)\"", string(HTMLData2))
269+
// regex, _ := regexp.Compile("Shopify.Checkout.token = \"([a-zA-Z0-9]+)\"")
270+
// tokenFound := regex.FindStringSubmatch(string(HTMLCartData))
271+
// token := tokenFound[1]
272+
// jww.INFO.Printf("[ShippingOptions] - Found Token: %s", token)
273+
274+
// fetch CART request
275+
// jww.INFO.Printf("[ShippingOptions] - CART Request URL: %s", cartjsonCompleteURL)
276+
// r, err = http.NewRequest("GET", cartjsonCompleteURL, nil)
277+
// r.Header.Set("User-Agent", `Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.80 Safari/537.36`)
278+
//
279+
// jww.INFO.Printf("-----")
280+
// for i, v := range r.Header {
281+
// jww.INFO.Printf("\n\n")
282+
// jww.INFO.Printf("\n\n")
283+
// jww.INFO.Printf("[ShippingOptions] - Cart.json header %#v: %#v", i, v)
284+
// }
285+
// jww.INFO.Printf("-----")
286+
//
287+
// resp, err = client.Do(r)
288+
// defer resp.Body.Close()
289+
//
290+
// //err = json.NewDecoder(resp.Body).Decode(shopifyCartResponse)
291+
// htmlData, err := ioutil.ReadAll(resp.Body)
292+
// jww.INFO.Printf("[ShippingOptions] - Cart.json response %s", string(htmlData))
293+
// // jww.INFO.Printf("\n\n")
294+
// HTMLData, err := ioutil.ReadAll(resp.Body)
295+
// jww.INFO.Printf("BODY RESPONSE: %s", string(HTMLData))
296+
// jww.INFO.Printf(shopifyCartResponse.Token)
297+
// jww.INFO.Printf("\n\n")
298+
//
299+
// cartCookie := &http.Cookie{Name: "cart", Value: tokens[0]}
300+
// shopifyCookie1 := &http.Cookie{Name: "_shopify_s", Value: "E7C1EB87-1A90-4119-399E"}
301+
// shopifyCookie2 := &http.Cookie{Name: "_shopify_y", Value: "5C976DB8-DF8F-4CCB-B585"}
302+
// cookiesList3 := append(cookies, cartCookie)
303+
// cookiesList2 := append(cookiesList3, shopifyCookie1)
304+
// cookiesList := append(cookiesList2, shopifyCookie2)
305+
// cookieJar.SetCookies(u, cookiesList)
306+
//
307+
// if err != nil {
308+
// jww.ERROR.Printf("[ShippingOptions] - Error executing request : %s", err)
309+
// return shopifyResponse.ShippingRates, err
310+
// }
311+
//
312+
// // GET shipping Options given the cart (cookies used)
313+
// address := order.ShippingAddress
314+
//
315+
// urlStr := cartURLStr + "shipping_rates.json?"
316+
// v := url.Values{}
317+
// v.Set("shipping_address[zip]", address.PostalCode)
318+
// v.Add("shipping_address[country]", address.CountryCode)
319+
// v.Add("shipping_address[province]", address.State)
320+
// v.Encode()
321+
// urlStr = urlStr + v.Encode()
322+
//
323+
// completeURL = fmt.Sprintf("%s%s", shopifyClient.shopifyPublicURL, urlStr)
324+
// jww.INFO.Printf("[ShippingOptions] - Request URL: %s", completeURL)
325+
//
326+
// // fetch shipping options request
327+
// r, err = http.NewRequest("GET", completeURL, nil)
328+
// resp, err = client.Do(r)
329+
// defer resp.Body.Close()
330+
//
331+
// cookies = cookieJar.Cookies(u)
332+
// for i := 0; i < len(cookies); i++ {
333+
// jww.INFO.Printf("\n\n")
334+
// jww.INFO.Printf("[ShippingOptions] - CookieJar : %d: %#v\n", i, cookies[i])
335+
// }
336+
//
337+
// if err != nil {
338+
// jww.ERROR.Printf("[ShippingOptions] - Error executing request : %s", err)
339+
// return shopifyResponse.ShippingRates, err
340+
// }
341+
//
342+
// err = json.NewDecoder(resp.Body).Decode(shopifyResponse)
343+
//
344+
// if err != nil {
345+
// jww.ERROR.Printf("[ShippingOptions] - Decoding error: %#v", err)
346+
// jww.ERROR.Printf("[ShippingOptions] - Response: %#v", resp.Body)
347+
// return shopifyResponse.ShippingRates, err
348+
// }
349+
//
350+
// if shopifyResponse.Error != nil {
351+
// genericError := errors.New(strings.Join(shopifyResponse.Error, ", "))
352+
// jww.ERROR.Printf("[ShippingOptions] - Generic Error: %s", genericError)
353+
// return shopifyResponse.ShippingRates, genericError
354+
// }
355+
//
356+
// // Address not supported error handling
357+
// if shopifyResponse.Country != nil || shopifyResponse.Zip != nil || shopifyResponse.Province != nil {
358+
// var errorsArray []string
359+
// errorMessageStr := "Address Not supported: "
360+
//
361+
// if shopifyResponse.Country != nil {
362+
// errorsArray = append(errorsArray, address.CountryCode+" "+shopifyResponse.Country[0])
363+
// }
364+
// if shopifyResponse.Zip != nil {
365+
// errorsArray = append(errorsArray, address.PostalCode+" "+shopifyResponse.Zip[0])
366+
// }
367+
// if shopifyResponse.Province != nil {
368+
// errorsArray = append(errorsArray, address.State+" "+shopifyResponse.Province[0])
369+
// }
370+
// errorMessageStr = errorMessageStr + strings.Join(errorsArray, ", ")
371+
// addressNotSupported := errors.New(errorMessageStr)
372+
// return shopifyResponse.ShippingRates, addressNotSupported
373+
// }
374+
//
375+
// jww.INFO.Printf("[ShippingOptions] - Shipping Rates: %#v", shopifyResponse.ShippingRates)
264376
return shopifyResponse.ShippingRates, nil
265377
}
266378

shopify/shopifycart.go

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
Copyright 2015 Arduino LLC (http://www.arduino.cc/)
3+
4+
This file is part of go-shopify.
5+
6+
go-shopify is free software: you can redistribute it and/or modify
7+
it under the terms of the GNU General Public License as published by
8+
the Free Software Foundation, version 3 of the License,
9+
go-shopify is distributed in the hope that it will be useful,
10+
but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
GNU General Public License for more details.
13+
14+
You should have received a copy of the GNU General Public License
15+
along with go-shopify. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
/*
19+
{
20+
"token": "f04c38b0b44ba72d222034452ce723ff",
21+
"note": null,
22+
"attributes": {},
23+
"total_price": 500,
24+
"total_discount": 0,
25+
"total_weight": 3997,
26+
"item_count": 10,
27+
"items": [{
28+
"id": 2171133763,
29+
"properties": null,
30+
"quantity": 10,
31+
"variant_id": 2171133763,
32+
"title": "Logistic Services for AutoDesk Arduino Basic Kit",
33+
"price": 50,
34+
"line_price": 500,
35+
"total_discount": 0,
36+
"discounts": [],
37+
"sku": "AKX00001",
38+
"grams": 400,
39+
"vendor": "Arduino LLC",
40+
"product_id": 769682435,
41+
"gift_card": false,
42+
"url": "\/products\/logistic-services-for-autodesk-arduino-basic-kit?variant=2171133763",
43+
"image": "https:\/\/cdn.shopify.com\/s\/files\/1\/0870\/7082\/products\/AKX00001_Bk_3_Front.jpg?v=1433317209",
44+
"handle": "logistic-services-for-autodesk-arduino-basic-kit",
45+
"requires_shipping": true,
46+
"product_type": "",
47+
"product_title": "Logistic Services for AutoDesk Arduino Basic Kit",
48+
"product_description": "This kit contains all the components you need to build simple projects and learn how to turn an idea into reality using Arduino. At arduino.cc\/basicstarterkit you will find the step-by-step tutorials to realise 15 simple projects.",
49+
"variant_title": null,
50+
"variant_options": ["Default Title"]
51+
}],
52+
"requires_shipping": true
53+
}
54+
*/
55+
56+
package shopify
57+
58+
// CartResponse models the shopify API response for cart
59+
type CartResponse struct {
60+
Token string `json:"token"`
61+
Note string `json:"note,omitempty"`
62+
}

0 commit comments

Comments
 (0)