vendure-ecommerce / vendure

The commerce platform with customization in its DNA.
https://www.vendure.io
Other
5.6k stars 991 forks source link

Ability to return multiples prices in ShippingCalculator response #399

Closed jonyw4 closed 3 months ago

jonyw4 commented 4 years ago

I have a plugin using ShippingCalculator that returns multiple prices from a carrier. Would be nice to get all prices in one request and return these values in ShippingCalculator. Today the ShippingCalculator must return a object with the price and metadata, maybe transform this response to an array could solve the problem.

michaelbromley commented 4 years ago

Can you clarify to me why a given carrier would have more than one price?

jonyw4 commented 4 years ago

Ok. I have an example. Here in Brazil, I use a service called Melhor Envio its really similar to GoShippo, it's multi-carrier shipping software for e-commerce. If I make a request in this software with the package box dimensions and postal code, they return to me a response with all carriers and options with price and delivery time.

So, If I need to integrate this solution in Vendure it's easy, but I can only return just one value per shipping method. If the provider has 3 carriers to simulate shipping, I need to create 3 shipping methods in vendure, which its fine to me... But to return all values I will need to make 3 requests to the same provider.

michaelbromley commented 4 years ago

OK thanks for the explanation. I'll leave this open and let's see if in future others also have this requirement.

For now, you'll have to do it as 3 separate shipping methods as you said. You could perhaps get around the 3 API calls issue by creating a service which calls Melhor Envio and caches the request for a short period of time, so each ShippingMethod shares the same API call & response.

jonyw4 commented 4 years ago

This is a really good workaround @michaelbromley! How I can cache this values in Vendure? Do you have some ideia?

michaelbromley commented 4 years ago

I would create a service, e.g. CarrierService (name it whatever makes most sense of course) and then expose a getShippingCosts(order) method.

The first time it gets called, it makes the API call and then stores the resulting Promise in a JavaScript Map object, with the order id as the key. Subsequent calls to the getShippingCosts method with the same order id would just return that stored promise rather than making a new API call.

Once the API call resolves, all 3 callers of the getShippingCosts method will have the data they need. You'll have to implement some mechanism to then clear the cache or maybe also store the time that the API call was made, and if it was longer than e.g. 5 seconds ago, then make a fresh call.

jonyw4 commented 4 years ago

I love the ideia. I will try to implement that in my MelhorEnvio ShippingCalculator

barakamwakisha commented 10 months ago

I have this requirement as well. Integrating with ShipStation, there are multiple carriers e.g. UPS, USPS, DHL and each of these carriers have multiple services all with different prices e.g. UPS® Ground, UPS Next Day Air®, USPS Priority Mail - Package et al.

martijnvdbrug commented 3 months ago

@barakamwakisha Have you found a workaround or solution for this?

Although I understand the use case, I feel like it's 'wrong' to have the shipping calculator return multiple prices, because the prices returned from the mentioned API's are actually multiple shipping methods, not 1 single method, right?

The caching option seems like the way to go, but maybe we should create a guide/tutorial/docs somewhere that explains this case, as it's pretty common.

Closing it for now, because it can already be done, but needs documenting.

Please feel free to reopen this issue if you think it requires any core changes

michaelbromley commented 3 months ago

There's a related issue that has been explored more recently, which might make it into a future major version since it is a breaking change: