diff --git a/packages/medusa/src/api/routes/store/shipping-options/index.js b/packages/medusa/src/api/routes/store/shipping-options/index.js index e710b97798..ed2b50692e 100644 --- a/packages/medusa/src/api/routes/store/shipping-options/index.js +++ b/packages/medusa/src/api/routes/store/shipping-options/index.js @@ -6,6 +6,7 @@ const route = Router() export default app => { app.use("/shipping-options", route) + route.get("/", middlewares.wrap(require("./list-options").default)) route.get( "/:cart_id", middlewares.wrap(require("./list-shipping-options").default) diff --git a/packages/medusa/src/api/routes/store/shipping-options/list-options.js b/packages/medusa/src/api/routes/store/shipping-options/list-options.js new file mode 100644 index 0000000000..a785cdbc00 --- /dev/null +++ b/packages/medusa/src/api/routes/store/shipping-options/list-options.js @@ -0,0 +1,22 @@ +import { Validator, MedusaError } from "medusa-core-utils" + +export default async (req, res) => { + const productIds = + (req.query.product_ids && req.query.product_ids.split(",")) || [] + const regionId = req.query.region_id + + try { + const shippingProfileService = req.scope.resolve("shippingProfileService") + + const options = await shippingProfileService.fetchOptionsByProductIds( + productIds, + { + region_id: regionId, + } + ) + + res.status(200).json({ shipping_options: options }) + } catch (err) { + throw err + } +} diff --git a/packages/medusa/src/services/shipping-profile.js b/packages/medusa/src/services/shipping-profile.js index a6fdb668d1..cc81edf212 100644 --- a/packages/medusa/src/services/shipping-profile.js +++ b/packages/medusa/src/services/shipping-profile.js @@ -1,4 +1,3 @@ -import mongoose from "mongoose" import _ from "lodash" import { Validator, MedusaError } from "medusa-core-utils" import { BaseService } from "medusa-interfaces" @@ -52,6 +51,36 @@ class ShippingProfileService extends BaseService { return this.profileModel_.find(selector) } + async fetchOptionsByProductIds(productIds, filter) { + const profiles = await this.list({ products: { $in: productIds } }) + const optionIds = profiles.reduce( + (acc, next) => acc.concat(next.shipping_options), + [] + ) + + const options = await Promise.all( + optionIds.map(async oId => { + const option = await this.shippingOptionService_ + .retrieve(oId) + .catch(_ => undefined) + + if (!option) { + return null + } + + let canSend = true + if (filter.region_id) { + if (filter.region_id !== option.region_id) { + canSend = false + } + } + return canSend ? option : null + }) + ) + + return options.filter(o => !!o) + } + /** * Gets a profile by id. * Throws in case of DB Error and if profile was not found. @@ -297,7 +326,7 @@ class ShippingProfileService extends BaseService { const profile = await this.retrieve(profileId) return this.profileModel_.updateOne( - { _id: profileId }, + { _id: profile._id }, { $pull: { shipping_options: optionId } } ) } @@ -391,7 +420,7 @@ class ShippingProfileService extends BaseService { optionIds.map(async oId => { const option = await this.shippingOptionService_ .validateCartOption(oId, cart) - .catch(err => { + .catch(_ => { // If validation failed we skip the option return null })