-
Notifications
You must be signed in to change notification settings - Fork 2.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Properly create/remove/prune shipping records everywhere #2847
Changes from all commits
4aa4a5e
de5933d
b9e619e
da648a4
b94937d
5305b9d
22b5713
6f6d9ae
543b6f7
349a17f
3a7212b
a357d9e
569c069
2161e59
dc8ecae
2e647da
72c6d56
67befc5
35892a0
1f0c6c3
6096784
3e3eb0e
266b1d5
61efb98
3f9b058
d3418df
8afd110
ca58e66
1b4941a
0427418
3367dad
95a6d0b
5b0ec19
03ab67a
3923b8e
a5615e8
c507b71
5ce25b8
eb148d2
bd75724
3d60e1d
a904b79
81fec90
fa5d5c3
2994411
c659aeb
3f8edbf
feb9603
1643664
4314a50
c798c33
4341665
c9d9756
1c46531
3ac502d
db1307b
75c6bb3
6bd6562
55330ba
e6fdd9c
6d36a5e
b4e694b
8b5bd21
bac0a5e
304f605
a71fa92
94cd6a6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
import { check } from "meteor/check"; | ||
import { Meteor } from "meteor/meteor"; | ||
import { Shipping, Packages } from "/lib/collections"; | ||
import { Logger, Reaction, Hooks } from "/server/api"; | ||
import { Cart as CartSchema } from "/lib/collections/schemas"; | ||
|
@@ -34,20 +35,35 @@ function getShippingRates(previousQueryResults, cart) { | |
return previousQueryResults; | ||
} | ||
} | ||
if (!(cart.shipping && cart.shipping[0] && cart.shipping[0].address)) { | ||
|
||
// Verify that we have shipping records | ||
if (!cart.shipping || !cart.shipping.length) { | ||
const errorDetails = { | ||
requestStatus: "error", | ||
shippingProvider: "shippo", | ||
message: "The 'shipping' property of this cart is either missing or incomplete." | ||
shippingProvider: "flat-rate-shipping", | ||
message: "this cart is missing shipping records" | ||
}; | ||
rates.push(errorDetails); | ||
return [rates, retrialTargets]; | ||
return [[errorDetails], []]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My guess is we're returning an array of arrays here because we want to proceed to the next hook? Where does the error get logged or thrown? What does the empty array represent? I think some comments here would be good There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I feel like these comments are about the error handling techniques of the shipping method hooks which I am not creating or changing, just correcting the fact that it calls out the wrong shipment method. These comments are valid but probably better for a separate issue. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You were the reviewer on the PR (#2738) that introduced this pattern a few weeks ago and this is the first I've seen of this pattern. We can punt to a separate issue to fix this, but I'd like to understand what is happening here if you know. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I will go through the code and try to add comments to try and make this more clear. I do feel like the general pattern here makes sense and works well. It's a little challenging trying to deal with a series of Hooks that can be extended by any plugin and deal with feedback from each hook on how to proceed (do I retry?, etc.) especially since how they need to communicate is with a record on the cart. The timing of putting in this change while also dealing with multi-shop was extremely unfortunate however. |
||
} | ||
if (!(cart.items && cart.items[0] && cart.items[0].parcel)) { | ||
|
||
// Verify that we have a valid address to work with | ||
let shippingErrorDetails; | ||
if (cart.shipping.find((shippingRecord) => !shippingRecord.address)) { | ||
shippingErrorDetails = { | ||
requestStatus: "error", | ||
shippingProvider: "flat-rate-shipping", | ||
message: "The address property on one or more shipping records are incomplete" | ||
}; | ||
return [[shippingErrorDetails], []]; | ||
} | ||
|
||
// Validate that we have valid items to work with. We should never get here since we filter for this | ||
// at the cart level | ||
if (!cart.items || !cart.items.length) { | ||
const errorDetails = { | ||
requestStatus: "error", | ||
shippingProvider: "shippo", | ||
message: "This cart has no items, or the first item has no 'parcel' property." | ||
shippingProvider: "flat-rate-shipping", | ||
message: "this cart has no items" | ||
}; | ||
return [[errorDetails], []]; | ||
} | ||
|
@@ -58,21 +74,20 @@ function getShippingRates(previousQueryResults, cart) { | |
merchantShippingRates = marketplaceSettings.public.merchantShippingRates; | ||
} | ||
|
||
// TODO: Check to see if the merchantShippingRates flag is set in | ||
// marketplace and get rates from the correct shop. | ||
const pkgData = Packages.findOne({ | ||
name: "reaction-shipping-rates", | ||
shopId: Reaction.getPrimaryShopId() | ||
}); | ||
let pkgData; | ||
if (merchantShippingRates) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I can tell what's going on here, but might be nice to spell it out in comments There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added comments |
||
// TODO this needs to be rewritten to handle getting rates from each shops that's represented on the order | ||
Logger.fatal("Multiple shipping providers is currently not supported"); | ||
throw new Meteor.Error("not-implemented", "Multiple shipping providers is currently not supported"); | ||
} else { | ||
pkgData = Packages.findOne({ | ||
name: "reaction-shipping-rates", | ||
shopId: Reaction.getPrimaryShopId() | ||
}); | ||
} | ||
|
||
|
||
if (!pkgData || !cart.items || pkgData.settings.flatRates.enabled !== true) { | ||
const errorDetails = { | ||
requestStatus: "error", | ||
shippingProvider: "flat-rate-shipping", | ||
message: "Error. Flat rate shipping might be uninstalled or disabled, or your cart is empty." | ||
}; | ||
// There's no need for a retry in this case. | ||
rates.push(errorDetails); | ||
return [rates, retrialTargets]; | ||
} | ||
|
||
|
@@ -82,6 +97,8 @@ function getShippingRates(previousQueryResults, cart) { | |
"provider.enabled": true | ||
}; | ||
|
||
// Get rates from shops if merchantShippingRates is enabled | ||
// Otherwise just get them from the primaryShop | ||
if (merchantShippingRates) { | ||
// create an array of shops, allowing | ||
// the cart to have products from multiple shops | ||
|
@@ -90,7 +107,6 @@ function getShippingRates(previousQueryResults, cart) { | |
shops.push(product.shopId); | ||
} | ||
} | ||
|
||
// if we have multiple shops in cart | ||
if ((shops !== null ? shops.length : void 0) > 0) { | ||
selector = { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -32,19 +32,27 @@ function createShippoAddress(reactionAddress, email, purpose) { | |
|
||
// Creates a parcel object suitable for Shippo Api Calls given | ||
// a reaction product's parcel and units of measure for mass and distance | ||
function createShippoParcel(reactionParcel, reactionMassUnit, reactionDistanceUnit) { | ||
function createShippoParcel(reactionParcel, cartWeight, reactionMassUnit, reactionDistanceUnit) { | ||
const shippoParcel = { | ||
width: reactionParcel.width || "", | ||
length: reactionParcel.length || "", | ||
height: reactionParcel.height || "", | ||
weight: reactionParcel.weight || "", | ||
weight: cartWeight, | ||
distance_unit: reactionDistanceUnit, | ||
mass_unit: reactionMassUnit | ||
}; | ||
|
||
return shippoParcel; | ||
} | ||
|
||
function getTotalCartweight(cart) { | ||
const totalWeight = cart.items.reduce((sum, cartItem) => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should this be getting total weight by shop? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No. Right now we only do one call to Shippo. There's a lot more to be done to make Shippo actually work for multi-shop. (as in different quotes for different shops) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 Didn't realize this was within the Shippo plugin here. |
||
const itemWeight = cartItem.quantity * cartItem.parcel.weight; | ||
return sum + itemWeight; | ||
}, 0); | ||
return totalWeight; | ||
} | ||
|
||
// converts the Rates List fetched from the Shippo Api to Reaction Shipping Rates form | ||
function ratesParser(shippoRates, shippoDocs) { | ||
return shippoRates.map(rate => { | ||
|
@@ -411,7 +419,8 @@ export const methods = { | |
if (cart.items && cart.items[0] && cart.items[0].parcel) { | ||
const unitOfMeasure = shop && shop.baseUOM || "kg"; | ||
const unitOfLength = shop && shop.baseUOL || "cm"; | ||
shippoParcel = createShippoParcel(cart.items[0].parcel, unitOfMeasure, unitOfLength); | ||
const cartWeight = getTotalCartweight(cart); | ||
shippoParcel = createShippoParcel(cart.items[0].parcel, cartWeight, unitOfMeasure, unitOfLength); | ||
} else { | ||
errorDetails.message = "This cart has no items, or the first item has no 'parcel' property."; | ||
return [[errorDetails], []]; | ||
|
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be proper jsdoc using
@private
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed